1*2d9fd380Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2*2d9fd380Sjfb8856606 *
3*2d9fd380Sjfb8856606 * Copyright(c) 2019-2020 Xilinx, Inc.
4*2d9fd380Sjfb8856606 * Copyright(c) 2018-2019 Solarflare Communications Inc.
5*2d9fd380Sjfb8856606 */
6*2d9fd380Sjfb8856606
7*2d9fd380Sjfb8856606 #include "efx.h"
8*2d9fd380Sjfb8856606 #include "efx_impl.h"
9*2d9fd380Sjfb8856606
10*2d9fd380Sjfb8856606 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER
11*2d9fd380Sjfb8856606
12*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_init(__in efx_nic_t * enp)13*2d9fd380Sjfb8856606 ef10_proxy_auth_init(
14*2d9fd380Sjfb8856606 __in efx_nic_t *enp)
15*2d9fd380Sjfb8856606 {
16*2d9fd380Sjfb8856606 EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
17*2d9fd380Sjfb8856606
18*2d9fd380Sjfb8856606 return (0);
19*2d9fd380Sjfb8856606 }
20*2d9fd380Sjfb8856606
21*2d9fd380Sjfb8856606 void
ef10_proxy_auth_fini(__in efx_nic_t * enp)22*2d9fd380Sjfb8856606 ef10_proxy_auth_fini(
23*2d9fd380Sjfb8856606 __in efx_nic_t *enp)
24*2d9fd380Sjfb8856606 {
25*2d9fd380Sjfb8856606 EFSYS_ASSERT(EFX_FAMILY_IS_EF10(enp));
26*2d9fd380Sjfb8856606 }
27*2d9fd380Sjfb8856606
28*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_mcdi_proxy_configure(__in efx_nic_t * enp,__in boolean_t disable_proxy,__in uint64_t req_buffer_addr,__in uint64_t resp_buffer_addr,__in uint64_t stat_buffer_addr,__in size_t req_size,__in size_t resp_size,__in uint32_t block_cnt,__in uint8_t * op_maskp,__in size_t op_mask_size)29*2d9fd380Sjfb8856606 efx_mcdi_proxy_configure(
30*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
31*2d9fd380Sjfb8856606 __in boolean_t disable_proxy,
32*2d9fd380Sjfb8856606 __in uint64_t req_buffer_addr,
33*2d9fd380Sjfb8856606 __in uint64_t resp_buffer_addr,
34*2d9fd380Sjfb8856606 __in uint64_t stat_buffer_addr,
35*2d9fd380Sjfb8856606 __in size_t req_size,
36*2d9fd380Sjfb8856606 __in size_t resp_size,
37*2d9fd380Sjfb8856606 __in uint32_t block_cnt,
38*2d9fd380Sjfb8856606 __in uint8_t *op_maskp,
39*2d9fd380Sjfb8856606 __in size_t op_mask_size)
40*2d9fd380Sjfb8856606 {
41*2d9fd380Sjfb8856606 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN,
42*2d9fd380Sjfb8856606 MC_CMD_PROXY_CONFIGURE_OUT_LEN);
43*2d9fd380Sjfb8856606 efx_mcdi_req_t req;
44*2d9fd380Sjfb8856606 efx_rc_t rc;
45*2d9fd380Sjfb8856606
46*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PROXY_CONFIGURE;
47*2d9fd380Sjfb8856606 req.emr_in_buf = payload;
48*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PROXY_CONFIGURE_EXT_IN_LEN;
49*2d9fd380Sjfb8856606 req.emr_out_buf = payload;
50*2d9fd380Sjfb8856606 req.emr_out_length = MC_CMD_PROXY_CONFIGURE_OUT_LEN;
51*2d9fd380Sjfb8856606
52*2d9fd380Sjfb8856606 if (!disable_proxy) {
53*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_FLAGS, 1);
54*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_LO,
55*2d9fd380Sjfb8856606 req_buffer_addr & 0xffffffff);
56*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BUFF_ADDR_HI,
57*2d9fd380Sjfb8856606 req_buffer_addr >> 32);
58*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_LO,
59*2d9fd380Sjfb8856606 resp_buffer_addr & 0xffffffff);
60*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BUFF_ADDR_HI,
61*2d9fd380Sjfb8856606 resp_buffer_addr >> 32);
62*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_LO,
63*2d9fd380Sjfb8856606 stat_buffer_addr & 0xffffffff);
64*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BUFF_ADDR_HI,
65*2d9fd380Sjfb8856606 stat_buffer_addr >> 32);
66*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REQUEST_BLOCK_SIZE,
67*2d9fd380Sjfb8856606 req_size);
68*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_REPLY_BLOCK_SIZE,
69*2d9fd380Sjfb8856606 resp_size);
70*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_STATUS_BLOCK_SIZE,
71*2d9fd380Sjfb8856606 MC_PROXY_STATUS_BUFFER_LEN);
72*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_IN_NUM_BLOCKS,
73*2d9fd380Sjfb8856606 block_cnt);
74*2d9fd380Sjfb8856606 memcpy(MCDI_IN2(req, efx_byte_t,
75*2d9fd380Sjfb8856606 PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK),
76*2d9fd380Sjfb8856606 op_maskp, op_mask_size);
77*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_CONFIGURE_EXT_IN_RESERVED,
78*2d9fd380Sjfb8856606 EFX_PROXY_CONFIGURE_MAGIC);
79*2d9fd380Sjfb8856606 }
80*2d9fd380Sjfb8856606
81*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
82*2d9fd380Sjfb8856606
83*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
84*2d9fd380Sjfb8856606 rc = req.emr_rc;
85*2d9fd380Sjfb8856606 goto fail1;
86*2d9fd380Sjfb8856606 }
87*2d9fd380Sjfb8856606
88*2d9fd380Sjfb8856606 return (0);
89*2d9fd380Sjfb8856606
90*2d9fd380Sjfb8856606 fail1:
91*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
92*2d9fd380Sjfb8856606 return (rc);
93*2d9fd380Sjfb8856606 }
94*2d9fd380Sjfb8856606
95*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_mcdi_privilege_modify(__in efx_nic_t * enp,__in uint32_t fn_group,__in uint32_t pf_index,__in uint32_t vf_index,__in uint32_t add_privileges_mask,__in uint32_t remove_privileges_mask)96*2d9fd380Sjfb8856606 efx_mcdi_privilege_modify(
97*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
98*2d9fd380Sjfb8856606 __in uint32_t fn_group,
99*2d9fd380Sjfb8856606 __in uint32_t pf_index,
100*2d9fd380Sjfb8856606 __in uint32_t vf_index,
101*2d9fd380Sjfb8856606 __in uint32_t add_privileges_mask,
102*2d9fd380Sjfb8856606 __in uint32_t remove_privileges_mask)
103*2d9fd380Sjfb8856606 {
104*2d9fd380Sjfb8856606 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MODIFY_IN_LEN,
105*2d9fd380Sjfb8856606 MC_CMD_PRIVILEGE_MODIFY_OUT_LEN);
106*2d9fd380Sjfb8856606 efx_mcdi_req_t req;
107*2d9fd380Sjfb8856606 efx_rc_t rc;
108*2d9fd380Sjfb8856606
109*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PRIVILEGE_MODIFY;
110*2d9fd380Sjfb8856606 req.emr_in_buf = payload;
111*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PRIVILEGE_MODIFY_IN_LEN;
112*2d9fd380Sjfb8856606 req.emr_out_buf = payload;
113*2d9fd380Sjfb8856606 req.emr_out_length = MC_CMD_PRIVILEGE_MODIFY_OUT_LEN;
114*2d9fd380Sjfb8856606
115*2d9fd380Sjfb8856606 EFSYS_ASSERT(fn_group <= MC_CMD_PRIVILEGE_MODIFY_IN_ONE);
116*2d9fd380Sjfb8856606
117*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_FN_GROUP, fn_group);
118*2d9fd380Sjfb8856606
119*2d9fd380Sjfb8856606 if ((fn_group == MC_CMD_PRIVILEGE_MODIFY_IN_ONE) ||
120*2d9fd380Sjfb8856606 (fn_group == MC_CMD_PRIVILEGE_MODIFY_IN_VFS_OF_PF)) {
121*2d9fd380Sjfb8856606 MCDI_IN_POPULATE_DWORD_2(req,
122*2d9fd380Sjfb8856606 PRIVILEGE_MODIFY_IN_FUNCTION,
123*2d9fd380Sjfb8856606 PRIVILEGE_MODIFY_IN_FUNCTION_PF, pf_index,
124*2d9fd380Sjfb8856606 PRIVILEGE_MODIFY_IN_FUNCTION_VF, vf_index);
125*2d9fd380Sjfb8856606 }
126*2d9fd380Sjfb8856606
127*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_ADD_MASK,
128*2d9fd380Sjfb8856606 add_privileges_mask);
129*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PRIVILEGE_MODIFY_IN_REMOVE_MASK,
130*2d9fd380Sjfb8856606 remove_privileges_mask);
131*2d9fd380Sjfb8856606
132*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
133*2d9fd380Sjfb8856606
134*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
135*2d9fd380Sjfb8856606 rc = req.emr_rc;
136*2d9fd380Sjfb8856606 goto fail1;
137*2d9fd380Sjfb8856606 }
138*2d9fd380Sjfb8856606
139*2d9fd380Sjfb8856606 return (0);
140*2d9fd380Sjfb8856606
141*2d9fd380Sjfb8856606 fail1:
142*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
143*2d9fd380Sjfb8856606 return (rc);
144*2d9fd380Sjfb8856606 }
145*2d9fd380Sjfb8856606
146*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_proxy_auth_fill_op_mask(__in_ecount (op_count)uint32_t * op_listp,__in size_t op_count,__out_ecount (op_mask_size)uint32_t * op_maskp,__in size_t op_mask_size)147*2d9fd380Sjfb8856606 efx_proxy_auth_fill_op_mask(
148*2d9fd380Sjfb8856606 __in_ecount(op_count) uint32_t *op_listp,
149*2d9fd380Sjfb8856606 __in size_t op_count,
150*2d9fd380Sjfb8856606 __out_ecount(op_mask_size) uint32_t *op_maskp,
151*2d9fd380Sjfb8856606 __in size_t op_mask_size)
152*2d9fd380Sjfb8856606 {
153*2d9fd380Sjfb8856606 efx_rc_t rc;
154*2d9fd380Sjfb8856606 uint32_t op;
155*2d9fd380Sjfb8856606
156*2d9fd380Sjfb8856606 if ((op_listp == NULL) || (op_maskp == NULL)) {
157*2d9fd380Sjfb8856606 rc = EINVAL;
158*2d9fd380Sjfb8856606 goto fail1;
159*2d9fd380Sjfb8856606 }
160*2d9fd380Sjfb8856606
161*2d9fd380Sjfb8856606 while (op_count--) {
162*2d9fd380Sjfb8856606 op = *op_listp++;
163*2d9fd380Sjfb8856606 if (op > op_mask_size * 32) {
164*2d9fd380Sjfb8856606 rc = EINVAL;
165*2d9fd380Sjfb8856606 goto fail2;
166*2d9fd380Sjfb8856606 }
167*2d9fd380Sjfb8856606 op_maskp[op / 32] |= 1u << (op & 31);
168*2d9fd380Sjfb8856606 }
169*2d9fd380Sjfb8856606
170*2d9fd380Sjfb8856606 return (0);
171*2d9fd380Sjfb8856606
172*2d9fd380Sjfb8856606 fail2:
173*2d9fd380Sjfb8856606 EFSYS_PROBE(fail2);
174*2d9fd380Sjfb8856606 fail1:
175*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
176*2d9fd380Sjfb8856606 return (rc);
177*2d9fd380Sjfb8856606 }
178*2d9fd380Sjfb8856606
179*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_mc_config(__in efx_nic_t * enp,__in_ecount (block_cnt)efsys_mem_t * request_bufferp,__in_ecount (block_cnt)efsys_mem_t * response_bufferp,__in_ecount (block_cnt)efsys_mem_t * status_bufferp,__in uint32_t block_cnt,__in_ecount (op_count)uint32_t * op_listp,__in size_t op_count)180*2d9fd380Sjfb8856606 ef10_proxy_auth_mc_config(
181*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
182*2d9fd380Sjfb8856606 __in_ecount(block_cnt) efsys_mem_t *request_bufferp,
183*2d9fd380Sjfb8856606 __in_ecount(block_cnt) efsys_mem_t *response_bufferp,
184*2d9fd380Sjfb8856606 __in_ecount(block_cnt) efsys_mem_t *status_bufferp,
185*2d9fd380Sjfb8856606 __in uint32_t block_cnt,
186*2d9fd380Sjfb8856606 __in_ecount(op_count) uint32_t *op_listp,
187*2d9fd380Sjfb8856606 __in size_t op_count)
188*2d9fd380Sjfb8856606 {
189*2d9fd380Sjfb8856606 #define PROXY_OPS_MASK_SIZE \
190*2d9fd380Sjfb8856606 (EFX_DIV_ROUND_UP( \
191*2d9fd380Sjfb8856606 MC_CMD_PROXY_CONFIGURE_IN_ALLOWED_MCDI_MASK_LEN, \
192*2d9fd380Sjfb8856606 sizeof (uint32_t)))
193*2d9fd380Sjfb8856606
194*2d9fd380Sjfb8856606 efx_rc_t rc;
195*2d9fd380Sjfb8856606 uint32_t op_mask[PROXY_OPS_MASK_SIZE] = {0};
196*2d9fd380Sjfb8856606
197*2d9fd380Sjfb8856606 /* Prepare the operation mask from operation list array */
198*2d9fd380Sjfb8856606 if ((rc = efx_proxy_auth_fill_op_mask(op_listp, op_count,
199*2d9fd380Sjfb8856606 op_mask, PROXY_OPS_MASK_SIZE) != 0))
200*2d9fd380Sjfb8856606 goto fail1;
201*2d9fd380Sjfb8856606
202*2d9fd380Sjfb8856606 if ((rc = efx_mcdi_proxy_configure(enp, B_FALSE,
203*2d9fd380Sjfb8856606 EFSYS_MEM_ADDR(request_bufferp),
204*2d9fd380Sjfb8856606 EFSYS_MEM_ADDR(response_bufferp),
205*2d9fd380Sjfb8856606 EFSYS_MEM_ADDR(status_bufferp),
206*2d9fd380Sjfb8856606 EFSYS_MEM_SIZE(request_bufferp) / block_cnt,
207*2d9fd380Sjfb8856606 EFSYS_MEM_SIZE(response_bufferp) / block_cnt,
208*2d9fd380Sjfb8856606 block_cnt, (uint8_t *)&op_mask,
209*2d9fd380Sjfb8856606 sizeof (op_mask))) != 0)
210*2d9fd380Sjfb8856606 goto fail2;
211*2d9fd380Sjfb8856606
212*2d9fd380Sjfb8856606 return (0);
213*2d9fd380Sjfb8856606
214*2d9fd380Sjfb8856606 fail2:
215*2d9fd380Sjfb8856606 EFSYS_PROBE(fail2);
216*2d9fd380Sjfb8856606
217*2d9fd380Sjfb8856606 fail1:
218*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
219*2d9fd380Sjfb8856606 return (rc);
220*2d9fd380Sjfb8856606 }
221*2d9fd380Sjfb8856606
222*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_disable(__in efx_nic_t * enp)223*2d9fd380Sjfb8856606 ef10_proxy_auth_disable(
224*2d9fd380Sjfb8856606 __in efx_nic_t *enp)
225*2d9fd380Sjfb8856606 {
226*2d9fd380Sjfb8856606 efx_rc_t rc;
227*2d9fd380Sjfb8856606
228*2d9fd380Sjfb8856606 if ((rc = efx_mcdi_proxy_configure(enp, B_TRUE,
229*2d9fd380Sjfb8856606 0, 0, 0, 0, 0, 0, NULL, 0) != 0))
230*2d9fd380Sjfb8856606 goto fail1;
231*2d9fd380Sjfb8856606
232*2d9fd380Sjfb8856606 return (0);
233*2d9fd380Sjfb8856606
234*2d9fd380Sjfb8856606 fail1:
235*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
236*2d9fd380Sjfb8856606 return (rc);
237*2d9fd380Sjfb8856606 }
238*2d9fd380Sjfb8856606
239*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_privilege_modify(__in efx_nic_t * enp,__in uint32_t fn_group,__in uint32_t pf_index,__in uint32_t vf_index,__in uint32_t add_privileges_mask,__in uint32_t remove_privileges_mask)240*2d9fd380Sjfb8856606 ef10_proxy_auth_privilege_modify(
241*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
242*2d9fd380Sjfb8856606 __in uint32_t fn_group,
243*2d9fd380Sjfb8856606 __in uint32_t pf_index,
244*2d9fd380Sjfb8856606 __in uint32_t vf_index,
245*2d9fd380Sjfb8856606 __in uint32_t add_privileges_mask,
246*2d9fd380Sjfb8856606 __in uint32_t remove_privileges_mask)
247*2d9fd380Sjfb8856606 {
248*2d9fd380Sjfb8856606 return (efx_mcdi_privilege_modify(enp, fn_group, pf_index, vf_index,
249*2d9fd380Sjfb8856606 add_privileges_mask, remove_privileges_mask));
250*2d9fd380Sjfb8856606 }
251*2d9fd380Sjfb8856606
252*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_mcdi_privilege_mask_set(__in efx_nic_t * enp,__in uint32_t vf_index,__in uint32_t mask,__in uint32_t value)253*2d9fd380Sjfb8856606 efx_mcdi_privilege_mask_set(
254*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
255*2d9fd380Sjfb8856606 __in uint32_t vf_index,
256*2d9fd380Sjfb8856606 __in uint32_t mask,
257*2d9fd380Sjfb8856606 __in uint32_t value)
258*2d9fd380Sjfb8856606 {
259*2d9fd380Sjfb8856606 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PRIVILEGE_MASK_IN_LEN,
260*2d9fd380Sjfb8856606 MC_CMD_PRIVILEGE_MASK_OUT_LEN);
261*2d9fd380Sjfb8856606 efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
262*2d9fd380Sjfb8856606 efx_mcdi_req_t req;
263*2d9fd380Sjfb8856606 efx_rc_t rc;
264*2d9fd380Sjfb8856606 uint32_t old_mask = 0;
265*2d9fd380Sjfb8856606 uint32_t new_mask = 0;
266*2d9fd380Sjfb8856606
267*2d9fd380Sjfb8856606 EFSYS_ASSERT((value & ~mask) == 0);
268*2d9fd380Sjfb8856606
269*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
270*2d9fd380Sjfb8856606 req.emr_in_buf = payload;
271*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
272*2d9fd380Sjfb8856606 req.emr_out_buf = payload;
273*2d9fd380Sjfb8856606 req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
274*2d9fd380Sjfb8856606
275*2d9fd380Sjfb8856606 /* Get privilege mask */
276*2d9fd380Sjfb8856606 MCDI_IN_POPULATE_DWORD_2(req, PRIVILEGE_MASK_IN_FUNCTION,
277*2d9fd380Sjfb8856606 PRIVILEGE_MASK_IN_FUNCTION_PF, encp->enc_pf,
278*2d9fd380Sjfb8856606 PRIVILEGE_MASK_IN_FUNCTION_VF, vf_index);
279*2d9fd380Sjfb8856606
280*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
281*2d9fd380Sjfb8856606
282*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
283*2d9fd380Sjfb8856606 rc = req.emr_rc;
284*2d9fd380Sjfb8856606 goto fail1;
285*2d9fd380Sjfb8856606 }
286*2d9fd380Sjfb8856606
287*2d9fd380Sjfb8856606 if (req.emr_out_length_used != MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
288*2d9fd380Sjfb8856606 rc = EMSGSIZE;
289*2d9fd380Sjfb8856606 goto fail2;
290*2d9fd380Sjfb8856606 }
291*2d9fd380Sjfb8856606
292*2d9fd380Sjfb8856606 old_mask = *MCDI_OUT2(req, uint32_t, PRIVILEGE_MASK_OUT_OLD_MASK);
293*2d9fd380Sjfb8856606 new_mask = old_mask & ~mask;
294*2d9fd380Sjfb8856606 new_mask |= (value & mask);
295*2d9fd380Sjfb8856606
296*2d9fd380Sjfb8856606 if (new_mask == old_mask)
297*2d9fd380Sjfb8856606 return (0);
298*2d9fd380Sjfb8856606
299*2d9fd380Sjfb8856606 new_mask |= MC_CMD_PRIVILEGE_MASK_IN_DO_CHANGE;
300*2d9fd380Sjfb8856606 memset(payload, 0, sizeof (payload));
301*2d9fd380Sjfb8856606
302*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PRIVILEGE_MASK;
303*2d9fd380Sjfb8856606 req.emr_in_buf = payload;
304*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PRIVILEGE_MASK_IN_LEN;
305*2d9fd380Sjfb8856606 req.emr_out_buf = payload;
306*2d9fd380Sjfb8856606 req.emr_out_length = MC_CMD_PRIVILEGE_MASK_OUT_LEN;
307*2d9fd380Sjfb8856606
308*2d9fd380Sjfb8856606 /* Set privilege mask */
309*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PRIVILEGE_MASK_IN_NEW_MASK, new_mask);
310*2d9fd380Sjfb8856606
311*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
312*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
313*2d9fd380Sjfb8856606 rc = req.emr_rc;
314*2d9fd380Sjfb8856606 goto fail3;
315*2d9fd380Sjfb8856606 }
316*2d9fd380Sjfb8856606
317*2d9fd380Sjfb8856606 if (req.emr_out_length_used != MC_CMD_PRIVILEGE_MASK_OUT_LEN) {
318*2d9fd380Sjfb8856606 rc = EMSGSIZE;
319*2d9fd380Sjfb8856606 goto fail4;
320*2d9fd380Sjfb8856606 }
321*2d9fd380Sjfb8856606
322*2d9fd380Sjfb8856606 return (0);
323*2d9fd380Sjfb8856606
324*2d9fd380Sjfb8856606 fail4:
325*2d9fd380Sjfb8856606 EFSYS_PROBE(fail4);
326*2d9fd380Sjfb8856606 fail3:
327*2d9fd380Sjfb8856606 EFSYS_PROBE(fail3);
328*2d9fd380Sjfb8856606 fail2:
329*2d9fd380Sjfb8856606 EFSYS_PROBE(fail2);
330*2d9fd380Sjfb8856606 fail1:
331*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
332*2d9fd380Sjfb8856606 return (rc);
333*2d9fd380Sjfb8856606 }
334*2d9fd380Sjfb8856606
335*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_set_privilege_mask(__in efx_nic_t * enp,__in uint32_t vf_index,__in uint32_t mask,__in uint32_t value)336*2d9fd380Sjfb8856606 ef10_proxy_auth_set_privilege_mask(
337*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
338*2d9fd380Sjfb8856606 __in uint32_t vf_index,
339*2d9fd380Sjfb8856606 __in uint32_t mask,
340*2d9fd380Sjfb8856606 __in uint32_t value)
341*2d9fd380Sjfb8856606 {
342*2d9fd380Sjfb8856606 return (efx_mcdi_privilege_mask_set(enp, vf_index,
343*2d9fd380Sjfb8856606 mask, value));
344*2d9fd380Sjfb8856606 }
345*2d9fd380Sjfb8856606
346*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_mcdi_proxy_complete(__in efx_nic_t * enp,__in uint32_t fn_index,__in uint32_t proxy_result,__in uint32_t handle)347*2d9fd380Sjfb8856606 efx_mcdi_proxy_complete(
348*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
349*2d9fd380Sjfb8856606 __in uint32_t fn_index,
350*2d9fd380Sjfb8856606 __in uint32_t proxy_result,
351*2d9fd380Sjfb8856606 __in uint32_t handle)
352*2d9fd380Sjfb8856606 {
353*2d9fd380Sjfb8856606 EFX_MCDI_DECLARE_BUF(payload, MC_CMD_PROXY_COMPLETE_IN_LEN,
354*2d9fd380Sjfb8856606 MC_CMD_PROXY_COMPLETE_OUT_LEN);
355*2d9fd380Sjfb8856606 efx_mcdi_req_t req;
356*2d9fd380Sjfb8856606 efx_rc_t rc;
357*2d9fd380Sjfb8856606
358*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PROXY_COMPLETE;
359*2d9fd380Sjfb8856606 req.emr_in_buf = payload;
360*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PROXY_COMPLETE_IN_LEN;
361*2d9fd380Sjfb8856606 req.emr_out_buf = payload;
362*2d9fd380Sjfb8856606 req.emr_out_length = MC_CMD_PROXY_COMPLETE_OUT_LEN;
363*2d9fd380Sjfb8856606
364*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_BLOCK_INDEX, fn_index);
365*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_STATUS, proxy_result);
366*2d9fd380Sjfb8856606 MCDI_IN_SET_DWORD(req, PROXY_COMPLETE_IN_HANDLE, handle);
367*2d9fd380Sjfb8856606
368*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
369*2d9fd380Sjfb8856606
370*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
371*2d9fd380Sjfb8856606 rc = req.emr_rc;
372*2d9fd380Sjfb8856606 goto fail1;
373*2d9fd380Sjfb8856606 }
374*2d9fd380Sjfb8856606
375*2d9fd380Sjfb8856606 return (0);
376*2d9fd380Sjfb8856606
377*2d9fd380Sjfb8856606 fail1:
378*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
379*2d9fd380Sjfb8856606 return (rc);
380*2d9fd380Sjfb8856606 }
381*2d9fd380Sjfb8856606
382*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_complete_request(__in efx_nic_t * enp,__in uint32_t fn_index,__in uint32_t proxy_result,__in uint32_t handle)383*2d9fd380Sjfb8856606 ef10_proxy_auth_complete_request(
384*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
385*2d9fd380Sjfb8856606 __in uint32_t fn_index,
386*2d9fd380Sjfb8856606 __in uint32_t proxy_result,
387*2d9fd380Sjfb8856606 __in uint32_t handle)
388*2d9fd380Sjfb8856606 {
389*2d9fd380Sjfb8856606 return (efx_mcdi_proxy_complete(enp, fn_index,
390*2d9fd380Sjfb8856606 proxy_result, handle));
391*2d9fd380Sjfb8856606 }
392*2d9fd380Sjfb8856606
393*2d9fd380Sjfb8856606 static __checkReturn efx_rc_t
efx_mcdi_proxy_cmd(__in efx_nic_t * enp,__in uint32_t pf_index,__in uint32_t vf_index,__in_bcount (request_size)uint8_t * request_bufferp,__in size_t request_size,__out_bcount (response_size)uint8_t * response_bufferp,__in size_t response_size,__out_opt size_t * response_size_actualp)394*2d9fd380Sjfb8856606 efx_mcdi_proxy_cmd(
395*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
396*2d9fd380Sjfb8856606 __in uint32_t pf_index,
397*2d9fd380Sjfb8856606 __in uint32_t vf_index,
398*2d9fd380Sjfb8856606 __in_bcount(request_size) uint8_t *request_bufferp,
399*2d9fd380Sjfb8856606 __in size_t request_size,
400*2d9fd380Sjfb8856606 __out_bcount(response_size) uint8_t *response_bufferp,
401*2d9fd380Sjfb8856606 __in size_t response_size,
402*2d9fd380Sjfb8856606 __out_opt size_t *response_size_actualp)
403*2d9fd380Sjfb8856606 {
404*2d9fd380Sjfb8856606 efx_dword_t *inbufp;
405*2d9fd380Sjfb8856606 efx_mcdi_req_t req;
406*2d9fd380Sjfb8856606 efx_rc_t rc;
407*2d9fd380Sjfb8856606
408*2d9fd380Sjfb8856606 if (request_size % sizeof (*inbufp) != 0) {
409*2d9fd380Sjfb8856606 rc = EINVAL;
410*2d9fd380Sjfb8856606 goto fail1;
411*2d9fd380Sjfb8856606 }
412*2d9fd380Sjfb8856606
413*2d9fd380Sjfb8856606 EFSYS_KMEM_ALLOC(enp, (MC_CMD_PROXY_CMD_IN_LEN + request_size), inbufp);
414*2d9fd380Sjfb8856606
415*2d9fd380Sjfb8856606 req.emr_cmd = MC_CMD_PROXY_CMD;
416*2d9fd380Sjfb8856606 req.emr_in_buf = (uint8_t *) inbufp;
417*2d9fd380Sjfb8856606 req.emr_in_length = MC_CMD_PROXY_CMD_IN_LEN + request_size;
418*2d9fd380Sjfb8856606 req.emr_out_buf = response_bufferp;
419*2d9fd380Sjfb8856606 req.emr_out_length = response_size;
420*2d9fd380Sjfb8856606
421*2d9fd380Sjfb8856606 MCDI_IN_POPULATE_DWORD_2(req, PROXY_CMD_IN_TARGET,
422*2d9fd380Sjfb8856606 PROXY_CMD_IN_TARGET_PF, pf_index,
423*2d9fd380Sjfb8856606 PROXY_CMD_IN_TARGET_VF, vf_index);
424*2d9fd380Sjfb8856606
425*2d9fd380Sjfb8856606 /* Proxied command should be located just after PROXY_CMD */
426*2d9fd380Sjfb8856606 memcpy(&inbufp[MC_CMD_PROXY_CMD_IN_LEN / sizeof (*inbufp)],
427*2d9fd380Sjfb8856606 request_bufferp, request_size);
428*2d9fd380Sjfb8856606
429*2d9fd380Sjfb8856606 efx_mcdi_execute(enp, &req);
430*2d9fd380Sjfb8856606
431*2d9fd380Sjfb8856606 EFSYS_KMEM_FREE(enp, (MC_CMD_PROXY_CMD_IN_LEN + request_size), inbufp);
432*2d9fd380Sjfb8856606 if (req.emr_rc != 0) {
433*2d9fd380Sjfb8856606 rc = req.emr_rc;
434*2d9fd380Sjfb8856606 goto fail2;
435*2d9fd380Sjfb8856606 }
436*2d9fd380Sjfb8856606
437*2d9fd380Sjfb8856606 if (response_size_actualp != NULL)
438*2d9fd380Sjfb8856606 *response_size_actualp = req.emr_out_length_used;
439*2d9fd380Sjfb8856606
440*2d9fd380Sjfb8856606 return (0);
441*2d9fd380Sjfb8856606
442*2d9fd380Sjfb8856606 fail2:
443*2d9fd380Sjfb8856606 EFSYS_PROBE(fail2);
444*2d9fd380Sjfb8856606 fail1:
445*2d9fd380Sjfb8856606 EFSYS_PROBE1(fail1, efx_rc_t, rc);
446*2d9fd380Sjfb8856606 return (rc);
447*2d9fd380Sjfb8856606 }
448*2d9fd380Sjfb8856606
449*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_get_privilege_mask(__in efx_nic_t * enp,__in uint32_t pf_index,__in uint32_t vf_index,__out uint32_t * maskp)450*2d9fd380Sjfb8856606 ef10_proxy_auth_get_privilege_mask(
451*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
452*2d9fd380Sjfb8856606 __in uint32_t pf_index,
453*2d9fd380Sjfb8856606 __in uint32_t vf_index,
454*2d9fd380Sjfb8856606 __out uint32_t *maskp)
455*2d9fd380Sjfb8856606 {
456*2d9fd380Sjfb8856606 return (efx_mcdi_privilege_mask(enp, pf_index, vf_index, maskp));
457*2d9fd380Sjfb8856606 }
458*2d9fd380Sjfb8856606
459*2d9fd380Sjfb8856606
460*2d9fd380Sjfb8856606 __checkReturn efx_rc_t
ef10_proxy_auth_exec_cmd(__in efx_nic_t * enp,__inout efx_proxy_cmd_params_t * paramsp)461*2d9fd380Sjfb8856606 ef10_proxy_auth_exec_cmd(
462*2d9fd380Sjfb8856606 __in efx_nic_t *enp,
463*2d9fd380Sjfb8856606 __inout efx_proxy_cmd_params_t *paramsp)
464*2d9fd380Sjfb8856606 {
465*2d9fd380Sjfb8856606 return (efx_mcdi_proxy_cmd(enp, paramsp->pf_index, paramsp->vf_index,
466*2d9fd380Sjfb8856606 paramsp->request_bufferp, paramsp->request_size,
467*2d9fd380Sjfb8856606 paramsp->response_bufferp, paramsp->response_size,
468*2d9fd380Sjfb8856606 paramsp->response_size_actualp));
469*2d9fd380Sjfb8856606 }
470*2d9fd380Sjfb8856606 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */
471