162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright (C) 2021, Intel Corporation. */ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci/* Inter-Driver Communication */ 562306a36Sopenharmony_ci#include "ice.h" 662306a36Sopenharmony_ci#include "ice_lib.h" 762306a36Sopenharmony_ci#include "ice_dcb_lib.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_cistatic DEFINE_XARRAY_ALLOC1(ice_aux_id); 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/** 1262306a36Sopenharmony_ci * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct 1362306a36Sopenharmony_ci * @pf: pointer to PF struct 1462306a36Sopenharmony_ci * 1562306a36Sopenharmony_ci * This function has to be called with a device_lock on the 1662306a36Sopenharmony_ci * pf->adev.dev to avoid race conditions. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_cistatic struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci struct auxiliary_device *adev; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci adev = pf->adev; 2362306a36Sopenharmony_ci if (!adev || !adev->dev.driver) 2462306a36Sopenharmony_ci return NULL; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci return container_of(adev->dev.driver, struct iidc_auxiliary_drv, 2762306a36Sopenharmony_ci adrv.driver); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/** 3162306a36Sopenharmony_ci * ice_send_event_to_aux - send event to RDMA AUX driver 3262306a36Sopenharmony_ci * @pf: pointer to PF struct 3362306a36Sopenharmony_ci * @event: event struct 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_civoid ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci struct iidc_auxiliary_drv *iadrv; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (WARN_ON_ONCE(!in_task())) 4062306a36Sopenharmony_ci return; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci mutex_lock(&pf->adev_mutex); 4362306a36Sopenharmony_ci if (!pf->adev) 4462306a36Sopenharmony_ci goto finish; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci device_lock(&pf->adev->dev); 4762306a36Sopenharmony_ci iadrv = ice_get_auxiliary_drv(pf); 4862306a36Sopenharmony_ci if (iadrv && iadrv->event_handler) 4962306a36Sopenharmony_ci iadrv->event_handler(pf, event); 5062306a36Sopenharmony_ci device_unlock(&pf->adev->dev); 5162306a36Sopenharmony_cifinish: 5262306a36Sopenharmony_ci mutex_unlock(&pf->adev_mutex); 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci/** 5662306a36Sopenharmony_ci * ice_add_rdma_qset - Add Leaf Node for RDMA Qset 5762306a36Sopenharmony_ci * @pf: PF struct 5862306a36Sopenharmony_ci * @qset: Resource to be allocated 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ciint ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS]; 6362306a36Sopenharmony_ci struct ice_vsi *vsi; 6462306a36Sopenharmony_ci struct device *dev; 6562306a36Sopenharmony_ci u32 qset_teid; 6662306a36Sopenharmony_ci u16 qs_handle; 6762306a36Sopenharmony_ci int status; 6862306a36Sopenharmony_ci int i; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci if (WARN_ON(!pf || !qset)) 7162306a36Sopenharmony_ci return -EINVAL; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci dev = ice_pf_to_dev(pf); 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci if (!ice_is_rdma_ena(pf)) 7662306a36Sopenharmony_ci return -EINVAL; 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci vsi = ice_get_main_vsi(pf); 7962306a36Sopenharmony_ci if (!vsi) { 8062306a36Sopenharmony_ci dev_err(dev, "RDMA QSet invalid VSI\n"); 8162306a36Sopenharmony_ci return -EINVAL; 8262306a36Sopenharmony_ci } 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci ice_for_each_traffic_class(i) 8562306a36Sopenharmony_ci max_rdmaqs[i] = 0; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci max_rdmaqs[qset->tc]++; 8862306a36Sopenharmony_ci qs_handle = qset->qs_handle; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc, 9162306a36Sopenharmony_ci max_rdmaqs); 9262306a36Sopenharmony_ci if (status) { 9362306a36Sopenharmony_ci dev_err(dev, "Failed VSI RDMA Qset config\n"); 9462306a36Sopenharmony_ci return status; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc, 9862306a36Sopenharmony_ci &qs_handle, 1, &qset_teid); 9962306a36Sopenharmony_ci if (status) { 10062306a36Sopenharmony_ci dev_err(dev, "Failed VSI RDMA Qset enable\n"); 10162306a36Sopenharmony_ci return status; 10262306a36Sopenharmony_ci } 10362306a36Sopenharmony_ci vsi->qset_handle[qset->tc] = qset->qs_handle; 10462306a36Sopenharmony_ci qset->teid = qset_teid; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_add_rdma_qset); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci/** 11162306a36Sopenharmony_ci * ice_del_rdma_qset - Delete leaf node for RDMA Qset 11262306a36Sopenharmony_ci * @pf: PF struct 11362306a36Sopenharmony_ci * @qset: Resource to be freed 11462306a36Sopenharmony_ci */ 11562306a36Sopenharmony_ciint ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci struct ice_vsi *vsi; 11862306a36Sopenharmony_ci u32 teid; 11962306a36Sopenharmony_ci u16 q_id; 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci if (WARN_ON(!pf || !qset)) 12262306a36Sopenharmony_ci return -EINVAL; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci vsi = ice_find_vsi(pf, qset->vport_id); 12562306a36Sopenharmony_ci if (!vsi) { 12662306a36Sopenharmony_ci dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n"); 12762306a36Sopenharmony_ci return -EINVAL; 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci q_id = qset->qs_handle; 13162306a36Sopenharmony_ci teid = qset->teid; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci vsi->qset_handle[qset->tc] = 0; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id); 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_del_rdma_qset); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci/** 14062306a36Sopenharmony_ci * ice_rdma_request_reset - accept request from RDMA to perform a reset 14162306a36Sopenharmony_ci * @pf: struct for PF 14262306a36Sopenharmony_ci * @reset_type: type of reset 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ciint ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type) 14562306a36Sopenharmony_ci{ 14662306a36Sopenharmony_ci enum ice_reset_req reset; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci if (WARN_ON(!pf)) 14962306a36Sopenharmony_ci return -EINVAL; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci switch (reset_type) { 15262306a36Sopenharmony_ci case IIDC_PFR: 15362306a36Sopenharmony_ci reset = ICE_RESET_PFR; 15462306a36Sopenharmony_ci break; 15562306a36Sopenharmony_ci case IIDC_CORER: 15662306a36Sopenharmony_ci reset = ICE_RESET_CORER; 15762306a36Sopenharmony_ci break; 15862306a36Sopenharmony_ci case IIDC_GLOBR: 15962306a36Sopenharmony_ci reset = ICE_RESET_GLOBR; 16062306a36Sopenharmony_ci break; 16162306a36Sopenharmony_ci default: 16262306a36Sopenharmony_ci dev_err(ice_pf_to_dev(pf), "incorrect reset request\n"); 16362306a36Sopenharmony_ci return -EINVAL; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci return ice_schedule_reset(pf, reset); 16762306a36Sopenharmony_ci} 16862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_rdma_request_reset); 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/** 17162306a36Sopenharmony_ci * ice_rdma_update_vsi_filter - update main VSI filters for RDMA 17262306a36Sopenharmony_ci * @pf: pointer to struct for PF 17362306a36Sopenharmony_ci * @vsi_id: VSI HW idx to update filter on 17462306a36Sopenharmony_ci * @enable: bool whether to enable or disable filters 17562306a36Sopenharmony_ci */ 17662306a36Sopenharmony_ciint ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci struct ice_vsi *vsi; 17962306a36Sopenharmony_ci int status; 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci if (WARN_ON(!pf)) 18262306a36Sopenharmony_ci return -EINVAL; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci vsi = ice_find_vsi(pf, vsi_id); 18562306a36Sopenharmony_ci if (!vsi) 18662306a36Sopenharmony_ci return -EINVAL; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable); 18962306a36Sopenharmony_ci if (status) { 19062306a36Sopenharmony_ci dev_err(ice_pf_to_dev(pf), "Failed to %sable RDMA filtering\n", 19162306a36Sopenharmony_ci enable ? "en" : "dis"); 19262306a36Sopenharmony_ci } else { 19362306a36Sopenharmony_ci if (enable) 19462306a36Sopenharmony_ci vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 19562306a36Sopenharmony_ci else 19662306a36Sopenharmony_ci vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN; 19762306a36Sopenharmony_ci } 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci return status; 20062306a36Sopenharmony_ci} 20162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci/** 20462306a36Sopenharmony_ci * ice_get_qos_params - parse QoS params for RDMA consumption 20562306a36Sopenharmony_ci * @pf: pointer to PF struct 20662306a36Sopenharmony_ci * @qos: set of QoS values 20762306a36Sopenharmony_ci */ 20862306a36Sopenharmony_civoid ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci struct ice_dcbx_cfg *dcbx_cfg; 21162306a36Sopenharmony_ci unsigned int i; 21262306a36Sopenharmony_ci u32 up2tc; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg; 21562306a36Sopenharmony_ci up2tc = rd32(&pf->hw, PRTDCB_TUP2TC); 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg); 21862306a36Sopenharmony_ci for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++) 21962306a36Sopenharmony_ci qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) 22262306a36Sopenharmony_ci qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i]; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci qos->pfc_mode = dcbx_cfg->pfc_mode; 22562306a36Sopenharmony_ci if (qos->pfc_mode == IIDC_DSCP_PFC_MODE) 22662306a36Sopenharmony_ci for (i = 0; i < IIDC_MAX_DSCP_MAPPING; i++) 22762306a36Sopenharmony_ci qos->dscp_map[i] = dcbx_cfg->dscp_map[i]; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ice_get_qos_params); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci/** 23262306a36Sopenharmony_ci * ice_alloc_rdma_qvectors - Allocate vector resources for RDMA driver 23362306a36Sopenharmony_ci * @pf: board private structure to initialize 23462306a36Sopenharmony_ci */ 23562306a36Sopenharmony_cistatic int ice_alloc_rdma_qvectors(struct ice_pf *pf) 23662306a36Sopenharmony_ci{ 23762306a36Sopenharmony_ci if (ice_is_rdma_ena(pf)) { 23862306a36Sopenharmony_ci int i; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci pf->msix_entries = kcalloc(pf->num_rdma_msix, 24162306a36Sopenharmony_ci sizeof(*pf->msix_entries), 24262306a36Sopenharmony_ci GFP_KERNEL); 24362306a36Sopenharmony_ci if (!pf->msix_entries) 24462306a36Sopenharmony_ci return -ENOMEM; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci /* RDMA is the only user of pf->msix_entries array */ 24762306a36Sopenharmony_ci pf->rdma_base_vector = 0; 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci for (i = 0; i < pf->num_rdma_msix; i++) { 25062306a36Sopenharmony_ci struct msix_entry *entry = &pf->msix_entries[i]; 25162306a36Sopenharmony_ci struct msi_map map; 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_ci map = ice_alloc_irq(pf, false); 25462306a36Sopenharmony_ci if (map.index < 0) 25562306a36Sopenharmony_ci break; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci entry->entry = map.index; 25862306a36Sopenharmony_ci entry->vector = map.virq; 25962306a36Sopenharmony_ci } 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci return 0; 26262306a36Sopenharmony_ci} 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci/** 26562306a36Sopenharmony_ci * ice_free_rdma_qvector - free vector resources reserved for RDMA driver 26662306a36Sopenharmony_ci * @pf: board private structure to initialize 26762306a36Sopenharmony_ci */ 26862306a36Sopenharmony_cistatic void ice_free_rdma_qvector(struct ice_pf *pf) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci int i; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci if (!pf->msix_entries) 27362306a36Sopenharmony_ci return; 27462306a36Sopenharmony_ci 27562306a36Sopenharmony_ci for (i = 0; i < pf->num_rdma_msix; i++) { 27662306a36Sopenharmony_ci struct msi_map map; 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci map.index = pf->msix_entries[i].entry; 27962306a36Sopenharmony_ci map.virq = pf->msix_entries[i].vector; 28062306a36Sopenharmony_ci ice_free_irq(pf, map); 28162306a36Sopenharmony_ci } 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci kfree(pf->msix_entries); 28462306a36Sopenharmony_ci pf->msix_entries = NULL; 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci/** 28862306a36Sopenharmony_ci * ice_adev_release - function to be mapped to AUX dev's release op 28962306a36Sopenharmony_ci * @dev: pointer to device to free 29062306a36Sopenharmony_ci */ 29162306a36Sopenharmony_cistatic void ice_adev_release(struct device *dev) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci struct iidc_auxiliary_dev *iadev; 29462306a36Sopenharmony_ci 29562306a36Sopenharmony_ci iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev); 29662306a36Sopenharmony_ci kfree(iadev); 29762306a36Sopenharmony_ci} 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci/** 30062306a36Sopenharmony_ci * ice_plug_aux_dev - allocate and register AUX device 30162306a36Sopenharmony_ci * @pf: pointer to pf struct 30262306a36Sopenharmony_ci */ 30362306a36Sopenharmony_ciint ice_plug_aux_dev(struct ice_pf *pf) 30462306a36Sopenharmony_ci{ 30562306a36Sopenharmony_ci struct iidc_auxiliary_dev *iadev; 30662306a36Sopenharmony_ci struct auxiliary_device *adev; 30762306a36Sopenharmony_ci int ret; 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci /* if this PF doesn't support a technology that requires auxiliary 31062306a36Sopenharmony_ci * devices, then gracefully exit 31162306a36Sopenharmony_ci */ 31262306a36Sopenharmony_ci if (!ice_is_rdma_ena(pf)) 31362306a36Sopenharmony_ci return 0; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci iadev = kzalloc(sizeof(*iadev), GFP_KERNEL); 31662306a36Sopenharmony_ci if (!iadev) 31762306a36Sopenharmony_ci return -ENOMEM; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_ci adev = &iadev->adev; 32062306a36Sopenharmony_ci iadev->pf = pf; 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_ci adev->id = pf->aux_idx; 32362306a36Sopenharmony_ci adev->dev.release = ice_adev_release; 32462306a36Sopenharmony_ci adev->dev.parent = &pf->pdev->dev; 32562306a36Sopenharmony_ci adev->name = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? "roce" : "iwarp"; 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci ret = auxiliary_device_init(adev); 32862306a36Sopenharmony_ci if (ret) { 32962306a36Sopenharmony_ci kfree(iadev); 33062306a36Sopenharmony_ci return ret; 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci ret = auxiliary_device_add(adev); 33462306a36Sopenharmony_ci if (ret) { 33562306a36Sopenharmony_ci auxiliary_device_uninit(adev); 33662306a36Sopenharmony_ci return ret; 33762306a36Sopenharmony_ci } 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci mutex_lock(&pf->adev_mutex); 34062306a36Sopenharmony_ci pf->adev = adev; 34162306a36Sopenharmony_ci mutex_unlock(&pf->adev_mutex); 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_ci return 0; 34462306a36Sopenharmony_ci} 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci/* ice_unplug_aux_dev - unregister and free AUX device 34762306a36Sopenharmony_ci * @pf: pointer to pf struct 34862306a36Sopenharmony_ci */ 34962306a36Sopenharmony_civoid ice_unplug_aux_dev(struct ice_pf *pf) 35062306a36Sopenharmony_ci{ 35162306a36Sopenharmony_ci struct auxiliary_device *adev; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci mutex_lock(&pf->adev_mutex); 35462306a36Sopenharmony_ci adev = pf->adev; 35562306a36Sopenharmony_ci pf->adev = NULL; 35662306a36Sopenharmony_ci mutex_unlock(&pf->adev_mutex); 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci if (adev) { 35962306a36Sopenharmony_ci auxiliary_device_delete(adev); 36062306a36Sopenharmony_ci auxiliary_device_uninit(adev); 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci} 36362306a36Sopenharmony_ci 36462306a36Sopenharmony_ci/** 36562306a36Sopenharmony_ci * ice_init_rdma - initializes PF for RDMA use 36662306a36Sopenharmony_ci * @pf: ptr to ice_pf 36762306a36Sopenharmony_ci */ 36862306a36Sopenharmony_ciint ice_init_rdma(struct ice_pf *pf) 36962306a36Sopenharmony_ci{ 37062306a36Sopenharmony_ci struct device *dev = &pf->pdev->dev; 37162306a36Sopenharmony_ci int ret; 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci if (!ice_is_rdma_ena(pf)) { 37462306a36Sopenharmony_ci dev_warn(dev, "RDMA is not supported on this device\n"); 37562306a36Sopenharmony_ci return 0; 37662306a36Sopenharmony_ci } 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci ret = xa_alloc(&ice_aux_id, &pf->aux_idx, NULL, XA_LIMIT(1, INT_MAX), 37962306a36Sopenharmony_ci GFP_KERNEL); 38062306a36Sopenharmony_ci if (ret) { 38162306a36Sopenharmony_ci dev_err(dev, "Failed to allocate device ID for AUX driver\n"); 38262306a36Sopenharmony_ci return -ENOMEM; 38362306a36Sopenharmony_ci } 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_ci /* Reserve vector resources */ 38662306a36Sopenharmony_ci ret = ice_alloc_rdma_qvectors(pf); 38762306a36Sopenharmony_ci if (ret < 0) { 38862306a36Sopenharmony_ci dev_err(dev, "failed to reserve vectors for RDMA\n"); 38962306a36Sopenharmony_ci goto err_reserve_rdma_qvector; 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2; 39262306a36Sopenharmony_ci ret = ice_plug_aux_dev(pf); 39362306a36Sopenharmony_ci if (ret) 39462306a36Sopenharmony_ci goto err_plug_aux_dev; 39562306a36Sopenharmony_ci return 0; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_cierr_plug_aux_dev: 39862306a36Sopenharmony_ci ice_free_rdma_qvector(pf); 39962306a36Sopenharmony_cierr_reserve_rdma_qvector: 40062306a36Sopenharmony_ci pf->adev = NULL; 40162306a36Sopenharmony_ci xa_erase(&ice_aux_id, pf->aux_idx); 40262306a36Sopenharmony_ci return ret; 40362306a36Sopenharmony_ci} 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci/** 40662306a36Sopenharmony_ci * ice_deinit_rdma - deinitialize RDMA on PF 40762306a36Sopenharmony_ci * @pf: ptr to ice_pf 40862306a36Sopenharmony_ci */ 40962306a36Sopenharmony_civoid ice_deinit_rdma(struct ice_pf *pf) 41062306a36Sopenharmony_ci{ 41162306a36Sopenharmony_ci if (!ice_is_rdma_ena(pf)) 41262306a36Sopenharmony_ci return; 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ci ice_unplug_aux_dev(pf); 41562306a36Sopenharmony_ci ice_free_rdma_qvector(pf); 41662306a36Sopenharmony_ci xa_erase(&ice_aux_id, pf->aux_idx); 41762306a36Sopenharmony_ci} 418