forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c
....@@ -2,7 +2,9 @@
22 // Copyright (c) 2016-2017 Hisilicon Limited.
33
44 #include "hclge_main.h"
5
+#include "hclge_dcb.h"
56 #include "hclge_tm.h"
7
+#include "hclge_dcb.h"
68 #include "hnae3.h"
79
810 #define BW_PERCENT 100
....@@ -35,7 +37,9 @@
3537 }
3638 }
3739
38
- return hclge_tm_prio_tc_info_update(hdev, ets->prio_tc);
40
+ hclge_tm_prio_tc_info_update(hdev, ets->prio_tc);
41
+
42
+ return 0;
3943 }
4044
4145 static void hclge_tm_info_to_ieee_ets(struct hclge_dev *hdev,
....@@ -49,7 +53,10 @@
4953
5054 for (i = 0; i < HNAE3_MAX_TC; i++) {
5155 ets->prio_tc[i] = hdev->tm_info.prio_tc[i];
52
- ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
56
+ if (i < hdev->tm_info.num_tc)
57
+ ets->tc_tx_bw[i] = hdev->tm_info.pg_info[0].tc_dwrr[i];
58
+ else
59
+ ets->tc_tx_bw[i] = 0;
5360
5461 if (hdev->tm_info.tc_info[i].tc_sch_mode ==
5562 HCLGE_SCH_MODE_SP)
....@@ -70,25 +77,64 @@
7077 return 0;
7178 }
7279
73
-static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
74
- u8 *tc, bool *changed)
80
+static int hclge_dcb_common_validate(struct hclge_dev *hdev, u8 num_tc,
81
+ u8 *prio_tc)
7582 {
76
- bool has_ets_tc = false;
77
- u32 total_ets_bw = 0;
78
- u8 max_tc = 0;
83
+ int i;
84
+
85
+ if (num_tc > hdev->tc_max) {
86
+ dev_err(&hdev->pdev->dev,
87
+ "tc num checking failed, %u > tc_max(%u)\n",
88
+ num_tc, hdev->tc_max);
89
+ return -EINVAL;
90
+ }
91
+
92
+ for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
93
+ if (prio_tc[i] >= num_tc) {
94
+ dev_err(&hdev->pdev->dev,
95
+ "prio_tc[%d] checking failed, %u >= num_tc(%u)\n",
96
+ i, prio_tc[i], num_tc);
97
+ return -EINVAL;
98
+ }
99
+ }
100
+
101
+ if (num_tc > hdev->vport[0].alloc_tqps) {
102
+ dev_err(&hdev->pdev->dev,
103
+ "allocated tqp checking failed, %u > tqp(%u)\n",
104
+ num_tc, hdev->vport[0].alloc_tqps);
105
+ return -EINVAL;
106
+ }
107
+
108
+ return 0;
109
+}
110
+
111
+static u8 hclge_ets_tc_changed(struct hclge_dev *hdev, struct ieee_ets *ets,
112
+ bool *changed)
113
+{
114
+ u8 max_tc_id = 0;
79115 u8 i;
80116
81
- for (i = 0; i < HNAE3_MAX_TC; i++) {
82
- if (ets->prio_tc[i] >= hdev->tc_max ||
83
- i >= hdev->tc_max)
84
- return -EINVAL;
85
-
117
+ for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
86118 if (ets->prio_tc[i] != hdev->tm_info.prio_tc[i])
87119 *changed = true;
88120
89
- if (ets->prio_tc[i] > max_tc)
90
- max_tc = ets->prio_tc[i];
121
+ if (ets->prio_tc[i] > max_tc_id)
122
+ max_tc_id = ets->prio_tc[i];
123
+ }
91124
125
+ /* return max tc number, max tc id need to plus 1 */
126
+ return max_tc_id + 1;
127
+}
128
+
129
+static int hclge_ets_sch_mode_validate(struct hclge_dev *hdev,
130
+ struct ieee_ets *ets, bool *changed,
131
+ u8 tc_num)
132
+{
133
+ bool has_ets_tc = false;
134
+ u32 total_ets_bw = 0;
135
+ u8 i;
136
+
137
+ for (i = 0; i < HNAE3_MAX_TC; i++) {
92138 switch (ets->tc_tsa[i]) {
93139 case IEEE_8021QAZ_TSA_STRICT:
94140 if (hdev->tm_info.tc_info[i].tc_sch_mode !=
....@@ -96,6 +142,13 @@
96142 *changed = true;
97143 break;
98144 case IEEE_8021QAZ_TSA_ETS:
145
+ if (i >= tc_num) {
146
+ dev_err(&hdev->pdev->dev,
147
+ "tc%u is disabled, cannot set ets bw\n",
148
+ i);
149
+ return -EINVAL;
150
+ }
151
+
99152 /* The hardware will switch to sp mode if bandwidth is
100153 * 0, so limit ets bandwidth must be greater than 0.
101154 */
....@@ -120,28 +173,41 @@
120173 if (has_ets_tc && total_ets_bw != BW_PERCENT)
121174 return -EINVAL;
122175
123
- *tc = max_tc + 1;
176
+ return 0;
177
+}
178
+
179
+static int hclge_ets_validate(struct hclge_dev *hdev, struct ieee_ets *ets,
180
+ u8 *tc, bool *changed)
181
+{
182
+ u8 tc_num;
183
+ int ret;
184
+
185
+ tc_num = hclge_ets_tc_changed(hdev, ets, changed);
186
+
187
+ ret = hclge_dcb_common_validate(hdev, tc_num, ets->prio_tc);
188
+ if (ret)
189
+ return ret;
190
+
191
+ ret = hclge_ets_sch_mode_validate(hdev, ets, changed, tc_num);
192
+ if (ret)
193
+ return ret;
194
+
195
+ *tc = tc_num;
124196 if (*tc != hdev->tm_info.num_tc)
125197 *changed = true;
126198
127199 return 0;
128200 }
129201
130
-static int hclge_map_update(struct hnae3_handle *h)
202
+static int hclge_map_update(struct hclge_dev *hdev)
131203 {
132
- struct hclge_vport *vport = hclge_get_vport(h);
133
- struct hclge_dev *hdev = vport->back;
134204 int ret;
135205
136
- ret = hclge_tm_map_cfg(hdev);
206
+ ret = hclge_tm_schd_setup_hw(hdev);
137207 if (ret)
138208 return ret;
139209
140
- ret = hclge_tm_schd_mode_hw(hdev);
141
- if (ret)
142
- return ret;
143
-
144
- ret = hclge_pause_setup_hw(hdev);
210
+ ret = hclge_pause_setup_hw(hdev, false);
145211 if (ret)
146212 return ret;
147213
....@@ -177,9 +243,32 @@
177243 return 0;
178244 }
179245
246
+static int hclge_notify_down_uinit(struct hclge_dev *hdev)
247
+{
248
+ int ret;
249
+
250
+ ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
251
+ if (ret)
252
+ return ret;
253
+
254
+ return hclge_notify_client(hdev, HNAE3_UNINIT_CLIENT);
255
+}
256
+
257
+static int hclge_notify_init_up(struct hclge_dev *hdev)
258
+{
259
+ int ret;
260
+
261
+ ret = hclge_notify_client(hdev, HNAE3_INIT_CLIENT);
262
+ if (ret)
263
+ return ret;
264
+
265
+ return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
266
+}
267
+
180268 static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)
181269 {
182270 struct hclge_vport *vport = hclge_get_vport(h);
271
+ struct net_device *netdev = h->kinfo.netdev;
183272 struct hclge_dev *hdev = vport->back;
184273 bool map_changed = false;
185274 u8 num_tc = 0;
....@@ -193,19 +282,47 @@
193282 if (ret)
194283 return ret;
195284
285
+ if (map_changed) {
286
+ netif_dbg(h, drv, netdev, "set ets\n");
287
+
288
+ ret = hclge_notify_down_uinit(hdev);
289
+ if (ret)
290
+ return ret;
291
+ }
292
+
196293 hclge_tm_schd_info_update(hdev, num_tc);
294
+ if (num_tc > 1)
295
+ hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
296
+ else
297
+ hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
197298
198299 ret = hclge_ieee_ets_to_tm_info(hdev, ets);
199300 if (ret)
200
- return ret;
301
+ goto err_out;
201302
202303 if (map_changed) {
304
+ ret = hclge_map_update(hdev);
305
+ if (ret)
306
+ goto err_out;
307
+
203308 ret = hclge_client_setup_tc(hdev);
309
+ if (ret)
310
+ goto err_out;
311
+
312
+ ret = hclge_notify_init_up(hdev);
204313 if (ret)
205314 return ret;
206315 }
207316
208317 return hclge_tm_dwrr_cfg(hdev);
318
+
319
+err_out:
320
+ if (!map_changed)
321
+ return ret;
322
+
323
+ hclge_notify_init_up(hdev);
324
+
325
+ return ret;
209326 }
210327
211328 static int hclge_ieee_getpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
....@@ -238,11 +355,12 @@
238355 static int hclge_ieee_setpfc(struct hnae3_handle *h, struct ieee_pfc *pfc)
239356 {
240357 struct hclge_vport *vport = hclge_get_vport(h);
358
+ struct net_device *netdev = h->kinfo.netdev;
241359 struct hclge_dev *hdev = vport->back;
242360 u8 i, j, pfc_map, *prio_tc;
361
+ int ret;
243362
244
- if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
245
- hdev->flag & HCLGE_FLAG_MQPRIO_ENABLE)
363
+ if (!(hdev->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
246364 return -EINVAL;
247365
248366 if (pfc->pfc_en == hdev->tm_info.pfc_en)
....@@ -263,7 +381,27 @@
263381 hdev->tm_info.hw_pfc_map = pfc_map;
264382 hdev->tm_info.pfc_en = pfc->pfc_en;
265383
266
- return hclge_pause_setup_hw(hdev);
384
+ netif_dbg(h, drv, netdev,
385
+ "set pfc: pfc_en=%x, pfc_map=%x, num_tc=%u\n",
386
+ pfc->pfc_en, pfc_map, hdev->tm_info.num_tc);
387
+
388
+ hclge_tm_pfc_info_update(hdev);
389
+
390
+ ret = hclge_pause_setup_hw(hdev, false);
391
+ if (ret)
392
+ return ret;
393
+
394
+ ret = hclge_notify_client(hdev, HNAE3_DOWN_CLIENT);
395
+ if (ret)
396
+ return ret;
397
+
398
+ ret = hclge_buffer_alloc(hdev);
399
+ if (ret) {
400
+ hclge_notify_client(hdev, HNAE3_UP_CLIENT);
401
+ return ret;
402
+ }
403
+
404
+ return hclge_notify_client(hdev, HNAE3_UP_CLIENT);
267405 }
268406
269407 /* DCBX configuration */
....@@ -281,7 +419,10 @@
281419 static u8 hclge_setdcbx(struct hnae3_handle *h, u8 mode)
282420 {
283421 struct hclge_vport *vport = hclge_get_vport(h);
422
+ struct net_device *netdev = h->kinfo.netdev;
284423 struct hclge_dev *hdev = vport->back;
424
+
425
+ netif_dbg(h, drv, netdev, "set dcbx: mode=%u\n", mode);
285426
286427 /* No support for LLD_MANAGED modes or CEE */
287428 if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
....@@ -304,22 +445,24 @@
304445 if (hdev->flag & HCLGE_FLAG_DCB_ENABLE)
305446 return -EINVAL;
306447
307
- if (tc > hdev->tc_max) {
308
- dev_err(&hdev->pdev->dev,
309
- "setup tc failed, tc(%u) > tc_max(%u)\n",
310
- tc, hdev->tc_max);
448
+ ret = hclge_dcb_common_validate(hdev, tc, prio_tc);
449
+ if (ret)
311450 return -EINVAL;
312
- }
451
+
452
+ ret = hclge_notify_down_uinit(hdev);
453
+ if (ret)
454
+ return ret;
313455
314456 hclge_tm_schd_info_update(hdev, tc);
457
+ hclge_tm_prio_tc_info_update(hdev, prio_tc);
315458
316
- ret = hclge_tm_prio_tc_info_update(hdev, prio_tc);
459
+ ret = hclge_tm_init_hw(hdev, false);
317460 if (ret)
318
- return ret;
461
+ goto err_out;
319462
320
- ret = hclge_tm_init_hw(hdev);
463
+ ret = hclge_client_setup_tc(hdev);
321464 if (ret)
322
- return ret;
465
+ goto err_out;
323466
324467 hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
325468
....@@ -328,7 +471,12 @@
328471 else
329472 hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE;
330473
331
- return 0;
474
+ return hclge_notify_init_up(hdev);
475
+
476
+err_out:
477
+ hclge_notify_init_up(hdev);
478
+
479
+ return ret;
332480 }
333481
334482 static const struct hnae3_dcb_ops hns3_dcb_ops = {
....@@ -338,7 +486,6 @@
338486 .ieee_setpfc = hclge_ieee_setpfc,
339487 .getdcbx = hclge_getdcbx,
340488 .setdcbx = hclge_setdcbx,
341
- .map_update = hclge_map_update,
342489 .setup_tc = hclge_setup_tc,
343490 };
344491