diff options
author | John Fastabend <john.r.fastabend@intel.com> | 2011-09-27 03:51:56 +0000 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-10-06 03:23:11 -0700 |
commit | 32701dc2e616ca64e3d24b41c78671c4528671c1 (patch) | |
tree | 27911ab1fb1b2b99be48e8c77d9b5b38600e1497 /drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | |
parent | 2ad30e2633430717dbdf857962ba0c697dc471ef (diff) |
ixgbe: fixup hard dependencies on supporting 8 traffic classes
This patch correctly configures DCB when less than 8 traffic classes
are available in hardware.
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c')
-rw-r--r-- | drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c index 1d38955ca19d..be66bb679d5a 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_nl.c @@ -123,7 +123,7 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state) return err; if (state > 0) - err = ixgbe_setup_tc(netdev, MAX_TRAFFIC_CLASS); + err = ixgbe_setup_tc(netdev, adapter->dcb_cfg.num_tcs.pg_tcs); else err = ixgbe_setup_tc(netdev, 0); @@ -158,6 +158,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, { struct ixgbe_adapter *adapter = netdev_priv(netdev); + /* Abort a bad configuration */ + if (ffs(up_map) > adapter->dcb_cfg.num_tcs.pg_tcs) + return; + if (prio != DCB_ATTR_VALUE_UNDEFINED) adapter->temp_dcb_cfg.tc_config[tc].path[0].prio_type = prio; if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) @@ -178,6 +182,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc, (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) adapter->dcb_set_bitmap |= BIT_PG_TX; + + if (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap) + adapter->dcb_set_bitmap |= BIT_PFC; } static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id, @@ -198,6 +206,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, { struct ixgbe_adapter *adapter = netdev_priv(netdev); + /* Abort bad configurations */ + if (ffs(up_map) > adapter->dcb_cfg.num_tcs.pg_tcs) + return; + if (prio != DCB_ATTR_VALUE_UNDEFINED) adapter->temp_dcb_cfg.tc_config[tc].path[1].prio_type = prio; if (bwg_id != DCB_ATTR_VALUE_UNDEFINED) @@ -218,6 +230,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc, (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) adapter->dcb_set_bitmap |= BIT_PG_RX; + + if (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap != + adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap) + adapter->dcb_set_bitmap |= BIT_PFC; } static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id, @@ -296,7 +312,7 @@ 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; + int ret, i; #ifdef IXGBE_FCOE struct dcb_app app = { .selector = DCB_APP_IDTYPE_ETHTYPE, @@ -370,18 +386,11 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) } #endif - if (adapter->dcb_set_bitmap & BIT_PFC) { - u8 pfc_en; - ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); - ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en); - ret = DCB_HW_CHG; - } - if (adapter->dcb_set_bitmap & (BIT_PG_TX|BIT_PG_RX)) { u16 refill[MAX_TRAFFIC_CLASS], max[MAX_TRAFFIC_CLASS]; u8 bwg_id[MAX_TRAFFIC_CLASS], prio_type[MAX_TRAFFIC_CLASS]; /* Priority to TC mapping in CEE case default to 1:1 */ - u8 prio_tc[MAX_TRAFFIC_CLASS] = {0, 1, 2, 3, 4, 5, 6, 7}; + u8 prio_tc[MAX_USER_PRIORITY]; int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; #ifdef IXGBE_FCOE @@ -401,9 +410,25 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) DCB_TX_CONFIG, bwg_id); ixgbe_dcb_unpack_prio(&adapter->dcb_cfg, DCB_TX_CONFIG, prio_type); + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_tc); ixgbe_dcb_hw_ets_config(&adapter->hw, refill, max, bwg_id, prio_type, prio_tc); + + for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) + netdev_set_prio_tc_map(netdev, i, prio_tc[i]); + } + + if (adapter->dcb_set_bitmap & BIT_PFC) { + u8 pfc_en; + u8 prio_tc[MAX_USER_PRIORITY]; + + ixgbe_dcb_unpack_map(&adapter->dcb_cfg, + DCB_TX_CONFIG, prio_tc); + ixgbe_dcb_unpack_pfc(&adapter->dcb_cfg, &pfc_en); + ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc_en, prio_tc); + ret = DCB_HW_CHG; } if (adapter->dcb_cfg.pfc_mode_enable) @@ -460,10 +485,10 @@ static u8 ixgbe_dcbnl_getnumtcs(struct net_device *netdev, int tcid, u8 *num) if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { switch (tcid) { case DCB_NUMTCS_ATTR_PG: - *num = MAX_TRAFFIC_CLASS; + *num = adapter->dcb_cfg.num_tcs.pg_tcs; break; case DCB_NUMTCS_ATTR_PFC: - *num = MAX_TRAFFIC_CLASS; + *num = adapter->dcb_cfg.num_tcs.pfc_tcs; break; default: rval = -EINVAL; @@ -532,7 +557,7 @@ static int ixgbe_dcbnl_ieee_getets(struct net_device *dev, if (!my_ets) return -EINVAL; - ets->ets_cap = MAX_TRAFFIC_CLASS; + ets->ets_cap = adapter->dcb_cfg.num_tcs.pg_tcs; ets->cbs = my_ets->cbs; memcpy(ets->tc_tx_bw, my_ets->tc_tx_bw, sizeof(ets->tc_tx_bw)); memcpy(ets->tc_rx_bw, my_ets->tc_rx_bw, sizeof(ets->tc_rx_bw)); @@ -569,6 +594,9 @@ static int ixgbe_dcbnl_ieee_setets(struct net_device *dev, if (max_tc) max_tc++; + if (max_tc > adapter->dcb_cfg.num_tcs.pg_tcs) + return -EINVAL; + if (max_tc != netdev_get_num_tc(dev)) ixgbe_setup_tc(dev, max_tc); @@ -589,7 +617,7 @@ static int ixgbe_dcbnl_ieee_getpfc(struct net_device *dev, if (!my_pfc) return -EINVAL; - pfc->pfc_cap = MAX_TRAFFIC_CLASS; + pfc->pfc_cap = adapter->dcb_cfg.num_tcs.pfc_tcs; pfc->pfc_en = my_pfc->pfc_en; pfc->mbc = my_pfc->mbc; pfc->delay = my_pfc->delay; @@ -606,6 +634,7 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) { struct ixgbe_adapter *adapter = netdev_priv(dev); + u8 *prio_tc; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; @@ -617,8 +646,9 @@ static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, return -ENOMEM; } + prio_tc = adapter->ixgbe_ieee_ets->prio_tc; memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); - return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en); + return ixgbe_dcb_hw_pfc_config(&adapter->hw, pfc->pfc_en, prio_tc); } #ifdef IXGBE_FCOE |