Skip to content

Commit 3a6a931

Browse files
Huy Nguyendavem330
authored andcommitted
net/mlx5e: Support DCBX CEE API
Add DCBX CEE API interface for ConnectX-4. Configurations are stored in a temporary structure and are applied to the card's firmware when the CEE's setall callback function is called. Note: priority group in CEE is equivalent to traffic class in ConnectX-4 hardware spec. bw allocation per priority in CEE is not supported because ConnectX-4 only supports bw allocation per traffic class. user priority in CEE does not have an equivalent term in ConnectX-4. Therefore, user priority to priority mapping in CEE is not supported. Signed-off-by: Huy Nguyen <huyn@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 80653f7 commit 3a6a931

File tree

4 files changed

+370
-2
lines changed

4 files changed

+370
-2
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,26 @@ struct mlx5e_params {
221221
u32 lro_timeout;
222222
};
223223

224+
#ifdef CONFIG_MLX5_CORE_EN_DCB
225+
struct mlx5e_cee_config {
226+
/* bw pct for priority group */
227+
u8 pg_bw_pct[CEE_DCBX_MAX_PGS];
228+
u8 prio_to_pg_map[CEE_DCBX_MAX_PRIO];
229+
bool pfc_setting[CEE_DCBX_MAX_PRIO];
230+
bool pfc_enable;
231+
};
232+
233+
enum {
234+
MLX5_DCB_CHG_RESET,
235+
MLX5_DCB_NO_CHG,
236+
MLX5_DCB_CHG_NO_RESET,
237+
};
238+
239+
struct mlx5e_dcbx {
240+
struct mlx5e_cee_config cee_cfg; /* pending configuration */
241+
};
242+
#endif
243+
224244
struct mlx5e_tstamp {
225245
rwlock_t lock;
226246
struct cyclecounter cycles;
@@ -688,6 +708,10 @@ struct mlx5e_priv {
688708
struct mlx5e_stats stats;
689709
struct mlx5e_tstamp tstamp;
690710
u16 q_counter;
711+
#ifdef CONFIG_MLX5_CORE_EN_DCB
712+
struct mlx5e_dcbx dcbx;
713+
#endif
714+
691715
const struct mlx5e_profile *profile;
692716
void *ppriv;
693717
};

drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c

Lines changed: 299 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#define MLX5E_100MB (100000)
3939
#define MLX5E_1GB (1000000)
4040

41+
#define MLX5E_CEE_STATE_UP 1
42+
#define MLX5E_CEE_STATE_DOWN 0
43+
4144
static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
4245
struct ieee_ets *ets)
4346
{
@@ -222,13 +225,15 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
222225

223226
static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
224227
{
225-
return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
228+
return DCB_CAP_DCBX_HOST |
229+
DCB_CAP_DCBX_VER_IEEE |
230+
DCB_CAP_DCBX_VER_CEE;
226231
}
227232

228233
static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
229234
{
230235
if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
231-
(mode & DCB_CAP_DCBX_VER_CEE) ||
236+
!(mode & DCB_CAP_DCBX_VER_CEE) ||
232237
!(mode & DCB_CAP_DCBX_VER_IEEE) ||
233238
!(mode & DCB_CAP_DCBX_HOST))
234239
return 1;
@@ -304,6 +309,281 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
304309
return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
305310
}
306311

312+
static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
313+
{
314+
struct mlx5e_priv *priv = netdev_priv(netdev);
315+
struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
316+
struct mlx5_core_dev *mdev = priv->mdev;
317+
struct ieee_ets ets;
318+
struct ieee_pfc pfc;
319+
int err;
320+
int i;
321+
322+
memset(&ets, 0, sizeof(ets));
323+
memset(&pfc, 0, sizeof(pfc));
324+
325+
ets.ets_cap = IEEE_8021QAZ_MAX_TCS;
326+
for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
327+
ets.tc_tx_bw[i] = cee_cfg->pg_bw_pct[i];
328+
ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i];
329+
ets.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
330+
ets.prio_tc[i] = cee_cfg->prio_to_pg_map[i];
331+
}
332+
333+
err = mlx5e_dbcnl_validate_ets(netdev, &ets);
334+
if (err) {
335+
netdev_err(netdev,
336+
"%s, Failed to validate ETS: %d\n", __func__, err);
337+
goto out;
338+
}
339+
340+
err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
341+
if (err) {
342+
netdev_err(netdev,
343+
"%s, Failed to set ETS: %d\n", __func__, err);
344+
goto out;
345+
}
346+
347+
/* Set PFC */
348+
pfc.pfc_cap = mlx5_max_tc(mdev) + 1;
349+
if (!cee_cfg->pfc_enable)
350+
pfc.pfc_en = 0;
351+
else
352+
for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
353+
pfc.pfc_en |= cee_cfg->pfc_setting[i] << i;
354+
355+
err = mlx5e_dcbnl_ieee_setpfc(netdev, &pfc);
356+
if (err) {
357+
netdev_err(netdev,
358+
"%s, Failed to set PFC: %d\n", __func__, err);
359+
goto out;
360+
}
361+
out:
362+
return err ? MLX5_DCB_NO_CHG : MLX5_DCB_CHG_RESET;
363+
}
364+
365+
static u8 mlx5e_dcbnl_getstate(struct net_device *netdev)
366+
{
367+
return MLX5E_CEE_STATE_UP;
368+
}
369+
370+
static void mlx5e_dcbnl_getpermhwaddr(struct net_device *netdev,
371+
u8 *perm_addr)
372+
{
373+
struct mlx5e_priv *priv = netdev_priv(netdev);
374+
375+
if (!perm_addr)
376+
return;
377+
378+
mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr);
379+
}
380+
381+
static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev,
382+
int priority, u8 prio_type,
383+
u8 pgid, u8 bw_pct, u8 up_map)
384+
{
385+
struct mlx5e_priv *priv = netdev_priv(netdev);
386+
struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
387+
388+
if (priority >= CEE_DCBX_MAX_PRIO) {
389+
netdev_err(netdev,
390+
"%s, priority is out of range\n", __func__);
391+
return;
392+
}
393+
394+
if (pgid >= CEE_DCBX_MAX_PGS) {
395+
netdev_err(netdev,
396+
"%s, priority group is out of range\n", __func__);
397+
return;
398+
}
399+
400+
cee_cfg->prio_to_pg_map[priority] = pgid;
401+
}
402+
403+
static void mlx5e_dcbnl_setpgbwgcfgtx(struct net_device *netdev,
404+
int pgid, u8 bw_pct)
405+
{
406+
struct mlx5e_priv *priv = netdev_priv(netdev);
407+
struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
408+
409+
if (pgid >= CEE_DCBX_MAX_PGS) {
410+
netdev_err(netdev,
411+
"%s, priority group is out of range\n", __func__);
412+
return;
413+
}
414+
415+
cee_cfg->pg_bw_pct[pgid] = bw_pct;
416+
}
417+
418+
static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
419+
int priority, u8 *prio_type,
420+
u8 *pgid, u8 *bw_pct, u8 *up_map)
421+
{
422+
struct mlx5e_priv *priv = netdev_priv(netdev);
423+
struct mlx5_core_dev *mdev = priv->mdev;
424+
425+
if (priority >= CEE_DCBX_MAX_PRIO) {
426+
netdev_err(netdev,
427+
"%s, priority is out of range\n", __func__);
428+
return;
429+
}
430+
431+
*prio_type = 0;
432+
*bw_pct = 0;
433+
*up_map = 0;
434+
435+
if (mlx5_query_port_prio_tc(mdev, priority, pgid))
436+
*pgid = 0;
437+
}
438+
439+
static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
440+
int pgid, u8 *bw_pct)
441+
{
442+
struct mlx5e_priv *priv = netdev_priv(netdev);
443+
struct mlx5_core_dev *mdev = priv->mdev;
444+
445+
if (pgid >= CEE_DCBX_MAX_PGS) {
446+
netdev_err(netdev,
447+
"%s, priority group is out of range\n", __func__);
448+
return;
449+
}
450+
451+
if (mlx5_query_port_tc_bw_alloc(mdev, pgid, bw_pct))
452+
*bw_pct = 0;
453+
}
454+
455+
static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
456+
int priority, u8 setting)
457+
{
458+
struct mlx5e_priv *priv = netdev_priv(netdev);
459+
struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
460+
461+
if (priority >= CEE_DCBX_MAX_PRIO) {
462+
netdev_err(netdev,
463+
"%s, priority is out of range\n", __func__);
464+
return;
465+
}
466+
467+
if (setting > 1)
468+
return;
469+
470+
cee_cfg->pfc_setting[priority] = setting;
471+
}
472+
473+
static int
474+
mlx5e_dcbnl_get_priority_pfc(struct net_device *netdev,
475+
int priority, u8 *setting)
476+
{
477+
struct ieee_pfc pfc;
478+
int err;
479+
480+
err = mlx5e_dcbnl_ieee_getpfc(netdev, &pfc);
481+
482+
if (err)
483+
*setting = 0;
484+
else
485+
*setting = (pfc.pfc_en >> priority) & 0x01;
486+
487+
return err;
488+
}
489+
490+
static void mlx5e_dcbnl_getpfccfg(struct net_device *netdev,
491+
int priority, u8 *setting)
492+
{
493+
if (priority >= CEE_DCBX_MAX_PRIO) {
494+
netdev_err(netdev,
495+
"%s, priority is out of range\n", __func__);
496+
return;
497+
}
498+
499+
if (!setting)
500+
return;
501+
502+
mlx5e_dcbnl_get_priority_pfc(netdev, priority, setting);
503+
}
504+
505+
static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
506+
int capid, u8 *cap)
507+
{
508+
struct mlx5e_priv *priv = netdev_priv(netdev);
509+
struct mlx5_core_dev *mdev = priv->mdev;
510+
u8 rval = 0;
511+
512+
switch (capid) {
513+
case DCB_CAP_ATTR_PG:
514+
*cap = true;
515+
break;
516+
case DCB_CAP_ATTR_PFC:
517+
*cap = true;
518+
break;
519+
case DCB_CAP_ATTR_UP2TC:
520+
*cap = false;
521+
break;
522+
case DCB_CAP_ATTR_PG_TCS:
523+
*cap = 1 << mlx5_max_tc(mdev);
524+
break;
525+
case DCB_CAP_ATTR_PFC_TCS:
526+
*cap = 1 << mlx5_max_tc(mdev);
527+
break;
528+
case DCB_CAP_ATTR_GSP:
529+
*cap = false;
530+
break;
531+
case DCB_CAP_ATTR_BCN:
532+
*cap = false;
533+
break;
534+
case DCB_CAP_ATTR_DCBX:
535+
*cap = (DCB_CAP_DCBX_LLD_MANAGED |
536+
DCB_CAP_DCBX_VER_CEE |
537+
DCB_CAP_DCBX_STATIC);
538+
break;
539+
default:
540+
*cap = 0;
541+
rval = 1;
542+
break;
543+
}
544+
545+
return rval;
546+
}
547+
548+
static int mlx5e_dcbnl_getnumtcs(struct net_device *netdev,
549+
int tcs_id, u8 *num)
550+
{
551+
struct mlx5e_priv *priv = netdev_priv(netdev);
552+
struct mlx5_core_dev *mdev = priv->mdev;
553+
554+
switch (tcs_id) {
555+
case DCB_NUMTCS_ATTR_PG:
556+
case DCB_NUMTCS_ATTR_PFC:
557+
*num = mlx5_max_tc(mdev) + 1;
558+
break;
559+
default:
560+
return -EINVAL;
561+
}
562+
563+
return 0;
564+
}
565+
566+
static u8 mlx5e_dcbnl_getpfcstate(struct net_device *netdev)
567+
{
568+
struct ieee_pfc pfc;
569+
570+
if (mlx5e_dcbnl_ieee_getpfc(netdev, &pfc))
571+
return MLX5E_CEE_STATE_DOWN;
572+
573+
return pfc.pfc_en ? MLX5E_CEE_STATE_UP : MLX5E_CEE_STATE_DOWN;
574+
}
575+
576+
static void mlx5e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
577+
{
578+
struct mlx5e_priv *priv = netdev_priv(netdev);
579+
struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
580+
581+
if ((state != MLX5E_CEE_STATE_UP) && (state != MLX5E_CEE_STATE_DOWN))
582+
return;
583+
584+
cee_cfg->pfc_enable = state;
585+
}
586+
307587
const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
308588
.ieee_getets = mlx5e_dcbnl_ieee_getets,
309589
.ieee_setets = mlx5e_dcbnl_ieee_setets,
@@ -313,4 +593,21 @@ const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
313593
.ieee_setpfc = mlx5e_dcbnl_ieee_setpfc,
314594
.getdcbx = mlx5e_dcbnl_getdcbx,
315595
.setdcbx = mlx5e_dcbnl_setdcbx,
596+
597+
/* CEE interfaces */
598+
.setall = mlx5e_dcbnl_setall,
599+
.getstate = mlx5e_dcbnl_getstate,
600+
.getpermhwaddr = mlx5e_dcbnl_getpermhwaddr,
601+
602+
.setpgtccfgtx = mlx5e_dcbnl_setpgtccfgtx,
603+
.setpgbwgcfgtx = mlx5e_dcbnl_setpgbwgcfgtx,
604+
.getpgtccfgtx = mlx5e_dcbnl_getpgtccfgtx,
605+
.getpgbwgcfgtx = mlx5e_dcbnl_getpgbwgcfgtx,
606+
607+
.setpfccfg = mlx5e_dcbnl_setpfccfg,
608+
.getpfccfg = mlx5e_dcbnl_getpfccfg,
609+
.getcap = mlx5e_dcbnl_getcap,
610+
.getnumtcs = mlx5e_dcbnl_getnumtcs,
611+
.getpfcstate = mlx5e_dcbnl_getpfcstate,
612+
.setpfcstate = mlx5e_dcbnl_setpfcstate,
316613
};

0 commit comments

Comments
 (0)