From d3f8999b1d8777ed15a3eecced0ca42a67545d26 Mon Sep 17 00:00:00 2001 From: Bogdan Purcareata Date: Mon, 7 Aug 2017 09:53:18 +0000 Subject: 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 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 +#include #include #include #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) \ -- cgit v0.10.2