All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support
@ 2016-08-30 11:29 Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API Saeed Mahameed
                   ` (5 more replies)
  0 siblings, 6 replies; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Saeed Mahameed

Hi Dave,

This series from Huy provides mlx5 DCBX updates to support DCBX CEE
API and DCBX firmware/host modes support.

1st patch adds the support for CEE interfaces into mlx5 dcbnl_rtnl_ops.

2nd patch refactors ETS query to read ETS configuration directly from 
firmware rather than having a software shadow to it.

3rd patch adds the support for MLX5_REG_DCBX_PARAM and MLX5_REG_DCBX_APP
firmware commands to manipulate mlx5 DCBX mode.

4th patch adds driver support for moving mlx5 DCBX mode between firmware
and host.

5th patch adds a private flag for setting special hybrid DCBX firmware/host
mode "qos_with_dcbx_by_fw".

6th patch adds support for module events log.

Thanks,
Saeed.

Huy Nguyen (6):
  net/mlx5e: Support DCBX CEE API
  net/mlx5e: Read ETS settings directly from firmware
  net/mlx5: Add DCBX firmware commands support
  net/mlx5e: ConnectX-4 firmware support for DCBX
  net/mlx5e: Add DCBX control interface
  net/mlx5: Add handling for port module event

 drivers/net/ethernet/mellanox/mlx5/core/en.h       |  38 +-
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 505 ++++++++++++++++++++-
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   |  25 +
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |  24 +-
 drivers/net/ethernet/mellanox/mlx5/core/eq.c       |  12 +
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |   1 +
 drivers/net/ethernet/mellanox/mlx5/core/port.c     | 150 ++++++
 include/linux/mlx5/device.h                        |  11 +
 include/linux/mlx5/driver.h                        |   7 +
 include/linux/mlx5/mlx5_ifc.h                      |   3 +-
 include/linux/mlx5/port.h                          |   6 +
 11 files changed, 747 insertions(+), 35 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-30 20:33   ` Or Gerlitz
  2016-08-30 11:29 ` [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware Saeed Mahameed
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

Add DCBX CEE API interface for CX4. 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 CX4
  only supports bw allocation per traffic class.

  user priority in CEE does not have an equivalent term in CX4.
  Therefore, user priority to priority mapping in CEE is not supported.

Test: see DCBX_LinuxDriverCX4 document section 6.4
Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |  24 ++
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 301 ++++++++++++++++++++-
 drivers/net/ethernet/mellanox/mlx5/core/port.c     |  43 +++
 include/linux/mlx5/port.h                          |   4 +
 4 files changed, 370 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 9699560..6919e3c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -209,6 +209,26 @@ struct mlx5e_params {
 	bool rx_am_enabled;
 };
 
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+struct mlx5e_cee_config {
+	/* bw pct for priority group */
+	u8                         pg_bw_pct[CEE_DCBX_MAX_PGS];
+	u8                         prio_to_pg_map[CEE_DCBX_MAX_PRIO];
+	bool                       pfc_setting[CEE_DCBX_MAX_PRIO];
+	bool                       pfc_enable;
+};
+
+enum {
+	MLX5_DCB_CHG_RESET,
+	MLX5_DCB_NO_CHG,
+	MLX5_DCB_CHG_NO_RESET,
+};
+
+struct mlx5e_dcbx {
+	struct mlx5e_cee_config    cee_cfg; /* pending configuration */
+};
+#endif
+
 struct mlx5e_tstamp {
 	rwlock_t                   lock;
 	struct cyclecounter        cycles;
@@ -650,6 +670,10 @@ struct mlx5e_priv {
 	struct mlx5e_stats         stats;
 	struct mlx5e_tstamp        tstamp;
 	u16 q_counter;
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+	struct mlx5e_dcbx          dcbx;
+#endif
+
 	const struct mlx5e_profile *profile;
 	void                      *ppriv;
 };
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 762af16..b161dd9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -38,6 +38,9 @@
 #define MLX5E_100MB (100000)
 #define MLX5E_1GB   (1000000)
 
+#define MLX5E_CEE_STATE_UP    1
+#define MLX5E_CEE_STATE_DOWN  0
+
 static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 				   struct ieee_ets *ets)
 {
@@ -222,13 +225,15 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
 
 static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
 {
-	return DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
+	return DCB_CAP_DCBX_HOST |
+	       DCB_CAP_DCBX_VER_IEEE |
+	       DCB_CAP_DCBX_VER_CEE;
 }
 
 static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
 {
 	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
-	    (mode & DCB_CAP_DCBX_VER_CEE) ||
+	    !(mode & DCB_CAP_DCBX_VER_CEE) ||
 	    !(mode & DCB_CAP_DCBX_VER_IEEE) ||
 	    !(mode & DCB_CAP_DCBX_HOST))
 		return 1;
@@ -304,6 +309,281 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
 	return mlx5_modify_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
 }
 
+static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
+	struct mlx5_core_dev *mdev = priv->mdev;
+	struct ieee_ets ets;
+	struct ieee_pfc pfc;
+	int err;
+	int i;
+
+	memset(&ets, 0, sizeof(ets));
+	memset(&pfc, 0, sizeof(pfc));
+
+	ets.ets_cap = IEEE_8021QAZ_MAX_TCS;
+	for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+		ets.tc_tx_bw[i] = cee_cfg->pg_bw_pct[i];
+		ets.tc_rx_bw[i] = cee_cfg->pg_bw_pct[i];
+		ets.tc_tsa[i]   = IEEE_8021QAZ_TSA_ETS;
+		ets.prio_tc[i]  = cee_cfg->prio_to_pg_map[i];
+	}
+
+	err = mlx5e_dbcnl_validate_ets(&ets);
+	if (err) {
+		netdev_err(netdev,
+			   "%s, Failed to validate ETS: %d\n", __func__, err);
+		goto out;
+	}
+
+	err = mlx5e_dcbnl_ieee_setets_core(priv, &ets);
+	if (err) {
+		netdev_err(netdev,
+			   "%s, Failed to set ETS: %d\n", __func__, err);
+		goto out;
+	}
+
+	/* Set PFC */
+	pfc.pfc_cap = mlx5_max_tc(mdev) + 1;
+	if (!cee_cfg->pfc_enable)
+		pfc.pfc_en = 0;
+	else
+		for (i = 0; i < CEE_DCBX_MAX_PRIO; i++)
+			pfc.pfc_en |= cee_cfg->pfc_setting[i] << i;
+
+	err = mlx5e_dcbnl_ieee_setpfc(netdev, &pfc);
+	if (err) {
+		netdev_err(netdev,
+			   "%s, Failed to set PFC: %d\n", __func__, err);
+		goto out;
+	}
+out:
+	return err ? MLX5_DCB_NO_CHG : MLX5_DCB_CHG_RESET;
+}
+
+static u8 mlx5e_dcbnl_getstate(struct net_device *netdev)
+{
+	return MLX5E_CEE_STATE_UP;
+}
+
+static void mlx5e_dcbnl_getpermhwaddr(struct net_device *netdev,
+				      u8 *perm_addr)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (!perm_addr)
+		return;
+
+	mlx5_query_nic_vport_mac_address(priv->mdev, 0, perm_addr);
+}
+
+static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev,
+				     int priority, u8 prio_type,
+				     u8 pgid, u8 bw_pct, u8 up_map)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
+
+	if (priority >= CEE_DCBX_MAX_PRIO) {
+		netdev_err(netdev,
+			   "%s, priority is out of range\n", __func__);
+		return;
+	}
+
+	if (pgid >= CEE_DCBX_MAX_PGS) {
+		netdev_err(netdev,
+			   "%s, priority group is out of range\n", __func__);
+		return;
+	}
+
+	cee_cfg->prio_to_pg_map[priority] = pgid;
+}
+
+static void mlx5e_dcbnl_setpgbwgcfgtx(struct net_device *netdev,
+				      int pgid, u8 bw_pct)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
+
+	if (pgid >= CEE_DCBX_MAX_PGS) {
+		netdev_err(netdev,
+			   "%s, priority group is out of range\n", __func__);
+		return;
+	}
+
+	cee_cfg->pg_bw_pct[pgid] = bw_pct;
+}
+
+static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
+				     int priority, u8 *prio_type,
+				     u8 *pgid, u8 *bw_pct, u8 *up_map)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	if (priority >= CEE_DCBX_MAX_PRIO) {
+		netdev_err(netdev,
+			   "%s, priority is out of range\n", __func__);
+		return;
+	}
+
+	*prio_type = 0;
+	*bw_pct = 0;
+	*up_map = 0;
+
+	if (mlx5_query_port_prio_tc(mdev, priority, pgid))
+		*pgid = 0;
+}
+
+static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
+				      int pgid, u8 *bw_pct)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	if (pgid >= CEE_DCBX_MAX_PGS) {
+		netdev_err(netdev,
+			   "%s, priority group is out of range\n", __func__);
+		return;
+	}
+
+	if (mlx5_query_port_tc_bw_alloc(mdev, pgid, bw_pct))
+		*bw_pct = 0;
+}
+
+static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
+				  int priority, u8 setting)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
+
+	if (priority >= CEE_DCBX_MAX_PRIO) {
+		netdev_err(netdev,
+			   "%s, priority is out of range\n", __func__);
+		return;
+	}
+
+	if (setting > 1)
+		return;
+
+	cee_cfg->pfc_setting[priority] = setting;
+}
+
+static int
+mlx5e_dcbnl_get_priority_pfc(struct net_device *netdev,
+			     int priority, u8 *setting)
+{
+	struct ieee_pfc pfc;
+	int err;
+
+	err = mlx5e_dcbnl_ieee_getpfc(netdev, &pfc);
+
+	if (err)
+		*setting = 0;
+	else
+		*setting = (pfc.pfc_en >> priority) & 0x01;
+
+	return err;
+}
+
+static void mlx5e_dcbnl_getpfccfg(struct net_device *netdev,
+				  int priority, u8 *setting)
+{
+	if (priority >= CEE_DCBX_MAX_PRIO) {
+		netdev_err(netdev,
+			   "%s, priority is out of range\n", __func__);
+		return;
+	}
+
+	if (!setting)
+		return;
+
+	mlx5e_dcbnl_get_priority_pfc(netdev, priority, setting);
+}
+
+static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
+			     int capid, u8 *cap)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	u8 rval = 0;
+
+	switch (capid) {
+	case DCB_CAP_ATTR_PG:
+		*cap = true;
+		break;
+	case DCB_CAP_ATTR_PFC:
+		*cap = true;
+		break;
+	case DCB_CAP_ATTR_UP2TC:
+		*cap = false;
+		break;
+	case DCB_CAP_ATTR_PG_TCS:
+		*cap = 1 << mlx5_max_tc(mdev);
+		break;
+	case DCB_CAP_ATTR_PFC_TCS:
+		*cap = 1 << mlx5_max_tc(mdev);
+		break;
+	case DCB_CAP_ATTR_GSP:
+		*cap = false;
+		break;
+	case DCB_CAP_ATTR_BCN:
+		*cap = false;
+		break;
+	case DCB_CAP_ATTR_DCBX:
+		*cap = (DCB_CAP_DCBX_LLD_MANAGED |
+			DCB_CAP_DCBX_VER_CEE |
+			DCB_CAP_DCBX_STATIC);
+		break;
+	default:
+		*cap = 0;
+		rval = 1;
+		break;
+	}
+
+	return rval;
+}
+
+static int mlx5e_dcbnl_getnumtcs(struct net_device *netdev,
+				 int tcs_id, u8 *num)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+
+	switch (tcs_id) {
+	case DCB_NUMTCS_ATTR_PG:
+	case DCB_NUMTCS_ATTR_PFC:
+		*num = mlx5_max_tc(mdev) + 1;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u8 mlx5e_dcbnl_getpfcstate(struct net_device *netdev)
+{
+	struct ieee_pfc pfc;
+
+	if (mlx5e_dcbnl_ieee_getpfc(netdev, &pfc))
+		return MLX5E_CEE_STATE_DOWN;
+
+	return pfc.pfc_en ? MLX5E_CEE_STATE_UP : MLX5E_CEE_STATE_DOWN;
+}
+
+static void mlx5e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
+
+	if ((state != MLX5E_CEE_STATE_UP) && (state != MLX5E_CEE_STATE_DOWN))
+		return;
+
+	cee_cfg->pfc_enable = state;
+}
+
 const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
 	.ieee_getets	= mlx5e_dcbnl_ieee_getets,
 	.ieee_setets	= mlx5e_dcbnl_ieee_setets,
@@ -313,4 +593,21 @@ const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
 	.ieee_setpfc	= mlx5e_dcbnl_ieee_setpfc,
 	.getdcbx	= mlx5e_dcbnl_getdcbx,
 	.setdcbx	= mlx5e_dcbnl_setdcbx,
+
+/* CEE interfaces */
+	.setall         = mlx5e_dcbnl_setall,
+	.getstate       = mlx5e_dcbnl_getstate,
+	.getpermhwaddr  = mlx5e_dcbnl_getpermhwaddr,
+
+	.setpgtccfgtx   = mlx5e_dcbnl_setpgtccfgtx,
+	.setpgbwgcfgtx  = mlx5e_dcbnl_setpgbwgcfgtx,
+	.getpgtccfgtx   = mlx5e_dcbnl_getpgtccfgtx,
+	.getpgbwgcfgtx  = mlx5e_dcbnl_getpgbwgcfgtx,
+
+	.setpfccfg      = mlx5e_dcbnl_setpfccfg,
+	.getpfccfg      = mlx5e_dcbnl_getpfccfg,
+	.getcap         = mlx5e_dcbnl_getcap,
+	.getnumtcs      = mlx5e_dcbnl_getnumtcs,
+	.getpfcstate    = mlx5e_dcbnl_getpfcstate,
+	.setpfcstate    = mlx5e_dcbnl_setpfcstate,
 };
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 34e7184..2f75f86 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -572,6 +572,28 @@ int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
 }
 EXPORT_SYMBOL_GPL(mlx5_set_port_prio_tc);
 
+int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
+			    u8 prio, u8 *tc)
+{
+	u32 in[MLX5_ST_SZ_DW(qtct_reg)];
+	u32 out[MLX5_ST_SZ_DW(qtct_reg)];
+	int err;
+
+	memset(in, 0, sizeof(in));
+	memset(out, 0, sizeof(out));
+
+	MLX5_SET(qtct_reg, in, port_number, 1);
+	MLX5_SET(qtct_reg, in, prio, prio);
+
+	err = mlx5_core_access_reg(mdev, in, sizeof(in), out,
+				   sizeof(out), MLX5_REG_QTCT, 0, 0);
+	if (!err)
+		*tc = MLX5_GET(qtct_reg, out, tclass);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_prio_tc);
+
 static int mlx5_set_port_qetcr_reg(struct mlx5_core_dev *mdev, u32 *in,
 				   int inlen)
 {
@@ -625,6 +647,27 @@ int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw)
 }
 EXPORT_SYMBOL_GPL(mlx5_set_port_tc_bw_alloc);
 
+int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
+				u8 tc, u8 *bw_pct)
+{
+	u32 out[MLX5_ST_SZ_DW(qetc_reg)];
+	void *ets_tcn_conf;
+	int err;
+
+	err = mlx5_query_port_qetcr_reg(mdev, out, sizeof(out));
+	if (err)
+		return err;
+
+	ets_tcn_conf = MLX5_ADDR_OF(qetc_reg, out,
+				    tc_configuration[tc]);
+
+	*bw_pct = MLX5_GET(ets_tcn_config_reg, ets_tcn_conf,
+			   bw_allocation);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mlx5_query_port_tc_bw_alloc);
+
 int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
 				    u8 *max_bw_value,
 				    u8 *max_bw_units)
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
index b3065ac..ddad24d 100644
--- a/include/linux/mlx5/port.h
+++ b/include/linux/mlx5/port.h
@@ -138,8 +138,12 @@ int mlx5_query_port_pfc(struct mlx5_core_dev *dev, u8 *pfc_en_tx,
 int mlx5_max_tc(struct mlx5_core_dev *mdev);
 
 int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc);
+int mlx5_query_port_prio_tc(struct mlx5_core_dev *mdev,
+			    u8 prio, u8 *tc);
 int mlx5_set_port_tc_group(struct mlx5_core_dev *mdev, u8 *tc_group);
 int mlx5_set_port_tc_bw_alloc(struct mlx5_core_dev *mdev, u8 *tc_bw);
+int mlx5_query_port_tc_bw_alloc(struct mlx5_core_dev *mdev,
+				u8 tc, u8 *bw_pct);
 int mlx5_modify_port_ets_rate_limit(struct mlx5_core_dev *mdev,
 				    u8 *max_bw_value,
 				    u8 *max_bw_unit);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-30 20:34   ` Or Gerlitz
  2016-08-30 11:29 ` [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support Saeed Mahameed
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

Current implementation does not read the setting
directly from FW when ieee_getets is called.

Solution:
1. Read the ETS settings directly from firmware.
2. For tc_tsa:
   a. Initialize tc_tsa to vendor IEEE_8021QAZ_TSA_VENDOR at netdev
      creation.
   b. When reading ETS setting from FW, if the traffic class bandwidth
      is less than 100, set tc_tsa to IEEE_8021QAZ_TSA_ETS. This
      implementation solves the scenarios when the DCBX is in FW control
      and willing bit is on which means the ETS setting is dictated
      by remote switch.

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |  6 ++--
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 35 ++++++++++++++++++----
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  | 26 ++++++++--------
 3 files changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 6919e3c..0d41287 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -203,9 +203,6 @@ struct mlx5e_params {
 	u8  toeplitz_hash_key[40];
 	u32 indirection_rqt[MLX5E_INDIR_RQT_SIZE];
 	bool vlan_strip_disable;
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-	struct ieee_ets ets;
-#endif
 	bool rx_am_enabled;
 };
 
@@ -226,6 +223,9 @@ enum {
 
 struct mlx5e_dcbx {
 	struct mlx5e_cee_config    cee_cfg; /* pending configuration */
+
+	/* The only setting that cannot be read from FW */
+	u8                         tc_tsa[IEEE_8021QAZ_MAX_TCS];
 };
 #endif
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index b161dd9..1c10f9c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -45,12 +45,31 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 				   struct ieee_ets *ets)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
+	struct mlx5_core_dev *mdev = priv->mdev;
+	int i;
+	int err = 0;
 
 	if (!MLX5_CAP_GEN(priv->mdev, ets))
 		return -ENOTSUPP;
 
-	memcpy(ets, &priv->params.ets, sizeof(*ets));
-	return 0;
+	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
+	for (i = 0; i < ets->ets_cap; i++) {
+		err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
+		if (err)
+			return err;
+	}
+
+	for (i = 0; i < ets->ets_cap; i++) {
+		err = mlx5_query_port_tc_bw_alloc(mdev, i, &ets->tc_tx_bw[i]);
+		if (err)
+			return err;
+		if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC)
+			priv->dcbx.tc_tsa[i] = IEEE_8021QAZ_TSA_ETS;
+	}
+
+	memcpy(ets->tc_tsa, priv->dcbx.tc_tsa, sizeof(ets->tc_tsa));
+
+	return err;
 }
 
 enum {
@@ -127,7 +146,14 @@ int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets)
 	if (err)
 		return err;
 
-	return mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw);
+	err = mlx5_set_port_tc_bw_alloc(mdev, tc_tx_bw);
+
+	if (err)
+		return err;
+
+	memcpy(priv->dcbx.tc_tsa, ets->tc_tsa, sizeof(ets->tc_tsa));
+
+	return err;
 }
 
 static int mlx5e_dbcnl_validate_ets(struct net_device *netdev,
@@ -181,9 +207,6 @@ static int mlx5e_dcbnl_ieee_setets(struct net_device *netdev,
 	if (err)
 		return err;
 
-	memcpy(&priv->params.ets, ets, sizeof(*ets));
-	priv->params.ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
-
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 03586ee..8f17928 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2875,17 +2875,23 @@ u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)
 static void mlx5e_ets_init(struct mlx5e_priv *priv)
 {
 	int i;
+	struct ieee_ets ets;
 
-	priv->params.ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
-	for (i = 0; i < priv->params.ets.ets_cap; i++) {
-		priv->params.ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
-		priv->params.ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
-		priv->params.ets.prio_tc[i] = i;
+	memset(&ets, 0, sizeof(ets));
+	ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
+	for (i = 0; i < ets.ets_cap; i++) {
+		ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
+		ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
+		ets.prio_tc[i] = i;
 	}
 
+	memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa));
+
 	/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
-	priv->params.ets.prio_tc[0] = 1;
-	priv->params.ets.prio_tc[1] = 0;
+	ets.prio_tc[0] = 1;
+	ets.prio_tc[1] = 0;
+
+	mlx5e_dcbnl_ieee_setets_core(priv, &ets);
 }
 #endif
 
@@ -3071,10 +3077,6 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
 	priv->profile                      = profile;
 	priv->ppriv                        = ppriv;
 
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-	mlx5e_ets_init(priv);
-#endif
-
 	mutex_init(&priv->state_lock);
 
 	INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
@@ -3347,7 +3349,7 @@ static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)
 	}
 
 #ifdef CONFIG_MLX5_CORE_EN_DCB
-	mlx5e_dcbnl_ieee_setets_core(priv, &priv->params.ets);
+	mlx5e_ets_init(priv);
 #endif
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-31 11:24   ` zhuyj
  2016-08-30 11:29 ` [PATCH net-next 4/6] net/mlx5e: ConnectX-4 firmware support for DCBX Saeed Mahameed
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

Add set/query commands for DCBX_PARAM register

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/port.c | 22 ++++++++++++++++++++++
 include/linux/mlx5/driver.h                    |  7 +++++++
 include/linux/mlx5/port.h                      |  2 ++
 3 files changed, 31 insertions(+)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 2f75f86..8a66595 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -548,6 +548,28 @@ int mlx5_max_tc(struct mlx5_core_dev *mdev)
 	return num_tc - 1;
 }
 
+int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out)
+{
+	u32 in[MLX5_ST_SZ_DW(dcbx_param)];
+
+	memset(in, 0, sizeof(in));
+
+	MLX5_SET(dcbx_param, in, port_number, 1);
+
+	return  mlx5_core_access_reg(mdev, in, sizeof(in), out,
+				    sizeof(in), MLX5_REG_DCBX_PARAM, 0, 0);
+}
+
+int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in)
+{
+	u32 out[MLX5_ST_SZ_DW(dcbx_param)];
+
+	MLX5_SET(dcbx_param, in, port_number, 1);
+
+	return mlx5_core_access_reg(mdev, in, sizeof(out), out,
+				    sizeof(out), MLX5_REG_DCBX_PARAM, 0, 1);
+}
+
 int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
 {
 	u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {0};
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 5cb9fa7..b53f19c 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -104,6 +104,8 @@ enum {
 enum {
 	MLX5_REG_QETCR		 = 0x4005,
 	MLX5_REG_QTCT		 = 0x400a,
+	MLX5_REG_DCBX_PARAM      = 0x4020,
+	MLX5_REG_DCBX_APP        = 0x4021,
 	MLX5_REG_PCAP		 = 0x5001,
 	MLX5_REG_PMTU		 = 0x5003,
 	MLX5_REG_PTYS		 = 0x5004,
@@ -123,6 +125,11 @@ enum {
 	MLX5_REG_MLCR		 = 0x902b,
 };
 
+enum mlx5_dcbx_oper_mode {
+	MLX5E_DCBX_PARAM_VER_OPER_HOST  = 0x0,
+	MLX5E_DCBX_PARAM_VER_OPER_AUTO  = 0x3,
+};
+
 enum {
 	MLX5_ATOMIC_OPS_CMP_SWAP	= 1 << 0,
 	MLX5_ATOMIC_OPS_FETCH_ADD	= 1 << 1,
diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
index ddad24d..62e2259 100644
--- a/include/linux/mlx5/port.h
+++ b/include/linux/mlx5/port.h
@@ -159,4 +159,6 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
 int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
 			     u16 offset, u16 size, u8 *data);
 
+int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
+int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
 #endif /* __MLX5_PORT_H__ */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 4/6] net/mlx5e: ConnectX-4 firmware support for DCBX
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
                   ` (2 preceding siblings ...)
  2016-08-30 11:29 ` [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 5/6] net/mlx5e: Add DCBX control interface Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 6/6] net/mlx5: Add handling for port module event Saeed Mahameed
  5 siblings, 0 replies; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

DBCX by default is controlled by firmware. In this
mode, firmware is responsible for reading/sending the TLVs packets
from/to the remote partner. When the driver is loaded, the driver
can leave the DCBX in firmware controlled mode or
switch the DCBX back to host controlled mode.

This patch sets up the infrastructure to support changing
DCBX control mode.

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |   6 +
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 147 +++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlx5/core/en_main.c  |  26 +---
 3 files changed, 154 insertions(+), 25 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 0d41287..806f5e8 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -222,6 +222,7 @@ enum {
 };
 
 struct mlx5e_dcbx {
+	enum mlx5_dcbx_oper_mode   mode;
 	struct mlx5e_cee_config    cee_cfg; /* pending configuration */
 
 	/* The only setting that cannot be read from FW */
@@ -810,6 +811,11 @@ extern const struct ethtool_ops mlx5e_ethtool_ops;
 #ifdef CONFIG_MLX5_CORE_EN_DCB
 extern const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops;
 int mlx5e_dcbnl_ieee_setets_core(struct mlx5e_priv *priv, struct ieee_ets *ets);
+int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv,
+			      enum mlx5_dcbx_oper_mode mode);
+void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv,
+				 enum mlx5_dcbx_oper_mode *mode);
+void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv);
 #endif
 
 #ifndef CONFIG_RFS_ACCEL
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 1c10f9c..5d1b402 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -41,6 +41,26 @@
 #define MLX5E_CEE_STATE_UP    1
 #define MLX5E_CEE_STATE_DOWN  0
 
+/* If dcbx mode is non-host and qos_with_dcbx_by_fw is off, set the
+ * dcbx mode to host.
+ */
+static inline bool mlx5e_dcbnl_is_allowed(struct mlx5e_priv *priv)
+{
+	struct mlx5e_dcbx *dcbx = &priv->dcbx;
+
+	if (!MLX5_CAP_GEN(priv->mdev, dcbx))
+		return true;
+
+	if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
+		return true;
+
+	if (mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_HOST))
+		return false;
+
+	dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_HOST;
+	return true;
+}
+
 static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 				   struct ieee_ets *ets)
 {
@@ -52,6 +72,9 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
 	if (!MLX5_CAP_GEN(priv->mdev, ets))
 		return -ENOTSUPP;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	ets->ets_cap = mlx5_max_tc(priv->mdev) + 1;
 	for (i = 0; i < ets->ets_cap; i++) {
 		err = mlx5_query_port_prio_tc(mdev, i, &ets->prio_tc[i]);
@@ -199,6 +222,12 @@ static int mlx5e_dcbnl_ieee_setets(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	int err;
 
+	if (!MLX5_CAP_GEN(priv->mdev, ets))
+		return -ENOTSUPP;
+
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	err = mlx5e_dbcnl_validate_ets(netdev, ets);
 	if (err)
 		return err;
@@ -218,6 +247,9 @@ static int mlx5e_dcbnl_ieee_getpfc(struct net_device *dev,
 	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
 	int i;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	pfc->pfc_cap = mlx5_max_tc(mdev) + 1;
 	for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) {
 		pfc->requests[i]    = PPORT_PER_PRIO_GET(pstats, i, tx_pause);
@@ -235,6 +267,9 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
 	u8 curr_pfc_en;
 	int ret;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	mlx5_query_port_pfc(mdev, &curr_pfc_en, NULL);
 
 	if (pfc->pfc_en == curr_pfc_en)
@@ -255,6 +290,9 @@ static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
 
 static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
 {
+	if (!mlx5e_dcbnl_is_allowed(netdev_priv(dev)))
+		return 1;
+
 	if ((mode & DCB_CAP_DCBX_LLD_MANAGED) ||
 	    !(mode & DCB_CAP_DCBX_VER_CEE) ||
 	    !(mode & DCB_CAP_DCBX_VER_IEEE) ||
@@ -274,6 +312,9 @@ static int mlx5e_dcbnl_ieee_getmaxrate(struct net_device *netdev,
 	int err;
 	int i;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	err = mlx5_query_port_ets_rate_limit(mdev, max_bw_value, max_bw_unit);
 	if (err)
 		return err;
@@ -309,6 +350,9 @@ static int mlx5e_dcbnl_ieee_setmaxrate(struct net_device *netdev,
 	__u64 upper_limit_mbps = roundup(255 * MLX5E_100MB, MLX5E_1GB);
 	int i;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	memset(max_bw_value, 0, sizeof(max_bw_value));
 	memset(max_bw_unit, 0, sizeof(max_bw_unit));
 
@@ -342,6 +386,9 @@ static u8 mlx5e_dcbnl_setall(struct net_device *netdev)
 	int err;
 	int i;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return MLX5_DCB_NO_CHG;
+
 	memset(&ets, 0, sizeof(ets));
 	memset(&pfc, 0, sizeof(pfc));
 
@@ -395,6 +442,9 @@ static void mlx5e_dcbnl_getpermhwaddr(struct net_device *netdev,
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (!perm_addr)
 		return;
 
@@ -408,6 +458,9 @@ static void mlx5e_dcbnl_setpgtccfgtx(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (priority >= CEE_DCBX_MAX_PRIO) {
 		netdev_err(netdev,
 			   "%s, priority is out of range\n", __func__);
@@ -429,6 +482,9 @@ static void mlx5e_dcbnl_setpgbwgcfgtx(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (pgid >= CEE_DCBX_MAX_PGS) {
 		netdev_err(netdev,
 			   "%s, priority group is out of range\n", __func__);
@@ -445,6 +501,9 @@ static void mlx5e_dcbnl_getpgtccfgtx(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *mdev = priv->mdev;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (priority >= CEE_DCBX_MAX_PRIO) {
 		netdev_err(netdev,
 			   "%s, priority is out of range\n", __func__);
@@ -465,6 +524,9 @@ static void mlx5e_dcbnl_getpgbwgcfgtx(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *mdev = priv->mdev;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (pgid >= CEE_DCBX_MAX_PGS) {
 		netdev_err(netdev,
 			   "%s, priority group is out of range\n", __func__);
@@ -481,6 +543,9 @@ static void mlx5e_dcbnl_setpfccfg(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if (priority >= CEE_DCBX_MAX_PRIO) {
 		netdev_err(netdev,
 			   "%s, priority is out of range\n", __func__);
@@ -513,6 +578,9 @@ mlx5e_dcbnl_get_priority_pfc(struct net_device *netdev,
 static void mlx5e_dcbnl_getpfccfg(struct net_device *netdev,
 				  int priority, u8 *setting)
 {
+	if (!mlx5e_dcbnl_is_allowed(netdev_priv(netdev)))
+		return;
+
 	if (priority >= CEE_DCBX_MAX_PRIO) {
 		netdev_err(netdev,
 			   "%s, priority is out of range\n", __func__);
@@ -532,6 +600,9 @@ static u8 mlx5e_dcbnl_getcap(struct net_device *netdev,
 	struct mlx5_core_dev *mdev = priv->mdev;
 	u8 rval = 0;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return 1;
+
 	switch (capid) {
 	case DCB_CAP_ATTR_PG:
 		*cap = true;
@@ -574,6 +645,9 @@ static int mlx5e_dcbnl_getnumtcs(struct net_device *netdev,
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5_core_dev *mdev = priv->mdev;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return -EPERM;
+
 	switch (tcs_id) {
 	case DCB_NUMTCS_ATTR_PG:
 	case DCB_NUMTCS_ATTR_PFC:
@@ -590,6 +664,9 @@ static u8 mlx5e_dcbnl_getpfcstate(struct net_device *netdev)
 {
 	struct ieee_pfc pfc;
 
+	if (!mlx5e_dcbnl_is_allowed(netdev_priv(netdev)))
+		return MLX5E_CEE_STATE_DOWN;
+
 	if (mlx5e_dcbnl_ieee_getpfc(netdev, &pfc))
 		return MLX5E_CEE_STATE_DOWN;
 
@@ -601,6 +678,9 @@ static void mlx5e_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
 	struct mlx5e_priv *priv = netdev_priv(netdev);
 	struct mlx5e_cee_config *cee_cfg = &priv->dcbx.cee_cfg;
 
+	if (!mlx5e_dcbnl_is_allowed(priv))
+		return;
+
 	if ((state != MLX5E_CEE_STATE_UP) && (state != MLX5E_CEE_STATE_DOWN))
 		return;
 
@@ -634,3 +714,70 @@ const struct dcbnl_rtnl_ops mlx5e_dcbnl_ops = {
 	.getpfcstate    = mlx5e_dcbnl_getpfcstate,
 	.setpfcstate    = mlx5e_dcbnl_setpfcstate,
 };
+
+void mlx5e_dcbnl_query_dcbx_mode(struct mlx5e_priv *priv,
+				 enum mlx5_dcbx_oper_mode *mode)
+{
+	u32 out[MLX5_ST_SZ_DW(dcbx_param)];
+
+	*mode = MLX5E_DCBX_PARAM_VER_OPER_HOST;
+
+	if (!mlx5_query_port_dcbx_param(priv->mdev, out))
+		*mode = MLX5_GET(dcbx_param, out, version_oper);
+
+	/* From driver's point of view, we only care if the mode
+	 * is host (HOST) or non-host (AUTO)
+	 */
+	if (*mode != MLX5E_DCBX_PARAM_VER_OPER_HOST)
+		*mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
+}
+
+int mlx5e_dcbnl_set_dcbx_mode(struct mlx5e_priv *priv,
+			      enum mlx5_dcbx_oper_mode mode)
+{
+	struct mlx5_core_dev *mdev = priv->mdev;
+	u32 tmp[MLX5_ST_SZ_DW(dcbx_param)];
+	int err;
+
+	err = mlx5_query_port_dcbx_param(mdev, tmp);
+	if (err)
+		return err;
+
+	MLX5_SET(dcbx_param, tmp, version_admin, mode);
+	if (mode != MLX5E_DCBX_PARAM_VER_OPER_HOST)
+		MLX5_SET(dcbx_param, tmp, willing_admin, 1);
+
+	return mlx5_set_port_dcbx_param(mdev, tmp);
+}
+
+static void mlx5e_ets_init(struct mlx5e_priv *priv)
+{
+	int i;
+	struct ieee_ets ets;
+
+	memset(&ets, 0, sizeof(ets));
+	ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
+	for (i = 0; i < ets.ets_cap; i++) {
+		ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
+		ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
+		ets.prio_tc[i] = i;
+	}
+
+	memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa));
+
+	/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
+	ets.prio_tc[0] = 1;
+	ets.prio_tc[1] = 0;
+
+	mlx5e_dcbnl_ieee_setets_core(priv, &ets);
+}
+
+void mlx5e_dcbnl_initialize(struct mlx5e_priv *priv)
+{
+	struct mlx5e_dcbx *dcbx = &priv->dcbx;
+
+	if (MLX5_CAP_GEN(priv->mdev, dcbx))
+		mlx5e_dcbnl_query_dcbx_mode(priv, &dcbx->mode);
+
+	mlx5e_ets_init(priv);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 8f17928..8563181 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -2871,30 +2871,6 @@ u16 mlx5e_get_max_inline_cap(struct mlx5_core_dev *mdev)
 	       2 /*sizeof(mlx5e_tx_wqe.inline_hdr_start)*/;
 }
 
-#ifdef CONFIG_MLX5_CORE_EN_DCB
-static void mlx5e_ets_init(struct mlx5e_priv *priv)
-{
-	int i;
-	struct ieee_ets ets;
-
-	memset(&ets, 0, sizeof(ets));
-	ets.ets_cap = mlx5_max_tc(priv->mdev) + 1;
-	for (i = 0; i < ets.ets_cap; i++) {
-		ets.tc_tx_bw[i] = MLX5E_MAX_BW_ALLOC;
-		ets.tc_tsa[i] = IEEE_8021QAZ_TSA_VENDOR;
-		ets.prio_tc[i] = i;
-	}
-
-	memcpy(priv->dcbx.tc_tsa, ets.tc_tsa, sizeof(ets.tc_tsa));
-
-	/* tclass[prio=0]=1, tclass[prio=1]=0, tclass[prio=i]=i (for i>1) */
-	ets.prio_tc[0] = 1;
-	ets.prio_tc[1] = 0;
-
-	mlx5e_dcbnl_ieee_setets_core(priv, &ets);
-}
-#endif
-
 void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
 				   u32 *indirection_rqt, int len,
 				   int num_channels)
@@ -3349,7 +3325,7 @@ static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)
 	}
 
 #ifdef CONFIG_MLX5_CORE_EN_DCB
-	mlx5e_ets_init(priv);
+	mlx5e_dcbnl_initialize(priv);
 #endif
 	return 0;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 5/6] net/mlx5e: Add DCBX control interface
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
                   ` (3 preceding siblings ...)
  2016-08-30 11:29 ` [PATCH net-next 4/6] net/mlx5e: ConnectX-4 firmware support for DCBX Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-30 11:29 ` [PATCH net-next 6/6] net/mlx5: Add handling for port module event Saeed Mahameed
  5 siblings, 0 replies; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

1. Use setdcbx interface to set the DCBX mode to firmware or os.
   If setdcbx is called with mode value of zero, the DCBX mode
   is set to firmware.

2. Add private ethtool flag "qos_with_dcbx_by_fw". When this
   flag is "On", the DCBX is forced to firmware mode.

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/en.h       |  2 ++
 drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 24 ++++++++++++++++++++-
 .../net/ethernet/mellanox/mlx5/core/en_ethtool.c   | 25 ++++++++++++++++++++++
 3 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 806f5e8..501b1e4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -158,10 +158,12 @@ struct mlx5e_umr_wqe {
 
 static const char mlx5e_priv_flags[][ETH_GSTRING_LEN] = {
 	"rx_cqe_moder",
+	"qos_with_dcbx_by_fw",
 };
 
 enum mlx5e_priv_flag {
 	MLX5E_PFLAG_RX_CQE_BASED_MODER = (1 << 0),
+	MLX5E_PFLAG_QOS_WITH_DCBX_BY_FW = (1 << 1),
 };
 
 #define MLX5E_SET_PRIV_FLAG(priv, pflag, enable)    \
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 5d1b402..6c739c1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -54,6 +54,9 @@ static inline bool mlx5e_dcbnl_is_allowed(struct mlx5e_priv *priv)
 	if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
 		return true;
 
+	if (priv->pflags & MLX5E_PFLAG_QOS_WITH_DCBX_BY_FW)
+		return true;
+
 	if (mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_HOST))
 		return false;
 
@@ -283,13 +286,32 @@ static int mlx5e_dcbnl_ieee_setpfc(struct net_device *dev,
 
 static u8 mlx5e_dcbnl_getdcbx(struct net_device *dev)
 {
-	return DCB_CAP_DCBX_HOST |
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_dcbx *dcbx = &priv->dcbx;
+	u8 mode = 0;
+
+	if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
+		mode = DCB_CAP_DCBX_HOST;
+
+	return mode |
 	       DCB_CAP_DCBX_VER_IEEE |
 	       DCB_CAP_DCBX_VER_CEE;
 }
 
 static u8 mlx5e_dcbnl_setdcbx(struct net_device *dev, u8 mode)
 {
+	struct mlx5e_priv *priv = netdev_priv(dev);
+	struct mlx5e_dcbx *dcbx = &priv->dcbx;
+
+	if ((!mode) && MLX5_CAP_GEN(priv->mdev, dcbx)) {
+		/* set dcbx to fw controlled */
+		if (dcbx->mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
+			if (!mlx5e_dcbnl_set_dcbx_mode(priv, MLX5E_DCBX_PARAM_VER_OPER_AUTO))
+				dcbx->mode = MLX5E_DCBX_PARAM_VER_OPER_AUTO;
+
+		return 0;
+	}
+
 	if (!mlx5e_dcbnl_is_allowed(netdev_priv(dev)))
 		return 1;
 
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index d1cd156..9bc26cd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1460,6 +1460,25 @@ static int mlx5e_handle_pflag(struct net_device *netdev,
 	return 0;
 }
 
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+static int qos_with_dcbx_by_fw_handler(struct net_device *netdev, bool enable)
+{
+	struct mlx5e_priv *priv = netdev_priv(netdev);
+
+	if (!MLX5_CAP_GEN(priv->mdev, dcbx))
+		return -EPERM;
+
+	if (!enable)
+		return 0;
+
+	/* Not allow to turn on the flag if the dcbx mode is host */
+	if (priv->dcbx.mode == MLX5E_DCBX_PARAM_VER_OPER_HOST)
+		return -EPERM;
+
+	return 0;
+}
+#endif
+
 static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
 {
 	struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -1471,6 +1490,12 @@ static int mlx5e_set_priv_flags(struct net_device *netdev, u32 pflags)
 				 MLX5E_PFLAG_RX_CQE_BASED_MODER,
 				 set_pflag_rx_cqe_based_moder);
 
+#ifdef CONFIG_MLX5_CORE_EN_DCB
+	err  = mlx5e_handle_pflag(netdev, pflags,
+				  MLX5E_PFLAG_QOS_WITH_DCBX_BY_FW,
+				  qos_with_dcbx_by_fw_handler);
+#endif
+
 	mutex_unlock(&priv->state_lock);
 	return err ? -EINVAL : 0;
 }
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH net-next 6/6] net/mlx5: Add handling for port module event
  2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
                   ` (4 preceding siblings ...)
  2016-08-30 11:29 ` [PATCH net-next 5/6] net/mlx5e: Add DCBX control interface Saeed Mahameed
@ 2016-08-30 11:29 ` Saeed Mahameed
  2016-08-30 20:24   ` Or Gerlitz
  5 siblings, 1 reply; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-30 11:29 UTC (permalink / raw)
  To: David S. Miller; +Cc: netdev, Huy Nguyen, Saeed Mahameed

From: Huy Nguyen <huyn@mellanox.com>

Add dmesg log for asynchronous port module event.

Signed-off-by: Huy Nguyen <huyn@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/eq.c       | 12 +++
 .../net/ethernet/mellanox/mlx5/core/mlx5_core.h    |  1 +
 drivers/net/ethernet/mellanox/mlx5/core/port.c     | 85 ++++++++++++++++++++++
 include/linux/mlx5/device.h                        | 11 +++
 include/linux/mlx5/mlx5_ifc.h                      |  3 +-
 5 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eq.c b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
index aaca090..d775fea 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eq.c
@@ -139,6 +139,8 @@ static const char *eqe_type_str(u8 type)
 		return "MLX5_EVENT_TYPE_PORT_CHANGE";
 	case MLX5_EVENT_TYPE_GPIO_EVENT:
 		return "MLX5_EVENT_TYPE_GPIO_EVENT";
+	case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
+		return "MLX5_EVENT_TYPE_PORT_MODULE_EVENT";
 	case MLX5_EVENT_TYPE_REMOTE_CONFIG:
 		return "MLX5_EVENT_TYPE_REMOTE_CONFIG";
 	case MLX5_EVENT_TYPE_DB_BF_CONGESTION:
@@ -285,6 +287,11 @@ static int mlx5_eq_int(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
 			mlx5_eswitch_vport_event(dev->priv.eswitch, eqe);
 			break;
 #endif
+
+		case MLX5_EVENT_TYPE_PORT_MODULE_EVENT:
+			mlx5_port_module_event(dev, eqe);
+			break;
+
 		default:
 			mlx5_core_warn(dev, "Unhandled event 0x%x on EQ 0x%x\n",
 				       eqe->type, eq->eqn);
@@ -480,6 +487,11 @@ int mlx5_start_eqs(struct mlx5_core_dev *dev)
 	    mlx5_core_is_pf(dev))
 		async_event_mask |= (1ull << MLX5_EVENT_TYPE_NIC_VPORT_CHANGE);
 
+	if (MLX5_CAP_GEN(dev, port_module_event))
+		async_event_mask |= (1ull << MLX5_EVENT_TYPE_PORT_MODULE_EVENT);
+	else
+		mlx5_core_dbg(dev, "port_module_event is not set\n");
+
 	err = mlx5_create_map_eq(dev, &table->cmd_eq, MLX5_EQ_VEC_CMD,
 				 MLX5_NUM_CMD_EQE, 1ull << MLX5_EVENT_TYPE_CMD,
 				 "mlx5_cmd_eq", &dev->priv.uuari.uars[0]);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
index 714b71b..d023d05 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/mlx5_core.h
@@ -87,6 +87,7 @@ int mlx5_cmd_init_hca(struct mlx5_core_dev *dev);
 int mlx5_cmd_teardown_hca(struct mlx5_core_dev *dev);
 void mlx5_core_event(struct mlx5_core_dev *dev, enum mlx5_dev_event event,
 		     unsigned long param);
+void mlx5_port_module_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
 void mlx5_enter_error_state(struct mlx5_core_dev *dev);
 void mlx5_disable_device(struct mlx5_core_dev *dev);
 int mlx5_core_sriov_configure(struct pci_dev *dev, int num_vfs);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
index 8a66595..e5f62bb 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
@@ -36,6 +36,25 @@
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
 
+#define PORT_MODULE_EVENT_MODULE_STATUS_MASK 0xF
+#define PORT_MODULE_EVENT_ERROR_TYPE_MASK         0xF
+enum {
+	MLX5_MODULE_STATUS_PLUGGED  = 0x1,
+	MLX5_MODULE_STATUS_UNPLUGGED  = 0x2,
+	MLX5_MODULE_STATUS_ERROR  = 0x3,
+};
+
+enum {
+	MLX5_MODULE_EVENT_ERROR_POWER_BUDGET_EXCEEDED  = 0x0,
+	MLX5_MODULE_EVENT_ERROR_LONG_RANGE_FOR_NON_MLNX_CABLE_MODULE  = 0x1,
+	MLX5_MODULE_EVENT_ERROR_BUS_STUCK  = 0x2,
+	MLX5_MODULE_EVENT_ERROR_NO_EEPROM_RETRY_TIMEOUT  = 0x3,
+	MLX5_MODULE_EVENT_ERROR_ENFORCE_PART_NUMBER_LIST  = 0x4,
+	MLX5_MODULE_EVENT_ERROR_UNKNOWN_IDENTIFIER  = 0x5,
+	MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE  = 0x6,
+	MLX5_MODULE_EVENT_ERROR_BAD_CABLE = 0x7,
+};
+
 int mlx5_core_access_reg(struct mlx5_core_dev *dev, void *data_in,
 			 int size_in, void *data_out, int size_out,
 			 u16 reg_id, int arg, int write)
@@ -811,3 +830,69 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
 	*supported = !!(MLX5_GET(pcmr_reg, out, fcs_cap));
 	*enabled = !!(MLX5_GET(pcmr_reg, out, fcs_chk));
 }
+
+static const char *mlx5_port_event_error_type_to_string(u8 error_type)
+{
+	switch (error_type) {
+	case MLX5_MODULE_EVENT_ERROR_POWER_BUDGET_EXCEEDED:
+		return "Power Budget Exceeded";
+
+	case MLX5_MODULE_EVENT_ERROR_LONG_RANGE_FOR_NON_MLNX_CABLE_MODULE:
+		return "Long Range for non MLNX cable/module";
+
+	case MLX5_MODULE_EVENT_ERROR_BUS_STUCK:
+		return "Bus stuck(I2C or data shorted)";
+
+	case MLX5_MODULE_EVENT_ERROR_NO_EEPROM_RETRY_TIMEOUT:
+		return "No EEPROM/retry timeout";
+
+	case MLX5_MODULE_EVENT_ERROR_ENFORCE_PART_NUMBER_LIST:
+		return "Enforce part number list";
+
+	case MLX5_MODULE_EVENT_ERROR_UNKNOWN_IDENTIFIER:
+		return "Unknown identifier";
+
+	case MLX5_MODULE_EVENT_ERROR_HIGH_TEMPERATURE:
+		return "High Temperature";
+
+	case MLX5_MODULE_EVENT_ERROR_BAD_CABLE:
+		return "Bad cable (module/cable is shorted)";
+
+	default:
+		return "Unknown error type";
+	}
+}
+
+void mlx5_port_module_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe)
+{
+	struct mlx5_eqe_port_module *module_event_eqe;
+	u8 module_status;
+	u8 module_num;
+	u8 error_type;
+
+	module_event_eqe = &eqe->data.port_module;
+	module_num = module_event_eqe->module;
+	module_status = module_event_eqe->module_status &
+			PORT_MODULE_EVENT_MODULE_STATUS_MASK;
+	error_type = module_event_eqe->error_type &
+		     PORT_MODULE_EVENT_ERROR_TYPE_MASK;
+
+	switch (module_status) {
+	case MLX5_MODULE_STATUS_PLUGGED:
+		mlx5_core_info(dev, "Module %u, status: plugged", module_num);
+		break;
+
+	case MLX5_MODULE_STATUS_UNPLUGGED:
+		mlx5_core_info(dev, "Module %u, status: unplugged", module_num);
+		break;
+
+	case MLX5_MODULE_STATUS_ERROR:
+		mlx5_core_info(dev, "Module %u, status: error, %s", module_num,
+			       mlx5_port_event_error_type_to_string(error_type));
+		break;
+
+	default:
+		mlx5_core_info(dev, "Module %u, unknown module status %x",
+			       module_num, module_status);
+	}
+}
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 77c1417..3020b7f 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -268,6 +268,7 @@ enum mlx5_event {
 	MLX5_EVENT_TYPE_INTERNAL_ERROR	   = 0x08,
 	MLX5_EVENT_TYPE_PORT_CHANGE	   = 0x09,
 	MLX5_EVENT_TYPE_GPIO_EVENT	   = 0x15,
+	MLX5_EVENT_TYPE_PORT_MODULE_EVENT  = 0x16,
 	MLX5_EVENT_TYPE_REMOTE_CONFIG	   = 0x19,
 
 	MLX5_EVENT_TYPE_DB_BF_CONGESTION   = 0x1a,
@@ -543,6 +544,15 @@ struct mlx5_eqe_vport_change {
 	__be32		rsvd1[6];
 } __packed;
 
+struct mlx5_eqe_port_module {
+	u8        rsvd0[1];
+	u8        module;
+	u8        rsvd1[1];
+	u8        module_status;
+	u8        rsvd2[2];
+	u8        error_type;
+};
+
 union ev_data {
 	__be32				raw[7];
 	struct mlx5_eqe_cmd		cmd;
@@ -556,6 +566,7 @@ union ev_data {
 	struct mlx5_eqe_page_req	req_pages;
 	struct mlx5_eqe_page_fault	page_fault;
 	struct mlx5_eqe_vport_change	vport_change;
+	struct mlx5_eqe_port_module	port_module;
 } __packed;
 
 struct mlx5_eqe {
diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h
index 73a720f..57eaee3 100644
--- a/include/linux/mlx5/mlx5_ifc.h
+++ b/include/linux/mlx5/mlx5_ifc.h
@@ -804,7 +804,8 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 	u8	   early_vf_enable[0x1];
 	u8         reserved_at_1a9[0x2];
 	u8         local_ca_ack_delay[0x5];
-	u8         reserved_at_1af[0x2];
+	u8         port_module_event[0x1];
+	u8         reserved_at_1b0[0x1];
 	u8         ports_check[0x1];
 	u8         reserved_at_1b2[0x1];
 	u8         disable_link_up[0x1];
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 6/6] net/mlx5: Add handling for port module event
  2016-08-30 11:29 ` [PATCH net-next 6/6] net/mlx5: Add handling for port module event Saeed Mahameed
@ 2016-08-30 20:24   ` Or Gerlitz
  2016-08-31 11:05     ` Saeed Mahameed
  0 siblings, 1 reply; 14+ messages in thread
From: Or Gerlitz @ 2016-08-30 20:24 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: David S. Miller, Linux Netdev List, Huy Nguyen

On Tue, Aug 30, 2016 at 2:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Huy Nguyen <huyn@mellanox.com>

> +++ b/include/linux/mlx5/device.h
> @@ -543,6 +544,15 @@ struct mlx5_eqe_vport_change {
>         __be32          rsvd1[6];
>  } __packed;
>
> +struct mlx5_eqe_port_module {
> +       u8        rsvd0[1];
> +       u8        module;
> +       u8        rsvd1[1];
> +       u8        module_status;
> +       u8        rsvd2[2];
> +       u8        error_type;
> +};
> +

Saeed, any reason for this struct and friends not to be  @ the FW IFC file?

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API
  2016-08-30 11:29 ` [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API Saeed Mahameed
@ 2016-08-30 20:33   ` Or Gerlitz
  0 siblings, 0 replies; 14+ messages in thread
From: Or Gerlitz @ 2016-08-30 20:33 UTC (permalink / raw)
  To: Huy Nguyen; +Cc: David S. Miller, Linux Netdev List, Saeed Mahameed

On Tue, Aug 30, 2016 at 2:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Huy Nguyen <huyn@mellanox.com>
>
> Add DCBX CEE API interface for CX4. 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 CX4
>   only supports bw allocation per traffic class.
>
>   user priority in CEE does not have an equivalent term in CX4.
>   Therefore, user priority to priority mapping in CEE is not supported.

basically our drivers suits (mlx4/5) are not written to a certain HW,
but rather to multiple (past, present and future) brands using dev
caps advertized by the firmware towards the driver.

I see here lots of CX4 explicit mentioning... so (1) try to avoid it
or make the description more general (2) do you base your code on dev
caps or hard coded assumptions?


> Test: see DCBX_LinuxDriverCX4 document section 6.4

what's the relevancy for the upstream commit change log?

> Signed-off-by: Huy Nguyen <huyn@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware
  2016-08-30 11:29 ` [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware Saeed Mahameed
@ 2016-08-30 20:34   ` Or Gerlitz
  0 siblings, 0 replies; 14+ messages in thread
From: Or Gerlitz @ 2016-08-30 20:34 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: David S. Miller, Linux Netdev List, Huy Nguyen

On Tue, Aug 30, 2016 at 2:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Huy Nguyen <huyn@mellanox.com>
>
> Current implementation does not read the setting
> directly from FW when ieee_getets is called.


what's wrong with that? explain

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 6/6] net/mlx5: Add handling for port module event
  2016-08-30 20:24   ` Or Gerlitz
@ 2016-08-31 11:05     ` Saeed Mahameed
  0 siblings, 0 replies; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-31 11:05 UTC (permalink / raw)
  To: Or Gerlitz; +Cc: David S. Miller, Linux Netdev List, Huy Nguyen



On 8/30/2016 11:24 PM, Or Gerlitz wrote:
> On Tue, Aug 30, 2016 at 2:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
>> From: Huy Nguyen <huyn@mellanox.com>
>> +++ b/include/linux/mlx5/device.h
>> @@ -543,6 +544,15 @@ struct mlx5_eqe_vport_change {
>>          __be32          rsvd1[6];
>>   } __packed;
>>
>> +struct mlx5_eqe_port_module {
>> +       u8        rsvd0[1];
>> +       u8        module;
>> +       u8        rsvd1[1];
>> +       u8        module_status;
>> +       u8        rsvd2[2];
>> +       u8        error_type;
>> +};
>> +
> Saeed, any reason for this struct and friends not to be  @ the FW IFC file?

Yes, those structures are accessed from irq context, we need to keep it 
as fast as possible,
although for this case it is not that critical. But in order to keep the 
code uniform, all eqes are built this way.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support
  2016-08-30 11:29 ` [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support Saeed Mahameed
@ 2016-08-31 11:24   ` zhuyj
  2016-08-31 14:49     ` Huy Nguyen
  2016-08-31 16:08     ` Saeed Mahameed
  0 siblings, 2 replies; 14+ messages in thread
From: zhuyj @ 2016-08-31 11:24 UTC (permalink / raw)
  To: Saeed Mahameed; +Cc: David S. Miller, netdev, Huy Nguyen

+       u32 in[MLX5_ST_SZ_DW(dcbx_param)];
+
+       memset(in, 0, sizeof(in));

can we replace the above with "u32 in[MLX5_ST_SZ_DW(dcbx_param)] = {0};"?



On Tue, Aug 30, 2016 at 7:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
> From: Huy Nguyen <huyn@mellanox.com>
>
> Add set/query commands for DCBX_PARAM register
>
> Signed-off-by: Huy Nguyen <huyn@mellanox.com>
> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
> ---
>  drivers/net/ethernet/mellanox/mlx5/core/port.c | 22 ++++++++++++++++++++++
>  include/linux/mlx5/driver.h                    |  7 +++++++
>  include/linux/mlx5/port.h                      |  2 ++
>  3 files changed, 31 insertions(+)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> index 2f75f86..8a66595 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
> @@ -548,6 +548,28 @@ int mlx5_max_tc(struct mlx5_core_dev *mdev)
>         return num_tc - 1;
>  }
>
> +int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out)
> +{
> +       u32 in[MLX5_ST_SZ_DW(dcbx_param)];
> +
> +       memset(in, 0, sizeof(in));
> +
> +       MLX5_SET(dcbx_param, in, port_number, 1);
> +
> +       return  mlx5_core_access_reg(mdev, in, sizeof(in), out,
> +                                   sizeof(in), MLX5_REG_DCBX_PARAM, 0, 0);
> +}
> +
> +int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in)
> +{
> +       u32 out[MLX5_ST_SZ_DW(dcbx_param)];
> +
> +       MLX5_SET(dcbx_param, in, port_number, 1);
> +
> +       return mlx5_core_access_reg(mdev, in, sizeof(out), out,
> +                                   sizeof(out), MLX5_REG_DCBX_PARAM, 0, 1);
> +}
> +
>  int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
>  {
>         u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {0};
> diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
> index 5cb9fa7..b53f19c 100644
> --- a/include/linux/mlx5/driver.h
> +++ b/include/linux/mlx5/driver.h
> @@ -104,6 +104,8 @@ enum {
>  enum {
>         MLX5_REG_QETCR           = 0x4005,
>         MLX5_REG_QTCT            = 0x400a,
> +       MLX5_REG_DCBX_PARAM      = 0x4020,
> +       MLX5_REG_DCBX_APP        = 0x4021,
>         MLX5_REG_PCAP            = 0x5001,
>         MLX5_REG_PMTU            = 0x5003,
>         MLX5_REG_PTYS            = 0x5004,
> @@ -123,6 +125,11 @@ enum {
>         MLX5_REG_MLCR            = 0x902b,
>  };
>
> +enum mlx5_dcbx_oper_mode {
> +       MLX5E_DCBX_PARAM_VER_OPER_HOST  = 0x0,
> +       MLX5E_DCBX_PARAM_VER_OPER_AUTO  = 0x3,
> +};
> +
>  enum {
>         MLX5_ATOMIC_OPS_CMP_SWAP        = 1 << 0,
>         MLX5_ATOMIC_OPS_FETCH_ADD       = 1 << 1,
> diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
> index ddad24d..62e2259 100644
> --- a/include/linux/mlx5/port.h
> +++ b/include/linux/mlx5/port.h
> @@ -159,4 +159,6 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
>  int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
>                              u16 offset, u16 size, u8 *data);
>
> +int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
> +int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
>  #endif /* __MLX5_PORT_H__ */
> --
> 2.7.4
>

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support
  2016-08-31 11:24   ` zhuyj
@ 2016-08-31 14:49     ` Huy Nguyen
  2016-08-31 16:08     ` Saeed Mahameed
  1 sibling, 0 replies; 14+ messages in thread
From: Huy Nguyen @ 2016-08-31 14:49 UTC (permalink / raw)
  To: zhuyj; +Cc: Saeed Mahameed, David S. Miller, netdev



> On Aug 31, 2016, at 6:24 AM, zhuyj <zyjzyj2000@gmail.com> wrote:
> 
> +       u32 in[MLX5_ST_SZ_DW(dcbx_param)];
> +
> +       memset(in, 0, sizeof(in));
> 
> can we replace the above with "u32 in[MLX5_ST_SZ_DW(dcbx_param)] = {0};"?
> 
> 
> 
>> On Tue, Aug 30, 2016 at 7:29 PM, Saeed Mahameed <saeedm@mellanox.com> wrote:
>> From: Huy Nguyen <huyn@mellanox.com>
>> 
>> Add set/query commands for DCBX_PARAM register
>> 
>> Signed-off-by: Huy Nguyen <huyn@mellanox.com>
>> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
>> ---
>> drivers/net/ethernet/mellanox/mlx5/core/port.c | 22 ++++++++++++++++++++++
>> include/linux/mlx5/driver.h                    |  7 +++++++
>> include/linux/mlx5/port.h                      |  2 ++
>> 3 files changed, 31 insertions(+)
>> 
>> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/port.c b/drivers/net/ethernet/mellanox/mlx5/core/port.c
>> index 2f75f86..8a66595 100644
>> --- a/drivers/net/ethernet/mellanox/mlx5/core/port.c
>> +++ b/drivers/net/ethernet/mellanox/mlx5/core/port.c
>> @@ -548,6 +548,28 @@ int mlx5_max_tc(struct mlx5_core_dev *mdev)
>>        return num_tc - 1;
>> }
>> 
>> +int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out)
>> +{
>> +       u32 in[MLX5_ST_SZ_DW(dcbx_param)];
>> +
>> +       memset(in, 0, sizeof(in));
>> +
>> +       MLX5_SET(dcbx_param, in, port_number, 1);
>> +
>> +       return  mlx5_core_access_reg(mdev, in, sizeof(in), out,
>> +                                   sizeof(in), MLX5_REG_DCBX_PARAM, 0, 0);
>> +}
>> +
>> +int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in)
>> +{
>> +       u32 out[MLX5_ST_SZ_DW(dcbx_param)];
>> +
>> +       MLX5_SET(dcbx_param, in, port_number, 1);
>> +
>> +       return mlx5_core_access_reg(mdev, in, sizeof(out), out,
>> +                                   sizeof(out), MLX5_REG_DCBX_PARAM, 0, 1);
>> +}
>> +
>> int mlx5_set_port_prio_tc(struct mlx5_core_dev *mdev, u8 *prio_tc)
>> {
>>        u32 in[MLX5_ST_SZ_DW(qtct_reg)] = {0};
>> diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
>> index 5cb9fa7..b53f19c 100644
>> --- a/include/linux/mlx5/driver.h
>> +++ b/include/linux/mlx5/driver.h
>> @@ -104,6 +104,8 @@ enum {
>> enum {
>>        MLX5_REG_QETCR           = 0x4005,
>>        MLX5_REG_QTCT            = 0x400a,
>> +       MLX5_REG_DCBX_PARAM      = 0x4020,
>> +       MLX5_REG_DCBX_APP        = 0x4021,
>>        MLX5_REG_PCAP            = 0x5001,
>>        MLX5_REG_PMTU            = 0x5003,
>>        MLX5_REG_PTYS            = 0x5004,
>> @@ -123,6 +125,11 @@ enum {
>>        MLX5_REG_MLCR            = 0x902b,
>> };
>> 
>> +enum mlx5_dcbx_oper_mode {
>> +       MLX5E_DCBX_PARAM_VER_OPER_HOST  = 0x0,
>> +       MLX5E_DCBX_PARAM_VER_OPER_AUTO  = 0x3,
>> +};
>> +
>> enum {
>>        MLX5_ATOMIC_OPS_CMP_SWAP        = 1 << 0,
>>        MLX5_ATOMIC_OPS_FETCH_ADD       = 1 << 1,
>> diff --git a/include/linux/mlx5/port.h b/include/linux/mlx5/port.h
>> index ddad24d..62e2259 100644
>> --- a/include/linux/mlx5/port.h
>> +++ b/include/linux/mlx5/port.h
>> @@ -159,4 +159,6 @@ void mlx5_query_port_fcs(struct mlx5_core_dev *mdev, bool *supported,
>> int mlx5_query_module_eeprom(struct mlx5_core_dev *dev,
>>                             u16 offset, u16 size, u8 *data);
>> 
>> +int mlx5_query_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *out);
>> +int mlx5_set_port_dcbx_param(struct mlx5_core_dev *mdev, u32 *in);
>> #endif /* __MLX5_PORT_H__ */
>> --
>> 2.7.4
Yes I will fix. Thank you.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support
  2016-08-31 11:24   ` zhuyj
  2016-08-31 14:49     ` Huy Nguyen
@ 2016-08-31 16:08     ` Saeed Mahameed
  1 sibling, 0 replies; 14+ messages in thread
From: Saeed Mahameed @ 2016-08-31 16:08 UTC (permalink / raw)
  To: zhuyj; +Cc: Saeed Mahameed, David S. Miller, netdev, Huy Nguyen

On Wed, Aug 31, 2016 at 2:24 PM, zhuyj <zyjzyj2000@gmail.com> wrote:
> +       u32 in[MLX5_ST_SZ_DW(dcbx_param)];
> +
> +       memset(in, 0, sizeof(in));
>
> can we replace the above with "u32 in[MLX5_ST_SZ_DW(dcbx_param)] = {0};"?

yes, we will change it in V2.

Thanks.

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-09-01 14:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-30 11:29 [PATCH net-next 0/6] Mellanox 100G mlx5 DCBX CEE and firmware support Saeed Mahameed
2016-08-30 11:29 ` [PATCH net-next 1/6] net/mlx5e: Support DCBX CEE API Saeed Mahameed
2016-08-30 20:33   ` Or Gerlitz
2016-08-30 11:29 ` [PATCH net-next 2/6] net/mlx5e: Read ETS settings directly from firmware Saeed Mahameed
2016-08-30 20:34   ` Or Gerlitz
2016-08-30 11:29 ` [PATCH net-next 3/6] net/mlx5: Add DCBX firmware commands support Saeed Mahameed
2016-08-31 11:24   ` zhuyj
2016-08-31 14:49     ` Huy Nguyen
2016-08-31 16:08     ` Saeed Mahameed
2016-08-30 11:29 ` [PATCH net-next 4/6] net/mlx5e: ConnectX-4 firmware support for DCBX Saeed Mahameed
2016-08-30 11:29 ` [PATCH net-next 5/6] net/mlx5e: Add DCBX control interface Saeed Mahameed
2016-08-30 11:29 ` [PATCH net-next 6/6] net/mlx5: Add handling for port module event Saeed Mahameed
2016-08-30 20:24   ` Or Gerlitz
2016-08-31 11:05     ` Saeed Mahameed

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.