static int ixgbe_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc) { struct ixgbe_adapter *adapter = netdev_priv(dev); struct ixgbe_hw *hw = &adapter->hw; u8 *prio_tc; int err; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; if (!adapter->ixgbe_ieee_pfc) { adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), GFP_KERNEL); if (!adapter->ixgbe_ieee_pfc) return -ENOMEM; } prio_tc = adapter->ixgbe_ieee_ets->prio_tc; memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); /* Enable link flow control parameters if PFC is disabled */ if (pfc->pfc_en) err = ixgbe_dcb_config_pfc(hw, pfc->pfc_en, prio_tc); else err = hw->mac.ops.fc_enable(hw); ixgbe_set_rx_drop_en(adapter); return err; }
/** * ixgbe_dcb_hw_config_cee - Config and enable DCB * @hw: pointer to hardware structure * @dcb_config: pointer to ixgbe_dcb_config structure * * Configure dcb settings and enable dcb mode. */ s32 ixgbe_dcb_hw_config_cee(struct ixgbe_hw *hw, struct ixgbe_dcb_config *dcb_config) { s32 ret = IXGBE_NOT_IMPLEMENTED; u8 pfc_en; u8 tsa[IXGBE_DCB_MAX_TRAFFIC_CLASS]; u8 bwgid[IXGBE_DCB_MAX_TRAFFIC_CLASS]; u8 map[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; u16 refill[IXGBE_DCB_MAX_TRAFFIC_CLASS]; u16 max[IXGBE_DCB_MAX_TRAFFIC_CLASS]; /* Unpack CEE standard containers */ ixgbe_dcb_unpack_refill_cee(dcb_config, IXGBE_DCB_TX_CONFIG, refill); ixgbe_dcb_unpack_max_cee(dcb_config, max); ixgbe_dcb_unpack_bwgid_cee(dcb_config, IXGBE_DCB_TX_CONFIG, bwgid); ixgbe_dcb_unpack_tsa_cee(dcb_config, IXGBE_DCB_TX_CONFIG, tsa); ixgbe_dcb_unpack_map_cee(dcb_config, IXGBE_DCB_TX_CONFIG, map); hw->mac.ops.setup_rxpba(hw, dcb_config->num_tcs.pg_tcs, 0, dcb_config->rx_pba_cfg); switch (hw->mac.type) { case ixgbe_mac_82598EB: ret = ixgbe_dcb_hw_config_82598(hw, dcb_config->link_speed, refill, max, bwgid, tsa); break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: case ixgbe_mac_X550: case ixgbe_mac_X550EM_x: #if !defined(NO_82599_SUPPORT) || !defined(NO_X540_SUPPORT) ixgbe_dcb_config_82599(hw, dcb_config); ret = ixgbe_dcb_hw_config_82599(hw, dcb_config->link_speed, refill, max, bwgid, tsa, map); ixgbe_dcb_config_tc_stats_82599(hw, dcb_config); break; #endif default: break; } if (!ret && dcb_config->pfc_mode_enable) { ixgbe_dcb_unpack_pfc_cee(dcb_config, map, &pfc_en); ret = ixgbe_dcb_config_pfc(hw, pfc_en, map); } return ret; }
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; if (!adapter->ixgbe_ieee_pfc) { adapter->ixgbe_ieee_pfc = kmalloc(sizeof(struct ieee_pfc), GFP_KERNEL); if (!adapter->ixgbe_ieee_pfc) return -ENOMEM; } prio_tc = adapter->ixgbe_ieee_ets->prio_tc; memcpy(adapter->ixgbe_ieee_pfc, pfc, sizeof(*adapter->ixgbe_ieee_pfc)); return ixgbe_dcb_config_pfc(&adapter->hw, pfc->pfc_en, prio_tc); }
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); int ret; u8 prio_tc[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; u8 pfc_en; /* Fail command if not in CEE mode */ if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return 1; ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg, IXGBE_DCB_MAX_TRAFFIC_CLASS); if (ret) return DCB_NO_HW_CHG; if (adapter->dcb_cfg.pfc_mode_enable) { switch (adapter->hw.mac.type) { case ixgbe_mac_82599EB: case ixgbe_mac_X540: if (adapter->hw.fc.current_mode != ixgbe_fc_pfc) adapter->last_lfc_mode = adapter->hw.fc.current_mode; break; default: break; } adapter->hw.fc.requested_mode = ixgbe_fc_pfc; } else { switch (adapter->hw.mac.type) { case ixgbe_mac_82598EB: adapter->hw.fc.requested_mode = ixgbe_fc_none; break; case ixgbe_mac_82599EB: case ixgbe_mac_X540: adapter->hw.fc.requested_mode = adapter->last_lfc_mode; break; default: break; } } ixgbe_dcb_unpack_map_cee(&adapter->dcb_cfg, IXGBE_DCB_TX_CONFIG, prio_tc); if (adapter->dcb_set_bitmap & (BIT_PG_TX | BIT_PG_RX)) { /* Priority to TC mapping in CEE case default to 1:1 */ int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; #ifdef HAVE_MQPRIO int i; #endif #ifdef IXGBE_FCOE if (adapter->netdev->features & NETIF_F_FCOE_MTU) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif ixgbe_dcb_calculate_tc_credits_cee(&adapter->hw, &adapter->dcb_cfg, max_frame, IXGBE_DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits_cee(&adapter->hw, &adapter->dcb_cfg, max_frame, IXGBE_DCB_RX_CONFIG); ixgbe_dcb_hw_config_cee(&adapter->hw, &adapter->dcb_cfg); #ifdef HAVE_MQPRIO for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) netdev_set_prio_tc_map(netdev, i, prio_tc[i]); #endif /* HAVE_MQPRIO */ } if (adapter->dcb_set_bitmap & BIT_PFC) { ixgbe_dcb_unpack_pfc_cee(&adapter->dcb_cfg, prio_tc, &pfc_en); ixgbe_dcb_config_pfc(&adapter->hw, pfc_en, prio_tc); ret = DCB_HW_CHG; } if (adapter->dcb_cfg.pfc_mode_enable) adapter->hw.fc.current_mode = ixgbe_fc_pfc; #ifdef IXGBE_FCOE if ((adapter->fcoe.up_set != adapter->fcoe.up) || (adapter->dcb_set_bitmap & BIT_APP_UPCHG)) { adapter->fcoe.up_set = adapter->fcoe.up; ixgbe_dcbnl_devreset(netdev); } #endif /* IXGBE_FCOE */ adapter->dcb_set_bitmap = 0x00; return ret; }
static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_dcb_config *dcb_cfg = &adapter->dcb_cfg; struct ixgbe_hw *hw = &adapter->hw; int ret = DCB_NO_HW_CHG; u8 prio_tc[IXGBE_DCB_MAX_USER_PRIORITY] = { 0 }; /* Fail command if not in CEE mode */ if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE)) return ret; adapter->dcb_set_bitmap |= ixgbe_copy_dcb_cfg(adapter, IXGBE_DCB_MAX_TRAFFIC_CLASS); if (!adapter->dcb_set_bitmap) return ret; ixgbe_dcb_unpack_map_cee(dcb_cfg, IXGBE_DCB_TX_CONFIG, prio_tc); if (adapter->dcb_set_bitmap & (BIT_PG_TX | BIT_PG_RX)) { /* Priority to TC mapping in CEE case default to 1:1 */ int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; #ifdef HAVE_MQPRIO int i; #endif #ifdef IXGBE_FCOE if (adapter->netdev->features & NETIF_F_FCOE_MTU) max_frame = max(max_frame, IXGBE_FCOE_JUMBO_FRAME_SIZE); #endif ixgbe_dcb_calculate_tc_credits_cee(hw, dcb_cfg, max_frame, IXGBE_DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits_cee(hw, dcb_cfg, max_frame, IXGBE_DCB_RX_CONFIG); ixgbe_dcb_hw_config_cee(hw, dcb_cfg); #ifdef HAVE_MQPRIO for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) netdev_set_prio_tc_map(netdev, i, prio_tc[i]); #endif /* HAVE_MQPRIO */ ret = DCB_HW_CHG_RST; } if (adapter->dcb_set_bitmap & BIT_PFC) { if (dcb_cfg->pfc_mode_enable) { u8 pfc_en; ixgbe_dcb_unpack_pfc_cee(dcb_cfg, prio_tc, &pfc_en); ixgbe_dcb_config_pfc(hw, pfc_en, prio_tc); } else { hw->mac.ops.fc_enable(hw); } ixgbe_set_rx_drop_en(adapter); if (ret != DCB_HW_CHG_RST) ret = DCB_HW_CHG; } #ifdef IXGBE_FCOE /* Reprogam FCoE hardware offloads when the traffic class * FCoE is using changes. This happens if the APP info * changes or the up2tc mapping is updated. */ if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { adapter->fcoe.up_set = adapter->fcoe.up; ixgbe_dcbnl_devreset(netdev); ret = DCB_HW_CHG_RST; } #endif /* IXGBE_FCOE */ adapter->dcb_set_bitmap = 0x00; return ret; }