xref: /linux/drivers/net/ethernet/intel/ice/ice_dcb_lib.c (revision 4d66c56f7efe122d09d06cd3ebfa52a43d51a9cb)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2019, Intel Corporation. */
3 
4 #include "ice_dcb_lib.h"
5 #include "ice_dcb_nl.h"
6 
7 static void ice_pf_dcb_recfg(struct ice_pf *pf);
8 
9 /**
10  * ice_vsi_cfg_netdev_tc - Setup the netdev TC configuration
11  * @vsi: the VSI being configured
12  * @ena_tc: TC map to be enabled
13  */
14 void ice_vsi_cfg_netdev_tc(struct ice_vsi *vsi, u8 ena_tc)
15 {
16 	struct net_device *netdev = vsi->netdev;
17 	struct ice_pf *pf = vsi->back;
18 	struct ice_dcbx_cfg *dcbcfg;
19 	u8 netdev_tc;
20 	int i;
21 
22 	if (!netdev)
23 		return;
24 
25 	if (!ena_tc) {
26 		netdev_reset_tc(netdev);
27 		return;
28 	}
29 
30 	if (netdev_set_num_tc(netdev, vsi->tc_cfg.numtc))
31 		return;
32 
33 	dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
34 
35 	ice_for_each_traffic_class(i)
36 		if (vsi->tc_cfg.ena_tc & BIT(i))
37 			netdev_set_tc_queue(netdev,
38 					    vsi->tc_cfg.tc_info[i].netdev_tc,
39 					    vsi->tc_cfg.tc_info[i].qcount_tx,
40 					    vsi->tc_cfg.tc_info[i].qoffset);
41 
42 	for (i = 0; i < ICE_MAX_USER_PRIORITY; i++) {
43 		u8 ets_tc = dcbcfg->etscfg.prio_table[i];
44 
45 		/* Get the mapped netdev TC# for the UP */
46 		netdev_tc = vsi->tc_cfg.tc_info[ets_tc].netdev_tc;
47 		netdev_set_prio_tc_map(netdev, i, netdev_tc);
48 	}
49 }
50 
51 /**
52  * ice_dcb_get_ena_tc - return bitmap of enabled TCs
53  * @dcbcfg: DCB config to evaluate for enabled TCs
54  */
55 u8 ice_dcb_get_ena_tc(struct ice_dcbx_cfg *dcbcfg)
56 {
57 	u8 i, num_tc, ena_tc = 1;
58 
59 	num_tc = ice_dcb_get_num_tc(dcbcfg);
60 
61 	for (i = 0; i < num_tc; i++)
62 		ena_tc |= BIT(i);
63 
64 	return ena_tc;
65 }
66 
67 /**
68  * ice_dcb_get_num_tc - Get the number of TCs from DCBX config
69  * @dcbcfg: config to retrieve number of TCs from
70  */
71 u8 ice_dcb_get_num_tc(struct ice_dcbx_cfg *dcbcfg)
72 {
73 	bool tc_unused = false;
74 	u8 num_tc = 0;
75 	u8 ret = 0;
76 	int i;
77 
78 	/* Scan the ETS Config Priority Table to find traffic classes
79 	 * enabled and create a bitmask of enabled TCs
80 	 */
81 	for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
82 		num_tc |= BIT(dcbcfg->etscfg.prio_table[i]);
83 
84 	/* Scan bitmask for contiguous TCs starting with TC0 */
85 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
86 		if (num_tc & BIT(i)) {
87 			if (!tc_unused) {
88 				ret++;
89 			} else {
90 				pr_err("Non-contiguous TCs - Disabling DCB\n");
91 				return 1;
92 			}
93 		} else {
94 			tc_unused = true;
95 		}
96 	}
97 
98 	/* There is always at least 1 TC */
99 	if (!ret)
100 		ret = 1;
101 
102 	return ret;
103 }
104 
105 /**
106  * ice_dcb_get_tc - Get the TC associated with the queue
107  * @vsi: ptr to the VSI
108  * @queue_index: queue number associated with VSI
109  */
110 u8 ice_dcb_get_tc(struct ice_vsi *vsi, int queue_index)
111 {
112 	return vsi->tx_rings[queue_index]->dcb_tc;
113 }
114 
115 /**
116  * ice_vsi_cfg_dcb_rings - Update rings to reflect DCB TC
117  * @vsi: VSI owner of rings being updated
118  */
119 void ice_vsi_cfg_dcb_rings(struct ice_vsi *vsi)
120 {
121 	struct ice_ring *tx_ring, *rx_ring;
122 	u16 qoffset, qcount;
123 	int i, n;
124 
125 	if (!test_bit(ICE_FLAG_DCB_ENA, vsi->back->flags)) {
126 		/* Reset the TC information */
127 		for (i = 0; i < vsi->num_txq; i++) {
128 			tx_ring = vsi->tx_rings[i];
129 			tx_ring->dcb_tc = 0;
130 		}
131 		for (i = 0; i < vsi->num_rxq; i++) {
132 			rx_ring = vsi->rx_rings[i];
133 			rx_ring->dcb_tc = 0;
134 		}
135 		return;
136 	}
137 
138 	ice_for_each_traffic_class(n) {
139 		if (!(vsi->tc_cfg.ena_tc & BIT(n)))
140 			break;
141 
142 		qoffset = vsi->tc_cfg.tc_info[n].qoffset;
143 		qcount = vsi->tc_cfg.tc_info[n].qcount_tx;
144 		for (i = qoffset; i < (qoffset + qcount); i++) {
145 			tx_ring = vsi->tx_rings[i];
146 			rx_ring = vsi->rx_rings[i];
147 			tx_ring->dcb_tc = n;
148 			rx_ring->dcb_tc = n;
149 		}
150 	}
151 }
152 
153 /**
154  * ice_pf_dcb_cfg - Apply new DCB configuration
155  * @pf: pointer to the PF struct
156  * @new_cfg: DCBX config to apply
157  * @locked: is the RTNL held
158  */
159 int ice_pf_dcb_cfg(struct ice_pf *pf, struct ice_dcbx_cfg *new_cfg, bool locked)
160 {
161 	struct ice_aqc_port_ets_elem buf = { 0 };
162 	struct ice_dcbx_cfg *old_cfg, *curr_cfg;
163 	int ret = ICE_DCB_NO_HW_CHG;
164 	struct ice_vsi *pf_vsi;
165 
166 	curr_cfg = &pf->hw.port_info->local_dcbx_cfg;
167 
168 	/* FW does not care if change happened */
169 	if (!pf->hw.port_info->is_sw_lldp)
170 		ret = ICE_DCB_HW_CHG_RST;
171 
172 	/* Enable DCB tagging only when more than one TC */
173 	if (ice_dcb_get_num_tc(new_cfg) > 1) {
174 		dev_dbg(&pf->pdev->dev, "DCB tagging enabled (num TC > 1)\n");
175 		set_bit(ICE_FLAG_DCB_ENA, pf->flags);
176 	} else {
177 		dev_dbg(&pf->pdev->dev, "DCB tagging disabled (num TC = 1)\n");
178 		clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
179 	}
180 
181 	if (!memcmp(new_cfg, curr_cfg, sizeof(*new_cfg))) {
182 		dev_dbg(&pf->pdev->dev, "No change in DCB config required\n");
183 		return ret;
184 	}
185 
186 	/* Store old config in case FW config fails */
187 	old_cfg = kmemdup(curr_cfg, sizeof(*old_cfg), GFP_KERNEL);
188 	if (!old_cfg)
189 		return -ENOMEM;
190 
191 	dev_info(&pf->pdev->dev, "Commit DCB Configuration to the hardware\n");
192 	pf_vsi = ice_get_main_vsi(pf);
193 	if (!pf_vsi) {
194 		dev_dbg(&pf->pdev->dev, "PF VSI doesn't exist\n");
195 		ret = -EINVAL;
196 		goto free_cfg;
197 	}
198 
199 	/* avoid race conditions by holding the lock while disabling and
200 	 * re-enabling the VSI
201 	 */
202 	if (!locked)
203 		rtnl_lock();
204 	ice_dis_vsi(pf_vsi, true);
205 
206 	memcpy(curr_cfg, new_cfg, sizeof(*curr_cfg));
207 	memcpy(&curr_cfg->etsrec, &curr_cfg->etscfg, sizeof(curr_cfg->etsrec));
208 	memcpy(&new_cfg->etsrec, &curr_cfg->etscfg, sizeof(curr_cfg->etsrec));
209 
210 	/* Only send new config to HW if we are in SW LLDP mode. Otherwise,
211 	 * the new config came from the HW in the first place.
212 	 */
213 	if (pf->hw.port_info->is_sw_lldp) {
214 		ret = ice_set_dcb_cfg(pf->hw.port_info);
215 		if (ret) {
216 			dev_err(&pf->pdev->dev, "Set DCB Config failed\n");
217 			/* Restore previous settings to local config */
218 			memcpy(curr_cfg, old_cfg, sizeof(*curr_cfg));
219 			goto out;
220 		}
221 	}
222 
223 	ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
224 	if (ret) {
225 		dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
226 		goto out;
227 	}
228 
229 	ice_pf_dcb_recfg(pf);
230 
231 out:
232 	ice_ena_vsi(pf_vsi, true);
233 	if (!locked)
234 		rtnl_unlock();
235 free_cfg:
236 	kfree(old_cfg);
237 	return ret;
238 }
239 
240 /**
241  * ice_cfg_etsrec_defaults - Set default ETS recommended DCB config
242  * @pi: port information structure
243  */
244 static void ice_cfg_etsrec_defaults(struct ice_port_info *pi)
245 {
246 	struct ice_dcbx_cfg *dcbcfg = &pi->local_dcbx_cfg;
247 	u8 i;
248 
249 	/* Ensure ETS recommended DCB configuration is not already set */
250 	if (dcbcfg->etsrec.maxtcs)
251 		return;
252 
253 	/* In CEE mode, set the default to 1 TC */
254 	dcbcfg->etsrec.maxtcs = 1;
255 	for (i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) {
256 		dcbcfg->etsrec.tcbwtable[i] = i ? 0 : 100;
257 		dcbcfg->etsrec.tsatable[i] = i ? ICE_IEEE_TSA_STRICT :
258 						 ICE_IEEE_TSA_ETS;
259 	}
260 }
261 
262 /**
263  * ice_dcb_need_recfg - Check if DCB needs reconfig
264  * @pf: board private structure
265  * @old_cfg: current DCB config
266  * @new_cfg: new DCB config
267  */
268 static bool
269 ice_dcb_need_recfg(struct ice_pf *pf, struct ice_dcbx_cfg *old_cfg,
270 		   struct ice_dcbx_cfg *new_cfg)
271 {
272 	bool need_reconfig = false;
273 
274 	/* Check if ETS configuration has changed */
275 	if (memcmp(&new_cfg->etscfg, &old_cfg->etscfg,
276 		   sizeof(new_cfg->etscfg))) {
277 		/* If Priority Table has changed reconfig is needed */
278 		if (memcmp(&new_cfg->etscfg.prio_table,
279 			   &old_cfg->etscfg.prio_table,
280 			   sizeof(new_cfg->etscfg.prio_table))) {
281 			need_reconfig = true;
282 			dev_dbg(&pf->pdev->dev, "ETS UP2TC changed.\n");
283 		}
284 
285 		if (memcmp(&new_cfg->etscfg.tcbwtable,
286 			   &old_cfg->etscfg.tcbwtable,
287 			   sizeof(new_cfg->etscfg.tcbwtable)))
288 			dev_dbg(&pf->pdev->dev, "ETS TC BW Table changed.\n");
289 
290 		if (memcmp(&new_cfg->etscfg.tsatable,
291 			   &old_cfg->etscfg.tsatable,
292 			   sizeof(new_cfg->etscfg.tsatable)))
293 			dev_dbg(&pf->pdev->dev, "ETS TSA Table changed.\n");
294 	}
295 
296 	/* Check if PFC configuration has changed */
297 	if (memcmp(&new_cfg->pfc, &old_cfg->pfc, sizeof(new_cfg->pfc))) {
298 		need_reconfig = true;
299 		dev_dbg(&pf->pdev->dev, "PFC config change detected.\n");
300 	}
301 
302 	/* Check if APP Table has changed */
303 	if (memcmp(&new_cfg->app, &old_cfg->app, sizeof(new_cfg->app))) {
304 		need_reconfig = true;
305 		dev_dbg(&pf->pdev->dev, "APP Table change detected.\n");
306 	}
307 
308 	dev_dbg(&pf->pdev->dev, "dcb need_reconfig=%d\n", need_reconfig);
309 	return need_reconfig;
310 }
311 
312 /**
313  * ice_dcb_rebuild - rebuild DCB post reset
314  * @pf: physical function instance
315  */
316 void ice_dcb_rebuild(struct ice_pf *pf)
317 {
318 	struct ice_dcbx_cfg *local_dcbx_cfg, *desired_dcbx_cfg, *prev_cfg;
319 	struct ice_aqc_port_ets_elem buf = { 0 };
320 	enum ice_status ret;
321 
322 	ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
323 	if (ret) {
324 		dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
325 		goto dcb_error;
326 	}
327 
328 	/* If DCB was not enabled previously, we are done */
329 	if (!test_bit(ICE_FLAG_DCB_ENA, pf->flags))
330 		return;
331 
332 	local_dcbx_cfg = &pf->hw.port_info->local_dcbx_cfg;
333 	desired_dcbx_cfg = &pf->hw.port_info->desired_dcbx_cfg;
334 
335 	/* Save current willing state and force FW to unwilling */
336 	local_dcbx_cfg->etscfg.willing = 0x0;
337 	local_dcbx_cfg->pfc.willing = 0x0;
338 	local_dcbx_cfg->app_mode = ICE_DCBX_APPS_NON_WILLING;
339 
340 	ice_cfg_etsrec_defaults(pf->hw.port_info);
341 	ret = ice_set_dcb_cfg(pf->hw.port_info);
342 	if (ret) {
343 		dev_err(&pf->pdev->dev, "Failed to set DCB to unwilling\n");
344 		goto dcb_error;
345 	}
346 
347 	/* Retrieve DCB config and ensure same as current in SW */
348 	prev_cfg = devm_kmemdup(&pf->pdev->dev, local_dcbx_cfg,
349 				sizeof(*prev_cfg), GFP_KERNEL);
350 	if (!prev_cfg) {
351 		dev_err(&pf->pdev->dev, "Failed to alloc space for DCB cfg\n");
352 		goto dcb_error;
353 	}
354 
355 	ice_init_dcb(&pf->hw, true);
356 	if (pf->hw.port_info->dcbx_status == ICE_DCBX_STATUS_DIS)
357 		pf->hw.port_info->is_sw_lldp = true;
358 	else
359 		pf->hw.port_info->is_sw_lldp = false;
360 
361 	if (ice_dcb_need_recfg(pf, prev_cfg, local_dcbx_cfg)) {
362 		/* difference in cfg detected - disable DCB till next MIB */
363 		dev_err(&pf->pdev->dev, "Set local MIB not accurate\n");
364 		goto dcb_error;
365 	}
366 
367 	/* fetched config congruent to previous configuration */
368 	devm_kfree(&pf->pdev->dev, prev_cfg);
369 
370 	/* Set the local desired config */
371 	if (local_dcbx_cfg->dcbx_mode == ICE_DCBX_MODE_CEE)
372 		memcpy(local_dcbx_cfg, desired_dcbx_cfg,
373 		       sizeof(*local_dcbx_cfg));
374 
375 	ice_cfg_etsrec_defaults(pf->hw.port_info);
376 	ret = ice_set_dcb_cfg(pf->hw.port_info);
377 	if (ret) {
378 		dev_err(&pf->pdev->dev, "Failed to set desired config\n");
379 		goto dcb_error;
380 	}
381 	dev_info(&pf->pdev->dev, "DCB restored after reset\n");
382 	ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
383 	if (ret) {
384 		dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
385 		goto dcb_error;
386 	}
387 
388 	return;
389 
390 dcb_error:
391 	dev_err(&pf->pdev->dev, "Disabling DCB until new settings occur\n");
392 	prev_cfg = devm_kzalloc(&pf->pdev->dev, sizeof(*prev_cfg), GFP_KERNEL);
393 	prev_cfg->etscfg.willing = true;
394 	prev_cfg->etscfg.tcbwtable[0] = ICE_TC_MAX_BW;
395 	prev_cfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
396 	memcpy(&prev_cfg->etsrec, &prev_cfg->etscfg, sizeof(prev_cfg->etsrec));
397 	ice_pf_dcb_cfg(pf, prev_cfg, false);
398 	devm_kfree(&pf->pdev->dev, prev_cfg);
399 }
400 
401 /**
402  * ice_dcb_init_cfg - set the initial DCB config in SW
403  * @pf: PF to apply config to
404  * @locked: Is the RTNL held
405  */
406 static int ice_dcb_init_cfg(struct ice_pf *pf, bool locked)
407 {
408 	struct ice_dcbx_cfg *newcfg;
409 	struct ice_port_info *pi;
410 	int ret = 0;
411 
412 	pi = pf->hw.port_info;
413 	newcfg = devm_kzalloc(&pf->pdev->dev, sizeof(*newcfg), GFP_KERNEL);
414 	if (!newcfg)
415 		return -ENOMEM;
416 
417 	memcpy(newcfg, &pi->local_dcbx_cfg, sizeof(*newcfg));
418 	memset(&pi->local_dcbx_cfg, 0, sizeof(*newcfg));
419 
420 	dev_info(&pf->pdev->dev, "Configuring initial DCB values\n");
421 	if (ice_pf_dcb_cfg(pf, newcfg, locked))
422 		ret = -EINVAL;
423 
424 	devm_kfree(&pf->pdev->dev, newcfg);
425 
426 	return ret;
427 }
428 
429 /**
430  * ice_dcb_sw_default_config - Apply a default DCB config
431  * @pf: PF to apply config to
432  * @ets_willing: configure ets willing
433  * @locked: was this function called with RTNL held
434  */
435 static int ice_dcb_sw_dflt_cfg(struct ice_pf *pf, bool ets_willing, bool locked)
436 {
437 	struct ice_aqc_port_ets_elem buf = { 0 };
438 	struct ice_dcbx_cfg *dcbcfg;
439 	struct ice_port_info *pi;
440 	struct ice_hw *hw;
441 	int ret;
442 
443 	hw = &pf->hw;
444 	pi = hw->port_info;
445 	dcbcfg = devm_kzalloc(&pf->pdev->dev, sizeof(*dcbcfg), GFP_KERNEL);
446 
447 	memset(dcbcfg, 0, sizeof(*dcbcfg));
448 	memset(&pi->local_dcbx_cfg, 0, sizeof(*dcbcfg));
449 
450 	dcbcfg->etscfg.willing = ets_willing ? 1 : 0;
451 	dcbcfg->etscfg.maxtcs = hw->func_caps.common_cap.maxtc;
452 	dcbcfg->etscfg.tcbwtable[0] = 100;
453 	dcbcfg->etscfg.tsatable[0] = ICE_IEEE_TSA_ETS;
454 
455 	memcpy(&dcbcfg->etsrec, &dcbcfg->etscfg,
456 	       sizeof(dcbcfg->etsrec));
457 	dcbcfg->etsrec.willing = 0;
458 
459 	dcbcfg->pfc.willing = 1;
460 	dcbcfg->pfc.pfccap = hw->func_caps.common_cap.maxtc;
461 
462 	dcbcfg->numapps = 1;
463 	dcbcfg->app[0].selector = ICE_APP_SEL_ETHTYPE;
464 	dcbcfg->app[0].priority = 3;
465 	dcbcfg->app[0].prot_id = ICE_APP_PROT_ID_FCOE;
466 
467 	ret = ice_pf_dcb_cfg(pf, dcbcfg, locked);
468 	devm_kfree(&pf->pdev->dev, dcbcfg);
469 	if (ret)
470 		return ret;
471 
472 	return ice_query_port_ets(pi, &buf, sizeof(buf), NULL);
473 }
474 
475 /**
476  * ice_dcb_tc_contig - Check that TCs are contiguous
477  * @prio_table: pointer to priority table
478  *
479  * Check if TCs begin with TC0 and are contiguous
480  */
481 static bool ice_dcb_tc_contig(u8 *prio_table)
482 {
483 	u8 max_tc = 0;
484 	int i;
485 
486 	for (i = 0; i < CEE_DCBX_MAX_PRIO; i++) {
487 		u8 cur_tc = prio_table[i];
488 
489 		if (cur_tc > max_tc)
490 			return false;
491 		else if (cur_tc == max_tc)
492 			max_tc++;
493 	}
494 
495 	return true;
496 }
497 
498 /**
499  * ice_dcb_noncontig_cfg - Configure DCB for non-contiguous TCs
500  * @pf: pointer to the PF struct
501  *
502  * If non-contiguous TCs, then configure SW DCB with TC0 and ETS non-willing
503  */
504 static int ice_dcb_noncontig_cfg(struct ice_pf *pf)
505 {
506 	struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
507 	int ret;
508 
509 	/* Configure SW DCB default with ETS non-willing */
510 	ret = ice_dcb_sw_dflt_cfg(pf, false, true);
511 	if (ret) {
512 		dev_err(&pf->pdev->dev,
513 			"Failed to set local DCB config %d\n", ret);
514 		return ret;
515 	}
516 
517 	/* Reconfigure with ETS willing so that FW will send LLDP MIB event */
518 	dcbcfg->etscfg.willing = 1;
519 	ret = ice_set_dcb_cfg(pf->hw.port_info);
520 	if (ret)
521 		dev_err(&pf->pdev->dev, "Failed to set DCB to unwilling\n");
522 
523 	return ret;
524 }
525 
526 /**
527  * ice_pf_dcb_recfg - Reconfigure all VEBs and VSIs
528  * @pf: pointer to the PF struct
529  *
530  * Assumed caller has already disabled all VSIs before
531  * calling this function. Reconfiguring DCB based on
532  * local_dcbx_cfg.
533  */
534 static void ice_pf_dcb_recfg(struct ice_pf *pf)
535 {
536 	struct ice_dcbx_cfg *dcbcfg = &pf->hw.port_info->local_dcbx_cfg;
537 	u8 tc_map = 0;
538 	int v, ret;
539 
540 	/* Update each VSI */
541 	ice_for_each_vsi(pf, v) {
542 		if (!pf->vsi[v])
543 			continue;
544 
545 		if (pf->vsi[v]->type == ICE_VSI_PF) {
546 			tc_map = ice_dcb_get_ena_tc(dcbcfg);
547 
548 			/* If DCBX request non-contiguous TC, then configure
549 			 * default TC
550 			 */
551 			if (!ice_dcb_tc_contig(dcbcfg->etscfg.prio_table)) {
552 				tc_map = ICE_DFLT_TRAFFIC_CLASS;
553 				ice_dcb_noncontig_cfg(pf);
554 			}
555 		} else {
556 			tc_map = ICE_DFLT_TRAFFIC_CLASS;
557 		}
558 
559 		ret = ice_vsi_cfg_tc(pf->vsi[v], tc_map);
560 		if (ret) {
561 			dev_err(&pf->pdev->dev,
562 				"Failed to config TC for VSI index: %d\n",
563 				pf->vsi[v]->idx);
564 			continue;
565 		}
566 
567 		ice_vsi_map_rings_to_vectors(pf->vsi[v]);
568 		if (pf->vsi[v]->type == ICE_VSI_PF)
569 			ice_dcbnl_set_all(pf->vsi[v]);
570 	}
571 }
572 
573 /**
574  * ice_init_pf_dcb - initialize DCB for a PF
575  * @pf: PF to initialize DCB for
576  * @locked: Was function called with RTNL held
577  */
578 int ice_init_pf_dcb(struct ice_pf *pf, bool locked)
579 {
580 	struct device *dev = &pf->pdev->dev;
581 	struct ice_port_info *port_info;
582 	struct ice_hw *hw = &pf->hw;
583 	int err;
584 
585 	port_info = hw->port_info;
586 
587 	err = ice_init_dcb(hw, false);
588 	if (err && !port_info->is_sw_lldp) {
589 		dev_err(&pf->pdev->dev, "Error initializing DCB %d\n", err);
590 		goto dcb_init_err;
591 	}
592 
593 	dev_info(&pf->pdev->dev,
594 		 "DCB is enabled in the hardware, max number of TCs supported on this port are %d\n",
595 		 pf->hw.func_caps.common_cap.maxtc);
596 	if (err) {
597 		struct ice_vsi *pf_vsi;
598 
599 		/* FW LLDP is disabled, activate SW DCBX/LLDP mode */
600 		dev_info(&pf->pdev->dev,
601 			 "FW LLDP is disabled, DCBx/LLDP in SW mode.\n");
602 		clear_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
603 		err = ice_dcb_sw_dflt_cfg(pf, true, locked);
604 		if (err) {
605 			dev_err(&pf->pdev->dev,
606 				"Failed to set local DCB config %d\n", err);
607 			err = -EIO;
608 			goto dcb_init_err;
609 		}
610 
611 		/* If the FW DCBX engine is not running then Rx LLDP packets
612 		 * need to be redirected up the stack.
613 		 */
614 		pf_vsi = ice_get_main_vsi(pf);
615 		if (!pf_vsi) {
616 			dev_err(&pf->pdev->dev,
617 				"Failed to set local DCB config\n");
618 			err = -EIO;
619 			goto dcb_init_err;
620 		}
621 
622 		ice_cfg_sw_lldp(pf_vsi, false, true);
623 
624 		pf->dcbx_cap = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
625 		return 0;
626 	}
627 
628 	set_bit(ICE_FLAG_FW_LLDP_AGENT, pf->flags);
629 
630 	/* DCBX in FW and LLDP enabled in FW */
631 	pf->dcbx_cap = DCB_CAP_DCBX_LLD_MANAGED | DCB_CAP_DCBX_VER_IEEE;
632 
633 	err = ice_dcb_init_cfg(pf, locked);
634 	if (err)
635 		goto dcb_init_err;
636 
637 	return err;
638 
639 dcb_init_err:
640 	dev_err(dev, "DCB init failed\n");
641 	return err;
642 }
643 
644 /**
645  * ice_update_dcb_stats - Update DCB stats counters
646  * @pf: PF whose stats needs to be updated
647  */
648 void ice_update_dcb_stats(struct ice_pf *pf)
649 {
650 	struct ice_hw_port_stats *prev_ps, *cur_ps;
651 	struct ice_hw *hw = &pf->hw;
652 	u8 port;
653 	int i;
654 
655 	port = hw->port_info->lport;
656 	prev_ps = &pf->stats_prev;
657 	cur_ps = &pf->stats;
658 
659 	for (i = 0; i < 8; i++) {
660 		ice_stat_update32(hw, GLPRT_PXOFFRXC(port, i),
661 				  pf->stat_prev_loaded,
662 				  &prev_ps->priority_xoff_rx[i],
663 				  &cur_ps->priority_xoff_rx[i]);
664 		ice_stat_update32(hw, GLPRT_PXONRXC(port, i),
665 				  pf->stat_prev_loaded,
666 				  &prev_ps->priority_xon_rx[i],
667 				  &cur_ps->priority_xon_rx[i]);
668 		ice_stat_update32(hw, GLPRT_PXONTXC(port, i),
669 				  pf->stat_prev_loaded,
670 				  &prev_ps->priority_xon_tx[i],
671 				  &cur_ps->priority_xon_tx[i]);
672 		ice_stat_update32(hw, GLPRT_PXOFFTXC(port, i),
673 				  pf->stat_prev_loaded,
674 				  &prev_ps->priority_xoff_tx[i],
675 				  &cur_ps->priority_xoff_tx[i]);
676 		ice_stat_update32(hw, GLPRT_RXON2OFFCNT(port, i),
677 				  pf->stat_prev_loaded,
678 				  &prev_ps->priority_xon_2_xoff[i],
679 				  &cur_ps->priority_xon_2_xoff[i]);
680 	}
681 }
682 
683 /**
684  * ice_tx_prepare_vlan_flags_dcb - prepare VLAN tagging for DCB
685  * @tx_ring: ring to send buffer on
686  * @first: pointer to struct ice_tx_buf
687  */
688 int
689 ice_tx_prepare_vlan_flags_dcb(struct ice_ring *tx_ring,
690 			      struct ice_tx_buf *first)
691 {
692 	struct sk_buff *skb = first->skb;
693 
694 	if (!test_bit(ICE_FLAG_DCB_ENA, tx_ring->vsi->back->flags))
695 		return 0;
696 
697 	/* Insert 802.1p priority into VLAN header */
698 	if ((first->tx_flags & (ICE_TX_FLAGS_HW_VLAN | ICE_TX_FLAGS_SW_VLAN)) ||
699 	    skb->priority != TC_PRIO_CONTROL) {
700 		first->tx_flags &= ~ICE_TX_FLAGS_VLAN_PR_M;
701 		/* Mask the lower 3 bits to set the 802.1p priority */
702 		first->tx_flags |= (skb->priority & 0x7) <<
703 				   ICE_TX_FLAGS_VLAN_PR_S;
704 		if (first->tx_flags & ICE_TX_FLAGS_SW_VLAN) {
705 			struct vlan_ethhdr *vhdr;
706 			int rc;
707 
708 			rc = skb_cow_head(skb, 0);
709 			if (rc < 0)
710 				return rc;
711 			vhdr = (struct vlan_ethhdr *)skb->data;
712 			vhdr->h_vlan_TCI = htons(first->tx_flags >>
713 						 ICE_TX_FLAGS_VLAN_S);
714 		} else {
715 			first->tx_flags |= ICE_TX_FLAGS_HW_VLAN;
716 		}
717 	}
718 
719 	return 0;
720 }
721 
722 /**
723  * ice_dcb_process_lldp_set_mib_change - Process MIB change
724  * @pf: ptr to ice_pf
725  * @event: pointer to the admin queue receive event
726  */
727 void
728 ice_dcb_process_lldp_set_mib_change(struct ice_pf *pf,
729 				    struct ice_rq_event_info *event)
730 {
731 	struct ice_aqc_port_ets_elem buf = { 0 };
732 	struct ice_aqc_lldp_get_mib *mib;
733 	struct ice_dcbx_cfg tmp_dcbx_cfg;
734 	bool need_reconfig = false;
735 	struct ice_port_info *pi;
736 	struct ice_vsi *pf_vsi;
737 	u8 type;
738 	int ret;
739 
740 	/* Not DCB capable or capability disabled */
741 	if (!(test_bit(ICE_FLAG_DCB_CAPABLE, pf->flags)))
742 		return;
743 
744 	if (pf->dcbx_cap & DCB_CAP_DCBX_HOST) {
745 		dev_dbg(&pf->pdev->dev,
746 			"MIB Change Event in HOST mode\n");
747 		return;
748 	}
749 
750 	pi = pf->hw.port_info;
751 	mib = (struct ice_aqc_lldp_get_mib *)&event->desc.params.raw;
752 	/* Ignore if event is not for Nearest Bridge */
753 	type = ((mib->type >> ICE_AQ_LLDP_BRID_TYPE_S) &
754 		ICE_AQ_LLDP_BRID_TYPE_M);
755 	dev_dbg(&pf->pdev->dev, "LLDP event MIB bridge type 0x%x\n", type);
756 	if (type != ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID)
757 		return;
758 
759 	/* Check MIB Type and return if event for Remote MIB update */
760 	type = mib->type & ICE_AQ_LLDP_MIB_TYPE_M;
761 	dev_dbg(&pf->pdev->dev,
762 		"LLDP event mib type %s\n", type ? "remote" : "local");
763 	if (type == ICE_AQ_LLDP_MIB_REMOTE) {
764 		/* Update the remote cached instance and return */
765 		ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
766 					 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID,
767 					 &pi->remote_dcbx_cfg);
768 		if (ret) {
769 			dev_err(&pf->pdev->dev, "Failed to get remote DCB config\n");
770 			return;
771 		}
772 	}
773 
774 	/* store the old configuration */
775 	tmp_dcbx_cfg = pf->hw.port_info->local_dcbx_cfg;
776 
777 	/* Reset the old DCBX configuration data */
778 	memset(&pi->local_dcbx_cfg, 0, sizeof(pi->local_dcbx_cfg));
779 
780 	/* Get updated DCBX data from firmware */
781 	ret = ice_get_dcb_cfg(pf->hw.port_info);
782 	if (ret) {
783 		dev_err(&pf->pdev->dev, "Failed to get DCB config\n");
784 		return;
785 	}
786 
787 	/* No change detected in DCBX configs */
788 	if (!memcmp(&tmp_dcbx_cfg, &pi->local_dcbx_cfg, sizeof(tmp_dcbx_cfg))) {
789 		dev_dbg(&pf->pdev->dev,
790 			"No change detected in DCBX configuration.\n");
791 		return;
792 	}
793 
794 	need_reconfig = ice_dcb_need_recfg(pf, &tmp_dcbx_cfg,
795 					   &pi->local_dcbx_cfg);
796 	ice_dcbnl_flush_apps(pf, &tmp_dcbx_cfg, &pi->local_dcbx_cfg);
797 	if (!need_reconfig)
798 		return;
799 
800 	/* Enable DCB tagging only when more than one TC */
801 	if (ice_dcb_get_num_tc(&pi->local_dcbx_cfg) > 1) {
802 		dev_dbg(&pf->pdev->dev, "DCB tagging enabled (num TC > 1)\n");
803 		set_bit(ICE_FLAG_DCB_ENA, pf->flags);
804 	} else {
805 		dev_dbg(&pf->pdev->dev, "DCB tagging disabled (num TC = 1)\n");
806 		clear_bit(ICE_FLAG_DCB_ENA, pf->flags);
807 	}
808 
809 	pf_vsi = ice_get_main_vsi(pf);
810 	if (!pf_vsi) {
811 		dev_dbg(&pf->pdev->dev, "PF VSI doesn't exist\n");
812 		return;
813 	}
814 
815 	rtnl_lock();
816 	ice_dis_vsi(pf_vsi, true);
817 
818 	ret = ice_query_port_ets(pf->hw.port_info, &buf, sizeof(buf), NULL);
819 	if (ret) {
820 		dev_err(&pf->pdev->dev, "Query Port ETS failed\n");
821 		rtnl_unlock();
822 		return;
823 	}
824 
825 	/* changes in configuration update VSI */
826 	ice_pf_dcb_recfg(pf);
827 
828 	ice_ena_vsi(pf_vsi, true);
829 	rtnl_unlock();
830 }
831