1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2021, Intel Corporation. */
4 /* Inter-Driver Communication */
7 #include "ice_dcb_lib.h"
10 * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct
11 * @pf: pointer to PF struct
13 * This function has to be called with a device_lock on the
14 * pf->adev.dev to avoid race conditions.
16 static struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf)
18 struct auxiliary_device *adev;
21 if (!adev || !adev->dev.driver)
24 return container_of(adev->dev.driver, struct iidc_auxiliary_drv,
29 * ice_send_event_to_aux - send event to RDMA AUX driver
30 * @pf: pointer to PF struct
31 * @event: event struct
33 void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
35 struct iidc_auxiliary_drv *iadrv;
37 if (WARN_ON_ONCE(!in_task()))
43 device_lock(&pf->adev->dev);
44 iadrv = ice_get_auxiliary_drv(pf);
45 if (iadrv && iadrv->event_handler)
46 iadrv->event_handler(pf, event);
47 device_unlock(&pf->adev->dev);
51 * ice_find_vsi - Find the VSI from VSI ID
52 * @pf: The PF pointer to search in
53 * @vsi_num: The VSI ID to search for
55 static struct ice_vsi *ice_find_vsi(struct ice_pf *pf, u16 vsi_num)
59 ice_for_each_vsi(pf, i)
60 if (pf->vsi[i] && pf->vsi[i]->vsi_num == vsi_num)
66 * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
68 * @qset: Resource to be allocated
70 int ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
72 u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
80 if (WARN_ON(!pf || !qset))
83 dev = ice_pf_to_dev(pf);
85 if (!ice_is_rdma_ena(pf))
88 vsi = ice_get_main_vsi(pf);
90 dev_err(dev, "RDMA QSet invalid VSI\n");
94 ice_for_each_traffic_class(i)
97 max_rdmaqs[qset->tc]++;
98 qs_handle = qset->qs_handle;
100 status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
103 dev_err(dev, "Failed VSI RDMA Qset config\n");
107 status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
108 &qs_handle, 1, &qset_teid);
110 dev_err(dev, "Failed VSI RDMA Qset enable\n");
113 vsi->qset_handle[qset->tc] = qset->qs_handle;
114 qset->teid = qset_teid;
118 EXPORT_SYMBOL_GPL(ice_add_rdma_qset);
121 * ice_del_rdma_qset - Delete leaf node for RDMA Qset
123 * @qset: Resource to be freed
125 int ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
131 if (WARN_ON(!pf || !qset))
134 vsi = ice_find_vsi(pf, qset->vport_id);
136 dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
140 q_id = qset->qs_handle;
143 vsi->qset_handle[qset->tc] = 0;
145 return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
147 EXPORT_SYMBOL_GPL(ice_del_rdma_qset);
150 * ice_rdma_request_reset - accept request from RDMA to perform a reset
152 * @reset_type: type of reset
154 int ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
156 enum ice_reset_req reset;
161 switch (reset_type) {
163 reset = ICE_RESET_PFR;
166 reset = ICE_RESET_CORER;
169 reset = ICE_RESET_GLOBR;
172 dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
176 return ice_schedule_reset(pf, reset);
178 EXPORT_SYMBOL_GPL(ice_rdma_request_reset);
181 * ice_rdma_update_vsi_filter - update main VSI filters for RDMA
182 * @pf: pointer to struct for PF
183 * @vsi_id: VSI HW idx to update filter on
184 * @enable: bool whether to enable or disable filters
186 int ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
194 vsi = ice_find_vsi(pf, vsi_id);
198 status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
200 dev_err(ice_pf_to_dev(pf), "Failed to %sable RDMA filtering\n",
201 enable ? "en" : "dis");
204 vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
206 vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
211 EXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
214 * ice_get_qos_params - parse QoS params for RDMA consumption
215 * @pf: pointer to PF struct
216 * @qos: set of QoS values
218 void ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
220 struct ice_dcbx_cfg *dcbx_cfg;
224 dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
225 up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
227 qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg);
228 for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
229 qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7;
231 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
232 qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
234 qos->pfc_mode = dcbx_cfg->pfc_mode;
235 if (qos->pfc_mode == IIDC_DSCP_PFC_MODE)
236 for (i = 0; i < IIDC_MAX_DSCP_MAPPING; i++)
237 qos->dscp_map[i] = dcbx_cfg->dscp_map[i];
239 EXPORT_SYMBOL_GPL(ice_get_qos_params);
242 * ice_reserve_rdma_qvector - Reserve vector resources for RDMA driver
243 * @pf: board private structure to initialize
245 static int ice_reserve_rdma_qvector(struct ice_pf *pf)
247 if (ice_is_rdma_ena(pf)) {
250 index = ice_get_res(pf, pf->irq_tracker, pf->num_rdma_msix,
251 ICE_RES_RDMA_VEC_ID);
254 pf->num_avail_sw_msix -= pf->num_rdma_msix;
255 pf->rdma_base_vector = (u16)index;
261 * ice_adev_release - function to be mapped to AUX dev's release op
262 * @dev: pointer to device to free
264 static void ice_adev_release(struct device *dev)
266 struct iidc_auxiliary_dev *iadev;
268 iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
273 * ice_plug_aux_dev - allocate and register AUX device
274 * @pf: pointer to pf struct
276 int ice_plug_aux_dev(struct ice_pf *pf)
278 struct iidc_auxiliary_dev *iadev;
279 struct auxiliary_device *adev;
282 /* if this PF doesn't support a technology that requires auxiliary
283 * devices, then gracefully exit
285 if (!ice_is_rdma_ena(pf))
288 iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
296 adev->id = pf->aux_idx;
297 adev->dev.release = ice_adev_release;
298 adev->dev.parent = &pf->pdev->dev;
299 adev->name = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? "roce" : "iwarp";
301 ret = auxiliary_device_init(adev);
308 ret = auxiliary_device_add(adev);
311 auxiliary_device_uninit(adev);
318 /* ice_unplug_aux_dev - unregister and free AUX device
319 * @pf: pointer to pf struct
321 void ice_unplug_aux_dev(struct ice_pf *pf)
326 auxiliary_device_delete(pf->adev);
327 auxiliary_device_uninit(pf->adev);
332 * ice_init_rdma - initializes PF for RDMA use
335 int ice_init_rdma(struct ice_pf *pf)
337 struct device *dev = &pf->pdev->dev;
340 /* Reserve vector resources */
341 ret = ice_reserve_rdma_qvector(pf);
343 dev_err(dev, "failed to reserve vectors for RDMA\n");
346 pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
347 return ice_plug_aux_dev(pf);