1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (C) 2021, Intel Corporation. */
4 /* Inter-Driver Communication */
7 #include "ice_dcb_lib.h"
9 static DEFINE_XARRAY_ALLOC1(ice_aux_id);
12 * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct
13 * @pf: pointer to PF struct
15 * This function has to be called with a device_lock on the
16 * pf->adev.dev to avoid race conditions.
18 static struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf)
20 struct auxiliary_device *adev;
23 if (!adev || !adev->dev.driver)
26 return container_of(adev->dev.driver, struct iidc_auxiliary_drv,
31 * ice_send_event_to_aux - send event to RDMA AUX driver
32 * @pf: pointer to PF struct
33 * @event: event struct
35 void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
37 struct iidc_auxiliary_drv *iadrv;
39 if (WARN_ON_ONCE(!in_task()))
42 mutex_lock(&pf->adev_mutex);
46 device_lock(&pf->adev->dev);
47 iadrv = ice_get_auxiliary_drv(pf);
48 if (iadrv && iadrv->event_handler)
49 iadrv->event_handler(pf, event);
50 device_unlock(&pf->adev->dev);
52 mutex_unlock(&pf->adev_mutex);
56 * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
58 * @qset: Resource to be allocated
60 int ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
62 u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
70 if (WARN_ON(!pf || !qset))
73 dev = ice_pf_to_dev(pf);
75 if (!ice_is_rdma_ena(pf))
78 vsi = ice_get_main_vsi(pf);
80 dev_err(dev, "RDMA QSet invalid VSI\n");
84 ice_for_each_traffic_class(i)
87 max_rdmaqs[qset->tc]++;
88 qs_handle = qset->qs_handle;
90 status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
93 dev_err(dev, "Failed VSI RDMA Qset config\n");
97 status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
98 &qs_handle, 1, &qset_teid);
100 dev_err(dev, "Failed VSI RDMA Qset enable\n");
103 vsi->qset_handle[qset->tc] = qset->qs_handle;
104 qset->teid = qset_teid;
108 EXPORT_SYMBOL_GPL(ice_add_rdma_qset);
111 * ice_del_rdma_qset - Delete leaf node for RDMA Qset
113 * @qset: Resource to be freed
115 int ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
121 if (WARN_ON(!pf || !qset))
124 vsi = ice_find_vsi(pf, qset->vport_id);
126 dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
130 q_id = qset->qs_handle;
133 vsi->qset_handle[qset->tc] = 0;
135 return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
137 EXPORT_SYMBOL_GPL(ice_del_rdma_qset);
140 * ice_rdma_request_reset - accept request from RDMA to perform a reset
142 * @reset_type: type of reset
144 int ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
146 enum ice_reset_req reset;
151 switch (reset_type) {
153 reset = ICE_RESET_PFR;
156 reset = ICE_RESET_CORER;
159 reset = ICE_RESET_GLOBR;
162 dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
166 return ice_schedule_reset(pf, reset);
168 EXPORT_SYMBOL_GPL(ice_rdma_request_reset);
171 * ice_rdma_update_vsi_filter - update main VSI filters for RDMA
172 * @pf: pointer to struct for PF
173 * @vsi_id: VSI HW idx to update filter on
174 * @enable: bool whether to enable or disable filters
176 int ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
184 vsi = ice_find_vsi(pf, vsi_id);
188 status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
190 dev_err(ice_pf_to_dev(pf), "Failed to %sable RDMA filtering\n",
191 enable ? "en" : "dis");
194 vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
196 vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
201 EXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
204 * ice_get_qos_params - parse QoS params for RDMA consumption
205 * @pf: pointer to PF struct
206 * @qos: set of QoS values
208 void ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
210 struct ice_dcbx_cfg *dcbx_cfg;
214 dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
215 up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
217 qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg);
218 for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
219 qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7;
221 for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
222 qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
224 qos->pfc_mode = dcbx_cfg->pfc_mode;
225 if (qos->pfc_mode == IIDC_DSCP_PFC_MODE)
226 for (i = 0; i < IIDC_MAX_DSCP_MAPPING; i++)
227 qos->dscp_map[i] = dcbx_cfg->dscp_map[i];
229 EXPORT_SYMBOL_GPL(ice_get_qos_params);
232 * ice_alloc_rdma_qvectors - Allocate vector resources for RDMA driver
233 * @pf: board private structure to initialize
235 static int ice_alloc_rdma_qvectors(struct ice_pf *pf)
237 if (ice_is_rdma_ena(pf)) {
240 pf->msix_entries = kcalloc(pf->num_rdma_msix,
241 sizeof(*pf->msix_entries),
243 if (!pf->msix_entries)
246 /* RDMA is the only user of pf->msix_entries array */
247 pf->rdma_base_vector = 0;
249 for (i = 0; i < pf->num_rdma_msix; i++) {
250 struct msix_entry *entry = &pf->msix_entries[i];
253 map = ice_alloc_irq(pf, false);
257 entry->entry = map.index;
258 entry->vector = map.virq;
265 * ice_free_rdma_qvector - free vector resources reserved for RDMA driver
266 * @pf: board private structure to initialize
268 static void ice_free_rdma_qvector(struct ice_pf *pf)
272 if (!pf->msix_entries)
275 for (i = 0; i < pf->num_rdma_msix; i++) {
278 map.index = pf->msix_entries[i].entry;
279 map.virq = pf->msix_entries[i].vector;
280 ice_free_irq(pf, map);
283 kfree(pf->msix_entries);
284 pf->msix_entries = NULL;
288 * ice_adev_release - function to be mapped to AUX dev's release op
289 * @dev: pointer to device to free
291 static void ice_adev_release(struct device *dev)
293 struct iidc_auxiliary_dev *iadev;
295 iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
300 * ice_plug_aux_dev - allocate and register AUX device
301 * @pf: pointer to pf struct
303 int ice_plug_aux_dev(struct ice_pf *pf)
305 struct iidc_auxiliary_dev *iadev;
306 struct auxiliary_device *adev;
309 /* if this PF doesn't support a technology that requires auxiliary
310 * devices, then gracefully exit
312 if (!ice_is_rdma_ena(pf))
315 iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
322 adev->id = pf->aux_idx;
323 adev->dev.release = ice_adev_release;
324 adev->dev.parent = &pf->pdev->dev;
325 adev->name = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? "roce" : "iwarp";
327 ret = auxiliary_device_init(adev);
333 ret = auxiliary_device_add(adev);
335 auxiliary_device_uninit(adev);
339 mutex_lock(&pf->adev_mutex);
341 mutex_unlock(&pf->adev_mutex);
346 /* ice_unplug_aux_dev - unregister and free AUX device
347 * @pf: pointer to pf struct
349 void ice_unplug_aux_dev(struct ice_pf *pf)
351 struct auxiliary_device *adev;
353 mutex_lock(&pf->adev_mutex);
356 mutex_unlock(&pf->adev_mutex);
359 auxiliary_device_delete(adev);
360 auxiliary_device_uninit(adev);
365 * ice_init_rdma - initializes PF for RDMA use
368 int ice_init_rdma(struct ice_pf *pf)
370 struct device *dev = &pf->pdev->dev;
373 if (!ice_is_rdma_ena(pf)) {
374 dev_warn(dev, "RDMA is not supported on this device\n");
378 ret = xa_alloc(&ice_aux_id, &pf->aux_idx, NULL, XA_LIMIT(1, INT_MAX),
381 dev_err(dev, "Failed to allocate device ID for AUX driver\n");
385 /* Reserve vector resources */
386 ret = ice_alloc_rdma_qvectors(pf);
388 dev_err(dev, "failed to reserve vectors for RDMA\n");
389 goto err_reserve_rdma_qvector;
391 pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
392 ret = ice_plug_aux_dev(pf);
394 goto err_plug_aux_dev;
398 ice_free_rdma_qvector(pf);
399 err_reserve_rdma_qvector:
401 xa_erase(&ice_aux_id, pf->aux_idx);
406 * ice_deinit_rdma - deinitialize RDMA on PF
409 void ice_deinit_rdma(struct ice_pf *pf)
411 if (!ice_is_rdma_ena(pf))
414 ice_unplug_aux_dev(pf);
415 ice_free_rdma_qvector(pf);
416 xa_erase(&ice_aux_id, pf->aux_idx);