1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2018-2019 Solarflare Communications Inc. 5 */ 6 7 #include "efx.h" 8 #include "efx_impl.h" 9 10 #if EFSYS_OPT_MCDI_PROXY_AUTH_SERVER 11 12 #if EFSYS_OPT_SIENA 13 static const efx_proxy_ops_t __efx_proxy_dummy_ops = { 14 NULL, /* epo_init */ 15 NULL, /* epo_fini */ 16 NULL, /* epo_mc_config */ 17 NULL, /* epo_disable */ 18 NULL, /* epo_privilege_modify */ 19 NULL, /* epo_set_privilege_mask */ 20 NULL, /* epo_complete_request */ 21 NULL, /* epo_exec_cmd */ 22 NULL, /* epo_get_privilege_mask */ 23 }; 24 #endif /* EFSYS_OPT_SIENA */ 25 26 #if EFX_OPTS_EF10() 27 static const efx_proxy_ops_t __efx_proxy_ef10_ops = { 28 ef10_proxy_auth_init, /* epo_init */ 29 ef10_proxy_auth_fini, /* epo_fini */ 30 ef10_proxy_auth_mc_config, /* epo_mc_config */ 31 ef10_proxy_auth_disable, /* epo_disable */ 32 ef10_proxy_auth_privilege_modify, /* epo_privilege_modify */ 33 ef10_proxy_auth_set_privilege_mask, /* epo_set_privilege_mask */ 34 ef10_proxy_auth_complete_request, /* epo_complete_request */ 35 ef10_proxy_auth_exec_cmd, /* epo_exec_cmd */ 36 ef10_proxy_auth_get_privilege_mask, /* epo_get_privilege_mask */ 37 }; 38 #endif /* EFX_OPTS_EF10() */ 39 40 __checkReturn efx_rc_t 41 efx_proxy_auth_init( 42 __in efx_nic_t *enp) 43 { 44 const efx_proxy_ops_t *epop; 45 efx_rc_t rc; 46 47 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 48 EFSYS_ASSERT3U(enp->en_mod_flags, &, EFX_MOD_PROBE); 49 EFSYS_ASSERT(!(enp->en_mod_flags & EFX_MOD_PROXY)); 50 51 switch (enp->en_family) { 52 #if EFSYS_OPT_SIENA 53 case EFX_FAMILY_SIENA: 54 epop = &__efx_proxy_dummy_ops; 55 break; 56 #endif /* EFSYS_OPT_SIENA */ 57 58 #if EFSYS_OPT_HUNTINGTON 59 case EFX_FAMILY_HUNTINGTON: 60 epop = &__efx_proxy_ef10_ops; 61 break; 62 #endif /* EFSYS_OPT_HUNTINGTON */ 63 64 #if EFSYS_OPT_MEDFORD 65 case EFX_FAMILY_MEDFORD: 66 epop = &__efx_proxy_ef10_ops; 67 break; 68 #endif /* EFSYS_OPT_MEDFORD */ 69 70 #if EFSYS_OPT_MEDFORD2 71 case EFX_FAMILY_MEDFORD2: 72 epop = &__efx_proxy_ef10_ops; 73 break; 74 #endif /* EFSYS_OPT_MEDFORD2 */ 75 76 default: 77 EFSYS_ASSERT(0); 78 rc = ENOTSUP; 79 goto fail1; 80 } 81 82 if (epop->epo_init == NULL) { 83 rc = ENOTSUP; 84 goto fail2; 85 } 86 87 if ((rc = epop->epo_init(enp)) != 0) 88 goto fail3; 89 90 enp->en_epop = epop; 91 enp->en_mod_flags |= EFX_MOD_PROXY; 92 return (0); 93 94 fail3: 95 EFSYS_PROBE(fail3); 96 fail2: 97 EFSYS_PROBE(fail2); 98 fail1: 99 EFSYS_PROBE1(fail1, efx_rc_t, rc); 100 101 return (rc); 102 } 103 104 void 105 efx_proxy_auth_fini( 106 __in efx_nic_t *enp) 107 { 108 const efx_proxy_ops_t *epop = enp->en_epop; 109 110 EFSYS_ASSERT3U(enp->en_magic, ==, EFX_NIC_MAGIC); 111 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROBE); 112 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 113 114 if ((epop != NULL) && (epop->epo_fini != NULL)) 115 epop->epo_fini(enp); 116 117 enp->en_epop = NULL; 118 enp->en_mod_flags &= ~EFX_MOD_PROXY; 119 } 120 121 __checkReturn efx_rc_t 122 efx_proxy_auth_configure( 123 __in efx_nic_t *enp, 124 __in efx_proxy_auth_config_t *configp) 125 { 126 const efx_proxy_ops_t *epop = enp->en_epop; 127 efx_rc_t rc; 128 129 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 130 131 if ((configp == NULL) || 132 (configp->request_bufferp == NULL) || 133 (configp->response_bufferp == NULL) || 134 (configp->status_bufferp == NULL) || 135 (configp->op_listp == NULL) || 136 (configp->block_cnt == 0)) { 137 rc = EINVAL; 138 goto fail1; 139 } 140 141 if ((epop->epo_mc_config == NULL) || 142 (epop->epo_privilege_modify == NULL)) { 143 rc = ENOTSUP; 144 goto fail2; 145 } 146 147 rc = epop->epo_mc_config(enp, configp->request_bufferp, 148 configp->response_bufferp, configp->status_bufferp, 149 configp->block_cnt, configp->op_listp, 150 configp->op_count); 151 if (rc != 0) 152 goto fail3; 153 154 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL, 155 0, 0, 0, configp->handled_privileges); 156 if (rc != 0) 157 goto fail4; 158 159 return (0); 160 161 fail4: 162 EFSYS_PROBE(fail4); 163 fail3: 164 EFSYS_PROBE(fail3); 165 fail2: 166 EFSYS_PROBE(fail2); 167 fail1: 168 EFSYS_PROBE1(fail1, efx_rc_t, rc); 169 return (rc); 170 } 171 172 __checkReturn efx_rc_t 173 efx_proxy_auth_destroy( 174 __in efx_nic_t *enp, 175 __in uint32_t handled_privileges) 176 { 177 const efx_proxy_ops_t *epop = enp->en_epop; 178 efx_rc_t rc; 179 180 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 181 182 if ((epop->epo_disable == NULL) || 183 (epop->epo_privilege_modify == NULL)) { 184 rc = ENOTSUP; 185 goto fail1; 186 } 187 188 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ALL, 189 0, 0, handled_privileges, 0); 190 if (rc != 0) 191 goto fail2; 192 193 rc = epop->epo_disable(enp); 194 if (rc != 0) 195 goto fail3; 196 197 return (0); 198 199 fail3: 200 EFSYS_PROBE(fail3); 201 fail2: 202 EFSYS_PROBE(fail2); 203 fail1: 204 EFSYS_PROBE1(fail1, efx_rc_t, rc); 205 return (rc); 206 } 207 208 __checkReturn efx_rc_t 209 efx_proxy_auth_complete_request( 210 __in efx_nic_t *enp, 211 __in uint32_t fn_index, 212 __in uint32_t proxy_result, 213 __in uint32_t handle) 214 { 215 const efx_proxy_ops_t *epop = enp->en_epop; 216 efx_rc_t rc; 217 218 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 219 220 if (epop->epo_complete_request == NULL) { 221 rc = ENOTSUP; 222 goto fail1; 223 } 224 225 rc = epop->epo_complete_request(enp, fn_index, proxy_result, handle); 226 if (rc != 0) 227 goto fail2; 228 229 return (0); 230 fail2: 231 EFSYS_PROBE(fail2); 232 fail1: 233 EFSYS_PROBE1(fail1, efx_rc_t, rc); 234 return (rc); 235 } 236 237 __checkReturn efx_rc_t 238 efx_proxy_auth_exec_cmd( 239 __in efx_nic_t *enp, 240 __inout efx_proxy_cmd_params_t *paramsp) 241 { 242 const efx_proxy_ops_t *epop = enp->en_epop; 243 efx_rc_t rc; 244 245 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 246 247 if (paramsp == NULL) { 248 rc = EINVAL; 249 goto fail1; 250 } 251 252 if (epop->epo_exec_cmd == NULL) { 253 rc = ENOTSUP; 254 goto fail2; 255 } 256 257 rc = epop->epo_exec_cmd(enp, paramsp); 258 if (rc != 0) 259 goto fail3; 260 261 return (0); 262 fail3: 263 EFSYS_PROBE(fail3); 264 fail2: 265 EFSYS_PROBE(fail2); 266 fail1: 267 EFSYS_PROBE1(fail1, efx_rc_t, rc); 268 return (rc); 269 } 270 271 __checkReturn efx_rc_t 272 efx_proxy_auth_set_privilege_mask( 273 __in efx_nic_t *enp, 274 __in uint32_t vf_index, 275 __in uint32_t mask, 276 __in uint32_t value) 277 { 278 const efx_proxy_ops_t *epop = enp->en_epop; 279 efx_rc_t rc; 280 281 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 282 283 if (epop->epo_set_privilege_mask == NULL) { 284 rc = ENOTSUP; 285 goto fail1; 286 } 287 288 rc = epop->epo_set_privilege_mask(enp, vf_index, mask, value); 289 if (rc != 0) 290 goto fail2; 291 292 return (0); 293 294 fail2: 295 EFSYS_PROBE(fail2); 296 fail1: 297 EFSYS_PROBE1(fail1, efx_rc_t, rc); 298 return (rc); 299 } 300 301 __checkReturn efx_rc_t 302 efx_proxy_auth_privilege_mask_get( 303 __in efx_nic_t *enp, 304 __in uint32_t pf_index, 305 __in uint32_t vf_index, 306 __out uint32_t *maskp) 307 { 308 const efx_proxy_ops_t *epop = enp->en_epop; 309 efx_rc_t rc; 310 311 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 312 313 if (epop->epo_get_privilege_mask == NULL) { 314 rc = ENOTSUP; 315 goto fail1; 316 } 317 318 rc = epop->epo_get_privilege_mask(enp, pf_index, vf_index, maskp); 319 if (rc != 0) 320 goto fail2; 321 322 return (0); 323 324 fail2: 325 EFSYS_PROBE(fail2); 326 fail1: 327 EFSYS_PROBE1(fail1, efx_rc_t, rc); 328 return (rc); 329 } 330 331 __checkReturn efx_rc_t 332 efx_proxy_auth_privilege_modify( 333 __in efx_nic_t *enp, 334 __in uint32_t pf_index, 335 __in uint32_t vf_index, 336 __in uint32_t add_privileges_mask, 337 __in uint32_t remove_privileges_mask) 338 { 339 const efx_proxy_ops_t *epop = enp->en_epop; 340 efx_rc_t rc; 341 342 EFSYS_ASSERT(enp->en_mod_flags & EFX_MOD_PROXY); 343 344 if (epop->epo_privilege_modify == NULL) { 345 rc = ENOTSUP; 346 goto fail1; 347 } 348 349 rc = epop->epo_privilege_modify(enp, MC_CMD_PRIVILEGE_MODIFY_IN_ONE, 350 pf_index, vf_index, add_privileges_mask, 351 remove_privileges_mask); 352 if (rc != 0) 353 goto fail2; 354 355 return (0); 356 357 fail2: 358 EFSYS_PROBE(fail2); 359 fail1: 360 EFSYS_PROBE1(fail1, efx_rc_t, rc); 361 return (rc); 362 } 363 364 #endif /* EFSYS_OPT_MCDI_PROXY_AUTH_SERVER */ 365