Linux Audio

Check our new training course

Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (C) 2021, Intel Corporation. */
  3
  4/* Inter-Driver Communication */
  5#include "ice.h"
  6#include "ice_lib.h"
  7#include "ice_dcb_lib.h"
  8
  9/**
 10 * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct
 11 * @pf: pointer to PF struct
 12 *
 13 * This function has to be called with a device_lock on the
 14 * pf->adev.dev to avoid race conditions.
 15 */
 16static struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf)
 17{
 18	struct auxiliary_device *adev;
 19
 20	adev = pf->adev;
 21	if (!adev || !adev->dev.driver)
 22		return NULL;
 23
 24	return container_of(adev->dev.driver, struct iidc_auxiliary_drv,
 25			    adrv.driver);
 26}
 27
 28/**
 29 * ice_send_event_to_aux - send event to RDMA AUX driver
 30 * @pf: pointer to PF struct
 31 * @event: event struct
 32 */
 33void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
 34{
 35	struct iidc_auxiliary_drv *iadrv;
 36
 37	if (WARN_ON_ONCE(!in_task()))
 38		return;
 39
 40	mutex_lock(&pf->adev_mutex);
 41	if (!pf->adev)
 42		goto finish;
 43
 44	device_lock(&pf->adev->dev);
 45	iadrv = ice_get_auxiliary_drv(pf);
 46	if (iadrv && iadrv->event_handler)
 47		iadrv->event_handler(pf, event);
 48	device_unlock(&pf->adev->dev);
 49finish:
 50	mutex_unlock(&pf->adev_mutex);
 
 
 
 
 
 
 
 
 
 
 
 
 
 51}
 52
 53/**
 54 * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
 55 * @pf: PF struct
 56 * @qset: Resource to be allocated
 57 */
 58int ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
 59{
 60	u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
 61	struct ice_vsi *vsi;
 62	struct device *dev;
 63	u32 qset_teid;
 64	u16 qs_handle;
 65	int status;
 66	int i;
 67
 68	if (WARN_ON(!pf || !qset))
 69		return -EINVAL;
 70
 71	dev = ice_pf_to_dev(pf);
 72
 73	if (!ice_is_rdma_ena(pf))
 74		return -EINVAL;
 75
 76	vsi = ice_get_main_vsi(pf);
 77	if (!vsi) {
 78		dev_err(dev, "RDMA QSet invalid VSI\n");
 79		return -EINVAL;
 80	}
 81
 82	ice_for_each_traffic_class(i)
 83		max_rdmaqs[i] = 0;
 84
 85	max_rdmaqs[qset->tc]++;
 86	qs_handle = qset->qs_handle;
 87
 88	status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
 89				  max_rdmaqs);
 90	if (status) {
 91		dev_err(dev, "Failed VSI RDMA Qset config\n");
 92		return status;
 93	}
 94
 95	status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
 96				       &qs_handle, 1, &qset_teid);
 97	if (status) {
 98		dev_err(dev, "Failed VSI RDMA Qset enable\n");
 99		return status;
100	}
101	vsi->qset_handle[qset->tc] = qset->qs_handle;
102	qset->teid = qset_teid;
103
104	return 0;
105}
106EXPORT_SYMBOL_GPL(ice_add_rdma_qset);
107
108/**
109 * ice_del_rdma_qset - Delete leaf node for RDMA Qset
110 * @pf: PF struct
111 * @qset: Resource to be freed
112 */
113int ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
114{
115	struct ice_vsi *vsi;
116	u32 teid;
117	u16 q_id;
118
119	if (WARN_ON(!pf || !qset))
120		return -EINVAL;
121
122	vsi = ice_find_vsi(pf, qset->vport_id);
123	if (!vsi) {
124		dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
125		return -EINVAL;
126	}
127
128	q_id = qset->qs_handle;
129	teid = qset->teid;
130
131	vsi->qset_handle[qset->tc] = 0;
132
133	return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
134}
135EXPORT_SYMBOL_GPL(ice_del_rdma_qset);
136
137/**
138 * ice_rdma_request_reset - accept request from RDMA to perform a reset
139 * @pf: struct for PF
140 * @reset_type: type of reset
141 */
142int ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
143{
144	enum ice_reset_req reset;
145
146	if (WARN_ON(!pf))
147		return -EINVAL;
148
149	switch (reset_type) {
150	case IIDC_PFR:
151		reset = ICE_RESET_PFR;
152		break;
153	case IIDC_CORER:
154		reset = ICE_RESET_CORER;
155		break;
156	case IIDC_GLOBR:
157		reset = ICE_RESET_GLOBR;
158		break;
159	default:
160		dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
161		return -EINVAL;
162	}
163
164	return ice_schedule_reset(pf, reset);
165}
166EXPORT_SYMBOL_GPL(ice_rdma_request_reset);
167
168/**
169 * ice_rdma_update_vsi_filter - update main VSI filters for RDMA
170 * @pf: pointer to struct for PF
171 * @vsi_id: VSI HW idx to update filter on
172 * @enable: bool whether to enable or disable filters
173 */
174int ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
175{
176	struct ice_vsi *vsi;
177	int status;
178
179	if (WARN_ON(!pf))
180		return -EINVAL;
181
182	vsi = ice_find_vsi(pf, vsi_id);
183	if (!vsi)
184		return -EINVAL;
185
186	status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
187	if (status) {
188		dev_err(ice_pf_to_dev(pf), "Failed to  %sable RDMA filtering\n",
189			enable ? "en" : "dis");
190	} else {
191		if (enable)
192			vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
193		else
194			vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
195	}
196
197	return status;
198}
199EXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
200
201/**
202 * ice_get_qos_params - parse QoS params for RDMA consumption
203 * @pf: pointer to PF struct
204 * @qos: set of QoS values
205 */
206void ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
207{
208	struct ice_dcbx_cfg *dcbx_cfg;
209	unsigned int i;
210	u32 up2tc;
211
212	dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
213	up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
214
215	qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg);
216	for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
217		qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7;
218
219	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
220		qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
221
222	qos->pfc_mode = dcbx_cfg->pfc_mode;
223	if (qos->pfc_mode == IIDC_DSCP_PFC_MODE)
224		for (i = 0; i < IIDC_MAX_DSCP_MAPPING; i++)
225			qos->dscp_map[i] = dcbx_cfg->dscp_map[i];
226}
227EXPORT_SYMBOL_GPL(ice_get_qos_params);
228
229/**
230 * ice_reserve_rdma_qvector - Reserve vector resources for RDMA driver
231 * @pf: board private structure to initialize
232 */
233static int ice_reserve_rdma_qvector(struct ice_pf *pf)
234{
235	if (ice_is_rdma_ena(pf)) {
236		int index;
237
238		index = ice_get_res(pf, pf->irq_tracker, pf->num_rdma_msix,
239				    ICE_RES_RDMA_VEC_ID);
240		if (index < 0)
241			return index;
242		pf->num_avail_sw_msix -= pf->num_rdma_msix;
243		pf->rdma_base_vector = (u16)index;
244	}
245	return 0;
246}
247
248/**
249 * ice_adev_release - function to be mapped to AUX dev's release op
250 * @dev: pointer to device to free
251 */
252static void ice_adev_release(struct device *dev)
253{
254	struct iidc_auxiliary_dev *iadev;
255
256	iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
257	kfree(iadev);
258}
259
260/**
261 * ice_plug_aux_dev - allocate and register AUX device
262 * @pf: pointer to pf struct
263 */
264int ice_plug_aux_dev(struct ice_pf *pf)
265{
266	struct iidc_auxiliary_dev *iadev;
267	struct auxiliary_device *adev;
268	int ret;
269
270	/* if this PF doesn't support a technology that requires auxiliary
271	 * devices, then gracefully exit
272	 */
273	if (!ice_is_rdma_ena(pf))
274		return 0;
275
276	iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
277	if (!iadev)
278		return -ENOMEM;
279
280	adev = &iadev->adev;
 
281	iadev->pf = pf;
282
283	adev->id = pf->aux_idx;
284	adev->dev.release = ice_adev_release;
285	adev->dev.parent = &pf->pdev->dev;
286	adev->name = pf->rdma_mode & IIDC_RDMA_PROTOCOL_ROCEV2 ? "roce" : "iwarp";
287
288	ret = auxiliary_device_init(adev);
289	if (ret) {
 
290		kfree(iadev);
291		return ret;
292	}
293
294	ret = auxiliary_device_add(adev);
295	if (ret) {
 
296		auxiliary_device_uninit(adev);
297		return ret;
298	}
299
300	mutex_lock(&pf->adev_mutex);
301	pf->adev = adev;
302	mutex_unlock(&pf->adev_mutex);
303
304	return 0;
305}
306
307/* ice_unplug_aux_dev - unregister and free AUX device
308 * @pf: pointer to pf struct
309 */
310void ice_unplug_aux_dev(struct ice_pf *pf)
311{
312	struct auxiliary_device *adev;
 
313
314	mutex_lock(&pf->adev_mutex);
315	adev = pf->adev;
316	pf->adev = NULL;
317	mutex_unlock(&pf->adev_mutex);
318
319	if (adev) {
320		auxiliary_device_delete(adev);
321		auxiliary_device_uninit(adev);
322	}
323}
324
325/**
326 * ice_init_rdma - initializes PF for RDMA use
327 * @pf: ptr to ice_pf
328 */
329int ice_init_rdma(struct ice_pf *pf)
330{
331	struct device *dev = &pf->pdev->dev;
332	int ret;
333
334	/* Reserve vector resources */
335	ret = ice_reserve_rdma_qvector(pf);
336	if (ret < 0) {
337		dev_err(dev, "failed to reserve vectors for RDMA\n");
338		return ret;
339	}
340	pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
341	return ice_plug_aux_dev(pf);
342}
v5.14.15
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (C) 2021, Intel Corporation. */
  3
  4/* Inter-Driver Communication */
  5#include "ice.h"
  6#include "ice_lib.h"
  7#include "ice_dcb_lib.h"
  8
  9/**
 10 * ice_get_auxiliary_drv - retrieve iidc_auxiliary_drv struct
 11 * @pf: pointer to PF struct
 12 *
 13 * This function has to be called with a device_lock on the
 14 * pf->adev.dev to avoid race conditions.
 15 */
 16static struct iidc_auxiliary_drv *ice_get_auxiliary_drv(struct ice_pf *pf)
 17{
 18	struct auxiliary_device *adev;
 19
 20	adev = pf->adev;
 21	if (!adev || !adev->dev.driver)
 22		return NULL;
 23
 24	return container_of(adev->dev.driver, struct iidc_auxiliary_drv,
 25			    adrv.driver);
 26}
 27
 28/**
 29 * ice_send_event_to_aux - send event to RDMA AUX driver
 30 * @pf: pointer to PF struct
 31 * @event: event struct
 32 */
 33void ice_send_event_to_aux(struct ice_pf *pf, struct iidc_event *event)
 34{
 35	struct iidc_auxiliary_drv *iadrv;
 36
 
 
 
 
 37	if (!pf->adev)
 38		return;
 39
 40	device_lock(&pf->adev->dev);
 41	iadrv = ice_get_auxiliary_drv(pf);
 42	if (iadrv && iadrv->event_handler)
 43		iadrv->event_handler(pf, event);
 44	device_unlock(&pf->adev->dev);
 45}
 46
 47/**
 48 * ice_find_vsi - Find the VSI from VSI ID
 49 * @pf: The PF pointer to search in
 50 * @vsi_num: The VSI ID to search for
 51 */
 52static struct ice_vsi *ice_find_vsi(struct ice_pf *pf, u16 vsi_num)
 53{
 54	int i;
 55
 56	ice_for_each_vsi(pf, i)
 57		if (pf->vsi[i] && pf->vsi[i]->vsi_num == vsi_num)
 58			return  pf->vsi[i];
 59	return NULL;
 60}
 61
 62/**
 63 * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
 64 * @pf: PF struct
 65 * @qset: Resource to be allocated
 66 */
 67int ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
 68{
 69	u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
 70	struct ice_vsi *vsi;
 71	struct device *dev;
 72	u32 qset_teid;
 73	u16 qs_handle;
 74	int status;
 75	int i;
 76
 77	if (WARN_ON(!pf || !qset))
 78		return -EINVAL;
 79
 80	dev = ice_pf_to_dev(pf);
 81
 82	if (!test_bit(ICE_FLAG_RDMA_ENA, pf->flags))
 83		return -EINVAL;
 84
 85	vsi = ice_get_main_vsi(pf);
 86	if (!vsi) {
 87		dev_err(dev, "RDMA QSet invalid VSI\n");
 88		return -EINVAL;
 89	}
 90
 91	ice_for_each_traffic_class(i)
 92		max_rdmaqs[i] = 0;
 93
 94	max_rdmaqs[qset->tc]++;
 95	qs_handle = qset->qs_handle;
 96
 97	status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
 98				  max_rdmaqs);
 99	if (status) {
100		dev_err(dev, "Failed VSI RDMA Qset config\n");
101		return status;
102	}
103
104	status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
105				       &qs_handle, 1, &qset_teid);
106	if (status) {
107		dev_err(dev, "Failed VSI RDMA Qset enable\n");
108		return status;
109	}
110	vsi->qset_handle[qset->tc] = qset->qs_handle;
111	qset->teid = qset_teid;
112
113	return 0;
114}
115EXPORT_SYMBOL_GPL(ice_add_rdma_qset);
116
117/**
118 * ice_del_rdma_qset - Delete leaf node for RDMA Qset
119 * @pf: PF struct
120 * @qset: Resource to be freed
121 */
122int ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
123{
124	struct ice_vsi *vsi;
125	u32 teid;
126	u16 q_id;
127
128	if (WARN_ON(!pf || !qset))
129		return -EINVAL;
130
131	vsi = ice_find_vsi(pf, qset->vport_id);
132	if (!vsi) {
133		dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
134		return -EINVAL;
135	}
136
137	q_id = qset->qs_handle;
138	teid = qset->teid;
139
140	vsi->qset_handle[qset->tc] = 0;
141
142	return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
143}
144EXPORT_SYMBOL_GPL(ice_del_rdma_qset);
145
146/**
147 * ice_rdma_request_reset - accept request from RDMA to perform a reset
148 * @pf: struct for PF
149 * @reset_type: type of reset
150 */
151int ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
152{
153	enum ice_reset_req reset;
154
155	if (WARN_ON(!pf))
156		return -EINVAL;
157
158	switch (reset_type) {
159	case IIDC_PFR:
160		reset = ICE_RESET_PFR;
161		break;
162	case IIDC_CORER:
163		reset = ICE_RESET_CORER;
164		break;
165	case IIDC_GLOBR:
166		reset = ICE_RESET_GLOBR;
167		break;
168	default:
169		dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
170		return -EINVAL;
171	}
172
173	return ice_schedule_reset(pf, reset);
174}
175EXPORT_SYMBOL_GPL(ice_rdma_request_reset);
176
177/**
178 * ice_rdma_update_vsi_filter - update main VSI filters for RDMA
179 * @pf: pointer to struct for PF
180 * @vsi_id: VSI HW idx to update filter on
181 * @enable: bool whether to enable or disable filters
182 */
183int ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
184{
185	struct ice_vsi *vsi;
186	int status;
187
188	if (WARN_ON(!pf))
189		return -EINVAL;
190
191	vsi = ice_find_vsi(pf, vsi_id);
192	if (!vsi)
193		return -EINVAL;
194
195	status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
196	if (status) {
197		dev_err(ice_pf_to_dev(pf), "Failed to  %sable RDMA filtering\n",
198			enable ? "en" : "dis");
199	} else {
200		if (enable)
201			vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
202		else
203			vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
204	}
205
206	return status;
207}
208EXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
209
210/**
211 * ice_get_qos_params - parse QoS params for RDMA consumption
212 * @pf: pointer to PF struct
213 * @qos: set of QoS values
214 */
215void ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
216{
217	struct ice_dcbx_cfg *dcbx_cfg;
218	unsigned int i;
219	u32 up2tc;
220
221	dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
222	up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
223
224	qos->num_tc = ice_dcb_get_num_tc(dcbx_cfg);
225	for (i = 0; i < IIDC_MAX_USER_PRIORITY; i++)
226		qos->up2tc[i] = (up2tc >> (i * 3)) & 0x7;
227
228	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
229		qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
 
 
 
 
 
230}
231EXPORT_SYMBOL_GPL(ice_get_qos_params);
232
233/**
234 * ice_reserve_rdma_qvector - Reserve vector resources for RDMA driver
235 * @pf: board private structure to initialize
236 */
237static int ice_reserve_rdma_qvector(struct ice_pf *pf)
238{
239	if (test_bit(ICE_FLAG_RDMA_ENA, pf->flags)) {
240		int index;
241
242		index = ice_get_res(pf, pf->irq_tracker, pf->num_rdma_msix,
243				    ICE_RES_RDMA_VEC_ID);
244		if (index < 0)
245			return index;
246		pf->num_avail_sw_msix -= pf->num_rdma_msix;
247		pf->rdma_base_vector = (u16)index;
248	}
249	return 0;
250}
251
252/**
253 * ice_adev_release - function to be mapped to AUX dev's release op
254 * @dev: pointer to device to free
255 */
256static void ice_adev_release(struct device *dev)
257{
258	struct iidc_auxiliary_dev *iadev;
259
260	iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
261	kfree(iadev);
262}
263
264/**
265 * ice_plug_aux_dev - allocate and register AUX device
266 * @pf: pointer to pf struct
267 */
268int ice_plug_aux_dev(struct ice_pf *pf)
269{
270	struct iidc_auxiliary_dev *iadev;
271	struct auxiliary_device *adev;
272	int ret;
273
274	/* if this PF doesn't support a technology that requires auxiliary
275	 * devices, then gracefully exit
276	 */
277	if (!ice_is_aux_ena(pf))
278		return 0;
279
280	iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
281	if (!iadev)
282		return -ENOMEM;
283
284	adev = &iadev->adev;
285	pf->adev = adev;
286	iadev->pf = pf;
287
288	adev->id = pf->aux_idx;
289	adev->dev.release = ice_adev_release;
290	adev->dev.parent = &pf->pdev->dev;
291	adev->name = IIDC_RDMA_ROCE_NAME;
292
293	ret = auxiliary_device_init(adev);
294	if (ret) {
295		pf->adev = NULL;
296		kfree(iadev);
297		return ret;
298	}
299
300	ret = auxiliary_device_add(adev);
301	if (ret) {
302		pf->adev = NULL;
303		auxiliary_device_uninit(adev);
304		return ret;
305	}
306
 
 
 
 
307	return 0;
308}
309
310/* ice_unplug_aux_dev - unregister and free AUX device
311 * @pf: pointer to pf struct
312 */
313void ice_unplug_aux_dev(struct ice_pf *pf)
314{
315	if (!pf->adev)
316		return;
317
318	auxiliary_device_delete(pf->adev);
319	auxiliary_device_uninit(pf->adev);
320	pf->adev = NULL;
 
 
 
 
 
 
321}
322
323/**
324 * ice_init_rdma - initializes PF for RDMA use
325 * @pf: ptr to ice_pf
326 */
327int ice_init_rdma(struct ice_pf *pf)
328{
329	struct device *dev = &pf->pdev->dev;
330	int ret;
331
332	/* Reserve vector resources */
333	ret = ice_reserve_rdma_qvector(pf);
334	if (ret < 0) {
335		dev_err(dev, "failed to reserve vectors for RDMA\n");
336		return ret;
337	}
338
339	return ice_plug_aux_dev(pf);
340}