summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBogdan Purcareata <bogdan.purcareata@nxp.com>2017-08-07 09:53:18 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-12-12 07:32:40 (GMT)
commitd3f8999b1d8777ed15a3eecced0ca42a67545d26 (patch)
tree1a56d1f97610bfefe91ec3600f1b6b7a91fbc282
parentf39bb308c9217d1fbebbd1a3abedd74d73868f9b (diff)
downloadlinux-d3f8999b1d8777ed15a3eecced0ca42a67545d26.tar.xz
staging: fsl-dpaa2/eth: Add DCB support
Add initial DCB ops in the DPAA2 Ethernet driver. Currently they are dummy calls. Tested integration with userspace lldpad: - lldpad daemon running - bring interface up - lldptool -L -i niX adminStatus=rxtx - lldptool -T -i niX -V PFC -c enabled={prio comma separated list} - lldptool -t -i niX -V PFC -c enabled Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c74
-rw-r--r--drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h4
2 files changed, 78 insertions, 0 deletions
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index e37e25f..a959d4c 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2933,6 +2933,76 @@ static void dpaa2_eth_sysfs_remove(struct device *dev)
device_remove_file(dev, &dpaa2_eth_attrs[i]);
}
+#ifdef CONFIG_FSL_DPAA2_ETH_DCB
+static int dpaa2_eth_dcbnl_ieee_getpfc(struct net_device *net_dev,
+ struct ieee_pfc *pfc)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+ pfc->pfc_cap = dpaa2_eth_tc_count(priv);
+ pfc->pfc_en = priv->pfc.pfc_en;
+ pfc->mbc = priv->pfc.mbc;
+ pfc->delay = priv->pfc.delay;
+
+ return 0;
+}
+
+static int dpaa2_eth_dcbnl_ieee_setpfc(struct net_device *net_dev,
+ struct ieee_pfc *pfc)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+ memcpy(&priv->pfc, pfc, sizeof(priv->pfc));
+
+ return 0;
+}
+
+static u8 dpaa2_eth_dcbnl_getdcbx(struct net_device *net_dev)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+ return priv->dcbx_mode;
+}
+
+static u8 dpaa2_eth_dcbnl_setdcbx(struct net_device *net_dev, u8 mode)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+ priv->dcbx_mode = mode;
+ return 0;
+}
+
+static u8 dpaa2_eth_dcbnl_getcap(struct net_device *net_dev, int capid, u8 *cap)
+{
+ struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+
+ switch (capid) {
+ case DCB_CAP_ATTR_PFC:
+ *cap = true;
+ break;
+ case DCB_CAP_ATTR_PFC_TCS:
+ *cap = 1 << dpaa2_eth_tc_count(priv);
+ break;
+ case DCB_CAP_ATTR_DCBX:
+ *cap = priv->dcbx_mode;
+ break;
+ default:
+ *cap = false;
+ break;
+ }
+
+ return 0;
+}
+
+const struct dcbnl_rtnl_ops dpaa2_eth_dcbnl_ops = {
+ .ieee_getpfc = dpaa2_eth_dcbnl_ieee_getpfc,
+ .ieee_setpfc = dpaa2_eth_dcbnl_ieee_setpfc,
+ .getdcbx = dpaa2_eth_dcbnl_getdcbx,
+ .setdcbx = dpaa2_eth_dcbnl_setdcbx,
+ .getcap = dpaa2_eth_dcbnl_getcap,
+};
+#endif
+
static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
{
struct device *dev;
@@ -3033,6 +3103,10 @@ static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
goto err_alloc_rings;
net_dev->ethtool_ops = &dpaa2_ethtool_ops;
+#ifdef CONFIG_FSL_DPAA2_ETH_DCB
+ net_dev->dcbnl_ops = &dpaa2_eth_dcbnl_ops;
+ priv->dcbx_mode = DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_IEEE;
+#endif
err = setup_irqs(dpni_dev);
if (err) {
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
index ce1668c..056c453 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.h
@@ -33,6 +33,7 @@
#define __DPAA2_ETH_H
#include <linux/atomic.h>
+#include <linux/dcbnl.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include "../../fsl-mc/include/dpaa2-io.h"
@@ -431,6 +432,9 @@ struct dpaa2_eth_priv {
struct dpaa2_eth_cls_rule *cls_rule;
struct dpni_tx_shaping_cfg shaping_cfg;
+
+ u8 dcbx_mode;
+ struct ieee_pfc pfc;
};
#define dpaa2_eth_hash_enabled(priv) \