1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Intel Corporation. */
3 
4 #include "ice.h"
5 #include "ice_dcb.h"
6 #include "ice_dcb_lib.h"
7 #include "ice_dcb_nl.h"
8 #include <net/dcbnl.h>
9 
10 /**
11  * ice_dcbnl_devreset - perform enough of a ifdown/ifup to sync DCBNL info
12  * @netdev: device associated with interface that needs reset
13  */
14 static void ice_dcbnl_devreset(struct net_device *netdev)
15 {
16 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
17 
18 	while (ice_is_reset_in_progress(pf->state))
19 		usleep_range(1000, 2000);
20 
21 	dev_close(netdev);
22 	netdev_state_change(netdev);
23 	dev_open(netdev, NULL);
24 	netdev_state_change(netdev);
25 }
26 
27 /**
28  * ice_dcbnl_getets - retrieve local ETS configuration
29  * @netdev: the relevant netdev
30  * @ets: struct to hold ETS configuration
31  */
32 static int ice_dcbnl_getets(struct net_device *netdev, struct ieee_ets *ets)
33 {
34 	struct ice_dcbx_cfg *dcbxcfg;
35 	struct ice_pf *pf;
36 
37 	pf = ice_netdev_to_pf(netdev);
38 	dcbxcfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
39 
40 	ets->willing = dcbxcfg->etscfg.willing;
41 	ets->ets_cap = dcbxcfg->etscfg.maxtcs;
42 	ets->cbs = dcbxcfg->etscfg.cbs;
43 	memcpy(ets->tc_tx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_tx_bw));
44 	memcpy(ets->tc_rx_bw, dcbxcfg->etscfg.tcbwtable, sizeof(ets->tc_rx_bw));
45 	memcpy(ets->tc_tsa, dcbxcfg->etscfg.tsatable, sizeof(ets->tc_tsa));
46 	memcpy(ets->prio_tc, dcbxcfg->etscfg.prio_table, sizeof(ets->prio_tc));
47 	memcpy(ets->tc_reco_bw, dcbxcfg->etsrec.tcbwtable,
48 	       sizeof(ets->tc_reco_bw));
49 	memcpy(ets->tc_reco_tsa, dcbxcfg->etsrec.tsatable,
50 	       sizeof(ets->tc_reco_tsa));
51 	memcpy(ets->reco_prio_tc, dcbxcfg->etscfg.prio_table,
52 	       sizeof(ets->reco_prio_tc));
53 
54 	return 0;
55 }
56 
57 /**
58  * ice_dcbnl_setets - set IEEE ETS configuration
59  * @netdev: pointer to relevant netdev
60  * @ets: struct to hold ETS configuration
61  */
62 static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets)
63 {
64 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
65 	struct ice_dcbx_cfg *new_cfg;
66 	int bwcfg = 0, bwrec = 0;
67 	int err, i;
68 
69 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
70 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
71 		return -EINVAL;
72 
73 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
74 
75 	mutex_lock(&pf->tc_mutex);
76 
77 	new_cfg->etscfg.willing = ets->willing;
78 	new_cfg->etscfg.cbs = ets->cbs;
79 	ice_for_each_traffic_class(i) {
80 		new_cfg->etscfg.tcbwtable[i] = ets->tc_tx_bw[i];
81 		bwcfg += ets->tc_tx_bw[i];
82 		new_cfg->etscfg.tsatable[i] = ets->tc_tsa[i];
83 		if (new_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
84 			/* in DSCP mode up->tc mapping cannot change */
85 			new_cfg->etscfg.prio_table[i] = ets->prio_tc[i];
86 			new_cfg->etsrec.prio_table[i] = ets->reco_prio_tc[i];
87 		}
88 		new_cfg->etsrec.tcbwtable[i] = ets->tc_reco_bw[i];
89 		bwrec += ets->tc_reco_bw[i];
90 		new_cfg->etsrec.tsatable[i] = ets->tc_reco_tsa[i];
91 	}
92 
93 	if (ice_dcb_bwchk(pf, new_cfg)) {
94 		err = -EINVAL;
95 		goto ets_out;
96 	}
97 
98 	new_cfg->etscfg.maxtcs = pf->hw.func_caps.common_cap.maxtc;
99 
100 	if (!bwrec)
101 		new_cfg->etsrec.tcbwtable[0] = 100;
102 
103 	err = ice_pf_dcb_cfg(pf, new_cfg, true);
104 	/* return of zero indicates new cfg applied */
105 	if (err == ICE_DCB_HW_CHG_RST)
106 		ice_dcbnl_devreset(netdev);
107 	if (err == ICE_DCB_NO_HW_CHG)
108 		err = ICE_DCB_HW_CHG_RST;
109 
110 ets_out:
111 	mutex_unlock(&pf->tc_mutex);
112 	return err;
113 }
114 
115 /**
116  * ice_dcbnl_getnumtcs - Get max number of traffic classes supported
117  * @dev: pointer to netdev struct
118  * @tcid: TC ID
119  * @num: total number of TCs supported by the adapter
120  *
121  * Return the total number of TCs supported
122  */
123 static int
124 ice_dcbnl_getnumtcs(struct net_device *dev, int __always_unused tcid, u8 *num)
125 {
126 	struct ice_pf *pf = ice_netdev_to_pf(dev);
127 
128 	if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
129 		return -EINVAL;
130 
131 	*num = pf->hw.func_caps.common_cap.maxtc;
132 	return 0;
133 }
134 
135 /**
136  * ice_dcbnl_getdcbx - retrieve current DCBX capability
137  * @netdev: pointer to the netdev struct
138  */
139 static u8 ice_dcbnl_getdcbx(struct net_device *netdev)
140 {
141 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
142 
143 	return pf->dcbx_cap;
144 }
145 
146 /**
147  * ice_dcbnl_setdcbx - set required DCBX capability
148  * @netdev: the corresponding netdev
149  * @mode: required mode
150  */
151 static u8 ice_dcbnl_setdcbx(struct net_device *netdev, u8 mode)
152 {
153 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
154 	struct ice_qos_cfg *qos_cfg;
155 
156 	/* if FW LLDP agent is running, DCBNL not allowed to change mode */
157 	if (test_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags))
158 		return ICE_DCB_NO_HW_CHG;
159 
160 	/* No support for LLD_MANAGED modes or CEE+IEEE */
161 	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
162 	    ((mode & DCB_CAP_DCBX_VER_IEEE) && (mode & DCB_CAP_DCBX_VER_CEE)) ||
163 	    !(mode & DCB_CAP_DCBX_HOST))
164 		return ICE_DCB_NO_HW_CHG;
165 
166 	/* Already set to the given mode no change */
167 	if (mode == pf->dcbx_cap)
168 		return ICE_DCB_NO_HW_CHG;
169 
170 	pf->dcbx_cap = mode;
171 	qos_cfg = &pf->hw.port_info->qos_cfg;
172 	if (mode & DCB_CAP_DCBX_VER_CEE) {
173 		if (qos_cfg->local_dcbx_cfg.pfc_mode == ICE_QOS_MODE_DSCP)
174 			return ICE_DCB_NO_HW_CHG;
175 		qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_CEE;
176 	} else {
177 		qos_cfg->local_dcbx_cfg.dcbx_mode = ICE_DCBX_MODE_IEEE;
178 	}
179 
180 	dev_info(ice_pf_to_dev(pf), "DCBx mode = 0x%x\n", mode);
181 	return ICE_DCB_HW_CHG_RST;
182 }
183 
184 /**
185  * ice_dcbnl_get_perm_hw_addr - MAC address used by DCBX
186  * @netdev: pointer to netdev struct
187  * @perm_addr: buffer to return permanent MAC address
188  */
189 static void ice_dcbnl_get_perm_hw_addr(struct net_device *netdev, u8 *perm_addr)
190 {
191 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
192 	struct ice_port_info *pi = pf->hw.port_info;
193 	int i, j;
194 
195 	memset(perm_addr, 0xff, MAX_ADDR_LEN);
196 
197 	for (i = 0; i < netdev->addr_len; i++)
198 		perm_addr[i] = pi->mac.perm_addr[i];
199 
200 	for (j = 0; j < netdev->addr_len; j++, i++)
201 		perm_addr[i] = pi->mac.perm_addr[j];
202 }
203 
204 /**
205  * ice_get_pfc_delay - Retrieve PFC Link Delay
206  * @hw: pointer to HW struct
207  * @delay: holds the PFC Link Delay value
208  */
209 static void ice_get_pfc_delay(struct ice_hw *hw, u16 *delay)
210 {
211 	u32 val;
212 
213 	val = rd32(hw, PRTDCB_GENC);
214 	*delay = (u16)((val & PRTDCB_GENC_PFCLDA_M) >> PRTDCB_GENC_PFCLDA_S);
215 }
216 
217 /**
218  * ice_dcbnl_getpfc - retrieve local IEEE PFC config
219  * @netdev: pointer to netdev struct
220  * @pfc: struct to hold PFC info
221  */
222 static int ice_dcbnl_getpfc(struct net_device *netdev, struct ieee_pfc *pfc)
223 {
224 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
225 	struct ice_port_info *pi = pf->hw.port_info;
226 	struct ice_dcbx_cfg *dcbxcfg;
227 	int i;
228 
229 	dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;
230 	pfc->pfc_cap = dcbxcfg->pfc.pfccap;
231 	pfc->pfc_en = dcbxcfg->pfc.pfcena;
232 	pfc->mbc = dcbxcfg->pfc.mbc;
233 	ice_get_pfc_delay(&pf->hw, &pfc->delay);
234 
235 	ice_for_each_traffic_class(i) {
236 		pfc->requests[i] = pf->stats.priority_xoff_tx[i];
237 		pfc->indications[i] = pf->stats.priority_xoff_rx[i];
238 	}
239 
240 	return 0;
241 }
242 
243 /**
244  * ice_dcbnl_setpfc - set local IEEE PFC config
245  * @netdev: pointer to relevant netdev
246  * @pfc: pointer to struct holding PFC config
247  */
248 static int ice_dcbnl_setpfc(struct net_device *netdev, struct ieee_pfc *pfc)
249 {
250 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
251 	struct ice_dcbx_cfg *new_cfg;
252 	int err;
253 
254 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
255 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
256 		return -EINVAL;
257 
258 	mutex_lock(&pf->tc_mutex);
259 
260 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
261 
262 	if (pfc->pfc_cap)
263 		new_cfg->pfc.pfccap = pfc->pfc_cap;
264 	else
265 		new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;
266 
267 	new_cfg->pfc.pfcena = pfc->pfc_en;
268 
269 	err = ice_pf_dcb_cfg(pf, new_cfg, true);
270 	if (err == ICE_DCB_HW_CHG_RST)
271 		ice_dcbnl_devreset(netdev);
272 	if (err == ICE_DCB_NO_HW_CHG)
273 		err = ICE_DCB_HW_CHG_RST;
274 	mutex_unlock(&pf->tc_mutex);
275 	return err;
276 }
277 
278 /**
279  * ice_dcbnl_get_pfc_cfg - Get CEE PFC config
280  * @netdev: pointer to netdev struct
281  * @prio: corresponding user priority
282  * @setting: the PFC setting for given priority
283  */
284 static void
285 ice_dcbnl_get_pfc_cfg(struct net_device *netdev, int prio, u8 *setting)
286 {
287 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
288 	struct ice_port_info *pi = pf->hw.port_info;
289 
290 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
291 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
292 		return;
293 
294 	if (prio >= ICE_MAX_USER_PRIORITY)
295 		return;
296 
297 	*setting = (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena >> prio) & 0x1;
298 	dev_dbg(ice_pf_to_dev(pf), "Get PFC Config up=%d, setting=%d, pfcenable=0x%x\n",
299 		prio, *setting, pi->qos_cfg.local_dcbx_cfg.pfc.pfcena);
300 }
301 
302 /**
303  * ice_dcbnl_set_pfc_cfg - Set CEE PFC config
304  * @netdev: the corresponding netdev
305  * @prio: User Priority
306  * @set: PFC setting to apply
307  */
308 static void ice_dcbnl_set_pfc_cfg(struct net_device *netdev, int prio, u8 set)
309 {
310 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
311 	struct ice_dcbx_cfg *new_cfg;
312 
313 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
314 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
315 		return;
316 
317 	if (prio >= ICE_MAX_USER_PRIORITY)
318 		return;
319 
320 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
321 
322 	new_cfg->pfc.pfccap = pf->hw.func_caps.common_cap.maxtc;
323 	if (set)
324 		new_cfg->pfc.pfcena |= BIT(prio);
325 	else
326 		new_cfg->pfc.pfcena &= ~BIT(prio);
327 
328 	dev_dbg(ice_pf_to_dev(pf), "Set PFC config UP:%d set:%d pfcena:0x%x\n",
329 		prio, set, new_cfg->pfc.pfcena);
330 }
331 
332 /**
333  * ice_dcbnl_getpfcstate - get CEE PFC mode
334  * @netdev: pointer to netdev struct
335  */
336 static u8 ice_dcbnl_getpfcstate(struct net_device *netdev)
337 {
338 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
339 	struct ice_port_info *pi = pf->hw.port_info;
340 
341 	/* Return enabled if any UP enabled for PFC */
342 	if (pi->qos_cfg.local_dcbx_cfg.pfc.pfcena)
343 		return 1;
344 
345 	return 0;
346 }
347 
348 /**
349  * ice_dcbnl_getstate - get DCB enabled state
350  * @netdev: pointer to netdev struct
351  */
352 static u8 ice_dcbnl_getstate(struct net_device *netdev)
353 {
354 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
355 	u8 state = 0;
356 
357 	state = test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags);
358 
359 	dev_dbg(ice_pf_to_dev(pf), "DCB enabled state = %d\n", state);
360 	return state;
361 }
362 
363 /**
364  * ice_dcbnl_setstate - Set CEE DCB state
365  * @netdev: pointer to relevant netdev
366  * @state: state value to set
367  */
368 static u8 ice_dcbnl_setstate(struct net_device *netdev, u8 state)
369 {
370 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
371 
372 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
373 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
374 		return ICE_DCB_NO_HW_CHG;
375 
376 	/* Nothing to do */
377 	if (!!state == test_bit(ICE_FLAG_DCB_ENA, pf->flags))
378 		return ICE_DCB_NO_HW_CHG;
379 
380 	if (state) {
381 		set_bit(ICE_FLAG_DCB_ENA, pf->flags);
382 		memcpy(&pf->hw.port_info->qos_cfg.desired_dcbx_cfg,
383 		       &pf->hw.port_info->qos_cfg.local_dcbx_cfg,
384 		       sizeof(struct ice_dcbx_cfg));
385 	} else {
386 		clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
387 	}
388 
389 	return ICE_DCB_HW_CHG;
390 }
391 
392 /**
393  * ice_dcbnl_get_pg_tc_cfg_tx - get CEE PG Tx config
394  * @netdev: pointer to netdev struct
395  * @prio: the corresponding user priority
396  * @prio_type: traffic priority type
397  * @pgid: the BW group ID the traffic class belongs to
398  * @bw_pct: BW percentage for the corresponding BWG
399  * @up_map: prio mapped to corresponding TC
400  */
401 static void
402 ice_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int prio,
403 			   u8 __always_unused *prio_type, u8 *pgid,
404 			   u8 __always_unused *bw_pct,
405 			   u8 __always_unused *up_map)
406 {
407 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
408 	struct ice_port_info *pi = pf->hw.port_info;
409 
410 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
411 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
412 		return;
413 
414 	if (prio >= ICE_MAX_USER_PRIORITY)
415 		return;
416 
417 	*pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
418 	dev_dbg(ice_pf_to_dev(pf), "Get PG config prio=%d tc=%d\n", prio,
419 		*pgid);
420 }
421 
422 /**
423  * ice_dcbnl_set_pg_tc_cfg_tx - set CEE PG Tx config
424  * @netdev: pointer to relevant netdev
425  * @tc: the corresponding traffic class
426  * @prio_type: the traffic priority type
427  * @bwg_id: the BW group ID the TC belongs to
428  * @bw_pct: the BW perventage for the BWG
429  * @up_map: prio mapped to corresponding TC
430  */
431 static void
432 ice_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
433 			   u8 __always_unused prio_type,
434 			   u8 __always_unused bwg_id,
435 			   u8 __always_unused bw_pct, u8 up_map)
436 {
437 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
438 	struct ice_dcbx_cfg *new_cfg;
439 	int i;
440 
441 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
442 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
443 		return;
444 
445 	if (tc >= ICE_MAX_TRAFFIC_CLASS)
446 		return;
447 
448 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
449 
450 	/* prio_type, bwg_id and bw_pct per UP are not supported */
451 
452 	ice_for_each_traffic_class(i) {
453 		if (up_map & BIT(i))
454 			new_cfg->etscfg.prio_table[i] = tc;
455 	}
456 	new_cfg->etscfg.tsatable[tc] = ICE_IEEE_TSA_ETS;
457 }
458 
459 /**
460  * ice_dcbnl_get_pg_bwg_cfg_tx - Get CEE PGBW config
461  * @netdev: pointer to the netdev struct
462  * @pgid: corresponding traffic class
463  * @bw_pct: the BW percentage for the corresponding TC
464  */
465 static void
466 ice_dcbnl_get_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 *bw_pct)
467 {
468 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
469 	struct ice_port_info *pi = pf->hw.port_info;
470 
471 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
472 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
473 		return;
474 
475 	if (pgid >= ICE_MAX_TRAFFIC_CLASS)
476 		return;
477 
478 	*bw_pct = pi->qos_cfg.local_dcbx_cfg.etscfg.tcbwtable[pgid];
479 	dev_dbg(ice_pf_to_dev(pf), "Get PG BW config tc=%d bw_pct=%d\n",
480 		pgid, *bw_pct);
481 }
482 
483 /**
484  * ice_dcbnl_set_pg_bwg_cfg_tx - set CEE PG Tx BW config
485  * @netdev: the corresponding netdev
486  * @pgid: Correspongind traffic class
487  * @bw_pct: the BW percentage for the specified TC
488  */
489 static void
490 ice_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int pgid, u8 bw_pct)
491 {
492 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
493 	struct ice_dcbx_cfg *new_cfg;
494 
495 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
496 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
497 		return;
498 
499 	if (pgid >= ICE_MAX_TRAFFIC_CLASS)
500 		return;
501 
502 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
503 
504 	new_cfg->etscfg.tcbwtable[pgid] = bw_pct;
505 }
506 
507 /**
508  * ice_dcbnl_get_pg_tc_cfg_rx - Get CEE PG Rx config
509  * @netdev: pointer to netdev struct
510  * @prio: the corresponding user priority
511  * @prio_type: the traffic priority type
512  * @pgid: the PG ID
513  * @bw_pct: the BW percentage for the corresponding BWG
514  * @up_map: prio mapped to corresponding TC
515  */
516 static void
517 ice_dcbnl_get_pg_tc_cfg_rx(struct net_device *netdev, int prio,
518 			   u8 __always_unused *prio_type, u8 *pgid,
519 			   u8 __always_unused *bw_pct,
520 			   u8 __always_unused *up_map)
521 {
522 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
523 	struct ice_port_info *pi = pf->hw.port_info;
524 
525 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
526 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
527 		return;
528 
529 	if (prio >= ICE_MAX_USER_PRIORITY)
530 		return;
531 
532 	*pgid = pi->qos_cfg.local_dcbx_cfg.etscfg.prio_table[prio];
533 }
534 
535 /**
536  * ice_dcbnl_set_pg_tc_cfg_rx
537  * @netdev: relevant netdev struct
538  * @prio: corresponding user priority
539  * @prio_type: the traffic priority type
540  * @pgid: the PG ID
541  * @bw_pct: BW percentage for corresponding BWG
542  * @up_map: prio mapped to corresponding TC
543  *
544  * lldpad requires this function pointer to be non-NULL to complete CEE config.
545  */
546 static void
547 ice_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev,
548 			   int __always_unused prio,
549 			   u8 __always_unused prio_type,
550 			   u8 __always_unused pgid,
551 			   u8 __always_unused bw_pct,
552 			   u8 __always_unused up_map)
553 {
554 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
555 
556 	dev_dbg(ice_pf_to_dev(pf), "Rx TC PG Config Not Supported.\n");
557 }
558 
559 /**
560  * ice_dcbnl_get_pg_bwg_cfg_rx - Get CEE PG BW Rx config
561  * @netdev: pointer to netdev struct
562  * @pgid: the corresponding traffic class
563  * @bw_pct: the BW percentage for the corresponding TC
564  */
565 static void
566 ice_dcbnl_get_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
567 			    u8 *bw_pct)
568 {
569 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
570 
571 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
572 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
573 		return;
574 
575 	*bw_pct = 0;
576 }
577 
578 /**
579  * ice_dcbnl_set_pg_bwg_cfg_rx
580  * @netdev: the corresponding netdev
581  * @pgid: corresponding TC
582  * @bw_pct: BW percentage for given TC
583  *
584  * lldpad requires this function pointer to be non-NULL to complete CEE config.
585  */
586 static void
587 ice_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int __always_unused pgid,
588 			    u8 __always_unused bw_pct)
589 {
590 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
591 
592 	dev_dbg(ice_pf_to_dev(pf), "Rx BWG PG Config Not Supported.\n");
593 }
594 
595 /**
596  * ice_dcbnl_get_cap - Get DCBX capabilities of adapter
597  * @netdev: pointer to netdev struct
598  * @capid: the capability type
599  * @cap: the capability value
600  */
601 static u8 ice_dcbnl_get_cap(struct net_device *netdev, int capid, u8 *cap)
602 {
603 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
604 
605 	if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
606 		return ICE_DCB_NO_HW_CHG;
607 
608 	switch (capid) {
609 	case DCB_CAP_ATTR_PG:
610 		*cap = true;
611 		break;
612 	case DCB_CAP_ATTR_PFC:
613 		*cap = true;
614 		break;
615 	case DCB_CAP_ATTR_UP2TC:
616 		*cap = false;
617 		break;
618 	case DCB_CAP_ATTR_PG_TCS:
619 		*cap = 0x80;
620 		break;
621 	case DCB_CAP_ATTR_PFC_TCS:
622 		*cap = 0x80;
623 		break;
624 	case DCB_CAP_ATTR_GSP:
625 		*cap = false;
626 		break;
627 	case DCB_CAP_ATTR_BCN:
628 		*cap = false;
629 		break;
630 	case DCB_CAP_ATTR_DCBX:
631 		*cap = pf->dcbx_cap;
632 		break;
633 	default:
634 		*cap = false;
635 		break;
636 	}
637 
638 	dev_dbg(ice_pf_to_dev(pf), "DCBX Get Capability cap=%d capval=0x%x\n",
639 		capid, *cap);
640 	return 0;
641 }
642 
643 /**
644  * ice_dcbnl_getapp - get CEE APP
645  * @netdev: pointer to netdev struct
646  * @idtype: the App selector
647  * @id: the App ethtype or port number
648  */
649 static int ice_dcbnl_getapp(struct net_device *netdev, u8 idtype, u16 id)
650 {
651 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
652 	struct dcb_app app = {
653 				.selector = idtype,
654 				.protocol = id,
655 			     };
656 
657 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
658 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
659 		return -EINVAL;
660 
661 	return dcb_getapp(netdev, &app);
662 }
663 
664 /**
665  * ice_dcbnl_find_app - Search for APP in given DCB config
666  * @cfg: struct to hold DCBX config
667  * @app: struct to hold app data to look for
668  */
669 static bool
670 ice_dcbnl_find_app(struct ice_dcbx_cfg *cfg,
671 		   struct ice_dcb_app_priority_table *app)
672 {
673 	unsigned int i;
674 
675 	for (i = 0; i < cfg->numapps; i++) {
676 		if (app->selector == cfg->app[i].selector &&
677 		    app->prot_id == cfg->app[i].prot_id &&
678 		    app->priority == cfg->app[i].priority)
679 			return true;
680 	}
681 
682 	return false;
683 }
684 
685 #define ICE_BYTES_PER_DSCP_VAL		8
686 
687 /**
688  * ice_dcbnl_setapp - set local IEEE App config
689  * @netdev: relevant netdev struct
690  * @app: struct to hold app config info
691  */
692 static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app)
693 {
694 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
695 	struct ice_dcb_app_priority_table new_app;
696 	struct ice_dcbx_cfg *old_cfg, *new_cfg;
697 	u8 max_tc;
698 	int ret;
699 
700 	/* ONLY DSCP APP TLVs have operational significance */
701 	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
702 		return -EINVAL;
703 
704 	/* only allow APP TLVs in SW Mode */
705 	if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
706 		netdev_err(netdev, "can't do DSCP QoS when FW DCB agent active\n");
707 		return -EINVAL;
708 	}
709 
710 	if (!(pf->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
711 		return -EINVAL;
712 
713 	if (!ice_is_feature_supported(pf, ICE_F_DSCP))
714 		return -EOPNOTSUPP;
715 
716 	if (app->protocol >= ICE_DSCP_NUM_VAL) {
717 		netdev_err(netdev, "DSCP value 0x%04X out of range\n",
718 			   app->protocol);
719 		return -EINVAL;
720 	}
721 
722 	max_tc = pf->hw.func_caps.common_cap.maxtc;
723 	if (app->priority >= max_tc) {
724 		netdev_err(netdev, "TC %d out of range, max TC %d\n",
725 			   app->priority, max_tc);
726 		return -EINVAL;
727 	}
728 
729 	/* grab TC mutex */
730 	mutex_lock(&pf->tc_mutex);
731 
732 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
733 	old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
734 
735 	ret = dcb_ieee_setapp(netdev, app);
736 	if (ret)
737 		goto setapp_out;
738 
739 	if (test_and_set_bit(app->protocol, new_cfg->dscp_mapped)) {
740 		netdev_err(netdev, "DSCP value 0x%04X already user mapped\n",
741 			   app->protocol);
742 		ret = dcb_ieee_delapp(netdev, app);
743 		if (ret)
744 			netdev_err(netdev, "Failed to delete re-mapping TLV\n");
745 		ret = -EINVAL;
746 		goto setapp_out;
747 	}
748 
749 	new_app.selector = app->selector;
750 	new_app.prot_id = app->protocol;
751 	new_app.priority = app->priority;
752 
753 	/* If port is not in DSCP mode, need to set */
754 	if (old_cfg->pfc_mode == ICE_QOS_MODE_VLAN) {
755 		int i, j;
756 
757 		/* set DSCP mode */
758 		ret = ice_aq_set_pfc_mode(&pf->hw, ICE_AQC_PFC_DSCP_BASED_PFC,
759 					  NULL);
760 		if (ret) {
761 			netdev_err(netdev, "Failed to set DSCP PFC mode %d\n",
762 				   ret);
763 			goto setapp_out;
764 		}
765 		netdev_info(netdev, "Switched QoS to L3 DSCP mode\n");
766 
767 		new_cfg->pfc_mode = ICE_QOS_MODE_DSCP;
768 
769 		/* set default DSCP QoS values */
770 		new_cfg->etscfg.willing = 0;
771 		new_cfg->pfc.pfccap = max_tc;
772 		new_cfg->pfc.willing = 0;
773 
774 		for (i = 0; i < max_tc; i++)
775 			for (j = 0; j < ICE_BYTES_PER_DSCP_VAL; j++) {
776 				int dscp, offset;
777 
778 				dscp = (i * max_tc) + j;
779 				offset = max_tc * ICE_BYTES_PER_DSCP_VAL;
780 
781 				new_cfg->dscp_map[dscp] = i;
782 				/* if less that 8 TCs supported */
783 				if (max_tc < ICE_MAX_TRAFFIC_CLASS)
784 					new_cfg->dscp_map[dscp + offset] = i;
785 			}
786 
787 		new_cfg->etscfg.tcbwtable[0] = 100;
788 		new_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
789 		new_cfg->etscfg.prio_table[0] = 0;
790 
791 		for (i = 1; i < max_tc; i++) {
792 			new_cfg->etscfg.tcbwtable[i] = 0;
793 			new_cfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
794 			new_cfg->etscfg.prio_table[i] = i;
795 		}
796 	} /* end of switching to DSCP mode */
797 
798 	/* apply new mapping for this DSCP value */
799 	new_cfg->dscp_map[app->protocol] = app->priority;
800 	new_cfg->app[new_cfg->numapps++] = new_app;
801 
802 	ret = ice_pf_dcb_cfg(pf, new_cfg, true);
803 	/* return of zero indicates new cfg applied */
804 	if (ret == ICE_DCB_HW_CHG_RST)
805 		ice_dcbnl_devreset(netdev);
806 	else
807 		ret = ICE_DCB_NO_HW_CHG;
808 
809 setapp_out:
810 	mutex_unlock(&pf->tc_mutex);
811 	return ret;
812 }
813 
814 /**
815  * ice_dcbnl_delapp - Delete local IEEE App config
816  * @netdev: relevant netdev
817  * @app: struct to hold app too delete
818  *
819  * Will not delete first application required by the FW
820  */
821 static int ice_dcbnl_delapp(struct net_device *netdev, struct dcb_app *app)
822 {
823 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
824 	struct ice_dcbx_cfg *old_cfg, *new_cfg;
825 	unsigned int i, j;
826 	int ret = 0;
827 
828 	if (pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) {
829 		netdev_err(netdev, "can't delete DSCP netlink app when FW DCB agent is active\n");
830 		return -EINVAL;
831 	}
832 
833 	mutex_lock(&pf->tc_mutex);
834 	old_cfg = &pf->hw.port_info->qos_cfg.local_dcbx_cfg;
835 
836 	ret = dcb_ieee_delapp(netdev, app);
837 	if (ret)
838 		goto delapp_out;
839 
840 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
841 
842 	for (i = 0; i < new_cfg->numapps; i++) {
843 		if (app->selector == new_cfg->app[i].selector &&
844 		    app->protocol == new_cfg->app[i].prot_id &&
845 		    app->priority == new_cfg->app[i].priority) {
846 			new_cfg->app[i].selector = 0;
847 			new_cfg->app[i].prot_id = 0;
848 			new_cfg->app[i].priority = 0;
849 			break;
850 		}
851 	}
852 
853 	/* Did not find DCB App */
854 	if (i == new_cfg->numapps) {
855 		ret = -EINVAL;
856 		goto delapp_out;
857 	}
858 
859 	new_cfg->numapps--;
860 
861 	for (j = i; j < new_cfg->numapps; j++) {
862 		new_cfg->app[j].selector = old_cfg->app[j + 1].selector;
863 		new_cfg->app[j].prot_id = old_cfg->app[j + 1].prot_id;
864 		new_cfg->app[j].priority = old_cfg->app[j + 1].priority;
865 	}
866 
867 	/* if not a DSCP APP TLV or DSCP is not supported, we are done */
868 	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
869 	    !ice_is_feature_supported(pf, ICE_F_DSCP)) {
870 		ret = ICE_DCB_HW_CHG;
871 		goto delapp_out;
872 	}
873 
874 	/* if DSCP TLV, then need to address change in mapping */
875 	clear_bit(app->protocol, new_cfg->dscp_mapped);
876 	/* remap this DSCP value to default value */
877 	new_cfg->dscp_map[app->protocol] = app->protocol %
878 					   ICE_BYTES_PER_DSCP_VAL;
879 
880 	/* if the last DSCP mapping just got deleted, need to switch
881 	 * to L2 VLAN QoS mode
882 	 */
883 	if (bitmap_empty(new_cfg->dscp_mapped, ICE_DSCP_NUM_VAL) &&
884 	    new_cfg->pfc_mode == ICE_QOS_MODE_DSCP) {
885 		ret = ice_aq_set_pfc_mode(&pf->hw,
886 					  ICE_AQC_PFC_VLAN_BASED_PFC,
887 					  NULL);
888 		if (ret) {
889 			netdev_info(netdev, "Failed to set VLAN PFC mode %d\n",
890 				    ret);
891 			goto delapp_out;
892 		}
893 		netdev_info(netdev, "Switched QoS to L2 VLAN mode\n");
894 
895 		new_cfg->pfc_mode = ICE_QOS_MODE_VLAN;
896 
897 		ret = ice_dcb_sw_dflt_cfg(pf, true, true);
898 	} else {
899 		ret = ice_pf_dcb_cfg(pf, new_cfg, true);
900 	}
901 
902 	/* return of ICE_DCB_HW_CHG_RST indicates new cfg applied
903 	 * and reset needs to be performed
904 	 */
905 	if (ret == ICE_DCB_HW_CHG_RST)
906 		ice_dcbnl_devreset(netdev);
907 
908 	/* if the change was not siginificant enough to actually call
909 	 * the reconfiguration flow, we still need to tell caller that
910 	 * their request was successfully handled
911 	 */
912 	if (ret == ICE_DCB_NO_HW_CHG)
913 		ret = ICE_DCB_HW_CHG;
914 
915 delapp_out:
916 	mutex_unlock(&pf->tc_mutex);
917 	return ret;
918 }
919 
920 /**
921  * ice_dcbnl_cee_set_all - Commit CEE DCB settings to HW
922  * @netdev: the corresponding netdev
923  */
924 static u8 ice_dcbnl_cee_set_all(struct net_device *netdev)
925 {
926 	struct ice_pf *pf = ice_netdev_to_pf(netdev);
927 	struct ice_dcbx_cfg *new_cfg;
928 	int err;
929 
930 	if ((pf->dcbx_cap & DCB_CAP_DCBX_LLD_MANAGED) ||
931 	    !(pf->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
932 		return ICE_DCB_NO_HW_CHG;
933 
934 	new_cfg = &pf->hw.port_info->qos_cfg.desired_dcbx_cfg;
935 
936 	mutex_lock(&pf->tc_mutex);
937 
938 	err = ice_pf_dcb_cfg(pf, new_cfg, true);
939 
940 	mutex_unlock(&pf->tc_mutex);
941 	return (err != ICE_DCB_HW_CHG_RST) ? ICE_DCB_NO_HW_CHG : err;
942 }
943 
944 static const struct dcbnl_rtnl_ops dcbnl_ops = {
945 	/* IEEE 802.1Qaz std */
946 	.ieee_getets = ice_dcbnl_getets,
947 	.ieee_setets = ice_dcbnl_setets,
948 	.ieee_getpfc = ice_dcbnl_getpfc,
949 	.ieee_setpfc = ice_dcbnl_setpfc,
950 	.ieee_setapp = ice_dcbnl_setapp,
951 	.ieee_delapp = ice_dcbnl_delapp,
952 
953 	/* CEE std */
954 	.getstate = ice_dcbnl_getstate,
955 	.setstate = ice_dcbnl_setstate,
956 	.getpermhwaddr = ice_dcbnl_get_perm_hw_addr,
957 	.setpgtccfgtx = ice_dcbnl_set_pg_tc_cfg_tx,
958 	.setpgbwgcfgtx = ice_dcbnl_set_pg_bwg_cfg_tx,
959 	.setpgtccfgrx = ice_dcbnl_set_pg_tc_cfg_rx,
960 	.setpgbwgcfgrx = ice_dcbnl_set_pg_bwg_cfg_rx,
961 	.getpgtccfgtx = ice_dcbnl_get_pg_tc_cfg_tx,
962 	.getpgbwgcfgtx = ice_dcbnl_get_pg_bwg_cfg_tx,
963 	.getpgtccfgrx = ice_dcbnl_get_pg_tc_cfg_rx,
964 	.getpgbwgcfgrx = ice_dcbnl_get_pg_bwg_cfg_rx,
965 	.setpfccfg = ice_dcbnl_set_pfc_cfg,
966 	.getpfccfg = ice_dcbnl_get_pfc_cfg,
967 	.setall = ice_dcbnl_cee_set_all,
968 	.getcap = ice_dcbnl_get_cap,
969 	.getnumtcs = ice_dcbnl_getnumtcs,
970 	.getpfcstate = ice_dcbnl_getpfcstate,
971 	.getapp = ice_dcbnl_getapp,
972 
973 	/* DCBX configuration */
974 	.getdcbx = ice_dcbnl_getdcbx,
975 	.setdcbx = ice_dcbnl_setdcbx,
976 };
977 
978 /**
979  * ice_dcbnl_set_all - set all the apps and ieee data from DCBX config
980  * @vsi: pointer to VSI struct
981  */
982 void ice_dcbnl_set_all(struct ice_vsi *vsi)
983 {
984 	struct net_device *netdev = vsi->netdev;
985 	struct ice_dcbx_cfg *dcbxcfg;
986 	struct ice_port_info *pi;
987 	struct dcb_app sapp;
988 	struct ice_pf *pf;
989 	unsigned int i;
990 
991 	if (!netdev)
992 		return;
993 
994 	pf = ice_netdev_to_pf(netdev);
995 	pi = pf->hw.port_info;
996 
997 	/* SW DCB taken care of by SW Default Config */
998 	if (pf->dcbx_cap & DCB_CAP_DCBX_HOST)
999 		return;
1000 
1001 	/* DCB not enabled */
1002 	if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
1003 		return;
1004 
1005 	dcbxcfg = &pi->qos_cfg.local_dcbx_cfg;
1006 
1007 	for (i = 0; i < dcbxcfg->numapps; i++) {
1008 		u8 prio, tc_map;
1009 
1010 		prio = dcbxcfg->app[i].priority;
1011 		tc_map = BIT(dcbxcfg->etscfg.prio_table[prio]);
1012 
1013 		/* Add APP only if the TC is enabled for this VSI */
1014 		if (tc_map & vsi->tc_cfg.ena_tc) {
1015 			sapp.selector = dcbxcfg->app[i].selector;
1016 			sapp.protocol = dcbxcfg->app[i].prot_id;
1017 			sapp.priority = prio;
1018 			dcb_ieee_setapp(netdev, &sapp);
1019 		}
1020 	}
1021 	/* Notify user-space of the changes */
1022 	dcbnl_ieee_notify(netdev, RTM_SETDCB, DCB_CMD_IEEE_SET, 0, 0);
1023 }
1024 
1025 /**
1026  * ice_dcbnl_vsi_del_app - Delete APP on all VSIs
1027  * @vsi: pointer to the main VSI
1028  * @app: APP to delete
1029  *
1030  * Delete given APP from all the VSIs for given PF
1031  */
1032 static void
1033 ice_dcbnl_vsi_del_app(struct ice_vsi *vsi,
1034 		      struct ice_dcb_app_priority_table *app)
1035 {
1036 	struct dcb_app sapp;
1037 	int err;
1038 
1039 	sapp.selector = app->selector;
1040 	sapp.protocol = app->prot_id;
1041 	sapp.priority = app->priority;
1042 	err = ice_dcbnl_delapp(vsi->netdev, &sapp);
1043 	dev_dbg(ice_pf_to_dev(vsi->back), "Deleting app for VSI idx=%d err=%d sel=%d proto=0x%x, prio=%d\n",
1044 		vsi->idx, err, app->selector, app->prot_id, app->priority);
1045 }
1046 
1047 /**
1048  * ice_dcbnl_flush_apps - Delete all removed APPs
1049  * @pf: the corresponding PF
1050  * @old_cfg: old DCBX configuration data
1051  * @new_cfg: new DCBX configuration data
1052  *
1053  * Find and delete all APPS that are not present in the passed
1054  * DCB configuration
1055  */
1056 void
1057 ice_dcbnl_flush_apps(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
1058 		     struct ice_dcbx_cfg *new_cfg)
1059 {
1060 	struct ice_vsi *main_vsi = ice_get_main_vsi(pf);
1061 	unsigned int i;
1062 
1063 	if (!main_vsi)
1064 		return;
1065 
1066 	for (i = 0; i < old_cfg->numapps; i++) {
1067 		struct ice_dcb_app_priority_table app = old_cfg->app[i];
1068 
1069 		/* The APP is not available anymore delete it */
1070 		if (!ice_dcbnl_find_app(new_cfg, &app))
1071 			ice_dcbnl_vsi_del_app(main_vsi, &app);
1072 	}
1073 }
1074 
1075 /**
1076  * ice_dcbnl_setup - setup DCBNL
1077  * @vsi: VSI to get associated netdev from
1078  */
1079 void ice_dcbnl_setup(struct ice_vsi *vsi)
1080 {
1081 	struct net_device *netdev = vsi->netdev;
1082 	struct ice_pf *pf;
1083 
1084 	pf = ice_netdev_to_pf(netdev);
1085 	if (!test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags))
1086 		return;
1087 
1088 	netdev->dcbnl_ops = &dcbnl_ops;
1089 	ice_dcbnl_set_all(vsi);
1090 }
1091