25a436d342c29094e2f72410d30737ae36af6753
[platform/kernel/linux-starfive.git] / drivers / net / ethernet / intel / ice / ice_idc.c
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  */
16 static 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  */
33 void 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         if (!pf->adev)
41                 return;
42
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);
48 }
49
50 /**
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
54  */
55 static struct ice_vsi *ice_find_vsi(struct ice_pf *pf, u16 vsi_num)
56 {
57         int i;
58
59         ice_for_each_vsi(pf, i)
60                 if (pf->vsi[i] && pf->vsi[i]->vsi_num == vsi_num)
61                         return  pf->vsi[i];
62         return NULL;
63 }
64
65 /**
66  * ice_add_rdma_qset - Add Leaf Node for RDMA Qset
67  * @pf: PF struct
68  * @qset: Resource to be allocated
69  */
70 int ice_add_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
71 {
72         u16 max_rdmaqs[ICE_MAX_TRAFFIC_CLASS];
73         struct ice_vsi *vsi;
74         struct device *dev;
75         u32 qset_teid;
76         u16 qs_handle;
77         int status;
78         int i;
79
80         if (WARN_ON(!pf || !qset))
81                 return -EINVAL;
82
83         dev = ice_pf_to_dev(pf);
84
85         if (!ice_is_rdma_ena(pf))
86                 return -EINVAL;
87
88         vsi = ice_get_main_vsi(pf);
89         if (!vsi) {
90                 dev_err(dev, "RDMA QSet invalid VSI\n");
91                 return -EINVAL;
92         }
93
94         ice_for_each_traffic_class(i)
95                 max_rdmaqs[i] = 0;
96
97         max_rdmaqs[qset->tc]++;
98         qs_handle = qset->qs_handle;
99
100         status = ice_cfg_vsi_rdma(vsi->port_info, vsi->idx, vsi->tc_cfg.ena_tc,
101                                   max_rdmaqs);
102         if (status) {
103                 dev_err(dev, "Failed VSI RDMA Qset config\n");
104                 return status;
105         }
106
107         status = ice_ena_vsi_rdma_qset(vsi->port_info, vsi->idx, qset->tc,
108                                        &qs_handle, 1, &qset_teid);
109         if (status) {
110                 dev_err(dev, "Failed VSI RDMA Qset enable\n");
111                 return status;
112         }
113         vsi->qset_handle[qset->tc] = qset->qs_handle;
114         qset->teid = qset_teid;
115
116         return 0;
117 }
118 EXPORT_SYMBOL_GPL(ice_add_rdma_qset);
119
120 /**
121  * ice_del_rdma_qset - Delete leaf node for RDMA Qset
122  * @pf: PF struct
123  * @qset: Resource to be freed
124  */
125 int ice_del_rdma_qset(struct ice_pf *pf, struct iidc_rdma_qset_params *qset)
126 {
127         struct ice_vsi *vsi;
128         u32 teid;
129         u16 q_id;
130
131         if (WARN_ON(!pf || !qset))
132                 return -EINVAL;
133
134         vsi = ice_find_vsi(pf, qset->vport_id);
135         if (!vsi) {
136                 dev_err(ice_pf_to_dev(pf), "RDMA Invalid VSI\n");
137                 return -EINVAL;
138         }
139
140         q_id = qset->qs_handle;
141         teid = qset->teid;
142
143         vsi->qset_handle[qset->tc] = 0;
144
145         return ice_dis_vsi_rdma_qset(vsi->port_info, 1, &teid, &q_id);
146 }
147 EXPORT_SYMBOL_GPL(ice_del_rdma_qset);
148
149 /**
150  * ice_rdma_request_reset - accept request from RDMA to perform a reset
151  * @pf: struct for PF
152  * @reset_type: type of reset
153  */
154 int ice_rdma_request_reset(struct ice_pf *pf, enum iidc_reset_type reset_type)
155 {
156         enum ice_reset_req reset;
157
158         if (WARN_ON(!pf))
159                 return -EINVAL;
160
161         switch (reset_type) {
162         case IIDC_PFR:
163                 reset = ICE_RESET_PFR;
164                 break;
165         case IIDC_CORER:
166                 reset = ICE_RESET_CORER;
167                 break;
168         case IIDC_GLOBR:
169                 reset = ICE_RESET_GLOBR;
170                 break;
171         default:
172                 dev_err(ice_pf_to_dev(pf), "incorrect reset request\n");
173                 return -EINVAL;
174         }
175
176         return ice_schedule_reset(pf, reset);
177 }
178 EXPORT_SYMBOL_GPL(ice_rdma_request_reset);
179
180 /**
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
185  */
186 int ice_rdma_update_vsi_filter(struct ice_pf *pf, u16 vsi_id, bool enable)
187 {
188         struct ice_vsi *vsi;
189         int status;
190
191         if (WARN_ON(!pf))
192                 return -EINVAL;
193
194         vsi = ice_find_vsi(pf, vsi_id);
195         if (!vsi)
196                 return -EINVAL;
197
198         status = ice_cfg_rdma_fltr(&pf->hw, vsi->idx, enable);
199         if (status) {
200                 dev_err(ice_pf_to_dev(pf), "Failed to  %sable RDMA filtering\n",
201                         enable ? "en" : "dis");
202         } else {
203                 if (enable)
204                         vsi->info.q_opt_flags |= ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
205                 else
206                         vsi->info.q_opt_flags &= ~ICE_AQ_VSI_Q_OPT_PE_FLTR_EN;
207         }
208
209         return status;
210 }
211 EXPORT_SYMBOL_GPL(ice_rdma_update_vsi_filter);
212
213 /**
214  * ice_get_qos_params - parse QoS params for RDMA consumption
215  * @pf: pointer to PF struct
216  * @qos: set of QoS values
217  */
218 void ice_get_qos_params(struct ice_pf *pf, struct iidc_qos_params *qos)
219 {
220         struct ice_dcbx_cfg *dcbx_cfg;
221         unsigned int i;
222         u32 up2tc;
223
224         dcbx_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
225         up2tc = rd32(&pf->hw, PRTDCB_TUP2TC);
226
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;
230
231         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++)
232                 qos->tc_info[i].rel_bw = dcbx_cfg->etscfg.tcbwtable[i];
233
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];
238 }
239 EXPORT_SYMBOL_GPL(ice_get_qos_params);
240
241 /**
242  * ice_reserve_rdma_qvector - Reserve vector resources for RDMA driver
243  * @pf: board private structure to initialize
244  */
245 static int ice_reserve_rdma_qvector(struct ice_pf *pf)
246 {
247         if (ice_is_rdma_ena(pf)) {
248                 int index;
249
250                 index = ice_get_res(pf, pf->irq_tracker, pf->num_rdma_msix,
251                                     ICE_RES_RDMA_VEC_ID);
252                 if (index < 0)
253                         return index;
254                 pf->num_avail_sw_msix -= pf->num_rdma_msix;
255                 pf->rdma_base_vector = (u16)index;
256         }
257         return 0;
258 }
259
260 /**
261  * ice_adev_release - function to be mapped to AUX dev's release op
262  * @dev: pointer to device to free
263  */
264 static void ice_adev_release(struct device *dev)
265 {
266         struct iidc_auxiliary_dev *iadev;
267
268         iadev = container_of(dev, struct iidc_auxiliary_dev, adev.dev);
269         kfree(iadev);
270 }
271
272 /**
273  * ice_plug_aux_dev - allocate and register AUX device
274  * @pf: pointer to pf struct
275  */
276 int ice_plug_aux_dev(struct ice_pf *pf)
277 {
278         struct iidc_auxiliary_dev *iadev;
279         struct auxiliary_device *adev;
280         int ret;
281
282         /* if this PF doesn't support a technology that requires auxiliary
283          * devices, then gracefully exit
284          */
285         if (!ice_is_rdma_ena(pf))
286                 return 0;
287
288         iadev = kzalloc(sizeof(*iadev), GFP_KERNEL);
289         if (!iadev)
290                 return -ENOMEM;
291
292         adev = &iadev->adev;
293         pf->adev = adev;
294         iadev->pf = pf;
295
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";
300
301         ret = auxiliary_device_init(adev);
302         if (ret) {
303                 pf->adev = NULL;
304                 kfree(iadev);
305                 return ret;
306         }
307
308         ret = auxiliary_device_add(adev);
309         if (ret) {
310                 pf->adev = NULL;
311                 auxiliary_device_uninit(adev);
312                 return ret;
313         }
314
315         return 0;
316 }
317
318 /* ice_unplug_aux_dev - unregister and free AUX device
319  * @pf: pointer to pf struct
320  */
321 void ice_unplug_aux_dev(struct ice_pf *pf)
322 {
323         if (!pf->adev)
324                 return;
325
326         auxiliary_device_delete(pf->adev);
327         auxiliary_device_uninit(pf->adev);
328         pf->adev = NULL;
329 }
330
331 /**
332  * ice_init_rdma - initializes PF for RDMA use
333  * @pf: ptr to ice_pf
334  */
335 int ice_init_rdma(struct ice_pf *pf)
336 {
337         struct device *dev = &pf->pdev->dev;
338         int ret;
339
340         /* Reserve vector resources */
341         ret = ice_reserve_rdma_qvector(pf);
342         if (ret < 0) {
343                 dev_err(dev, "failed to reserve vectors for RDMA\n");
344                 return ret;
345         }
346         pf->rdma_mode |= IIDC_RDMA_PROTOCOL_ROCEV2;
347         return ice_plug_aux_dev(pf);
348 }