diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 74 |
1 files changed, 61 insertions, 13 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index bd2d75265389..0ace6ce1d0b4 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c @@ -330,24 +330,20 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority, static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + int ret; +#ifdef IXGBE_FCOE struct dcb_app app = { .selector = DCB_APP_IDTYPE_ETHTYPE, .protocol = ETH_P_FCOE, }; u8 up = dcb_getapp(netdev, &app); - int ret; +#endif ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, MAX_TRAFFIC_CLASS); if (ret) return DCB_NO_HW_CHG; - /* In IEEE mode app data must be parsed into DCBX format for - * hardware routines. - */ - if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) - up = (1 << up); - #ifdef IXGBE_FCOE if (up && (up != (1 << adapter->fcoe.up))) adapter->dcb_set_bitmap |= BIT_APP_UPCHG; @@ -361,7 +357,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) usleep_range(1000, 2000); - ixgbe_fcoe_setapp(adapter, up); + adapter->fcoe.up = ffs(up) - 1; if (netif_running(netdev)) netdev->netdev_ops->ndo_stop(netdev); @@ -674,24 +670,75 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return err; } +#ifdef IXGBE_FCOE +static void ixgbe_dcbnl_devreset(struct net_device *dev) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + + if (netif_running(dev)) + dev->netdev_ops->ndo_stop(dev); + + ixgbe_clear_interrupt_scheme(adapter); + ixgbe_init_interrupt_scheme(adapter); + + if (netif_running(dev)) + dev->netdev_ops->ndo_open(dev); +} +#endif + static int ixgbe_dcbnl_ieee_setapp(struct net_device *dev, struct dcb_app *app) { struct ixgbe_adapter *adapter = netdev_priv(dev); + int err = -EINVAL; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) - return -EINVAL; + return err; - dcb_setapp(dev, app); + err = dcb_ieee_setapp(dev, app); #ifdef IXGBE_FCOE - if (app->selector == 1 && app->protocol == ETH_P_FCOE && - adapter->fcoe.tc == app->priority) - ixgbe_dcbnl_set_all(dev); + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; + + adapter->fcoe.up = app->priority; + ixgbe_dcbnl_devreset(dev); + } #endif return 0; } +static int ixgbe_dcbnl_ieee_delapp(struct net_device *dev, + struct dcb_app *app) +{ + struct ixgbe_adapter *adapter = netdev_priv(dev); + int err; + + if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) + return -EINVAL; + + err = dcb_ieee_delapp(dev, app); + +#ifdef IXGBE_FCOE + if (!err && app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && + app->protocol == ETH_P_FCOE) { + u8 app_mask = dcb_ieee_getapp_mask(dev, app); + + if (app_mask & (1 << adapter->fcoe.up)) + return err; + + adapter->fcoe.up = app_mask ? + ffs(app_mask) - 1 : IXGBE_FCOE_DEFTC; + ixgbe_dcbnl_devreset(dev); + } +#endif + return err; +} + static u8 ixgbe_dcbnl_getdcbx(struct net_device *dev) { struct ixgbe_adapter *adapter = netdev_priv(dev); @@ -743,6 +790,7 @@ const struct dcbnl_rtnl_ops dcbnl_ops = { .ieee_getpfc = ixgbe_dcbnl_ieee_getpfc, .ieee_setpfc = ixgbe_dcbnl_ieee_setpfc, .ieee_setapp = ixgbe_dcbnl_ieee_setapp, + .ieee_delapp = ixgbe_dcbnl_ieee_delapp, .getstate = ixgbe_dcbnl_get_state, .setstate = ixgbe_dcbnl_set_state, .getpermhwaddr = ixgbe_dcbnl_get_perm_hw_addr, |