xref: /linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0+
2 // Copyright (c) 2016-2017 Hisilicon Limited.
3 
4 #include "hclge_main.h"
5 #include "hclge_dcb.h"
6 #include "hclge_tm.h"
7 #include "hnae3.h"
8 
9 #define BW_PERCENT	100
10 
11 static int hclge_ieee_ets_to_tm_info(struct hclge_dev *hdev,
12 				     struct ieee_ets *ets)
13 {
14 	u8 i;
15 
16 	for (i = 0; i < HNAE3_MAX_TC; i++) {
17 		switch (ets->tc_tsa[i]) {
18 		case IEEE_8021QAZ_TSA_STRICT:
19 			hdev->tm_info.tc_info[i].tc_sch_mode =
20 				HCLGE_SCH_MODE_SP;
21 			hdev->tm_info.pg_info[0].tc_dwrr[i] = 0;
22 			break;
23 		case IEEE_8021QAZ_TSA_ETS:
24 			hdev->tm_info.tc_info[i].tc_sch_mode =
25 				HCLGE_SCH_MODE_DWRR;
26 			hdev->tm_info.pg_info[0].tc_dwrr[i] =
27 				ets->tc_tx_bw[i];
28 			break;
29 		default:
30 			/* Hardware only supports SP (strict priority)
31 			 * or ETS (enhanced transmission selection)
32 			 * algorithms, if we receive some other value
33 			 * from dcbnl, then throw an error.
34 			 */
35 			return -EINVAL;
36 		}
37 	}
38 
39 	hclge_tm_prio_tc_info_update(hdev, ets->prio_tc);
40 
41 	return 0;
42 }
43 
44 static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev,
45 				      struct ieee_ets *ets)
46 {
47 	u32 i;
48 
49 	memset(ets, 0, sizeof(*ets));
50 	ets->willing = 1;
51 	ets->ets_cap = hdev->tc_max;
52 
53 	for (i = 0; i < HNAE3_MAX_TC; i++) {
54 		ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
55 		if (i < hdev->tm_info.num_tc)
56 			ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
57 		else
58 			ets->tc_tx_bw[i] = 0;
59 
60 		if (hdev->tm_info.tc_info[i].tc_sch_mode ==
61 		    HCLGE_SCH_MODE_SP)
62 			ets->tc_tsa[i] = IEEE_8021QAZ_TSA_STRICT;
63 		else
64 			ets->tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
65 	}
66 }
67 
68 /* IEEE std */
69 static int hclge_ieee_getets(struct hnae3_handle *h, struct ieee_ets *ets)
70 {
71 	struct hclge_vport *vport = hclge_get_vport(h);
72 	struct hclge_dev *hdev = vport->back;
73 
74 	hclge_tm_info_to_ieee_ets(hdev, ets);
75 
76 	return 0;
77 }
78 
79 static int hclge_dcb_common_validate(struct hclge_dev *hdev, u8 num_tc,
80 				     u8 *prio_tc)
81 {
82 	int i;
83 
84 	if (num_tc > hdev->tc_max) {
85 		dev_err(&hdev->pdev->dev,
86 			"tc num checking failed, %u > tc_max(%u)\n",
87 			num_tc, hdev->tc_max);
88 		return -EINVAL;
89 	}
90 
91 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
92 		if (prio_tc[i] >= num_tc) {
93 			dev_err(&hdev->pdev->dev,
94 				"prio_tc[%d] checking failed, %u >= num_tc(%u)\n",
95 				i, prio_tc[i], num_tc);
96 			return -EINVAL;
97 		}
98 	}
99 
100 	if (num_tc > hdev->vport[0].alloc_tqps) {
101 		dev_err(&hdev->pdev->dev,
102 			"allocated tqp checking failed, %u > tqp(%u)\n",
103 			num_tc, hdev->vport[0].alloc_tqps);
104 		return -EINVAL;
105 	}
106 
107 	return 0;
108 }
109 
110 static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets,
111 			       bool *changed)
112 {
113 	u8 max_tc_id = 0;
114 	u8 i;
115 
116 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
117 		if (ets->prio_tc[i] != hdev->tm_info.prio_tc[i])
118 			*changed = true;
119 
120 		if (ets->prio_tc[i] > max_tc_id)
121 			max_tc_id = ets->prio_tc[i];
122 	}
123 
124 	/* return max tc number, max tc id need to plus 1 */
125 	return max_tc_id + 1;
126 }
127 
128 static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
129 				       struct ieee_ets *ets, bool *changed,
130 				       u8 tc_num)
131 {
132 	bool has_ets_tc = false;
133 	u32 total_ets_bw = 0;
134 	u8 i;
135 
136 	for (i = 0; i < HNAE3_MAX_TC; i++) {
137 		switch (ets->tc_tsa[i]) {
138 		case IEEE_8021QAZ_TSA_STRICT:
139 			if (hdev->tm_info.tc_info[i].tc_sch_mode !=
140 				HCLGE_SCH_MODE_SP)
141 				*changed = true;
142 			break;
143 		case IEEE_8021QAZ_TSA_ETS:
144 			if (i >= tc_num) {
145 				dev_err(&hdev->pdev->dev,
146 					"tc%u is disabled, cannot set ets bw\n",
147 					i);
148 				return -EINVAL;
149 			}
150 
151 			/* The hardware will switch to sp mode if bandwidth is
152 			 * 0, so limit ets bandwidth must be greater than 0.
153 			 */
154 			if (!ets->tc_tx_bw[i]) {
155 				dev_err(&hdev->pdev->dev,
156 					"tc%u ets bw cannot be 0\n", i);
157 				return -EINVAL;
158 			}
159 
160 			if (hdev->tm_info.tc_info[i].tc_sch_mode !=
161 				HCLGE_SCH_MODE_DWRR)
162 				*changed = true;
163 
164 			total_ets_bw += ets->tc_tx_bw[i];
165 			has_ets_tc = true;
166 			break;
167 		default:
168 			return -EINVAL;
169 		}
170 	}
171 
172 	if (has_ets_tc && total_ets_bw != BW_PERCENT)
173 		return -EINVAL;
174 
175 	return 0;
176 }
177 
178 static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
179 			      u8 *tc, bool *changed)
180 {
181 	u8 tc_num;
182 	int ret;
183 
184 	tc_num = hclge_ets_tc_changed(hdev, ets, changed);
185 
186 	ret = hclge_dcb_common_validate(hdev, tc_num, ets->prio_tc);
187 	if (ret)
188 		return ret;
189 
190 	ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num);
191 	if (ret)
192 		return ret;
193 
194 	*tc = tc_num;
195 	if (*tc != hdev->tm_info.num_tc)
196 		*changed = true;
197 
198 	return 0;
199 }
200 
201 static int hclge_map_update(struct hclge_dev *hdev)
202 {
203 	int ret;
204 
205 	ret = hclge_tm_schd_setup_hw(hdev);
206 	if (ret)
207 		return ret;
208 
209 	ret = hclge_pause_setup_hw(hdev, false);
210 	if (ret)
211 		return ret;
212 
213 	ret = hclge_buffer_alloc(hdev);
214 	if (ret)
215 		return ret;
216 
217 	hclge_comm_rss_indir_init_cfg(hdev->ae_dev, &hdev->rss_cfg);
218 
219 	return hclge_rss_init_hw(hdev);
220 }
221 
222 static int hclge_notify_down_uinit(struct hclge_dev *hdev)
223 {
224 	int ret;
225 
226 	ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
227 	if (ret)
228 		return ret;
229 
230 	ret = hclge_tm_flush_cfg(hdev, true);
231 	if (ret)
232 		return ret;
233 
234 	return hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
235 }
236 
237 static int hclge_notify_init_up(struct hclge_dev *hdev)
238 {
239 	int ret;
240 
241 	ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
242 	if (ret)
243 		return ret;
244 
245 	ret = hclge_tm_flush_cfg(hdev, false);
246 	if (ret)
247 		return ret;
248 
249 	return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
250 }
251 
252 static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
253 {
254 	struct hclge_vport *vport = hclge_get_vport(h);
255 	struct net_device *netdev = h->kinfo.netdev;
256 	struct hclge_dev *hdev = vport->back;
257 	bool map_changed = false;
258 	u8 num_tc = 0;
259 	int ret;
260 
261 	if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
262 	    h->kinfo.tc_info.mqprio_active)
263 		return -EINVAL;
264 
265 	ret = hclge_ets_validate(hdev, ets, &num_tc, &map_changed);
266 	if (ret)
267 		return ret;
268 
269 	if (map_changed) {
270 		netif_dbg(h, drv, netdev, "set ets\n");
271 
272 		ret = hclge_notify_down_uinit(hdev);
273 		if (ret)
274 			return ret;
275 	}
276 
277 	hclge_tm_schd_info_update(hdev, num_tc);
278 	h->kinfo.tc_info.dcb_ets_active = num_tc > 1;
279 
280 	ret = hclge_ieee_ets_to_tm_info(hdev, ets);
281 	if (ret)
282 		goto err_out;
283 
284 	if (map_changed) {
285 		ret = hclge_map_update(hdev);
286 		if (ret)
287 			goto err_out;
288 
289 		return hclge_notify_init_up(hdev);
290 	}
291 
292 	return hclge_tm_dwrr_cfg(hdev);
293 
294 err_out:
295 	if (!map_changed)
296 		return ret;
297 
298 	hclge_notify_init_up(hdev);
299 
300 	return ret;
301 }
302 
303 static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
304 {
305 	struct hclge_vport *vport = hclge_get_vport(h);
306 	struct hclge_dev *hdev = vport->back;
307 	int ret;
308 
309 	memset(pfc, 0, sizeof(*pfc));
310 	pfc->pfc_cap = hdev->pfc_max;
311 	pfc->pfc_en = hdev->tm_info.pfc_en;
312 
313 	ret = hclge_mac_update_stats(hdev);
314 	if (ret) {
315 		dev_err(&hdev->pdev->dev,
316 			"failed to update MAC stats, ret = %d.\n", ret);
317 		return ret;
318 	}
319 
320 	hclge_pfc_tx_stats_get(hdev, pfc->requests);
321 	hclge_pfc_rx_stats_get(hdev, pfc->indications);
322 
323 	return 0;
324 }
325 
326 static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
327 {
328 	struct hclge_vport *vport = hclge_get_vport(h);
329 	struct net_device *netdev = h->kinfo.netdev;
330 	struct hclge_dev *hdev = vport->back;
331 	u8 i, j, pfc_map, *prio_tc;
332 	int last_bad_ret = 0;
333 	int ret;
334 
335 	if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
336 		return -EINVAL;
337 
338 	if (pfc->pfc_en == hdev->tm_info.pfc_en)
339 		return 0;
340 
341 	prio_tc = hdev->tm_info.prio_tc;
342 	pfc_map = 0;
343 
344 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
345 		for (j = 0; j < HNAE3_MAX_USER_PRIO; j++) {
346 			if ((prio_tc[j] == i) && (pfc->pfc_en & BIT(j))) {
347 				pfc_map |= BIT(i);
348 				break;
349 			}
350 		}
351 	}
352 
353 	hdev->tm_info.hw_pfc_map = pfc_map;
354 	hdev->tm_info.pfc_en = pfc->pfc_en;
355 
356 	netif_dbg(h, drv, netdev,
357 		  "set pfc: pfc_en=%x, pfc_map=%x, num_tc=%u\n",
358 		  pfc->pfc_en, pfc_map, hdev->tm_info.num_tc);
359 
360 	hclge_tm_pfc_info_update(hdev);
361 
362 	ret = hclge_pause_setup_hw(hdev, false);
363 	if (ret)
364 		return ret;
365 
366 	ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
367 	if (ret)
368 		return ret;
369 
370 	ret = hclge_tm_flush_cfg(hdev, true);
371 	if (ret)
372 		return ret;
373 
374 	/* No matter whether the following operations are performed
375 	 * successfully or not, disabling the tm flush and notify
376 	 * the network status to up are necessary.
377 	 * Do not return immediately.
378 	 */
379 	ret = hclge_buffer_alloc(hdev);
380 	if (ret)
381 		last_bad_ret = ret;
382 
383 	ret = hclge_tm_flush_cfg(hdev, false);
384 	if (ret)
385 		last_bad_ret = ret;
386 
387 	ret = hclge_notify_client(hdev, HNAE3_UP_CLIENT);
388 	if (ret)
389 		last_bad_ret = ret;
390 
391 	return last_bad_ret;
392 }
393 
394 static int hclge_ieee_setapp(struct hnae3_handle *h, struct dcb_app *app)
395 {
396 	struct hclge_vport *vport = hclge_get_vport(h);
397 	struct net_device *netdev = h->kinfo.netdev;
398 	struct hclge_dev *hdev = vport->back;
399 	struct dcb_app old_app;
400 	int ret;
401 
402 	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
403 	    app->protocol >= HNAE3_MAX_DSCP ||
404 	    app->priority >= HNAE3_MAX_USER_PRIO)
405 		return -EINVAL;
406 
407 	dev_info(&hdev->pdev->dev, "setapp dscp=%u priority=%u\n",
408 		 app->protocol, app->priority);
409 
410 	if (app->priority == h->kinfo.dscp_prio[app->protocol])
411 		return 0;
412 
413 	ret = dcb_ieee_setapp(netdev, app);
414 	if (ret)
415 		return ret;
416 
417 	old_app.selector = IEEE_8021QAZ_APP_SEL_DSCP;
418 	old_app.protocol = app->protocol;
419 	old_app.priority = h->kinfo.dscp_prio[app->protocol];
420 
421 	h->kinfo.dscp_prio[app->protocol] = app->priority;
422 	ret = hclge_dscp_to_tc_map(hdev);
423 	if (ret) {
424 		dev_err(&hdev->pdev->dev,
425 			"failed to set dscp to tc map, ret = %d\n", ret);
426 		h->kinfo.dscp_prio[app->protocol] = old_app.priority;
427 		(void)dcb_ieee_delapp(netdev, app);
428 		return ret;
429 	}
430 
431 	vport->nic.kinfo.tc_map_mode = HNAE3_TC_MAP_MODE_DSCP;
432 	if (old_app.priority == HNAE3_PRIO_ID_INVALID)
433 		h->kinfo.dscp_app_cnt++;
434 	else
435 		ret = dcb_ieee_delapp(netdev, &old_app);
436 
437 	return ret;
438 }
439 
440 static int hclge_ieee_delapp(struct hnae3_handle *h, struct dcb_app *app)
441 {
442 	struct hclge_vport *vport = hclge_get_vport(h);
443 	struct net_device *netdev = h->kinfo.netdev;
444 	struct hclge_dev *hdev = vport->back;
445 	int ret;
446 
447 	if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP ||
448 	    app->protocol >= HNAE3_MAX_DSCP ||
449 	    app->priority >= HNAE3_MAX_USER_PRIO ||
450 	    app->priority != h->kinfo.dscp_prio[app->protocol])
451 		return -EINVAL;
452 
453 	dev_info(&hdev->pdev->dev, "delapp dscp=%u priority=%u\n",
454 		 app->protocol, app->priority);
455 
456 	ret = dcb_ieee_delapp(netdev, app);
457 	if (ret)
458 		return ret;
459 
460 	h->kinfo.dscp_prio[app->protocol] = HNAE3_PRIO_ID_INVALID;
461 	ret = hclge_dscp_to_tc_map(hdev);
462 	if (ret) {
463 		dev_err(&hdev->pdev->dev,
464 			"failed to del dscp to tc map, ret = %d\n", ret);
465 		h->kinfo.dscp_prio[app->protocol] = app->priority;
466 		(void)dcb_ieee_setapp(netdev, app);
467 		return ret;
468 	}
469 
470 	if (h->kinfo.dscp_app_cnt)
471 		h->kinfo.dscp_app_cnt--;
472 
473 	if (!h->kinfo.dscp_app_cnt) {
474 		vport->nic.kinfo.tc_map_mode = HNAE3_TC_MAP_MODE_PRIO;
475 		ret = hclge_up_to_tc_map(hdev);
476 	}
477 
478 	return ret;
479 }
480 
481 /* DCBX configuration */
482 static u8 hclge_getdcbx(struct hnae3_handle *h)
483 {
484 	struct hclge_vport *vport = hclge_get_vport(h);
485 	struct hclge_dev *hdev = vport->back;
486 
487 	if (h->kinfo.tc_info.mqprio_active)
488 		return 0;
489 
490 	return hdev->dcbx_cap;
491 }
492 
493 static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
494 {
495 	struct hclge_vport *vport = hclge_get_vport(h);
496 	struct net_device *netdev = h->kinfo.netdev;
497 	struct hclge_dev *hdev = vport->back;
498 
499 	netif_dbg(h, drv, netdev, "set dcbx: mode=%u\n", mode);
500 
501 	/* No support for LLD_MANAGED modes or CEE */
502 	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
503 	    (mode & DCB_CAP_DCBX_VER_CEE) ||
504 	    !(mode & DCB_CAP_DCBX_HOST))
505 		return 1;
506 
507 	hdev->dcbx_cap = mode;
508 
509 	return 0;
510 }
511 
512 static int hclge_mqprio_qopt_check(struct hclge_dev *hdev,
513 				   struct tc_mqprio_qopt_offload *mqprio_qopt)
514 {
515 	u16 queue_sum = 0;
516 	int ret;
517 	int i;
518 
519 	if (!mqprio_qopt->qopt.num_tc) {
520 		mqprio_qopt->qopt.num_tc = 1;
521 		return 0;
522 	}
523 
524 	ret = hclge_dcb_common_validate(hdev, mqprio_qopt->qopt.num_tc,
525 					mqprio_qopt->qopt.prio_tc_map);
526 	if (ret)
527 		return ret;
528 
529 	for (i = 0; i < mqprio_qopt->qopt.num_tc; i++) {
530 		if (!is_power_of_2(mqprio_qopt->qopt.count[i])) {
531 			dev_err(&hdev->pdev->dev,
532 				"qopt queue count must be power of 2\n");
533 			return -EINVAL;
534 		}
535 
536 		if (mqprio_qopt->qopt.count[i] > hdev->pf_rss_size_max) {
537 			dev_err(&hdev->pdev->dev,
538 				"qopt queue count should be no more than %u\n",
539 				hdev->pf_rss_size_max);
540 			return -EINVAL;
541 		}
542 
543 		if (mqprio_qopt->qopt.offset[i] != queue_sum) {
544 			dev_err(&hdev->pdev->dev,
545 				"qopt queue offset must start from 0, and being continuous\n");
546 			return -EINVAL;
547 		}
548 
549 		if (mqprio_qopt->min_rate[i] || mqprio_qopt->max_rate[i]) {
550 			dev_err(&hdev->pdev->dev,
551 				"qopt tx_rate is not supported\n");
552 			return -EOPNOTSUPP;
553 		}
554 
555 		queue_sum = mqprio_qopt->qopt.offset[i];
556 		queue_sum += mqprio_qopt->qopt.count[i];
557 	}
558 	if (hdev->vport[0].alloc_tqps < queue_sum) {
559 		dev_err(&hdev->pdev->dev,
560 			"qopt queue count sum should be less than %u\n",
561 			hdev->vport[0].alloc_tqps);
562 		return -EINVAL;
563 	}
564 
565 	return 0;
566 }
567 
568 static void hclge_sync_mqprio_qopt(struct hnae3_tc_info *tc_info,
569 				   struct tc_mqprio_qopt_offload *mqprio_qopt)
570 {
571 	memset(tc_info, 0, sizeof(*tc_info));
572 	tc_info->num_tc = mqprio_qopt->qopt.num_tc;
573 	memcpy(tc_info->prio_tc, mqprio_qopt->qopt.prio_tc_map,
574 	       sizeof_field(struct hnae3_tc_info, prio_tc));
575 	memcpy(tc_info->tqp_count, mqprio_qopt->qopt.count,
576 	       sizeof_field(struct hnae3_tc_info, tqp_count));
577 	memcpy(tc_info->tqp_offset, mqprio_qopt->qopt.offset,
578 	       sizeof_field(struct hnae3_tc_info, tqp_offset));
579 }
580 
581 static int hclge_config_tc(struct hclge_dev *hdev,
582 			   struct hnae3_tc_info *tc_info)
583 {
584 	int i;
585 
586 	hclge_tm_schd_info_update(hdev, tc_info->num_tc);
587 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
588 		hdev->tm_info.prio_tc[i] = tc_info->prio_tc[i];
589 
590 	return hclge_map_update(hdev);
591 }
592 
593 /* Set up TC for hardware offloaded mqprio in channel mode */
594 static int hclge_setup_tc(struct hnae3_handle *h,
595 			  struct tc_mqprio_qopt_offload *mqprio_qopt)
596 {
597 	struct hclge_vport *vport = hclge_get_vport(h);
598 	struct hnae3_knic_private_info *kinfo;
599 	struct hclge_dev *hdev = vport->back;
600 	struct hnae3_tc_info old_tc_info;
601 	u8 tc = mqprio_qopt->qopt.num_tc;
602 	int ret;
603 
604 	/* if client unregistered, it's not allowed to change
605 	 * mqprio configuration, which may cause uninit ring
606 	 * fail.
607 	 */
608 	if (!test_bit(HCLGE_STATE_NIC_REGISTERED, &hdev->state))
609 		return -EBUSY;
610 
611 	kinfo = &vport->nic.kinfo;
612 	if (kinfo->tc_info.dcb_ets_active)
613 		return -EINVAL;
614 
615 	ret = hclge_mqprio_qopt_check(hdev, mqprio_qopt);
616 	if (ret) {
617 		dev_err(&hdev->pdev->dev,
618 			"failed to check mqprio qopt params, ret = %d\n", ret);
619 		return ret;
620 	}
621 
622 	kinfo->tc_info.mqprio_destroy = !tc;
623 
624 	ret = hclge_notify_down_uinit(hdev);
625 	if (ret)
626 		return ret;
627 
628 	memcpy(&old_tc_info, &kinfo->tc_info, sizeof(old_tc_info));
629 	hclge_sync_mqprio_qopt(&kinfo->tc_info, mqprio_qopt);
630 	kinfo->tc_info.mqprio_active = tc > 0;
631 
632 	ret = hclge_config_tc(hdev, &kinfo->tc_info);
633 	if (ret)
634 		goto err_out;
635 
636 	return hclge_notify_init_up(hdev);
637 
638 err_out:
639 	if (!tc) {
640 		dev_warn(&hdev->pdev->dev,
641 			 "failed to destroy mqprio, will active after reset, ret = %d\n",
642 			 ret);
643 	} else {
644 		/* roll-back */
645 		memcpy(&kinfo->tc_info, &old_tc_info, sizeof(old_tc_info));
646 		if (hclge_config_tc(hdev, &kinfo->tc_info))
647 			dev_err(&hdev->pdev->dev,
648 				"failed to roll back tc configuration\n");
649 	}
650 	hclge_notify_init_up(hdev);
651 
652 	return ret;
653 }
654 
655 static const struct hnae3_dcb_ops hns3_dcb_ops = {
656 	.ieee_getets	= hclge_ieee_getets,
657 	.ieee_setets	= hclge_ieee_setets,
658 	.ieee_getpfc	= hclge_ieee_getpfc,
659 	.ieee_setpfc	= hclge_ieee_setpfc,
660 	.ieee_setapp    = hclge_ieee_setapp,
661 	.ieee_delapp    = hclge_ieee_delapp,
662 	.getdcbx	= hclge_getdcbx,
663 	.setdcbx	= hclge_setdcbx,
664 	.setup_tc	= hclge_setup_tc,
665 };
666 
667 void hclge_dcb_ops_set(struct hclge_dev *hdev)
668 {
669 	struct hclge_vport *vport = hdev->vport;
670 	struct hnae3_knic_private_info *kinfo;
671 
672 	/* Hdev does not support DCB or vport is
673 	 * not a pf, then dcb_ops is not set.
674 	 */
675 	if (!hnae3_dev_dcb_supported(hdev) ||
676 	    vport->vport_id != 0)
677 		return;
678 
679 	kinfo = &vport->nic.kinfo;
680 	kinfo->dcb_ops = &hns3_dcb_ops;
681 	hdev->dcbx_cap = DCB_CAP_DCBX_VER_IEEE | DCB_CAP_DCBX_HOST;
682 }
683