Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_dcbnl.c
1 /*
2  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
3  *
4  * This software is available to you under a choice of one of two
5  * licenses.  You may choose to be licensed under the terms of the GNU
6  * General Public License (GPL) Version 2, available from the file
7  * COPYING in the main directory of this source tree, or the
8  * OpenIB.org BSD license below:
9  *
10  *     Redistribution and use in source and binary forms, with or
11  *     without modification, are permitted provided that the following
12  *     conditions are met:
13  *
14  *      - Redistributions of source code must retain the above
15  *        copyright notice, this list of conditions and the following
16  *        disclaimer.
17  *
18  *      - Redistributions in binary form must reproduce the above
19  *        copyright notice, this list of conditions and the following
20  *        disclaimer in the documentation and/or other materials
21  *        provided with the distribution.
22  *
23  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30  * SOFTWARE.
31  */
32 #include <linux/device.h>
33 #include <linux/netdevice.h>
34 #include "en.h"
35 #include "en/port.h"
36 #include "en/port_buffer.h"
37
38 #define MLX5E_100MB (100000)
39 #define MLX5E_1GB   (1000000)
40
41 #define MLX5E_CEE_STATE_UP    1
42 #define MLX5E_CEE_STATE_DOWN  0
43
44 /* Max supported cable length is 1000 meters */
45 #define MLX5E_MAX_CABLE_LENGTH 1000
46
47 enum {
48         MLX5E_VENDOR_TC_GROUP_NUM = 7,
49         MLX5E_LOWEST_PRIO_GROUP   = 0,
50 };
51
52 #define MLX5_DSCP_SUPPORTED(mdev) (MLX5_CAP_GEN(mdev, qcam_reg)  && \
53                                    MLX5_CAP_QCAM_REG(mdev, qpts) && \
54                                    MLX5_CAP_QCAM_REG(mdev, qpdpm))
55
56 static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state);
57 static int mlx5e_set_dscp2prio(struct mlx5e_priv *priv, u8 dscp, u8 prio);
58
59 /* If dcbx mode is non-host set the dcbx mode to host.
60  */
61 static int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv,
62                                      enum mlx5_dcbx_oper_mode mode)
63 {
64         struct mlx5_core_dev *mdev = priv->mdev;
65         u32 param[MLX5_ST_SZ_DW(dcbx_param)];
66         int err;
67
68         err = mlx5_query_port_dcbx_param(mdev, param);
69         if (err)
70                 return err;
71
72         MLX5_SET(dcbx_param, param, version_admin, mode);
73         if (mode != MLX5E_DCBX_PARAM_VER_OPER_HOST)
74                 MLX5_SET(dcbx_param, param, willing_admin, 1);
75
76         return mlx5_set_port_dcbx_param(mdev, param);
77 }
78
79 static int mlx5e_dcbnl_switch_to_host_mode(struct mlx5e_priv *priv)
80 {
81         struct mlx5e_dcbx *dcbx = &priv->dcbx;
82         int err;
83
84         if (!MLX5_CAP_GEN(priv->mdev, dcbx))
85                 return 0;
86
87         if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
88                 return 0;
89
90         err = mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_HOST);
91         if (err)
92                 return err;
93
94         dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_HOST;
95         return 0;
96 }
97
98 static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
99                                    struct ieee_ets *ets)
100 {
101         struct mlx5e_priv *priv = netdev_priv(netdev);
102         struct mlx5_core_dev *mdev = priv->mdev;
103         u8 tc_group[IEEE_8021QAZ_MAX_TCS];
104         bool is_tc_group_6_exist = false;
105         bool is_zero_bw_ets_tc = false;
106         int err = 0;
107         int i;
108
109         if (!MLX5_CAP_GEN(priv->mdev, ets))
110                 return -EOPNOTSUPP;
111
112         ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
113         for (i = 0; i < ets->ets_cap; i++) {
114                 err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
115                 if (err)
116                         return err;
117
118                 err = mlx5_query_port_tc_group(mdev, i, &tc_group[i]);
119                 if (err)
120                         return err;
121
122                 err = mlx5_query_port_tc_bw_alloc(mdev, i, &ets->tc_tx_bw[i]);
123                 if (err)
124                         return err;
125
126                 if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC &&
127                     tc_group[i] == (MLX5E_LOWEST_PRIO_GROUP + 1))
128                         is_zero_bw_ets_tc = true;
129
130                 if (tc_group[i] == (MLX5E_VENDOR_TC_GROUP_NUM - 1))
131                         is_tc_group_6_exist = true;
132         }
133
134         /* Report 0% ets tc if exits*/
135         if (is_zero_bw_ets_tc) {
136                 for (i = 0; i < ets->ets_cap; i++)
137                         if (tc_group[i] == MLX5E_LOWEST_PRIO_GROUP)
138                                 ets->tc_tx_bw[i] = 0;
139         }
140
141         /* Update tc_tsa based on fw setting*/
142         for (i = 0; i < ets->ets_cap; i++) {
143                 if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC)
144                         priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
145                 else if (tc_group[i] == MLX5E_VENDOR_TC_GROUP_NUM &&
146                          !is_tc_group_6_exist)
147                         priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
148         }
149         memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa));
150
151         return err;
152 }
153
154 static void mlx5e_build_tc_group(struct ieee_ets *ets, u8 *tc_group, int max_tc)
155 {
156         bool any_tc_mapped_to_ets = false;
157         bool ets_zero_bw = false;
158         int strict_group;
159         int i;
160
161         for (i = 0; i <= max_tc; i++) {
162                 if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
163                         any_tc_mapped_to_ets = true;
164                         if (!ets->tc_tx_bw[i])
165                                 ets_zero_bw = true;
166                 }
167         }
168
169         /* strict group has higher priority than ets group */
170         strict_group = MLX5E_LOWEST_PRIO_GROUP;
171         if (any_tc_mapped_to_ets)
172                 strict_group++;
173         if (ets_zero_bw)
174                 strict_group++;
175
176         for (i = 0; i <= max_tc; i++) {
177                 switch (ets->tc_tsa[i]) {
178                 case IEEE_8021QAZ_TSA_VENDOR:
179                         tc_group[i] = MLX5E_VENDOR_TC_GROUP_NUM;
180                         break;
181                 case IEEE_8021QAZ_TSA_STRICT:
182                         tc_group[i] = strict_group++;
183                         break;
184                 case IEEE_8021QAZ_TSA_ETS:
185                         tc_group[i] = MLX5E_LOWEST_PRIO_GROUP;
186                         if (ets->tc_tx_bw[i] && ets_zero_bw)
187                                 tc_group[i] = MLX5E_LOWEST_PRIO_GROUP + 1;
188                         break;
189                 }
190         }
191 }
192
193 static void mlx5e_build_tc_tx_bw(struct ieee_ets *ets, u8 *tc_tx_bw,
194                                  u8 *tc_group, int max_tc)
195 {
196         int bw_for_ets_zero_bw_tc = 0;
197         int last_ets_zero_bw_tc = -1;
198         int num_ets_zero_bw = 0;
199         int i;
200
201         for (i = 0; i <= max_tc; i++) {
202                 if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS &&
203                     !ets->tc_tx_bw[i]) {
204                         num_ets_zero_bw++;
205                         last_ets_zero_bw_tc = i;
206                 }
207         }
208
209         if (num_ets_zero_bw)
210                 bw_for_ets_zero_bw_tc = MLX5E_MAX_BW_ALLOC / num_ets_zero_bw;
211
212         for (i = 0; i <= max_tc; i++) {
213                 switch (ets->tc_tsa[i]) {
214                 case IEEE_8021QAZ_TSA_VENDOR:
215                         tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
216                         break;
217                 case IEEE_8021QAZ_TSA_STRICT:
218                         tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
219                         break;
220                 case IEEE_8021QAZ_TSA_ETS:
221                         tc_tx_bw[i] = ets->tc_tx_bw[i] ?
222                                       ets->tc_tx_bw[i] :
223                                       bw_for_ets_zero_bw_tc;
224                         break;
225                 }
226         }
227
228         /* Make sure the total bw for ets zero bw group is 100% */
229         if (last_ets_zero_bw_tc != -1)
230                 tc_tx_bw[last_ets_zero_bw_tc] +=
231                         MLX5E_MAX_BW_ALLOC % num_ets_zero_bw;
232 }
233
234 /* If there are ETS BW 0,
235  *   Set ETS group # to 1 for all ETS non zero BW tcs. Their sum must be 100%.
236  *   Set group #0 to all the ETS BW 0 tcs and
237  *     equally splits the 100% BW between them
238  *   Report both group #0 and #1 as ETS type.
239  *     All the tcs in group #0 will be reported with 0% BW.
240  */
241 int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
242 {
243         struct mlx5_core_dev *mdev = priv->mdev;
244         u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS];
245         u8 tc_group[IEEE_8021QAZ_MAX_TCS];
246         int max_tc = mlx5_max_tc(mdev);
247         int err, i;
248
249         mlx5e_build_tc_group(ets, tc_group, max_tc);
250         mlx5e_build_tc_tx_bw(ets, tc_tx_bw, tc_group, max_tc);
251
252         err = mlx5_set_port_prio_tc(mdev, ets->prio_tc);
253         if (err)
254                 return err;
255
256         err = mlx5_set_port_tc_group(mdev, tc_group);
257         if (err)
258                 return err;
259
260         err = mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw);
261
262         if (err)
263                 return err;
264
265         memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
266
267         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
268                 mlx5e_dbg(HW, priv, "%s: prio_%d <=> tc_%d\n",
269                           __func__, i, ets->prio_tc[i]);
270                 mlx5e_dbg(HW, priv, "%s: tc_%d <=> tx_bw_%d%%, group_%d\n",
271                           __func__, i, tc_tx_bw[i], tc_group[i]);
272         }
273
274         return err;
275 }
276
277 static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
278                                     struct ieee_ets *ets,
279                                     bool zero_sum_allowed)
280 {
281         bool have_ets_tc = false;
282         int bw_sum = 0;
283         int i;
284
285         /* Validate Priority */
286         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
287                 if (ets->prio_tc[i] >= MLX5E_MAX_PRIORITY) {
288                         netdev_err(netdev,
289                                    "Failed to validate ETS: priority value greater than max(%d)\n",
290                                     MLX5E_MAX_PRIORITY);
291                         return -EINVAL;
292                 }
293         }
294
295         /* Validate Bandwidth Sum */
296         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
297                 if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
298                         have_ets_tc = true;
299                         bw_sum += ets->tc_tx_bw[i];
300                 }
301         }
302
303         if (have_ets_tc && bw_sum != 100) {
304                 if (bw_sum || (!bw_sum && !zero_sum_allowed))
305                         netdev_err(netdev,
306                                    "Failed to validate ETS: BW sum is illegal\n");
307                 return -EINVAL;
308         }
309         return 0;
310 }
311
312 static int mlx5e_dcbnl_ieee_setets(struct net_device *netdev,
313                                    struct ieee_ets *ets)
314 {
315         struct mlx5e_priv *priv = netdev_priv(netdev);
316         int err;
317
318         if (!MLX5_CAP_GEN(priv->mdev, ets))
319                 return -EOPNOTSUPP;
320
321         err = mlx5e_dbcnl_validate_ets(netdev, ets, false);
322         if (err)
323                 return err;
324
325         err = mlx5e_dcbnl_ieee_setets_core(priv, ets);
326         if (err)
327                 return err;
328
329         return 0;
330 }
331
332 static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,
333                                    struct ieee_pfc *pfc)
334 {
335         struct mlx5e_priv *priv = netdev_priv(dev);
336         struct mlx5_core_dev *mdev = priv->mdev;
337         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
338         int i;
339
340         pfc->pfc_cap = mlx5_max_tc(mdev) + 1;
341         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
342                 pfc->requests[i]    = PPORT_PER_PRIO_GET(pstats, i, tx_pause);
343                 pfc->indications[i] = PPORT_PER_PRIO_GET(pstats, i, rx_pause);
344         }
345
346         if (MLX5_BUFFER_SUPPORTED(mdev))
347                 pfc->delay = priv->dcbx.cable_len;
348
349         return mlx5_query_port_pfc(mdev, &pfc->pfc_en, NULL);
350 }
351
352 static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
353                                    struct ieee_pfc *pfc)
354 {
355         struct mlx5e_priv *priv = netdev_priv(dev);
356         struct mlx5_core_dev *mdev = priv->mdev;
357         u32 old_cable_len = priv->dcbx.cable_len;
358         struct ieee_pfc pfc_new;
359         u32 changed = 0;
360         u8 curr_pfc_en;
361         int ret = 0;
362
363         /* pfc_en */
364         mlx5_query_port_pfc(mdev, &curr_pfc_en, NULL);
365         if (pfc->pfc_en != curr_pfc_en) {
366                 ret = mlx5_set_port_pfc(mdev, pfc->pfc_en, pfc->pfc_en);
367                 if (ret)
368                         return ret;
369                 mlx5_toggle_port_link(mdev);
370                 changed |= MLX5E_PORT_BUFFER_PFC;
371         }
372
373         if (pfc->delay &&
374             pfc->delay < MLX5E_MAX_CABLE_LENGTH &&
375             pfc->delay != priv->dcbx.cable_len) {
376                 priv->dcbx.cable_len = pfc->delay;
377                 changed |= MLX5E_PORT_BUFFER_CABLE_LEN;
378         }
379
380         if (MLX5_BUFFER_SUPPORTED(mdev)) {
381                 pfc_new.pfc_en = (changed & MLX5E_PORT_BUFFER_PFC) ? pfc->pfc_en : curr_pfc_en;
382                 if (priv->dcbx.manual_buffer)
383                         ret = mlx5e_port_manual_buffer_config(priv, changed,
384                                                               dev->mtu, &pfc_new,
385                                                               NULL, NULL);
386
387                 if (ret && (changed & MLX5E_PORT_BUFFER_CABLE_LEN))
388                         priv->dcbx.cable_len = old_cable_len;
389         }
390
391         if (!ret) {
392                 mlx5e_dbg(HW, priv,
393                           "%s: PFC per priority bit mask: 0x%x\n",
394                           __func__, pfc->pfc_en);
395         }
396         return ret;
397 }
398
399 static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
400 {
401         struct mlx5e_priv *priv = netdev_priv(dev);
402
403         return priv->dcbx.cap;
404 }
405
406 static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
407 {
408         struct mlx5e_priv *priv = netdev_priv(dev);
409         struct mlx5e_dcbx *dcbx = &priv->dcbx;
410
411         if (mode & DCB_CAP_DCBX_LLD_MANAGED)
412                 return 1;
413
414         if ((!mode) && MLX5_CAP_GEN(priv->mdev, dcbx)) {
415                 if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_AUTO)
416                         return 0;
417
418                 /* set dcbx to fw controlled */
419                 if (!mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_AUTO)) {
420                         dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
421                         dcbx->cap &= ~DCB_CAP_DCBX_HOST;
422                         return 0;
423                 }
424
425                 return 1;
426         }
427
428         if (!(mode & DCB_CAP_DCBX_HOST))
429                 return 1;
430
431         if (mlx5e_dcbnl_switch_to_host_mode(netdev_priv(dev)))
432                 return 1;
433
434         dcbx->cap = mode;
435
436         return 0;
437 }
438
439 static int mlx5e_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
440 {
441         struct mlx5e_priv *priv = netdev_priv(dev);
442         struct dcb_app temp;
443         bool is_new;
444         int err;
445
446         if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
447                 return -EINVAL;
448
449         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
450                 return -EINVAL;
451
452         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
453                 return -EINVAL;
454
455         if (app->protocol >= MLX5E_MAX_DSCP)
456                 return -EINVAL;
457
458         /* Save the old entry info */
459         temp.selector = IEEE_8021QAZ_APP_SEL_DSCP;
460         temp.protocol = app->protocol;
461         temp.priority = priv->dcbx_dp.dscp2prio[app->protocol];
462
463         /* Check if need to switch to dscp trust state */
464         if (!priv->dcbx.dscp_app_cnt) {
465                 err =  mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_DSCP);
466                 if (err)
467                         return err;
468         }
469
470         /* Skip the fw command if new and old mapping are the same */
471         if (app->priority != priv->dcbx_dp.dscp2prio[app->protocol]) {
472                 err = mlx5e_set_dscp2prio(priv, app->protocol, app->priority);
473                 if (err)
474                         goto fw_err;
475         }
476
477         /* Delete the old entry if exists */
478         is_new = false;
479         err = dcb_ieee_delapp(dev, &temp);
480         if (err)
481                 is_new = true;
482
483         /* Add new entry and update counter */
484         err = dcb_ieee_setapp(dev, app);
485         if (err)
486                 return err;
487
488         if (is_new)
489                 priv->dcbx.dscp_app_cnt++;
490
491         return err;
492
493 fw_err:
494         mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
495         return err;
496 }
497
498 static int mlx5e_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
499 {
500         struct mlx5e_priv *priv = netdev_priv(dev);
501         int err;
502
503         if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
504                 return -EINVAL;
505
506         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
507                 return -EINVAL;
508
509         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
510                 return -EINVAL;
511
512         if (app->protocol >= MLX5E_MAX_DSCP)
513                 return -EINVAL;
514
515         /* Skip if no dscp app entry */
516         if (!priv->dcbx.dscp_app_cnt)
517                 return -ENOENT;
518
519         /* Check if the entry matches fw setting */
520         if (app->priority != priv->dcbx_dp.dscp2prio[app->protocol])
521                 return -ENOENT;
522
523         /* Delete the app entry */
524         err = dcb_ieee_delapp(dev, app);
525         if (err)
526                 return err;
527
528         /* Reset the priority mapping back to zero */
529         err = mlx5e_set_dscp2prio(priv, app->protocol, 0);
530         if (err)
531                 goto fw_err;
532
533         priv->dcbx.dscp_app_cnt--;
534
535         /* Check if need to switch to pcp trust state */
536         if (!priv->dcbx.dscp_app_cnt)
537                 err = mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
538
539         return err;
540
541 fw_err:
542         mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
543         return err;
544 }
545
546 static int mlx5e_dcbnl_ieee_getmaxrate(struct net_device *netdev,
547                                        struct ieee_maxrate *maxrate)
548 {
549         struct mlx5e_priv *priv    = netdev_priv(netdev);
550         struct mlx5_core_dev *mdev = priv->mdev;
551         u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
552         u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
553         int err;
554         int i;
555
556         err = mlx5_query_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
557         if (err)
558                 return err;
559
560         memset(maxrate->tc_maxrate, 0, sizeof(maxrate->tc_maxrate));
561
562         for (i = 0; i <= mlx5_max_tc(mdev); i++) {
563                 switch (max_bw_unit[i]) {
564                 case MLX5_100_MBPS_UNIT:
565                         maxrate->tc_maxrate[i] = max_bw_value[i] * MLX5E_100MB;
566                         break;
567                 case MLX5_GBPS_UNIT:
568                         maxrate->tc_maxrate[i] = max_bw_value[i] * MLX5E_1GB;
569                         break;
570                 case MLX5_BW_NO_LIMIT:
571                         break;
572                 default:
573                         WARN(true, "non-supported BW unit");
574                         break;
575                 }
576         }
577
578         return 0;
579 }
580
581 static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
582                                        struct ieee_maxrate *maxrate)
583 {
584         struct mlx5e_priv *priv    = netdev_priv(netdev);
585         struct mlx5_core_dev *mdev = priv->mdev;
586         u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
587         u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
588         __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
589         int i;
590
591         memset(max_bw_value, 0, sizeof(max_bw_value));
592         memset(max_bw_unit, 0, sizeof(max_bw_unit));
593
594         for (i = 0; i <= mlx5_max_tc(mdev); i++) {
595                 if (!maxrate->tc_maxrate[i]) {
596                         max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
597                         continue;
598                 }
599                 if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
600                         max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
601                                                   MLX5E_100MB);
602                         max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
603                         max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
604                 } else {
605                         max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
606                                                   MLX5E_1GB);
607                         max_bw_unit[i]  = MLX5_GBPS_UNIT;
608                 }
609         }
610
611         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
612                 mlx5e_dbg(HW, priv, "%s: tc_%d <=> max_bw %d Gbps\n",
613                           __func__, i, max_bw_value[i]);
614         }
615
616         return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
617 }
618
619 static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
620 {
621         struct mlx5e_priv *priv = netdev_priv(netdev);
622         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
623         struct mlx5_core_dev *mdev = priv->mdev;
624         struct ieee_ets ets;
625         struct ieee_pfc pfc;
626         int err = -EOPNOTSUPP;
627         int i;
628
629         if (!MLX5_CAP_GEN(mdev, ets))
630                 goto out;
631
632         memset(&ets, 0, sizeof(ets));
633         memset(&pfc, 0, sizeof(pfc));
634
635         ets.ets_cap = IEEE_8021QAZ_MAX_TCS;
636         for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
637                 ets.tc_tx_bw[i] = cee_cfg->pg_bw_pct[i];
638                 ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i];
639                 ets.tc_tsa[i]   = IEEE_8021QAZ_TSA_ETS;
640                 ets.prio_tc[i]  = cee_cfg->prio_to_pg_map[i];
641                 mlx5e_dbg(HW, priv,
642                           "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n",
643                           __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i],
644                           ets.prio_tc[i]);
645         }
646
647         err = mlx5e_dbcnl_validate_ets(netdev, &ets, true);
648         if (err)
649                 goto out;
650
651         err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
652         if (err) {
653                 netdev_err(netdev,
654                            "%s, Failed to set ETS: %d\n", __func__, err);
655                 goto out;
656         }
657
658         /* Set PFC */
659         pfc.pfc_cap = mlx5_max_tc(mdev) + 1;
660         if (!cee_cfg->pfc_enable)
661                 pfc.pfc_en = 0;
662         else
663                 for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
664                         pfc.pfc_en |= cee_cfg->pfc_setting[i] << i;
665
666         err = mlx5e_dcbnl_ieee_setpfc(netdev, &pfc);
667         if (err) {
668                 netdev_err(netdev,
669                            "%s, Failed to set PFC: %d\n", __func__, err);
670                 goto out;
671         }
672 out:
673         return err ? MLX5_DCB_NO_CHG : MLX5_DCB_CHG_RESET;
674 }
675
676 static u8 mlx5e_dcbnl_getstate(struct net_device *netdev)
677 {
678         return MLX5E_CEE_STATE_UP;
679 }
680
681 static void mlx5e_dcbnl_getpermhwaddr(struct net_device *netdev,
682                                       u8 *perm_addr)
683 {
684         struct mlx5e_priv *priv = netdev_priv(netdev);
685
686         if (!perm_addr)
687                 return;
688
689         memset(perm_addr, 0xff, MAX_ADDR_LEN);
690
691         mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr);
692 }
693
694 static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev,
695                                      int priority, u8 prio_type,
696                                      u8 pgid, u8 bw_pct, u8 up_map)
697 {
698         struct mlx5e_priv *priv = netdev_priv(netdev);
699         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
700
701         if (priority >= CEE_DCBX_MAX_PRIO) {
702                 netdev_err(netdev,
703                            "%s, priority is out of range\n", __func__);
704                 return;
705         }
706
707         if (pgid >= CEE_DCBX_MAX_PGS) {
708                 netdev_err(netdev,
709                            "%s, priority group is out of range\n", __func__);
710                 return;
711         }
712
713         cee_cfg->prio_to_pg_map[priority] = pgid;
714 }
715
716 static void mlx5e_dcbnl_setpgbwgcfgtx(struct net_device *netdev,
717                                       int pgid, u8 bw_pct)
718 {
719         struct mlx5e_priv *priv = netdev_priv(netdev);
720         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
721
722         if (pgid >= CEE_DCBX_MAX_PGS) {
723                 netdev_err(netdev,
724                            "%s, priority group is out of range\n", __func__);
725                 return;
726         }
727
728         cee_cfg->pg_bw_pct[pgid] = bw_pct;
729 }
730
731 static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
732                                      int priority, u8 *prio_type,
733                                      u8 *pgid, u8 *bw_pct, u8 *up_map)
734 {
735         struct mlx5e_priv *priv = netdev_priv(netdev);
736         struct mlx5_core_dev *mdev = priv->mdev;
737
738         if (!MLX5_CAP_GEN(priv->mdev, ets)) {
739                 netdev_err(netdev, "%s, ets is not supported\n", __func__);
740                 return;
741         }
742
743         if (priority >= CEE_DCBX_MAX_PRIO) {
744                 netdev_err(netdev,
745                            "%s, priority is out of range\n", __func__);
746                 return;
747         }
748
749         *prio_type = 0;
750         *bw_pct = 0;
751         *up_map = 0;
752
753         if (mlx5_query_port_prio_tc(mdev, priority, pgid))
754                 *pgid = 0;
755 }
756
757 static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
758                                       int pgid, u8 *bw_pct)
759 {
760         struct ieee_ets ets;
761
762         if (pgid >= CEE_DCBX_MAX_PGS) {
763                 netdev_err(netdev,
764                            "%s, priority group is out of range\n", __func__);
765                 return;
766         }
767
768         mlx5e_dcbnl_ieee_getets(netdev, &ets);
769         *bw_pct = ets.tc_tx_bw[pgid];
770 }
771
772 static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
773                                   int priority, u8 setting)
774 {
775         struct mlx5e_priv *priv = netdev_priv(netdev);
776         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
777
778         if (priority >= CEE_DCBX_MAX_PRIO) {
779                 netdev_err(netdev,
780                            "%s, priority is out of range\n", __func__);
781                 return;
782         }
783
784         if (setting > 1)
785                 return;
786
787         cee_cfg->pfc_setting[priority] = setting;
788 }
789
790 static int
791 mlx5e_dcbnl_get_priority_pfc(struct net_device *netdev,
792                              int priority, u8 *setting)
793 {
794         struct ieee_pfc pfc;
795         int err;
796
797         err = mlx5e_dcbnl_ieee_getpfc(netdev, &pfc);
798
799         if (err)
800                 *setting = 0;
801         else
802                 *setting = (pfc.pfc_en >> priority) & 0x01;
803
804         return err;
805 }
806
807 static void mlx5e_dcbnl_getpfccfg(struct net_device *netdev,
808                                   int priority, u8 *setting)
809 {
810         if (priority >= CEE_DCBX_MAX_PRIO) {
811                 netdev_err(netdev,
812                            "%s, priority is out of range\n", __func__);
813                 return;
814         }
815
816         if (!setting)
817                 return;
818
819         mlx5e_dcbnl_get_priority_pfc(netdev, priority, setting);
820 }
821
822 static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
823                              int capid, u8 *cap)
824 {
825         struct mlx5e_priv *priv = netdev_priv(netdev);
826         struct mlx5_core_dev *mdev = priv->mdev;
827         u8 rval = 0;
828
829         switch (capid) {
830         case DCB_CAP_ATTR_PG:
831                 *cap = true;
832                 break;
833         case DCB_CAP_ATTR_PFC:
834                 *cap = true;
835                 break;
836         case DCB_CAP_ATTR_UP2TC:
837                 *cap = false;
838                 break;
839         case DCB_CAP_ATTR_PG_TCS:
840                 *cap = 1 << mlx5_max_tc(mdev);
841                 break;
842         case DCB_CAP_ATTR_PFC_TCS:
843                 *cap = 1 << mlx5_max_tc(mdev);
844                 break;
845         case DCB_CAP_ATTR_GSP:
846                 *cap = false;
847                 break;
848         case DCB_CAP_ATTR_BCN:
849                 *cap = false;
850                 break;
851         case DCB_CAP_ATTR_DCBX:
852                 *cap = priv->dcbx.cap |
853                        DCB_CAP_DCBX_VER_CEE |
854                        DCB_CAP_DCBX_VER_IEEE;
855                 break;
856         default:
857                 *cap = 0;
858                 rval = 1;
859                 break;
860         }
861
862         return rval;
863 }
864
865 static int mlx5e_dcbnl_getnumtcs(struct net_device *netdev,
866                                  int tcs_id, u8 *num)
867 {
868         struct mlx5e_priv *priv = netdev_priv(netdev);
869         struct mlx5_core_dev *mdev = priv->mdev;
870
871         switch (tcs_id) {
872         case DCB_NUMTCS_ATTR_PG:
873         case DCB_NUMTCS_ATTR_PFC:
874                 *num = mlx5_max_tc(mdev) + 1;
875                 break;
876         default:
877                 return -EINVAL;
878         }
879
880         return 0;
881 }
882
883 static u8 mlx5e_dcbnl_getpfcstate(struct net_device *netdev)
884 {
885         struct ieee_pfc pfc;
886
887         if (mlx5e_dcbnl_ieee_getpfc(netdev, &pfc))
888                 return MLX5E_CEE_STATE_DOWN;
889
890         return pfc.pfc_en ? MLX5E_CEE_STATE_UP : MLX5E_CEE_STATE_DOWN;
891 }
892
893 static void mlx5e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
894 {
895         struct mlx5e_priv *priv = netdev_priv(netdev);
896         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
897
898         if ((state != MLX5E_CEE_STATE_UP) && (state != MLX5E_CEE_STATE_DOWN))
899                 return;
900
901         cee_cfg->pfc_enable = state;
902 }
903
904 static int mlx5e_dcbnl_getbuffer(struct net_device *dev,
905                                  struct dcbnl_buffer *dcb_buffer)
906 {
907         struct mlx5e_priv *priv = netdev_priv(dev);
908         struct mlx5_core_dev *mdev = priv->mdev;
909         struct mlx5e_port_buffer port_buffer;
910         u8 buffer[MLX5E_MAX_PRIORITY];
911         int i, err;
912
913         if (!MLX5_BUFFER_SUPPORTED(mdev))
914                 return -EOPNOTSUPP;
915
916         err = mlx5e_port_query_priority2buffer(mdev, buffer);
917         if (err)
918                 return err;
919
920         for (i = 0; i < MLX5E_MAX_PRIORITY; i++)
921                 dcb_buffer->prio2buffer[i] = buffer[i];
922
923         err = mlx5e_port_query_buffer(priv, &port_buffer);
924         if (err)
925                 return err;
926
927         for (i = 0; i < MLX5E_MAX_BUFFER; i++)
928                 dcb_buffer->buffer_size[i] = port_buffer.buffer[i].size;
929         dcb_buffer->total_size = port_buffer.port_buffer_size;
930
931         return 0;
932 }
933
934 static int mlx5e_dcbnl_setbuffer(struct net_device *dev,
935                                  struct dcbnl_buffer *dcb_buffer)
936 {
937         struct mlx5e_priv *priv = netdev_priv(dev);
938         struct mlx5_core_dev *mdev = priv->mdev;
939         struct mlx5e_port_buffer port_buffer;
940         u8 old_prio2buffer[MLX5E_MAX_PRIORITY];
941         u32 *buffer_size = NULL;
942         u8 *prio2buffer = NULL;
943         u32 changed = 0;
944         int i, err;
945
946         if (!MLX5_BUFFER_SUPPORTED(mdev))
947                 return -EOPNOTSUPP;
948
949         for (i = 0; i < DCBX_MAX_BUFFERS; i++)
950                 mlx5_core_dbg(mdev, "buffer[%d]=%d\n", i, dcb_buffer->buffer_size[i]);
951
952         for (i = 0; i < MLX5E_MAX_PRIORITY; i++)
953                 mlx5_core_dbg(mdev, "priority %d buffer%d\n", i, dcb_buffer->prio2buffer[i]);
954
955         err = mlx5e_port_query_priority2buffer(mdev, old_prio2buffer);
956         if (err)
957                 return err;
958
959         for (i = 0; i < MLX5E_MAX_PRIORITY; i++) {
960                 if (dcb_buffer->prio2buffer[i] != old_prio2buffer[i]) {
961                         changed |= MLX5E_PORT_BUFFER_PRIO2BUFFER;
962                         prio2buffer = dcb_buffer->prio2buffer;
963                         break;
964                 }
965         }
966
967         err = mlx5e_port_query_buffer(priv, &port_buffer);
968         if (err)
969                 return err;
970
971         for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
972                 if (port_buffer.buffer[i].size != dcb_buffer->buffer_size[i]) {
973                         changed |= MLX5E_PORT_BUFFER_SIZE;
974                         buffer_size = dcb_buffer->buffer_size;
975                         break;
976                 }
977         }
978
979         if (!changed)
980                 return 0;
981
982         priv->dcbx.manual_buffer = true;
983         err = mlx5e_port_manual_buffer_config(priv, changed, dev->mtu, NULL,
984                                               buffer_size, prio2buffer);
985         return err;
986 }
987
988 const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
989         .ieee_getets    = mlx5e_dcbnl_ieee_getets,
990         .ieee_setets    = mlx5e_dcbnl_ieee_setets,
991         .ieee_getmaxrate = mlx5e_dcbnl_ieee_getmaxrate,
992         .ieee_setmaxrate = mlx5e_dcbnl_ieee_setmaxrate,
993         .ieee_getpfc    = mlx5e_dcbnl_ieee_getpfc,
994         .ieee_setpfc    = mlx5e_dcbnl_ieee_setpfc,
995         .ieee_setapp    = mlx5e_dcbnl_ieee_setapp,
996         .ieee_delapp    = mlx5e_dcbnl_ieee_delapp,
997         .getdcbx        = mlx5e_dcbnl_getdcbx,
998         .setdcbx        = mlx5e_dcbnl_setdcbx,
999         .dcbnl_getbuffer = mlx5e_dcbnl_getbuffer,
1000         .dcbnl_setbuffer = mlx5e_dcbnl_setbuffer,
1001
1002 /* CEE interfaces */
1003         .setall         = mlx5e_dcbnl_setall,
1004         .getstate       = mlx5e_dcbnl_getstate,
1005         .getpermhwaddr  = mlx5e_dcbnl_getpermhwaddr,
1006
1007         .setpgtccfgtx   = mlx5e_dcbnl_setpgtccfgtx,
1008         .setpgbwgcfgtx  = mlx5e_dcbnl_setpgbwgcfgtx,
1009         .getpgtccfgtx   = mlx5e_dcbnl_getpgtccfgtx,
1010         .getpgbwgcfgtx  = mlx5e_dcbnl_getpgbwgcfgtx,
1011
1012         .setpfccfg      = mlx5e_dcbnl_setpfccfg,
1013         .getpfccfg      = mlx5e_dcbnl_getpfccfg,
1014         .getcap         = mlx5e_dcbnl_getcap,
1015         .getnumtcs      = mlx5e_dcbnl_getnumtcs,
1016         .getpfcstate    = mlx5e_dcbnl_getpfcstate,
1017         .setpfcstate    = mlx5e_dcbnl_setpfcstate,
1018 };
1019
1020 static void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv,
1021                                         enum mlx5_dcbx_oper_mode *mode)
1022 {
1023         u32 out[MLX5_ST_SZ_DW(dcbx_param)];
1024
1025         *mode = MLX5E_DCBX_PARAM_VER_OPER_HOST;
1026
1027         if (!mlx5_query_port_dcbx_param(priv->mdev, out))
1028                 *mode = MLX5_GET(dcbx_param, out, version_oper);
1029
1030         /* From driver's point of view, we only care if the mode
1031          * is host (HOST) or non-host (AUTO)
1032          */
1033         if (*mode != MLX5E_DCBX_PARAM_VER_OPER_HOST)
1034                 *mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
1035 }
1036
1037 static void mlx5e_ets_init(struct mlx5e_priv *priv)
1038 {
1039         struct ieee_ets ets;
1040         int err;
1041         int i;
1042
1043         if (!MLX5_CAP_GEN(priv->mdev, ets))
1044                 return;
1045
1046         memset(&ets, 0, sizeof(ets));
1047         ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
1048         for (i = 0; i < ets.ets_cap; i++) {
1049                 ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
1050                 ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
1051                 ets.prio_tc[i] = i;
1052         }
1053
1054         if (ets.ets_cap > 1) {
1055                 /* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
1056                 ets.prio_tc[0] = 1;
1057                 ets.prio_tc[1] = 0;
1058         }
1059
1060         err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
1061         if (err)
1062                 netdev_err(priv->netdev,
1063                            "%s, Failed to init ETS: %d\n", __func__, err);
1064 }
1065
1066 enum {
1067         INIT,
1068         DELETE,
1069 };
1070
1071 static void mlx5e_dcbnl_dscp_app(struct mlx5e_priv *priv, int action)
1072 {
1073         struct dcb_app temp;
1074         int i;
1075
1076         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
1077                 return;
1078
1079         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
1080                 return;
1081
1082         /* No SEL_DSCP entry in non DSCP state */
1083         if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_DSCP)
1084                 return;
1085
1086         temp.selector = IEEE_8021QAZ_APP_SEL_DSCP;
1087         for (i = 0; i < MLX5E_MAX_DSCP; i++) {
1088                 temp.protocol = i;
1089                 temp.priority = priv->dcbx_dp.dscp2prio[i];
1090                 if (action == INIT)
1091                         dcb_ieee_setapp(priv->netdev, &temp);
1092                 else
1093                         dcb_ieee_delapp(priv->netdev, &temp);
1094         }
1095
1096         priv->dcbx.dscp_app_cnt = (action == INIT) ? MLX5E_MAX_DSCP : 0;
1097 }
1098
1099 void mlx5e_dcbnl_init_app(struct mlx5e_priv *priv)
1100 {
1101         mlx5e_dcbnl_dscp_app(priv, INIT);
1102 }
1103
1104 void mlx5e_dcbnl_delete_app(struct mlx5e_priv *priv)
1105 {
1106         mlx5e_dcbnl_dscp_app(priv, DELETE);
1107 }
1108
1109 static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv,
1110                                                   struct mlx5e_params *params)
1111 {
1112         params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(priv->mdev);
1113         if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP &&
1114             params->tx_min_inline_mode == MLX5_INLINE_MODE_L2)
1115                 params->tx_min_inline_mode = MLX5_INLINE_MODE_IP;
1116 }
1117
1118 static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv)
1119 {
1120         struct mlx5e_channels new_channels = {};
1121
1122         mutex_lock(&priv->state_lock);
1123
1124         new_channels.params = priv->channels.params;
1125         mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params);
1126
1127         if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1128                 priv->channels.params = new_channels.params;
1129                 goto out;
1130         }
1131
1132         /* Skip if tx_min_inline is the same */
1133         if (new_channels.params.tx_min_inline_mode ==
1134             priv->channels.params.tx_min_inline_mode)
1135                 goto out;
1136
1137         if (mlx5e_open_channels(priv, &new_channels))
1138                 goto out;
1139         mlx5e_switch_priv_channels(priv, &new_channels, NULL);
1140
1141 out:
1142         mutex_unlock(&priv->state_lock);
1143 }
1144
1145 static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
1146 {
1147         int err;
1148
1149         err =  mlx5_set_trust_state(priv->mdev, trust_state);
1150         if (err)
1151                 return err;
1152         priv->dcbx_dp.trust_state = trust_state;
1153         mlx5e_trust_update_sq_inline_mode(priv);
1154
1155         return err;
1156 }
1157
1158 static int mlx5e_set_dscp2prio(struct mlx5e_priv *priv, u8 dscp, u8 prio)
1159 {
1160         int err;
1161
1162         err = mlx5_set_dscp2prio(priv->mdev, dscp, prio);
1163         if (err)
1164                 return err;
1165
1166         priv->dcbx_dp.dscp2prio[dscp] = prio;
1167         return err;
1168 }
1169
1170 static int mlx5e_trust_initialize(struct mlx5e_priv *priv)
1171 {
1172         struct mlx5_core_dev *mdev = priv->mdev;
1173         int err;
1174
1175         if (!MLX5_DSCP_SUPPORTED(mdev))
1176                 return 0;
1177
1178         err = mlx5_query_trust_state(priv->mdev, &priv->dcbx_dp.trust_state);
1179         if (err)
1180                 return err;
1181
1182         mlx5e_trust_update_tx_min_inline_mode(priv, &priv->channels.params);
1183
1184         err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio);
1185         if (err)
1186                 return err;
1187
1188         return 0;
1189 }
1190
1191 void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
1192 {
1193         struct mlx5e_dcbx *dcbx = &priv->dcbx;
1194
1195         mlx5e_trust_initialize(priv);
1196
1197         if (!MLX5_CAP_GEN(priv->mdev, qos))
1198                 return;
1199
1200         if (MLX5_CAP_GEN(priv->mdev, dcbx))
1201                 mlx5e_dcbnl_query_dcbx_mode(priv, &dcbx->mode);
1202
1203         priv->dcbx.cap = DCB_CAP_DCBX_VER_CEE |
1204                          DCB_CAP_DCBX_VER_IEEE;
1205         if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
1206                 priv->dcbx.cap |= DCB_CAP_DCBX_HOST;
1207
1208         priv->dcbx.manual_buffer = false;
1209         priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN;
1210
1211         mlx5e_ets_init(priv);
1212 }