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 int ixgbe_dcbnl_ieee_setets(struct net_device *dev, struct ieee_ets *ets) { struct ixgbe_adapter *adapter = netdev_priv(dev); int max_frame = dev->mtu + ETH_HLEN + ETH_FCS_LEN; int i, err = 0; __u8 max_tc = 0; __u8 map_chg = 0; if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)) return -EINVAL; if (!adapter->ixgbe_ieee_ets) { adapter->ixgbe_ieee_ets = kmalloc(sizeof(struct ieee_ets), GFP_KERNEL); if (!adapter->ixgbe_ieee_ets) return -ENOMEM; /* initialize UP2TC mappings to invalid value */ for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) adapter->ixgbe_ieee_ets->prio_tc[i] = IEEE_8021QAZ_MAX_TCS; /* if possible update UP2TC mappings from HW */ ixgbe_dcb_read_rtrup2tc(&adapter->hw, adapter->ixgbe_ieee_ets->prio_tc); } for (i = 0; i < IEEE_8021QAZ_MAX_TCS; i++) { if (ets->prio_tc[i] > max_tc) max_tc = ets->prio_tc[i]; if (ets->prio_tc[i] != adapter->ixgbe_ieee_ets->prio_tc[i]) map_chg = 1; } memcpy(adapter->ixgbe_ieee_ets, ets, sizeof(*adapter->ixgbe_ieee_ets)); 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)) err = ixgbe_setup_tc(dev, max_tc); else if (map_chg) ixgbe_dcbnl_devreset(dev); if (err) goto err_out; err = ixgbe_dcb_hw_ets(&adapter->hw, ets, max_frame); err_out: return err; }
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 /* IF default priority is being removed clear VF default UP */ if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && app->protocol == 0 && adapter->default_up == app->priority) { int vf; long unsigned int app_mask = dcb_ieee_getapp_mask(dev, app); int qos = app_mask ? find_first_bit(&app_mask, 8) : 0; adapter->default_up = qos; for (vf = 0; vf < adapter->num_vfs; vf++) { struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; if (!vfinfo->pf_qos) ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, qos, vf); } } return err; }
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 err; err = dcb_ieee_setapp(dev, app); if (err) return err; #ifdef IXGBE_FCOE if (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 /* VF devices should use default UP when available */ if (app->selector == IEEE_8021QAZ_APP_SEL_ETHERTYPE && app->protocol == 0) { int vf; adapter->default_up = app->priority; for (vf = 0; vf < adapter->num_vfs; vf++) { struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; if (!vfinfo->pf_qos) ixgbe_set_vmvir(adapter, vfinfo->pf_vlan, app->priority, vf); } } return 0; }
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; int i; /* 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, MAX_TRAFFIC_CLASS); if (!adapter->dcb_set_bitmap) return ret; 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_USER_PRIORITY]; int max_frame = adapter->netdev->mtu + ETH_HLEN + ETH_FCS_LEN; #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(hw, dcb_cfg, max_frame, DCB_TX_CONFIG); ixgbe_dcb_calculate_tc_credits(hw, dcb_cfg, max_frame, DCB_RX_CONFIG); ixgbe_dcb_unpack_refill(dcb_cfg, DCB_TX_CONFIG, refill); ixgbe_dcb_unpack_max(dcb_cfg, max); ixgbe_dcb_unpack_bwgid(dcb_cfg, DCB_TX_CONFIG, bwg_id); ixgbe_dcb_unpack_prio(dcb_cfg, DCB_TX_CONFIG, prio_type); ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); ixgbe_dcb_hw_ets_config(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]); ret = DCB_HW_CHG_RST; } if (adapter->dcb_set_bitmap & BIT_PFC) { if (dcb_cfg->pfc_mode_enable) { u8 pfc_en; u8 prio_tc[MAX_USER_PRIORITY]; ixgbe_dcb_unpack_map(dcb_cfg, DCB_TX_CONFIG, prio_tc); ixgbe_dcb_unpack_pfc(dcb_cfg, &pfc_en); ixgbe_dcb_hw_pfc_config(hw, pfc_en, prio_tc); } else { hw->mac.ops.fc_enable(hw); } ixgbe_set_rx_drop_en(adapter); 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) { struct dcb_app app = { .selector = DCB_APP_IDTYPE_ETHTYPE, .protocol = ETH_P_FCOE, }; u8 up = dcb_getapp(netdev, &app); adapter->fcoe.up = ffs(up) - 1; ixgbe_dcbnl_devreset(netdev); ret = DCB_HW_CHG_RST; } #endif adapter->dcb_set_bitmap = 0x00; return ret; }
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; }