0a52f31fef377e40ae9f19c091c33aca58bee154
[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 {
280         bool have_ets_tc = false;
281         int bw_sum = 0;
282         int i;
283
284         /* Validate Priority */
285         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
286                 if (ets->prio_tc[i] >= MLX5E_MAX_PRIORITY) {
287                         netdev_err(netdev,
288                                    "Failed to validate ETS: priority value greater than max(%d)\n",
289                                     MLX5E_MAX_PRIORITY);
290                         return -EINVAL;
291                 }
292         }
293
294         /* Validate Bandwidth Sum */
295         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
296                 if (ets->tc_tsa[i] == IEEE_8021QAZ_TSA_ETS) {
297                         have_ets_tc = true;
298                         bw_sum += ets->tc_tx_bw[i];
299                 }
300         }
301
302         if (have_ets_tc && bw_sum != 100) {
303                 netdev_err(netdev,
304                            "Failed to validate ETS: BW sum is illegal\n");
305                 return -EINVAL;
306         }
307         return 0;
308 }
309
310 static int mlx5e_dcbnl_ieee_setets(struct net_device *netdev,
311                                    struct ieee_ets *ets)
312 {
313         struct mlx5e_priv *priv = netdev_priv(netdev);
314         int err;
315
316         if (!MLX5_CAP_GEN(priv->mdev, ets))
317                 return -EOPNOTSUPP;
318
319         err = mlx5e_dbcnl_validate_ets(netdev, ets);
320         if (err)
321                 return err;
322
323         err = mlx5e_dcbnl_ieee_setets_core(priv, ets);
324         if (err)
325                 return err;
326
327         return 0;
328 }
329
330 static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,
331                                    struct ieee_pfc *pfc)
332 {
333         struct mlx5e_priv *priv = netdev_priv(dev);
334         struct mlx5_core_dev *mdev = priv->mdev;
335         struct mlx5e_pport_stats *pstats = &priv->stats.pport;
336         int i;
337
338         pfc->pfc_cap = mlx5_max_tc(mdev) + 1;
339         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
340                 pfc->requests[i]    = PPORT_PER_PRIO_GET(pstats, i, tx_pause);
341                 pfc->indications[i] = PPORT_PER_PRIO_GET(pstats, i, rx_pause);
342         }
343
344         if (MLX5_BUFFER_SUPPORTED(mdev))
345                 pfc->delay = priv->dcbx.cable_len;
346
347         return mlx5_query_port_pfc(mdev, &pfc->pfc_en, NULL);
348 }
349
350 static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
351                                    struct ieee_pfc *pfc)
352 {
353         struct mlx5e_priv *priv = netdev_priv(dev);
354         struct mlx5_core_dev *mdev = priv->mdev;
355         u32 old_cable_len = priv->dcbx.cable_len;
356         struct ieee_pfc pfc_new;
357         u32 changed = 0;
358         u8 curr_pfc_en;
359         int ret = 0;
360
361         /* pfc_en */
362         mlx5_query_port_pfc(mdev, &curr_pfc_en, NULL);
363         if (pfc->pfc_en != curr_pfc_en) {
364                 ret = mlx5_set_port_pfc(mdev, pfc->pfc_en, pfc->pfc_en);
365                 if (ret)
366                         return ret;
367                 mlx5_toggle_port_link(mdev);
368                 changed |= MLX5E_PORT_BUFFER_PFC;
369         }
370
371         if (pfc->delay &&
372             pfc->delay < MLX5E_MAX_CABLE_LENGTH &&
373             pfc->delay != priv->dcbx.cable_len) {
374                 priv->dcbx.cable_len = pfc->delay;
375                 changed |= MLX5E_PORT_BUFFER_CABLE_LEN;
376         }
377
378         if (MLX5_BUFFER_SUPPORTED(mdev)) {
379                 pfc_new.pfc_en = (changed & MLX5E_PORT_BUFFER_PFC) ? pfc->pfc_en : curr_pfc_en;
380                 if (priv->dcbx.manual_buffer)
381                         ret = mlx5e_port_manual_buffer_config(priv, changed,
382                                                               dev->mtu, &pfc_new,
383                                                               NULL, NULL);
384
385                 if (ret && (changed & MLX5E_PORT_BUFFER_CABLE_LEN))
386                         priv->dcbx.cable_len = old_cable_len;
387         }
388
389         if (!ret) {
390                 mlx5e_dbg(HW, priv,
391                           "%s: PFC per priority bit mask: 0x%x\n",
392                           __func__, pfc->pfc_en);
393         }
394         return ret;
395 }
396
397 static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
398 {
399         struct mlx5e_priv *priv = netdev_priv(dev);
400
401         return priv->dcbx.cap;
402 }
403
404 static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
405 {
406         struct mlx5e_priv *priv = netdev_priv(dev);
407         struct mlx5e_dcbx *dcbx = &priv->dcbx;
408
409         if (mode & DCB_CAP_DCBX_LLD_MANAGED)
410                 return 1;
411
412         if ((!mode) && MLX5_CAP_GEN(priv->mdev, dcbx)) {
413                 if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_AUTO)
414                         return 0;
415
416                 /* set dcbx to fw controlled */
417                 if (!mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_AUTO)) {
418                         dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
419                         dcbx->cap &= ~DCB_CAP_DCBX_HOST;
420                         return 0;
421                 }
422
423                 return 1;
424         }
425
426         if (!(mode & DCB_CAP_DCBX_HOST))
427                 return 1;
428
429         if (mlx5e_dcbnl_switch_to_host_mode(netdev_priv(dev)))
430                 return 1;
431
432         dcbx->cap = mode;
433
434         return 0;
435 }
436
437 static int mlx5e_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app)
438 {
439         struct mlx5e_priv *priv = netdev_priv(dev);
440         struct dcb_app temp;
441         bool is_new;
442         int err;
443
444         if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
445                 return -EINVAL;
446
447         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
448                 return -EINVAL;
449
450         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
451                 return -EINVAL;
452
453         if (app->protocol >= MLX5E_MAX_DSCP)
454                 return -EINVAL;
455
456         /* Save the old entry info */
457         temp.selector = IEEE_8021QAZ_APP_SEL_DSCP;
458         temp.protocol = app->protocol;
459         temp.priority = priv->dcbx_dp.dscp2prio[app->protocol];
460
461         /* Check if need to switch to dscp trust state */
462         if (!priv->dcbx.dscp_app_cnt) {
463                 err =  mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_DSCP);
464                 if (err)
465                         return err;
466         }
467
468         /* Skip the fw command if new and old mapping are the same */
469         if (app->priority != priv->dcbx_dp.dscp2prio[app->protocol]) {
470                 err = mlx5e_set_dscp2prio(priv, app->protocol, app->priority);
471                 if (err)
472                         goto fw_err;
473         }
474
475         /* Delete the old entry if exists */
476         is_new = false;
477         err = dcb_ieee_delapp(dev, &temp);
478         if (err)
479                 is_new = true;
480
481         /* Add new entry and update counter */
482         err = dcb_ieee_setapp(dev, app);
483         if (err)
484                 return err;
485
486         if (is_new)
487                 priv->dcbx.dscp_app_cnt++;
488
489         return err;
490
491 fw_err:
492         mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
493         return err;
494 }
495
496 static int mlx5e_dcbnl_ieee_delapp(struct net_device *dev, struct dcb_app *app)
497 {
498         struct mlx5e_priv *priv = netdev_priv(dev);
499         int err;
500
501         if (app->selector != IEEE_8021QAZ_APP_SEL_DSCP)
502                 return -EINVAL;
503
504         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
505                 return -EINVAL;
506
507         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
508                 return -EINVAL;
509
510         if (app->protocol >= MLX5E_MAX_DSCP)
511                 return -EINVAL;
512
513         /* Skip if no dscp app entry */
514         if (!priv->dcbx.dscp_app_cnt)
515                 return -ENOENT;
516
517         /* Check if the entry matches fw setting */
518         if (app->priority != priv->dcbx_dp.dscp2prio[app->protocol])
519                 return -ENOENT;
520
521         /* Delete the app entry */
522         err = dcb_ieee_delapp(dev, app);
523         if (err)
524                 return err;
525
526         /* Reset the priority mapping back to zero */
527         err = mlx5e_set_dscp2prio(priv, app->protocol, 0);
528         if (err)
529                 goto fw_err;
530
531         priv->dcbx.dscp_app_cnt--;
532
533         /* Check if need to switch to pcp trust state */
534         if (!priv->dcbx.dscp_app_cnt)
535                 err = mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
536
537         return err;
538
539 fw_err:
540         mlx5e_set_trust_state(priv, MLX5_QPTS_TRUST_PCP);
541         return err;
542 }
543
544 static int mlx5e_dcbnl_ieee_getmaxrate(struct net_device *netdev,
545                                        struct ieee_maxrate *maxrate)
546 {
547         struct mlx5e_priv *priv    = netdev_priv(netdev);
548         struct mlx5_core_dev *mdev = priv->mdev;
549         u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
550         u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
551         int err;
552         int i;
553
554         err = mlx5_query_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
555         if (err)
556                 return err;
557
558         memset(maxrate->tc_maxrate, 0, sizeof(maxrate->tc_maxrate));
559
560         for (i = 0; i <= mlx5_max_tc(mdev); i++) {
561                 switch (max_bw_unit[i]) {
562                 case MLX5_100_MBPS_UNIT:
563                         maxrate->tc_maxrate[i] = max_bw_value[i] * MLX5E_100MB;
564                         break;
565                 case MLX5_GBPS_UNIT:
566                         maxrate->tc_maxrate[i] = max_bw_value[i] * MLX5E_1GB;
567                         break;
568                 case MLX5_BW_NO_LIMIT:
569                         break;
570                 default:
571                         WARN(true, "non-supported BW unit");
572                         break;
573                 }
574         }
575
576         return 0;
577 }
578
579 static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
580                                        struct ieee_maxrate *maxrate)
581 {
582         struct mlx5e_priv *priv    = netdev_priv(netdev);
583         struct mlx5_core_dev *mdev = priv->mdev;
584         u8 max_bw_value[IEEE_8021QAZ_MAX_TCS];
585         u8 max_bw_unit[IEEE_8021QAZ_MAX_TCS];
586         __u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
587         int i;
588
589         memset(max_bw_value, 0, sizeof(max_bw_value));
590         memset(max_bw_unit, 0, sizeof(max_bw_unit));
591
592         for (i = 0; i <= mlx5_max_tc(mdev); i++) {
593                 if (!maxrate->tc_maxrate[i]) {
594                         max_bw_unit[i]  = MLX5_BW_NO_LIMIT;
595                         continue;
596                 }
597                 if (maxrate->tc_maxrate[i] < upper_limit_mbps) {
598                         max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
599                                                   MLX5E_100MB);
600                         max_bw_value[i] = max_bw_value[i] ? max_bw_value[i] : 1;
601                         max_bw_unit[i]  = MLX5_100_MBPS_UNIT;
602                 } else {
603                         max_bw_value[i] = div_u64(maxrate->tc_maxrate[i],
604                                                   MLX5E_1GB);
605                         max_bw_unit[i]  = MLX5_GBPS_UNIT;
606                 }
607         }
608
609         for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
610                 mlx5e_dbg(HW, priv, "%s: tc_%d <=> max_bw %d Gbps\n",
611                           __func__, i, max_bw_value[i]);
612         }
613
614         return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
615 }
616
617 static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
618 {
619         struct mlx5e_priv *priv = netdev_priv(netdev);
620         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
621         struct mlx5_core_dev *mdev = priv->mdev;
622         struct ieee_ets ets;
623         struct ieee_pfc pfc;
624         int err = -EOPNOTSUPP;
625         int i;
626
627         if (!MLX5_CAP_GEN(mdev, ets))
628                 goto out;
629
630         memset(&ets, 0, sizeof(ets));
631         memset(&pfc, 0, sizeof(pfc));
632
633         ets.ets_cap = IEEE_8021QAZ_MAX_TCS;
634         for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
635                 ets.tc_tx_bw[i] = cee_cfg->pg_bw_pct[i];
636                 ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i];
637                 ets.tc_tsa[i]   = IEEE_8021QAZ_TSA_ETS;
638                 ets.prio_tc[i]  = cee_cfg->prio_to_pg_map[i];
639                 mlx5e_dbg(HW, priv,
640                           "%s: Priority group %d: tx_bw %d, rx_bw %d, prio_tc %d\n",
641                           __func__, i, ets.tc_tx_bw[i], ets.tc_rx_bw[i],
642                           ets.prio_tc[i]);
643         }
644
645         err = mlx5e_dbcnl_validate_ets(netdev, &ets);
646         if (err) {
647                 netdev_err(netdev,
648                            "%s, Failed to validate ETS: %d\n", __func__, err);
649                 goto out;
650         }
651
652         err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
653         if (err) {
654                 netdev_err(netdev,
655                            "%s, Failed to set ETS: %d\n", __func__, err);
656                 goto out;
657         }
658
659         /* Set PFC */
660         pfc.pfc_cap = mlx5_max_tc(mdev) + 1;
661         if (!cee_cfg->pfc_enable)
662                 pfc.pfc_en = 0;
663         else
664                 for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
665                         pfc.pfc_en |= cee_cfg->pfc_setting[i] << i;
666
667         err = mlx5e_dcbnl_ieee_setpfc(netdev, &pfc);
668         if (err) {
669                 netdev_err(netdev,
670                            "%s, Failed to set PFC: %d\n", __func__, err);
671                 goto out;
672         }
673 out:
674         return err ? MLX5_DCB_NO_CHG : MLX5_DCB_CHG_RESET;
675 }
676
677 static u8 mlx5e_dcbnl_getstate(struct net_device *netdev)
678 {
679         return MLX5E_CEE_STATE_UP;
680 }
681
682 static void mlx5e_dcbnl_getpermhwaddr(struct net_device *netdev,
683                                       u8 *perm_addr)
684 {
685         struct mlx5e_priv *priv = netdev_priv(netdev);
686
687         if (!perm_addr)
688                 return;
689
690         memset(perm_addr, 0xff, MAX_ADDR_LEN);
691
692         mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr);
693 }
694
695 static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev,
696                                      int priority, u8 prio_type,
697                                      u8 pgid, u8 bw_pct, u8 up_map)
698 {
699         struct mlx5e_priv *priv = netdev_priv(netdev);
700         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
701
702         if (priority >= CEE_DCBX_MAX_PRIO) {
703                 netdev_err(netdev,
704                            "%s, priority is out of range\n", __func__);
705                 return;
706         }
707
708         if (pgid >= CEE_DCBX_MAX_PGS) {
709                 netdev_err(netdev,
710                            "%s, priority group is out of range\n", __func__);
711                 return;
712         }
713
714         cee_cfg->prio_to_pg_map[priority] = pgid;
715 }
716
717 static void mlx5e_dcbnl_setpgbwgcfgtx(struct net_device *netdev,
718                                       int pgid, u8 bw_pct)
719 {
720         struct mlx5e_priv *priv = netdev_priv(netdev);
721         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
722
723         if (pgid >= CEE_DCBX_MAX_PGS) {
724                 netdev_err(netdev,
725                            "%s, priority group is out of range\n", __func__);
726                 return;
727         }
728
729         cee_cfg->pg_bw_pct[pgid] = bw_pct;
730 }
731
732 static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
733                                      int priority, u8 *prio_type,
734                                      u8 *pgid, u8 *bw_pct, u8 *up_map)
735 {
736         struct mlx5e_priv *priv = netdev_priv(netdev);
737         struct mlx5_core_dev *mdev = priv->mdev;
738
739         if (!MLX5_CAP_GEN(priv->mdev, ets)) {
740                 netdev_err(netdev, "%s, ets is not supported\n", __func__);
741                 return;
742         }
743
744         if (priority >= CEE_DCBX_MAX_PRIO) {
745                 netdev_err(netdev,
746                            "%s, priority is out of range\n", __func__);
747                 return;
748         }
749
750         *prio_type = 0;
751         *bw_pct = 0;
752         *up_map = 0;
753
754         if (mlx5_query_port_prio_tc(mdev, priority, pgid))
755                 *pgid = 0;
756 }
757
758 static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
759                                       int pgid, u8 *bw_pct)
760 {
761         struct ieee_ets ets;
762
763         if (pgid >= CEE_DCBX_MAX_PGS) {
764                 netdev_err(netdev,
765                            "%s, priority group is out of range\n", __func__);
766                 return;
767         }
768
769         mlx5e_dcbnl_ieee_getets(netdev, &ets);
770         *bw_pct = ets.tc_tx_bw[pgid];
771 }
772
773 static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
774                                   int priority, u8 setting)
775 {
776         struct mlx5e_priv *priv = netdev_priv(netdev);
777         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
778
779         if (priority >= CEE_DCBX_MAX_PRIO) {
780                 netdev_err(netdev,
781                            "%s, priority is out of range\n", __func__);
782                 return;
783         }
784
785         if (setting > 1)
786                 return;
787
788         cee_cfg->pfc_setting[priority] = setting;
789 }
790
791 static int
792 mlx5e_dcbnl_get_priority_pfc(struct net_device *netdev,
793                              int priority, u8 *setting)
794 {
795         struct ieee_pfc pfc;
796         int err;
797
798         err = mlx5e_dcbnl_ieee_getpfc(netdev, &pfc);
799
800         if (err)
801                 *setting = 0;
802         else
803                 *setting = (pfc.pfc_en >> priority) & 0x01;
804
805         return err;
806 }
807
808 static void mlx5e_dcbnl_getpfccfg(struct net_device *netdev,
809                                   int priority, u8 *setting)
810 {
811         if (priority >= CEE_DCBX_MAX_PRIO) {
812                 netdev_err(netdev,
813                            "%s, priority is out of range\n", __func__);
814                 return;
815         }
816
817         if (!setting)
818                 return;
819
820         mlx5e_dcbnl_get_priority_pfc(netdev, priority, setting);
821 }
822
823 static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
824                              int capid, u8 *cap)
825 {
826         struct mlx5e_priv *priv = netdev_priv(netdev);
827         struct mlx5_core_dev *mdev = priv->mdev;
828         u8 rval = 0;
829
830         switch (capid) {
831         case DCB_CAP_ATTR_PG:
832                 *cap = true;
833                 break;
834         case DCB_CAP_ATTR_PFC:
835                 *cap = true;
836                 break;
837         case DCB_CAP_ATTR_UP2TC:
838                 *cap = false;
839                 break;
840         case DCB_CAP_ATTR_PG_TCS:
841                 *cap = 1 << mlx5_max_tc(mdev);
842                 break;
843         case DCB_CAP_ATTR_PFC_TCS:
844                 *cap = 1 << mlx5_max_tc(mdev);
845                 break;
846         case DCB_CAP_ATTR_GSP:
847                 *cap = false;
848                 break;
849         case DCB_CAP_ATTR_BCN:
850                 *cap = false;
851                 break;
852         case DCB_CAP_ATTR_DCBX:
853                 *cap = priv->dcbx.cap |
854                        DCB_CAP_DCBX_VER_CEE |
855                        DCB_CAP_DCBX_VER_IEEE;
856                 break;
857         default:
858                 *cap = 0;
859                 rval = 1;
860                 break;
861         }
862
863         return rval;
864 }
865
866 static int mlx5e_dcbnl_getnumtcs(struct net_device *netdev,
867                                  int tcs_id, u8 *num)
868 {
869         struct mlx5e_priv *priv = netdev_priv(netdev);
870         struct mlx5_core_dev *mdev = priv->mdev;
871
872         switch (tcs_id) {
873         case DCB_NUMTCS_ATTR_PG:
874         case DCB_NUMTCS_ATTR_PFC:
875                 *num = mlx5_max_tc(mdev) + 1;
876                 break;
877         default:
878                 return -EINVAL;
879         }
880
881         return 0;
882 }
883
884 static u8 mlx5e_dcbnl_getpfcstate(struct net_device *netdev)
885 {
886         struct ieee_pfc pfc;
887
888         if (mlx5e_dcbnl_ieee_getpfc(netdev, &pfc))
889                 return MLX5E_CEE_STATE_DOWN;
890
891         return pfc.pfc_en ? MLX5E_CEE_STATE_UP : MLX5E_CEE_STATE_DOWN;
892 }
893
894 static void mlx5e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
895 {
896         struct mlx5e_priv *priv = netdev_priv(netdev);
897         struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
898
899         if ((state != MLX5E_CEE_STATE_UP) && (state != MLX5E_CEE_STATE_DOWN))
900                 return;
901
902         cee_cfg->pfc_enable = state;
903 }
904
905 static int mlx5e_dcbnl_getbuffer(struct net_device *dev,
906                                  struct dcbnl_buffer *dcb_buffer)
907 {
908         struct mlx5e_priv *priv = netdev_priv(dev);
909         struct mlx5_core_dev *mdev = priv->mdev;
910         struct mlx5e_port_buffer port_buffer;
911         u8 buffer[MLX5E_MAX_PRIORITY];
912         int i, err;
913
914         if (!MLX5_BUFFER_SUPPORTED(mdev))
915                 return -EOPNOTSUPP;
916
917         err = mlx5e_port_query_priority2buffer(mdev, buffer);
918         if (err)
919                 return err;
920
921         for (i = 0; i < MLX5E_MAX_PRIORITY; i++)
922                 dcb_buffer->prio2buffer[i] = buffer[i];
923
924         err = mlx5e_port_query_buffer(priv, &port_buffer);
925         if (err)
926                 return err;
927
928         for (i = 0; i < MLX5E_MAX_BUFFER; i++)
929                 dcb_buffer->buffer_size[i] = port_buffer.buffer[i].size;
930         dcb_buffer->total_size = port_buffer.port_buffer_size;
931
932         return 0;
933 }
934
935 static int mlx5e_dcbnl_setbuffer(struct net_device *dev,
936                                  struct dcbnl_buffer *dcb_buffer)
937 {
938         struct mlx5e_priv *priv = netdev_priv(dev);
939         struct mlx5_core_dev *mdev = priv->mdev;
940         struct mlx5e_port_buffer port_buffer;
941         u8 old_prio2buffer[MLX5E_MAX_PRIORITY];
942         u32 *buffer_size = NULL;
943         u8 *prio2buffer = NULL;
944         u32 changed = 0;
945         int i, err;
946
947         if (!MLX5_BUFFER_SUPPORTED(mdev))
948                 return -EOPNOTSUPP;
949
950         for (i = 0; i < DCBX_MAX_BUFFERS; i++)
951                 mlx5_core_dbg(mdev, "buffer[%d]=%d\n", i, dcb_buffer->buffer_size[i]);
952
953         for (i = 0; i < MLX5E_MAX_PRIORITY; i++)
954                 mlx5_core_dbg(mdev, "priority %d buffer%d\n", i, dcb_buffer->prio2buffer[i]);
955
956         err = mlx5e_port_query_priority2buffer(mdev, old_prio2buffer);
957         if (err)
958                 return err;
959
960         for (i = 0; i < MLX5E_MAX_PRIORITY; i++) {
961                 if (dcb_buffer->prio2buffer[i] != old_prio2buffer[i]) {
962                         changed |= MLX5E_PORT_BUFFER_PRIO2BUFFER;
963                         prio2buffer = dcb_buffer->prio2buffer;
964                         break;
965                 }
966         }
967
968         err = mlx5e_port_query_buffer(priv, &port_buffer);
969         if (err)
970                 return err;
971
972         for (i = 0; i < MLX5E_MAX_BUFFER; i++) {
973                 if (port_buffer.buffer[i].size != dcb_buffer->buffer_size[i]) {
974                         changed |= MLX5E_PORT_BUFFER_SIZE;
975                         buffer_size = dcb_buffer->buffer_size;
976                         break;
977                 }
978         }
979
980         if (!changed)
981                 return 0;
982
983         priv->dcbx.manual_buffer = true;
984         err = mlx5e_port_manual_buffer_config(priv, changed, dev->mtu, NULL,
985                                               buffer_size, prio2buffer);
986         return err;
987 }
988
989 const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
990         .ieee_getets    = mlx5e_dcbnl_ieee_getets,
991         .ieee_setets    = mlx5e_dcbnl_ieee_setets,
992         .ieee_getmaxrate = mlx5e_dcbnl_ieee_getmaxrate,
993         .ieee_setmaxrate = mlx5e_dcbnl_ieee_setmaxrate,
994         .ieee_getpfc    = mlx5e_dcbnl_ieee_getpfc,
995         .ieee_setpfc    = mlx5e_dcbnl_ieee_setpfc,
996         .ieee_setapp    = mlx5e_dcbnl_ieee_setapp,
997         .ieee_delapp    = mlx5e_dcbnl_ieee_delapp,
998         .getdcbx        = mlx5e_dcbnl_getdcbx,
999         .setdcbx        = mlx5e_dcbnl_setdcbx,
1000         .dcbnl_getbuffer = mlx5e_dcbnl_getbuffer,
1001         .dcbnl_setbuffer = mlx5e_dcbnl_setbuffer,
1002
1003 /* CEE interfaces */
1004         .setall         = mlx5e_dcbnl_setall,
1005         .getstate       = mlx5e_dcbnl_getstate,
1006         .getpermhwaddr  = mlx5e_dcbnl_getpermhwaddr,
1007
1008         .setpgtccfgtx   = mlx5e_dcbnl_setpgtccfgtx,
1009         .setpgbwgcfgtx  = mlx5e_dcbnl_setpgbwgcfgtx,
1010         .getpgtccfgtx   = mlx5e_dcbnl_getpgtccfgtx,
1011         .getpgbwgcfgtx  = mlx5e_dcbnl_getpgbwgcfgtx,
1012
1013         .setpfccfg      = mlx5e_dcbnl_setpfccfg,
1014         .getpfccfg      = mlx5e_dcbnl_getpfccfg,
1015         .getcap         = mlx5e_dcbnl_getcap,
1016         .getnumtcs      = mlx5e_dcbnl_getnumtcs,
1017         .getpfcstate    = mlx5e_dcbnl_getpfcstate,
1018         .setpfcstate    = mlx5e_dcbnl_setpfcstate,
1019 };
1020
1021 static void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv,
1022                                         enum mlx5_dcbx_oper_mode *mode)
1023 {
1024         u32 out[MLX5_ST_SZ_DW(dcbx_param)];
1025
1026         *mode = MLX5E_DCBX_PARAM_VER_OPER_HOST;
1027
1028         if (!mlx5_query_port_dcbx_param(priv->mdev, out))
1029                 *mode = MLX5_GET(dcbx_param, out, version_oper);
1030
1031         /* From driver's point of view, we only care if the mode
1032          * is host (HOST) or non-host (AUTO)
1033          */
1034         if (*mode != MLX5E_DCBX_PARAM_VER_OPER_HOST)
1035                 *mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
1036 }
1037
1038 static void mlx5e_ets_init(struct mlx5e_priv *priv)
1039 {
1040         struct ieee_ets ets;
1041         int err;
1042         int i;
1043
1044         if (!MLX5_CAP_GEN(priv->mdev, ets))
1045                 return;
1046
1047         memset(&ets, 0, sizeof(ets));
1048         ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
1049         for (i = 0; i < ets.ets_cap; i++) {
1050                 ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
1051                 ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
1052                 ets.prio_tc[i] = i;
1053         }
1054
1055         if (ets.ets_cap > 1) {
1056                 /* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
1057                 ets.prio_tc[0] = 1;
1058                 ets.prio_tc[1] = 0;
1059         }
1060
1061         err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
1062         if (err)
1063                 netdev_err(priv->netdev,
1064                            "%s, Failed to init ETS: %d\n", __func__, err);
1065 }
1066
1067 enum {
1068         INIT,
1069         DELETE,
1070 };
1071
1072 static void mlx5e_dcbnl_dscp_app(struct mlx5e_priv *priv, int action)
1073 {
1074         struct dcb_app temp;
1075         int i;
1076
1077         if (!MLX5_CAP_GEN(priv->mdev, vport_group_manager))
1078                 return;
1079
1080         if (!MLX5_DSCP_SUPPORTED(priv->mdev))
1081                 return;
1082
1083         /* No SEL_DSCP entry in non DSCP state */
1084         if (priv->dcbx_dp.trust_state != MLX5_QPTS_TRUST_DSCP)
1085                 return;
1086
1087         temp.selector = IEEE_8021QAZ_APP_SEL_DSCP;
1088         for (i = 0; i < MLX5E_MAX_DSCP; i++) {
1089                 temp.protocol = i;
1090                 temp.priority = priv->dcbx_dp.dscp2prio[i];
1091                 if (action == INIT)
1092                         dcb_ieee_setapp(priv->netdev, &temp);
1093                 else
1094                         dcb_ieee_delapp(priv->netdev, &temp);
1095         }
1096
1097         priv->dcbx.dscp_app_cnt = (action == INIT) ? MLX5E_MAX_DSCP : 0;
1098 }
1099
1100 void mlx5e_dcbnl_init_app(struct mlx5e_priv *priv)
1101 {
1102         mlx5e_dcbnl_dscp_app(priv, INIT);
1103 }
1104
1105 void mlx5e_dcbnl_delete_app(struct mlx5e_priv *priv)
1106 {
1107         mlx5e_dcbnl_dscp_app(priv, DELETE);
1108 }
1109
1110 static void mlx5e_trust_update_tx_min_inline_mode(struct mlx5e_priv *priv,
1111                                                   struct mlx5e_params *params)
1112 {
1113         params->tx_min_inline_mode = mlx5e_params_calculate_tx_min_inline(priv->mdev);
1114         if (priv->dcbx_dp.trust_state == MLX5_QPTS_TRUST_DSCP &&
1115             params->tx_min_inline_mode == MLX5_INLINE_MODE_L2)
1116                 params->tx_min_inline_mode = MLX5_INLINE_MODE_IP;
1117 }
1118
1119 static void mlx5e_trust_update_sq_inline_mode(struct mlx5e_priv *priv)
1120 {
1121         struct mlx5e_channels new_channels = {};
1122
1123         mutex_lock(&priv->state_lock);
1124
1125         new_channels.params = priv->channels.params;
1126         mlx5e_trust_update_tx_min_inline_mode(priv, &new_channels.params);
1127
1128         if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
1129                 priv->channels.params = new_channels.params;
1130                 goto out;
1131         }
1132
1133         /* Skip if tx_min_inline is the same */
1134         if (new_channels.params.tx_min_inline_mode ==
1135             priv->channels.params.tx_min_inline_mode)
1136                 goto out;
1137
1138         if (mlx5e_open_channels(priv, &new_channels))
1139                 goto out;
1140         mlx5e_switch_priv_channels(priv, &new_channels, NULL);
1141
1142 out:
1143         mutex_unlock(&priv->state_lock);
1144 }
1145
1146 static int mlx5e_set_trust_state(struct mlx5e_priv *priv, u8 trust_state)
1147 {
1148         int err;
1149
1150         err =  mlx5_set_trust_state(priv->mdev, trust_state);
1151         if (err)
1152                 return err;
1153         priv->dcbx_dp.trust_state = trust_state;
1154         mlx5e_trust_update_sq_inline_mode(priv);
1155
1156         return err;
1157 }
1158
1159 static int mlx5e_set_dscp2prio(struct mlx5e_priv *priv, u8 dscp, u8 prio)
1160 {
1161         int err;
1162
1163         err = mlx5_set_dscp2prio(priv->mdev, dscp, prio);
1164         if (err)
1165                 return err;
1166
1167         priv->dcbx_dp.dscp2prio[dscp] = prio;
1168         return err;
1169 }
1170
1171 static int mlx5e_trust_initialize(struct mlx5e_priv *priv)
1172 {
1173         struct mlx5_core_dev *mdev = priv->mdev;
1174         int err;
1175
1176         if (!MLX5_DSCP_SUPPORTED(mdev))
1177                 return 0;
1178
1179         err = mlx5_query_trust_state(priv->mdev, &priv->dcbx_dp.trust_state);
1180         if (err)
1181                 return err;
1182
1183         mlx5e_trust_update_tx_min_inline_mode(priv, &priv->channels.params);
1184
1185         err = mlx5_query_dscp2prio(priv->mdev, priv->dcbx_dp.dscp2prio);
1186         if (err)
1187                 return err;
1188
1189         return 0;
1190 }
1191
1192 void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
1193 {
1194         struct mlx5e_dcbx *dcbx = &priv->dcbx;
1195
1196         mlx5e_trust_initialize(priv);
1197
1198         if (!MLX5_CAP_GEN(priv->mdev, qos))
1199                 return;
1200
1201         if (MLX5_CAP_GEN(priv->mdev, dcbx))
1202                 mlx5e_dcbnl_query_dcbx_mode(priv, &dcbx->mode);
1203
1204         priv->dcbx.cap = DCB_CAP_DCBX_VER_CEE |
1205                          DCB_CAP_DCBX_VER_IEEE;
1206         if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
1207                 priv->dcbx.cap |= DCB_CAP_DCBX_HOST;
1208
1209         priv->dcbx.manual_buffer = false;
1210         priv->dcbx.cable_len = MLX5E_DEFAULT_CABLE_LEN;
1211
1212         mlx5e_ets_init(priv);
1213 }