Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says: ==================== 40GbE Intel Wired LAN Driver Updates 2016-12-07 This series contains updates to i40e and i40evf only. Filip modifies the i40e to log link speed change and when the link is brought up and down. Mitch replaces i40e_txd_use_count() with a new function which is slightly faster and better documented so the dim witted can better follow the code. Fixes the locking of the service task so that it is actually done in the service task and not in the scheduling function which calls the service task. Jacob, being the busy little beaver he is, provides most of the changes starting restores a workaround that is still needed in some configurations, specifically the Ethernet Controller XL710 for 40GbE QSFP+. Removes duplicate code and simplifies the i40e_vsi_add_vlan() and i40e_vsi_kill_vlan() functions. Removes detection of PTP frames over L4 (UDP) on the XL710 MAC, since there was a product decision to defeature it. Fixed a previous refactor of active filters which caused issues in the accounting of active_filters. Remaining work was done in the VLAN filters to improve readability and simplify code as much as possible to reduce inconsistencies. Alex fixes foul budget accounting in core code by returning actual work done, capped to budget-1. Henry fixes the "ethtool -p" function for 1G BaseT PHYs. Carolyn adds support for 25G devices for i40e and i40evf. Michal adds functions to apply the correct access method for external PHYs which could use Clause22 or Clause45 depending on the PHY. v2: dropped last patch from previous series, since changes are needed based on feedback from Sergei Shtylyov ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
63c36c40b9
|
@ -356,10 +356,11 @@ struct i40e_pf {
|
|||
#define I40E_FLAG_NO_DCB_SUPPORT BIT_ULL(45)
|
||||
#define I40E_FLAG_USE_SET_LLDP_MIB BIT_ULL(46)
|
||||
#define I40E_FLAG_STOP_FW_LLDP BIT_ULL(47)
|
||||
#define I40E_FLAG_HAVE_10GBASET_PHY BIT_ULL(48)
|
||||
#define I40E_FLAG_PHY_CONTROLS_LEDS BIT_ULL(48)
|
||||
#define I40E_FLAG_PF_MAC BIT_ULL(50)
|
||||
#define I40E_FLAG_TRUE_PROMISC_SUPPORT BIT_ULL(51)
|
||||
#define I40E_FLAG_HAVE_CRT_RETIMER BIT_ULL(52)
|
||||
#define I40E_FLAG_PTP_L4_CAPABLE BIT_ULL(53)
|
||||
|
||||
/* tracks features that get auto disabled by errors */
|
||||
u64 auto_disable_flags;
|
||||
|
@ -596,6 +597,7 @@ struct i40e_vsi {
|
|||
u16 veb_idx; /* index of VEB parent */
|
||||
struct kobject *kobj; /* sysfs object */
|
||||
bool current_isup; /* Sync 'link up' logging */
|
||||
enum i40e_aq_link_speed current_speed; /* Sync link speed logging */
|
||||
|
||||
void *priv; /* client driver data reference. */
|
||||
|
||||
|
@ -850,7 +852,9 @@ int i40e_open(struct net_device *netdev);
|
|||
int i40e_close(struct net_device *netdev);
|
||||
int i40e_vsi_open(struct i40e_vsi *vsi);
|
||||
void i40e_vlan_stripping_disable(struct i40e_vsi *vsi);
|
||||
int i40e_add_vlan_all_mac(struct i40e_vsi *vsi, s16 vid);
|
||||
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid);
|
||||
void i40e_rm_vlan_all_mac(struct i40e_vsi *vsi, s16 vid);
|
||||
void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid);
|
||||
struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi,
|
||||
const u8 *macaddr);
|
||||
|
|
|
@ -1642,6 +1642,10 @@ enum i40e_aq_phy_type {
|
|||
I40E_PHY_TYPE_1000BASE_LX = 0x1C,
|
||||
I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D,
|
||||
I40E_PHY_TYPE_20GBASE_KR2 = 0x1E,
|
||||
I40E_PHY_TYPE_25GBASE_KR = 0x1F,
|
||||
I40E_PHY_TYPE_25GBASE_CR = 0x20,
|
||||
I40E_PHY_TYPE_25GBASE_SR = 0x21,
|
||||
I40E_PHY_TYPE_25GBASE_LR = 0x22,
|
||||
I40E_PHY_TYPE_MAX
|
||||
};
|
||||
|
||||
|
@ -1650,6 +1654,7 @@ enum i40e_aq_phy_type {
|
|||
#define I40E_LINK_SPEED_10GB_SHIFT 0x3
|
||||
#define I40E_LINK_SPEED_40GB_SHIFT 0x4
|
||||
#define I40E_LINK_SPEED_20GB_SHIFT 0x5
|
||||
#define I40E_LINK_SPEED_25GB_SHIFT 0x6
|
||||
|
||||
enum i40e_aq_link_speed {
|
||||
I40E_LINK_SPEED_UNKNOWN = 0,
|
||||
|
@ -1657,7 +1662,8 @@ enum i40e_aq_link_speed {
|
|||
I40E_LINK_SPEED_1GB = BIT(I40E_LINK_SPEED_1000MB_SHIFT),
|
||||
I40E_LINK_SPEED_10GB = BIT(I40E_LINK_SPEED_10GB_SHIFT),
|
||||
I40E_LINK_SPEED_40GB = BIT(I40E_LINK_SPEED_40GB_SHIFT),
|
||||
I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT)
|
||||
I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT),
|
||||
I40E_LINK_SPEED_25GB = BIT(I40E_LINK_SPEED_25GB_SHIFT),
|
||||
};
|
||||
|
||||
struct i40e_aqc_module_desc {
|
||||
|
@ -1680,6 +1686,8 @@ struct i40e_aq_get_phy_abilities_resp {
|
|||
#define I40E_AQ_PHY_LINK_ENABLED 0x08
|
||||
#define I40E_AQ_PHY_AN_ENABLED 0x10
|
||||
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
|
||||
#define I40E_AQ_PHY_FEC_ABILITY_KR 0x40
|
||||
#define I40E_AQ_PHY_FEC_ABILITY_RS 0x80
|
||||
__le16 eee_capability;
|
||||
#define I40E_AQ_EEE_100BASE_TX 0x0002
|
||||
#define I40E_AQ_EEE_1000BASE_T 0x0004
|
||||
|
@ -1690,7 +1698,22 @@ struct i40e_aq_get_phy_abilities_resp {
|
|||
__le32 eeer_val;
|
||||
u8 d3_lpan;
|
||||
#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
|
||||
u8 reserved[3];
|
||||
u8 phy_type_ext;
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
|
||||
u8 fec_cfg_curr_mod_ext_info;
|
||||
#define I40E_AQ_ENABLE_FEC_KR 0x01
|
||||
#define I40E_AQ_ENABLE_FEC_RS 0x02
|
||||
#define I40E_AQ_REQUEST_FEC_KR 0x04
|
||||
#define I40E_AQ_REQUEST_FEC_RS 0x08
|
||||
#define I40E_AQ_ENABLE_FEC_AUTO 0x10
|
||||
#define I40E_AQ_FEC
|
||||
#define I40E_AQ_MODULE_TYPE_EXT_MASK 0xE0
|
||||
#define I40E_AQ_MODULE_TYPE_EXT_SHIFT 5
|
||||
|
||||
u8 ext_comp_code;
|
||||
u8 phy_id[4];
|
||||
u8 module_type[3];
|
||||
u8 qualified_module_count;
|
||||
|
@ -1712,7 +1735,20 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
|
|||
__le16 eee_capability;
|
||||
__le32 eeer;
|
||||
u8 low_power_ctrl;
|
||||
u8 reserved[3];
|
||||
u8 phy_type_ext;
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
|
||||
u8 fec_config;
|
||||
#define I40E_AQ_SET_FEC_ABILITY_KR BIT(0)
|
||||
#define I40E_AQ_SET_FEC_ABILITY_RS BIT(1)
|
||||
#define I40E_AQ_SET_FEC_REQUEST_KR BIT(2)
|
||||
#define I40E_AQ_SET_FEC_REQUEST_RS BIT(3)
|
||||
#define I40E_AQ_SET_FEC_AUTO BIT(4)
|
||||
#define I40E_AQ_PHY_FEC_CONFIG_SHIFT 0x0
|
||||
#define I40E_AQ_PHY_FEC_CONFIG_MASK (0x1F << I40E_AQ_PHY_FEC_CONFIG_SHIFT)
|
||||
u8 reserved;
|
||||
};
|
||||
|
||||
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
|
||||
|
@ -1792,9 +1828,18 @@ struct i40e_aqc_get_link_status {
|
|||
#define I40E_AQ_LINK_TX_DRAINED 0x01
|
||||
#define I40E_AQ_LINK_TX_FLUSHED 0x03
|
||||
#define I40E_AQ_LINK_FORCED_40G 0x10
|
||||
/* 25G Error Codes */
|
||||
#define I40E_AQ_25G_NO_ERR 0X00
|
||||
#define I40E_AQ_25G_NOT_PRESENT 0X01
|
||||
#define I40E_AQ_25G_NVM_CRC_ERR 0X02
|
||||
#define I40E_AQ_25G_SBUS_UCODE_ERR 0X03
|
||||
#define I40E_AQ_25G_SERDES_UCODE_ERR 0X04
|
||||
#define I40E_AQ_25G_NIMB_UCODE_ERR 0X05
|
||||
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
|
||||
__le16 max_frame_size;
|
||||
u8 config;
|
||||
#define I40E_AQ_CONFIG_FEC_KR_ENA 0x01
|
||||
#define I40E_AQ_CONFIG_FEC_RS_ENA 0x02
|
||||
#define I40E_AQ_CONFIG_CRC_ENA 0x04
|
||||
#define I40E_AQ_CONFIG_PACING_MASK 0x78
|
||||
u8 external_power_ability;
|
||||
|
|
|
@ -53,6 +53,8 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
|
|||
case I40E_DEV_ID_10G_BASE_T4:
|
||||
case I40E_DEV_ID_20G_KR2:
|
||||
case I40E_DEV_ID_20G_KR2_A:
|
||||
case I40E_DEV_ID_25G_B:
|
||||
case I40E_DEV_ID_25G_SFP28:
|
||||
hw->mac.type = I40E_MAC_XL710;
|
||||
break;
|
||||
case I40E_DEV_ID_KX_X722:
|
||||
|
@ -1183,6 +1185,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
|
|||
case I40E_PHY_TYPE_1000BASE_LX:
|
||||
case I40E_PHY_TYPE_40GBASE_SR4:
|
||||
case I40E_PHY_TYPE_40GBASE_LR4:
|
||||
case I40E_PHY_TYPE_25GBASE_LR:
|
||||
case I40E_PHY_TYPE_25GBASE_SR:
|
||||
media = I40E_MEDIA_TYPE_FIBER;
|
||||
break;
|
||||
case I40E_PHY_TYPE_100BASE_TX:
|
||||
|
@ -1197,6 +1201,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
|
|||
case I40E_PHY_TYPE_10GBASE_SFPP_CU:
|
||||
case I40E_PHY_TYPE_40GBASE_AOC:
|
||||
case I40E_PHY_TYPE_10GBASE_AOC:
|
||||
case I40E_PHY_TYPE_25GBASE_CR:
|
||||
media = I40E_MEDIA_TYPE_DA;
|
||||
break;
|
||||
case I40E_PHY_TYPE_1000BASE_KX:
|
||||
|
@ -1204,6 +1209,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
|
|||
case I40E_PHY_TYPE_10GBASE_KR:
|
||||
case I40E_PHY_TYPE_40GBASE_KR4:
|
||||
case I40E_PHY_TYPE_20GBASE_KR2:
|
||||
case I40E_PHY_TYPE_25GBASE_KR:
|
||||
media = I40E_MEDIA_TYPE_BACKPLANE;
|
||||
break;
|
||||
case I40E_PHY_TYPE_SGMII:
|
||||
|
@ -1608,8 +1614,10 @@ i40e_status i40e_aq_get_phy_capabilities(struct i40e_hw *hw,
|
|||
if (hw->aq.asq_last_status == I40E_AQ_RC_EIO)
|
||||
status = I40E_ERR_UNKNOWN_PHY;
|
||||
|
||||
if (report_init)
|
||||
if (report_init) {
|
||||
hw->phy.phy_types = le32_to_cpu(abilities->phy_type);
|
||||
hw->phy.phy_types |= ((u64)abilities->phy_type_ext << 32);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -1701,10 +1709,13 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures,
|
|||
config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
|
||||
/* Copy over all the old settings */
|
||||
config.phy_type = abilities.phy_type;
|
||||
config.phy_type_ext = abilities.phy_type_ext;
|
||||
config.link_speed = abilities.link_speed;
|
||||
config.eee_capability = abilities.eee_capability;
|
||||
config.eeer = abilities.eeer_val;
|
||||
config.low_power_ctrl = abilities.d3_lpan;
|
||||
config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
|
||||
I40E_AQ_PHY_FEC_CONFIG_MASK;
|
||||
status = i40e_aq_set_phy_config(hw, &config, NULL);
|
||||
|
||||
if (status)
|
||||
|
@ -4664,6 +4675,78 @@ phy_write_end:
|
|||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_write_phy_register
|
||||
* @hw: pointer to the HW structure
|
||||
* @page: registers page number
|
||||
* @reg: register address in the page
|
||||
* @phy_adr: PHY address on MDIO interface
|
||||
* @value: PHY register value
|
||||
*
|
||||
* Writes value to specified PHY register
|
||||
**/
|
||||
i40e_status i40e_write_phy_register(struct i40e_hw *hw,
|
||||
u8 page, u16 reg, u8 phy_addr, u16 value)
|
||||
{
|
||||
i40e_status status;
|
||||
|
||||
switch (hw->device_id) {
|
||||
case I40E_DEV_ID_1G_BASE_T_X722:
|
||||
status = i40e_write_phy_register_clause22(hw, reg, phy_addr,
|
||||
value);
|
||||
break;
|
||||
case I40E_DEV_ID_10G_BASE_T:
|
||||
case I40E_DEV_ID_10G_BASE_T4:
|
||||
case I40E_DEV_ID_10G_BASE_T_X722:
|
||||
case I40E_DEV_ID_25G_B:
|
||||
case I40E_DEV_ID_25G_SFP28:
|
||||
status = i40e_write_phy_register_clause45(hw, page, reg,
|
||||
phy_addr, value);
|
||||
break;
|
||||
default:
|
||||
status = I40E_ERR_UNKNOWN_PHY;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_read_phy_register
|
||||
* @hw: pointer to the HW structure
|
||||
* @page: registers page number
|
||||
* @reg: register address in the page
|
||||
* @phy_adr: PHY address on MDIO interface
|
||||
* @value: PHY register value
|
||||
*
|
||||
* Reads specified PHY register value
|
||||
**/
|
||||
i40e_status i40e_read_phy_register(struct i40e_hw *hw,
|
||||
u8 page, u16 reg, u8 phy_addr, u16 *value)
|
||||
{
|
||||
i40e_status status;
|
||||
|
||||
switch (hw->device_id) {
|
||||
case I40E_DEV_ID_1G_BASE_T_X722:
|
||||
status = i40e_read_phy_register_clause22(hw, reg, phy_addr,
|
||||
value);
|
||||
break;
|
||||
case I40E_DEV_ID_10G_BASE_T:
|
||||
case I40E_DEV_ID_10G_BASE_T4:
|
||||
case I40E_DEV_ID_10G_BASE_T_X722:
|
||||
case I40E_DEV_ID_25G_B:
|
||||
case I40E_DEV_ID_25G_SFP28:
|
||||
status = i40e_read_phy_register_clause45(hw, page, reg,
|
||||
phy_addr, value);
|
||||
break;
|
||||
default:
|
||||
status = I40E_ERR_UNKNOWN_PHY;
|
||||
break;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_get_phy_address
|
||||
* @hw: pointer to the HW structure
|
||||
|
|
|
@ -172,7 +172,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
|
|||
f->macaddr, f->vlan,
|
||||
i40e_filter_state_string[f->state]);
|
||||
}
|
||||
dev_info(&pf->pdev->dev, " active_filters %d, promisc_threshold %d, overflow promisc %s\n",
|
||||
dev_info(&pf->pdev->dev, " active_filters %u, promisc_threshold %u, overflow promisc %s\n",
|
||||
vsi->active_filters, vsi->promisc_threshold,
|
||||
(test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state) ?
|
||||
"ON" : "OFF"));
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#define I40E_DEV_ID_20G_KR2 0x1587
|
||||
#define I40E_DEV_ID_20G_KR2_A 0x1588
|
||||
#define I40E_DEV_ID_10G_BASE_T4 0x1589
|
||||
#define I40E_DEV_ID_25G_B 0x158A
|
||||
#define I40E_DEV_ID_25G_SFP28 0x158B
|
||||
#define I40E_DEV_ID_KX_X722 0x37CE
|
||||
#define I40E_DEV_ID_QSFP_X722 0x37CF
|
||||
#define I40E_DEV_ID_SFP_X722 0x37D0
|
||||
|
|
|
@ -265,8 +265,9 @@ static void i40e_partition_setting_complaint(struct i40e_pf *pf)
|
|||
static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
|
||||
u32 *advertising)
|
||||
{
|
||||
enum i40e_aq_capabilities_phy_type phy_types = pf->hw.phy.phy_types;
|
||||
struct i40e_link_status *hw_link_info = &pf->hw.phy.link_info;
|
||||
u64 phy_types = pf->hw.phy.phy_types;
|
||||
|
||||
*supported = 0x0;
|
||||
*advertising = 0x0;
|
||||
|
||||
|
@ -369,6 +370,13 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, u32 *supported,
|
|||
if (!(pf->flags & I40E_FLAG_HAVE_CRT_RETIMER))
|
||||
*advertising |= ADVERTISED_1000baseKX_Full;
|
||||
}
|
||||
if (phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR ||
|
||||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR ||
|
||||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_SR ||
|
||||
phy_types & I40E_CAP_PHY_TYPE_25GBASE_LR) {
|
||||
*supported |= SUPPORTED_Autoneg;
|
||||
*advertising |= ADVERTISED_Autoneg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -491,6 +499,14 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
|
|||
ADVERTISED_1000baseKX_Full |
|
||||
ADVERTISED_Autoneg;
|
||||
break;
|
||||
case I40E_PHY_TYPE_25GBASE_KR:
|
||||
case I40E_PHY_TYPE_25GBASE_CR:
|
||||
case I40E_PHY_TYPE_25GBASE_SR:
|
||||
case I40E_PHY_TYPE_25GBASE_LR:
|
||||
ecmd->supported = SUPPORTED_Autoneg;
|
||||
ecmd->advertising = ADVERTISED_Autoneg;
|
||||
/* TODO: add speeds when ethtool is ready to support*/
|
||||
break;
|
||||
default:
|
||||
/* if we got here and link is up something bad is afoot */
|
||||
netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
|
||||
|
@ -512,6 +528,14 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
|
|||
case I40E_LINK_SPEED_40GB:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_40000);
|
||||
break;
|
||||
case I40E_LINK_SPEED_25GB:
|
||||
#ifdef SPEED_25000
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_25000);
|
||||
#else
|
||||
netdev_info(netdev,
|
||||
"Speed is 25G, display not supported by this version of ethtool.\n");
|
||||
#endif
|
||||
break;
|
||||
case I40E_LINK_SPEED_20GB:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_20000);
|
||||
break;
|
||||
|
@ -1657,8 +1681,19 @@ static int i40e_get_ts_info(struct net_device *dev,
|
|||
info->tx_types = BIT(HWTSTAMP_TX_OFF) | BIT(HWTSTAMP_TX_ON);
|
||||
|
||||
info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V1_L4_EVENT) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_EVENT);
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ);
|
||||
|
||||
if (pf->flags & I40E_FLAG_PTP_L4_CAPABLE)
|
||||
info->rx_filters |= BIT(HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
|
||||
BIT(HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1890,7 +1925,7 @@ static int i40e_set_phys_id(struct net_device *netdev,
|
|||
|
||||
switch (state) {
|
||||
case ETHTOOL_ID_ACTIVE:
|
||||
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
|
||||
if (!(pf->flags & I40E_FLAG_PHY_CONTROLS_LEDS)) {
|
||||
pf->led_status = i40e_led_get(hw);
|
||||
} else {
|
||||
i40e_aq_set_phy_debug(hw, I40E_PHY_DEBUG_ALL, NULL);
|
||||
|
@ -1900,20 +1935,20 @@ static int i40e_set_phys_id(struct net_device *netdev,
|
|||
}
|
||||
return blink_freq;
|
||||
case ETHTOOL_ID_ON:
|
||||
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
|
||||
if (!(pf->flags & I40E_FLAG_PHY_CONTROLS_LEDS))
|
||||
i40e_led_set(hw, 0xf, false);
|
||||
else
|
||||
ret = i40e_led_set_phy(hw, true, pf->led_status, 0);
|
||||
break;
|
||||
case ETHTOOL_ID_OFF:
|
||||
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY))
|
||||
if (!(pf->flags & I40E_FLAG_PHY_CONTROLS_LEDS))
|
||||
i40e_led_set(hw, 0x0, false);
|
||||
else
|
||||
ret = i40e_led_set_phy(hw, false, pf->led_status, 0);
|
||||
break;
|
||||
case ETHTOOL_ID_INACTIVE:
|
||||
if (!(pf->flags & I40E_FLAG_HAVE_10GBASET_PHY)) {
|
||||
i40e_led_set(hw, false, pf->led_status);
|
||||
if (!(pf->flags & I40E_FLAG_PHY_CONTROLS_LEDS)) {
|
||||
i40e_led_set(hw, pf->led_status, false);
|
||||
} else {
|
||||
ret = i40e_led_set_phy(hw, false, pf->led_status,
|
||||
(pf->phy_led_val |
|
||||
|
|
|
@ -41,7 +41,7 @@ static const char i40e_driver_string[] =
|
|||
|
||||
#define DRV_VERSION_MAJOR 1
|
||||
#define DRV_VERSION_MINOR 6
|
||||
#define DRV_VERSION_BUILD 21
|
||||
#define DRV_VERSION_BUILD 25
|
||||
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
||||
__stringify(DRV_VERSION_MINOR) "." \
|
||||
__stringify(DRV_VERSION_BUILD) DRV_KERN
|
||||
|
@ -86,6 +86,8 @@ static const struct pci_device_id i40e_pci_tbl[] = {
|
|||
{PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_I_X722), 0},
|
||||
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2), 0},
|
||||
{PCI_VDEVICE(INTEL, I40E_DEV_ID_20G_KR2_A), 0},
|
||||
{PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_B), 0},
|
||||
{PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_SFP28), 0},
|
||||
/* required last entry */
|
||||
{0, }
|
||||
};
|
||||
|
@ -286,8 +288,7 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
|
|||
void i40e_service_event_schedule(struct i40e_pf *pf)
|
||||
{
|
||||
if (!test_bit(__I40E_DOWN, &pf->state) &&
|
||||
!test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state) &&
|
||||
!test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
|
||||
!test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state))
|
||||
queue_work(i40e_wq, &pf->service_task);
|
||||
}
|
||||
|
||||
|
@ -1225,6 +1226,140 @@ bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi)
|
|||
return vsi->has_vlan_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_correct_mac_vlan_filters - Correct non-VLAN filters if necessary
|
||||
* @vsi: the VSI to configure
|
||||
* @tmp_add_list: list of filters ready to be added
|
||||
* @tmp_del_list: list of filters ready to be deleted
|
||||
* @vlan_filters: the number of active VLAN filters
|
||||
*
|
||||
* Update VLAN=0 and VLAN=-1 (I40E_VLAN_ANY) filters properly so that they
|
||||
* behave as expected. If we have any active VLAN filters remaining or about
|
||||
* to be added then we need to update non-VLAN filters to be marked as VLAN=0
|
||||
* so that they only match against untagged traffic. If we no longer have any
|
||||
* active VLAN filters, we need to make all non-VLAN filters marked as VLAN=-1
|
||||
* so that they match against both tagged and untagged traffic. In this way,
|
||||
* we ensure that we correctly receive the desired traffic. This ensures that
|
||||
* when we have an active VLAN we will receive only untagged traffic and
|
||||
* traffic matching active VLANs. If we have no active VLANs then we will
|
||||
* operate in non-VLAN mode and receive all traffic, tagged or untagged.
|
||||
*
|
||||
* Finally, in a similar fashion, this function also corrects filters when
|
||||
* there is an active PVID assigned to this VSI.
|
||||
*
|
||||
* In case of memory allocation failure return -ENOMEM. Otherwise, return 0.
|
||||
*
|
||||
* This function is only expected to be called from within
|
||||
* i40e_sync_vsi_filters.
|
||||
*
|
||||
* NOTE: This function expects to be called while under the
|
||||
* mac_filter_hash_lock
|
||||
*/
|
||||
static int i40e_correct_mac_vlan_filters(struct i40e_vsi *vsi,
|
||||
struct hlist_head *tmp_add_list,
|
||||
struct hlist_head *tmp_del_list,
|
||||
int vlan_filters)
|
||||
{
|
||||
struct i40e_mac_filter *f, *add_head;
|
||||
struct hlist_node *h;
|
||||
int bkt, new_vlan;
|
||||
|
||||
/* To determine if a particular filter needs to be replaced we
|
||||
* have the three following conditions:
|
||||
*
|
||||
* a) if we have a PVID assigned, then all filters which are
|
||||
* not marked as VLAN=PVID must be replaced with filters that
|
||||
* are.
|
||||
* b) otherwise, if we have any active VLANS, all filters
|
||||
* which are marked as VLAN=-1 must be replaced with
|
||||
* filters marked as VLAN=0
|
||||
* c) finally, if we do not have any active VLANS, all filters
|
||||
* which are marked as VLAN=0 must be replaced with filters
|
||||
* marked as VLAN=-1
|
||||
*/
|
||||
|
||||
/* Update the filters about to be added in place */
|
||||
hlist_for_each_entry(f, tmp_add_list, hlist) {
|
||||
if (vsi->info.pvid && f->vlan != vsi->info.pvid)
|
||||
f->vlan = vsi->info.pvid;
|
||||
else if (vlan_filters && f->vlan == I40E_VLAN_ANY)
|
||||
f->vlan = 0;
|
||||
else if (!vlan_filters && f->vlan == 0)
|
||||
f->vlan = I40E_VLAN_ANY;
|
||||
}
|
||||
|
||||
/* Update the remaining active filters */
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
|
||||
/* Combine the checks for whether a filter needs to be changed
|
||||
* and then determine the new VLAN inside the if block, in
|
||||
* order to avoid duplicating code for adding the new filter
|
||||
* then deleting the old filter.
|
||||
*/
|
||||
if ((vsi->info.pvid && f->vlan != vsi->info.pvid) ||
|
||||
(vlan_filters && f->vlan == I40E_VLAN_ANY) ||
|
||||
(!vlan_filters && f->vlan == 0)) {
|
||||
/* Determine the new vlan we will be adding */
|
||||
if (vsi->info.pvid)
|
||||
new_vlan = vsi->info.pvid;
|
||||
else if (vlan_filters)
|
||||
new_vlan = 0;
|
||||
else
|
||||
new_vlan = I40E_VLAN_ANY;
|
||||
|
||||
/* Create the new filter */
|
||||
add_head = i40e_add_filter(vsi, f->macaddr, new_vlan);
|
||||
if (!add_head)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Put the replacement filter into the add list */
|
||||
hash_del(&add_head->hlist);
|
||||
hlist_add_head(&add_head->hlist, tmp_add_list);
|
||||
|
||||
/* Put the original filter into the delete list */
|
||||
f->state = I40E_FILTER_REMOVE;
|
||||
hash_del(&f->hlist);
|
||||
hlist_add_head(&f->hlist, tmp_del_list);
|
||||
}
|
||||
}
|
||||
|
||||
vsi->has_vlan_filter = !!vlan_filters;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM
|
||||
* @vsi: the PF Main VSI - inappropriate for any other VSI
|
||||
* @macaddr: the MAC address
|
||||
*
|
||||
* Remove whatever filter the firmware set up so the driver can manage
|
||||
* its own filtering intelligently.
|
||||
**/
|
||||
static void i40e_rm_default_mac_filter(struct i40e_vsi *vsi, u8 *macaddr)
|
||||
{
|
||||
struct i40e_aqc_remove_macvlan_element_data element;
|
||||
struct i40e_pf *pf = vsi->back;
|
||||
|
||||
/* Only appropriate for the PF main VSI */
|
||||
if (vsi->type != I40E_VSI_MAIN)
|
||||
return;
|
||||
|
||||
memset(&element, 0, sizeof(element));
|
||||
ether_addr_copy(element.mac_addr, macaddr);
|
||||
element.vlan_tag = 0;
|
||||
/* Ignore error returns, some firmware does it this way... */
|
||||
element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH;
|
||||
i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL);
|
||||
|
||||
memset(&element, 0, sizeof(element));
|
||||
ether_addr_copy(element.mac_addr, macaddr);
|
||||
element.vlan_tag = 0;
|
||||
/* ...and some firmware does it this way. */
|
||||
element.flags = I40E_AQC_MACVLAN_DEL_PERFECT_MATCH |
|
||||
I40E_AQC_MACVLAN_DEL_IGNORE_VLAN;
|
||||
i40e_aq_remove_macvlan(&pf->hw, vsi->seid, &element, 1, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_add_filter - Add a mac/vlan filter to the VSI
|
||||
* @vsi: the VSI to be searched
|
||||
|
@ -1723,7 +1858,6 @@ static void i40e_undo_filter_entries(struct i40e_vsi *vsi,
|
|||
* @count: Number of filters added
|
||||
* @add_list: return data from fw
|
||||
* @head: pointer to first filter in current batch
|
||||
* @aq_err: status from fw
|
||||
*
|
||||
* MAC filter entries from list were slated to be added to device. Returns
|
||||
* number of successful filters. Note that 0 does NOT mean success!
|
||||
|
@ -1731,47 +1865,30 @@ static void i40e_undo_filter_entries(struct i40e_vsi *vsi,
|
|||
static int
|
||||
i40e_update_filter_state(int count,
|
||||
struct i40e_aqc_add_macvlan_element_data *add_list,
|
||||
struct i40e_mac_filter *add_head, int aq_err)
|
||||
struct i40e_mac_filter *add_head)
|
||||
{
|
||||
int retval = 0;
|
||||
int i;
|
||||
|
||||
|
||||
if (!aq_err) {
|
||||
retval = count;
|
||||
/* Everything's good, mark all filters active. */
|
||||
for (i = 0; i < count ; i++) {
|
||||
add_head->state = I40E_FILTER_ACTIVE;
|
||||
add_head = hlist_entry(add_head->hlist.next,
|
||||
typeof(struct i40e_mac_filter),
|
||||
hlist);
|
||||
}
|
||||
} else if (aq_err == I40E_AQ_RC_ENOSPC) {
|
||||
/* Device ran out of filter space. Check the return value
|
||||
* for each filter to see which ones are active.
|
||||
for (i = 0; i < count; i++) {
|
||||
/* Always check status of each filter. We don't need to check
|
||||
* the firmware return status because we pre-set the filter
|
||||
* status to I40E_AQC_MM_ERR_NO_RES when sending the filter
|
||||
* request to the adminq. Thus, if it no longer matches then
|
||||
* we know the filter is active.
|
||||
*/
|
||||
for (i = 0; i < count ; i++) {
|
||||
if (add_list[i].match_method ==
|
||||
I40E_AQC_MM_ERR_NO_RES) {
|
||||
add_head->state = I40E_FILTER_FAILED;
|
||||
} else {
|
||||
add_head->state = I40E_FILTER_ACTIVE;
|
||||
retval++;
|
||||
}
|
||||
add_head = hlist_entry(add_head->hlist.next,
|
||||
typeof(struct i40e_mac_filter),
|
||||
hlist);
|
||||
}
|
||||
} else {
|
||||
/* Some other horrible thing happened, fail all filters */
|
||||
retval = 0;
|
||||
for (i = 0; i < count ; i++) {
|
||||
if (add_list[i].match_method == I40E_AQC_MM_ERR_NO_RES) {
|
||||
add_head->state = I40E_FILTER_FAILED;
|
||||
add_head = hlist_entry(add_head->hlist.next,
|
||||
typeof(struct i40e_mac_filter),
|
||||
hlist);
|
||||
} else {
|
||||
add_head->state = I40E_FILTER_ACTIVE;
|
||||
retval++;
|
||||
}
|
||||
|
||||
add_head = hlist_entry(add_head->hlist.next,
|
||||
typeof(struct i40e_mac_filter),
|
||||
hlist);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -1830,18 +1947,15 @@ void i40e_aqc_add_filters(struct i40e_vsi *vsi, const char *vsi_name,
|
|||
int num_add, bool *promisc_changed)
|
||||
{
|
||||
struct i40e_hw *hw = &vsi->back->hw;
|
||||
i40e_status aq_ret;
|
||||
int aq_err, fcnt;
|
||||
|
||||
aq_ret = i40e_aq_add_macvlan(hw, vsi->seid, list, num_add, NULL);
|
||||
i40e_aq_add_macvlan(hw, vsi->seid, list, num_add, NULL);
|
||||
aq_err = hw->aq.asq_last_status;
|
||||
fcnt = i40e_update_filter_state(num_add, list, add_head, aq_ret);
|
||||
vsi->active_filters += fcnt;
|
||||
fcnt = i40e_update_filter_state(num_add, list, add_head);
|
||||
|
||||
if (fcnt != num_add) {
|
||||
*promisc_changed = true;
|
||||
set_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
|
||||
vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
|
||||
dev_warn(&vsi->back->pdev->dev,
|
||||
"Error %s adding RX filters on %s, promiscuous mode forced on\n",
|
||||
i40e_aq_str(hw, aq_err),
|
||||
|
@ -1903,8 +2017,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
struct hlist_head tmp_add_list, tmp_del_list;
|
||||
struct i40e_mac_filter *f, *add_head = NULL;
|
||||
struct i40e_hw *hw = &vsi->back->hw;
|
||||
unsigned int vlan_any_filters = 0;
|
||||
unsigned int non_vlan_filters = 0;
|
||||
unsigned int failed_filters = 0;
|
||||
unsigned int vlan_filters = 0;
|
||||
bool promisc_changed = false;
|
||||
char vsi_name[16] = "PF";
|
||||
|
@ -1951,7 +2064,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
/* Move the element into temporary del_list */
|
||||
hash_del(&f->hlist);
|
||||
hlist_add_head(&f->hlist, &tmp_del_list);
|
||||
vsi->active_filters--;
|
||||
|
||||
/* Avoid counting removed filters */
|
||||
continue;
|
||||
|
@ -1961,67 +2073,21 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
hlist_add_head(&f->hlist, &tmp_add_list);
|
||||
}
|
||||
|
||||
/* Count the number of each type of filter we have
|
||||
* remaining, ignoring any filters we're about to
|
||||
* delete.
|
||||
/* Count the number of active (current and new) VLAN
|
||||
* filters we have now. Does not count filters which
|
||||
* are marked for deletion.
|
||||
*/
|
||||
if (f->vlan > 0)
|
||||
vlan_filters++;
|
||||
else if (!f->vlan)
|
||||
non_vlan_filters++;
|
||||
else
|
||||
vlan_any_filters++;
|
||||
}
|
||||
|
||||
/* We should never have VLAN=-1 filters at the same time as we
|
||||
* have either VLAN=0 or VLAN>0 filters, so warn about this
|
||||
* case here to help catch any issues.
|
||||
*/
|
||||
WARN_ON(vlan_any_filters && (vlan_filters + non_vlan_filters));
|
||||
retval = i40e_correct_mac_vlan_filters(vsi,
|
||||
&tmp_add_list,
|
||||
&tmp_del_list,
|
||||
vlan_filters);
|
||||
if (retval)
|
||||
goto err_no_memory_locked;
|
||||
|
||||
/* If we only have VLAN=0 filters remaining, and don't have
|
||||
* any other VLAN filters, we need to convert these VLAN=0
|
||||
* filters into VLAN=-1 (I40E_VLAN_ANY) so that we operate
|
||||
* correctly in non-VLAN mode and receive all traffic tagged
|
||||
* or untagged.
|
||||
*/
|
||||
if (non_vlan_filters && !vlan_filters) {
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f,
|
||||
hlist) {
|
||||
/* Only replace VLAN=0 filters */
|
||||
if (f->vlan)
|
||||
continue;
|
||||
|
||||
/* Allocate a replacement element */
|
||||
add_head = kzalloc(sizeof(*add_head),
|
||||
GFP_KERNEL);
|
||||
if (!add_head)
|
||||
goto err_no_memory_locked;
|
||||
|
||||
/* Copy the filter, with new state and VLAN */
|
||||
*add_head = *f;
|
||||
add_head->state = I40E_FILTER_NEW;
|
||||
add_head->vlan = I40E_VLAN_ANY;
|
||||
|
||||
/* Move the replacement to the add list */
|
||||
INIT_HLIST_NODE(&add_head->hlist);
|
||||
hlist_add_head(&add_head->hlist,
|
||||
&tmp_add_list);
|
||||
|
||||
/* Move the original to the delete list */
|
||||
f->state = I40E_FILTER_REMOVE;
|
||||
hash_del(&f->hlist);
|
||||
hlist_add_head(&f->hlist, &tmp_del_list);
|
||||
vsi->active_filters--;
|
||||
}
|
||||
|
||||
/* Also update any filters on the tmp_add list */
|
||||
hlist_for_each_entry(f, &tmp_add_list, hlist) {
|
||||
if (!f->vlan)
|
||||
f->vlan = I40E_VLAN_ANY;
|
||||
}
|
||||
add_head = NULL;
|
||||
}
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
}
|
||||
|
||||
|
@ -2086,14 +2152,6 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
del_list = NULL;
|
||||
}
|
||||
|
||||
/* After finishing notifying firmware of the deleted filters, update
|
||||
* the cached value of vsi->has_vlan_filter. Note that we are safe to
|
||||
* use just !!vlan_filters here because if we only have VLAN=0 (that
|
||||
* is, non_vlan_filters) these will all be converted to VLAN=-1 in the
|
||||
* logic above already so this value would still be correct.
|
||||
*/
|
||||
vsi->has_vlan_filter = !!vlan_filters;
|
||||
|
||||
if (!hlist_empty(&tmp_add_list)) {
|
||||
/* Do all the adds now. */
|
||||
filter_list_len = hw->aq.asq_buf_size /
|
||||
|
@ -2137,6 +2195,9 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
cpu_to_le16((u16)(f->vlan));
|
||||
}
|
||||
add_list[num_add].queue_number = 0;
|
||||
/* set invalid match method for later detection */
|
||||
add_list[num_add].match_method =
|
||||
cpu_to_le16((u16)I40E_AQC_MM_ERR_NO_RES);
|
||||
cmd_flags |= I40E_AQC_MACVLAN_ADD_PERFECT_MATCH;
|
||||
add_list[num_add].flags = cpu_to_le16(cmd_flags);
|
||||
num_add++;
|
||||
|
@ -2169,27 +2230,36 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
|
|||
add_list = NULL;
|
||||
}
|
||||
|
||||
/* Check to see if we can drop out of overflow promiscuous mode. */
|
||||
/* Determine the number of active and failed filters. */
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
vsi->active_filters = 0;
|
||||
hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
|
||||
if (f->state == I40E_FILTER_ACTIVE)
|
||||
vsi->active_filters++;
|
||||
else if (f->state == I40E_FILTER_FAILED)
|
||||
failed_filters++;
|
||||
}
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
/* If promiscuous mode has changed, we need to calculate a new
|
||||
* threshold for when we are safe to exit
|
||||
*/
|
||||
if (promisc_changed)
|
||||
vsi->promisc_threshold = (vsi->active_filters * 3) / 4;
|
||||
|
||||
/* Check if we are able to exit overflow promiscuous mode. We can
|
||||
* safely exit if we didn't just enter, we no longer have any failed
|
||||
* filters, and we have reduced filters below the threshold value.
|
||||
*/
|
||||
if (test_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state) &&
|
||||
!promisc_changed && !failed_filters &&
|
||||
(vsi->active_filters < vsi->promisc_threshold)) {
|
||||
int failed_count = 0;
|
||||
/* See if we have any failed filters. We can't drop out of
|
||||
* promiscuous until these have all been deleted.
|
||||
*/
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
hash_for_each(vsi->mac_filter_hash, bkt, f, hlist) {
|
||||
if (f->state == I40E_FILTER_FAILED)
|
||||
failed_count++;
|
||||
}
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
if (!failed_count) {
|
||||
dev_info(&pf->pdev->dev,
|
||||
"filter logjam cleared on %s, leaving overflow promiscuous mode\n",
|
||||
vsi_name);
|
||||
clear_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
|
||||
promisc_changed = true;
|
||||
vsi->promisc_threshold = 0;
|
||||
}
|
||||
dev_info(&pf->pdev->dev,
|
||||
"filter logjam cleared on %s, leaving overflow promiscuous mode\n",
|
||||
vsi_name);
|
||||
clear_bit(__I40E_FILTER_OVERFLOW_PROMISC, &vsi->state);
|
||||
promisc_changed = true;
|
||||
vsi->promisc_threshold = 0;
|
||||
}
|
||||
|
||||
/* if the VF is not trusted do not do promisc */
|
||||
|
@ -2469,30 +2539,24 @@ static void i40e_vlan_rx_register(struct net_device *netdev, u32 features)
|
|||
}
|
||||
|
||||
/**
|
||||
* i40e_vsi_add_vlan - Add vsi membership for given vlan
|
||||
* i40e_add_vlan_all_mac - Add a MAC/VLAN filter for each existing MAC address
|
||||
* @vsi: the vsi being configured
|
||||
* @vid: vlan id to be added (0 = untagged only , -1 = any)
|
||||
*
|
||||
* This is a helper function for adding a new MAC/VLAN filter with the
|
||||
* specified VLAN for each existing MAC address already in the hash table.
|
||||
* This function does *not* perform any accounting to update filters based on
|
||||
* VLAN mode.
|
||||
*
|
||||
* NOTE: this function expects to be called while under the
|
||||
* mac_filter_hash_lock
|
||||
**/
|
||||
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
|
||||
int i40e_add_vlan_all_mac(struct i40e_vsi *vsi, s16 vid)
|
||||
{
|
||||
struct i40e_mac_filter *f, *add_f, *del_f;
|
||||
struct i40e_mac_filter *f, *add_f;
|
||||
struct hlist_node *h;
|
||||
int bkt;
|
||||
|
||||
/* Locked once because all functions invoked below iterates list*/
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
if (vsi->netdev) {
|
||||
add_f = i40e_add_filter(vsi, vsi->netdev->dev_addr, vid);
|
||||
if (!add_f) {
|
||||
dev_info(&vsi->back->pdev->dev,
|
||||
"Could not add vlan filter %d for %pM\n",
|
||||
vid, vsi->netdev->dev_addr);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
|
||||
if (f->state == I40E_FILTER_REMOVE)
|
||||
continue;
|
||||
|
@ -2501,54 +2565,28 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
|
|||
dev_info(&vsi->back->pdev->dev,
|
||||
"Could not add vlan filter %d for %pM\n",
|
||||
vid, f->macaddr);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now if we add a vlan tag, make sure to check if it is the first
|
||||
* tag (i.e. a "tag" -1 does exist) and if so replace the -1 "tag"
|
||||
* with 0, so we now accept untagged and specified tagged traffic
|
||||
* (and not all tags along with untagged)
|
||||
*/
|
||||
if (vid > 0 && vsi->netdev) {
|
||||
del_f = i40e_find_filter(vsi, vsi->netdev->dev_addr,
|
||||
I40E_VLAN_ANY);
|
||||
if (del_f) {
|
||||
__i40e_del_filter(vsi, del_f);
|
||||
add_f = i40e_add_filter(vsi, vsi->netdev->dev_addr, 0);
|
||||
if (!add_f) {
|
||||
dev_info(&vsi->back->pdev->dev,
|
||||
"Could not add filter 0 for %pM\n",
|
||||
vsi->netdev->dev_addr);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do not assume that I40E_VLAN_ANY should be reset to VLAN 0 */
|
||||
if (vid > 0 && !vsi->info.pvid) {
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
|
||||
if (f->state == I40E_FILTER_REMOVE)
|
||||
continue;
|
||||
del_f = i40e_find_filter(vsi, f->macaddr,
|
||||
I40E_VLAN_ANY);
|
||||
if (!del_f)
|
||||
continue;
|
||||
__i40e_del_filter(vsi, del_f);
|
||||
add_f = i40e_add_filter(vsi, f->macaddr, 0);
|
||||
if (!add_f) {
|
||||
dev_info(&vsi->back->pdev->dev,
|
||||
"Could not add filter 0 for %pM\n",
|
||||
f->macaddr);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* i40e_vsi_add_vlan - Add VSI membership for given VLAN
|
||||
* @vsi: the VSI being configured
|
||||
* @vid: VLAN id to be added (0 = untagged only , -1 = any)
|
||||
**/
|
||||
int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Locked once because all functions invoked below iterates list*/
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
err = i40e_add_vlan_all_mac(vsi, vid);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* schedule our worker thread which will take care of
|
||||
* applying the new filter changes
|
||||
|
@ -2558,28 +2596,39 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid)
|
|||
}
|
||||
|
||||
/**
|
||||
* i40e_vsi_kill_vlan - Remove vsi membership for given vlan
|
||||
* i40e_rm_vlan_all_mac - Remove MAC/VLAN pair for all MAC with the given VLAN
|
||||
* @vsi: the vsi being configured
|
||||
* @vid: vlan id to be removed (0 = untagged only , -1 = any)
|
||||
**/
|
||||
void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
|
||||
*
|
||||
* This function should be used to remove all VLAN filters which match the
|
||||
* given VID. It does not schedule the service event and does not take the
|
||||
* mac_filter_hash_lock so it may be combined with other operations under
|
||||
* a single invocation of the mac_filter_hash_lock.
|
||||
*
|
||||
* NOTE: this function expects to be called while under the
|
||||
* mac_filter_hash_lock
|
||||
*/
|
||||
void i40e_rm_vlan_all_mac(struct i40e_vsi *vsi, s16 vid)
|
||||
{
|
||||
struct net_device *netdev = vsi->netdev;
|
||||
struct i40e_mac_filter *f;
|
||||
struct hlist_node *h;
|
||||
int bkt;
|
||||
|
||||
/* Locked once because all functions invoked below iterates list */
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
if (vsi->netdev)
|
||||
i40e_del_filter(vsi, netdev->dev_addr, vid);
|
||||
|
||||
hash_for_each_safe(vsi->mac_filter_hash, bkt, h, f, hlist) {
|
||||
if (f->vlan == vid)
|
||||
__i40e_del_filter(vsi, f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_vsi_kill_vlan - Remove VSI membership for given VLAN
|
||||
* @vsi: the VSI being configured
|
||||
* @vid: VLAN id to be removed (0 = untagged only , -1 = any)
|
||||
**/
|
||||
void i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid)
|
||||
{
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
i40e_rm_vlan_all_mac(vsi, vid);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
/* schedule our worker thread which will take care of
|
||||
|
@ -5225,12 +5274,16 @@ out:
|
|||
*/
|
||||
void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
|
||||
{
|
||||
enum i40e_aq_link_speed new_speed;
|
||||
char *speed = "Unknown";
|
||||
char *fc = "Unknown";
|
||||
|
||||
if (vsi->current_isup == isup)
|
||||
new_speed = vsi->back->hw.phy.link_info.link_speed;
|
||||
|
||||
if ((vsi->current_isup == isup) && (vsi->current_speed == new_speed))
|
||||
return;
|
||||
vsi->current_isup = isup;
|
||||
vsi->current_speed = new_speed;
|
||||
if (!isup) {
|
||||
netdev_info(vsi->netdev, "NIC Link is Down\n");
|
||||
return;
|
||||
|
@ -5252,6 +5305,9 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
|
|||
case I40E_LINK_SPEED_20GB:
|
||||
speed = "20 G";
|
||||
break;
|
||||
case I40E_LINK_SPEED_25GB:
|
||||
speed = "25 G";
|
||||
break;
|
||||
case I40E_LINK_SPEED_10GB:
|
||||
speed = "10 G";
|
||||
break;
|
||||
|
@ -5941,19 +5997,6 @@ static void i40e_handle_lan_overflow_event(struct i40e_pf *pf,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_service_event_complete - Finish up the service event
|
||||
* @pf: board private structure
|
||||
**/
|
||||
static void i40e_service_event_complete(struct i40e_pf *pf)
|
||||
{
|
||||
WARN_ON(!test_bit(__I40E_SERVICE_SCHED, &pf->state));
|
||||
|
||||
/* flush memory to make sure state is correct before next watchog */
|
||||
smp_mb__before_atomic();
|
||||
clear_bit(__I40E_SERVICE_SCHED, &pf->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_get_cur_guaranteed_fd_count - Get the consumed guaranteed FD filters
|
||||
* @pf: board private structure
|
||||
|
@ -7263,10 +7306,12 @@ static void i40e_service_task(struct work_struct *work)
|
|||
|
||||
/* don't bother with service tasks if a reset is in progress */
|
||||
if (test_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state)) {
|
||||
i40e_service_event_complete(pf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (test_and_set_bit(__I40E_SERVICE_SCHED, &pf->state))
|
||||
return;
|
||||
|
||||
i40e_detect_recover_hung(pf);
|
||||
i40e_sync_filters_subtask(pf);
|
||||
i40e_reset_subtask(pf);
|
||||
|
@ -7279,7 +7324,9 @@ static void i40e_service_task(struct work_struct *work)
|
|||
i40e_sync_udp_filters_subtask(pf);
|
||||
i40e_clean_adminq_subtask(pf);
|
||||
|
||||
i40e_service_event_complete(pf);
|
||||
/* flush memory to make sure state is correct before next watchdog */
|
||||
smp_mb__before_atomic();
|
||||
clear_bit(__I40E_SERVICE_SCHED, &pf->state);
|
||||
|
||||
/* If the tasks have taken longer than one timer cycle or there
|
||||
* is more work to be done, reschedule the service task now
|
||||
|
@ -8696,7 +8743,8 @@ static int i40e_sw_init(struct i40e_pf *pf)
|
|||
I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE |
|
||||
I40E_FLAG_NO_PCI_LINK_CHECK |
|
||||
I40E_FLAG_USE_SET_LLDP_MIB |
|
||||
I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
|
||||
I40E_FLAG_GENEVE_OFFLOAD_CAPABLE |
|
||||
I40E_FLAG_PTP_L4_CAPABLE;
|
||||
} else if ((pf->hw.aq.api_maj_ver > 1) ||
|
||||
((pf->hw.aq.api_maj_ver == 1) &&
|
||||
(pf->hw.aq.api_min_ver > 4))) {
|
||||
|
@ -9291,6 +9339,12 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
|
|||
if (vsi->type == I40E_VSI_MAIN) {
|
||||
SET_NETDEV_DEV(netdev, &pf->pdev->dev);
|
||||
ether_addr_copy(mac_addr, hw->mac.perm_addr);
|
||||
/* The following steps are necessary to prevent reception
|
||||
* of tagged packets - some older NVM configurations load a
|
||||
* default a MAC-VLAN filter that accepts any tagged packet
|
||||
* which must be replaced by a normal filter.
|
||||
*/
|
||||
i40e_rm_default_mac_filter(vsi, mac_addr);
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
i40e_add_filter(vsi, mac_addr, I40E_VLAN_ANY);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
@ -9824,6 +9878,8 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
|
|||
pf->vsi[pf->lan_vsi]->tc_config.enabled_tc = 0;
|
||||
pf->vsi[pf->lan_vsi]->seid = pf->main_vsi_seid;
|
||||
i40e_vsi_config_tc(pf->vsi[pf->lan_vsi], enabled_tc);
|
||||
if (vsi->type == I40E_VSI_MAIN)
|
||||
i40e_rm_default_mac_filter(vsi, pf->hw.mac.perm_addr);
|
||||
|
||||
/* assign it some queues */
|
||||
ret = i40e_alloc_rings(vsi);
|
||||
|
@ -11352,7 +11408,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
dev_dbg(&pf->pdev->dev, "get supported phy types ret = %s last_status = %s\n",
|
||||
i40e_stat_str(&pf->hw, err),
|
||||
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
|
||||
pf->hw.phy.phy_types = le32_to_cpu(abilities.phy_type);
|
||||
|
||||
/* Add a filter to drop all Flow control frames from any VSI from being
|
||||
* transmitted. By doing so we stop a malicious VF from sending out
|
||||
|
@ -11364,8 +11419,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
pf->main_vsi_seid);
|
||||
|
||||
if ((pf->hw.device_id == I40E_DEV_ID_10G_BASE_T) ||
|
||||
(pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))
|
||||
pf->flags |= I40E_FLAG_HAVE_10GBASET_PHY;
|
||||
(pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))
|
||||
pf->flags |= I40E_FLAG_PHY_CONTROLS_LEDS;
|
||||
if (pf->hw.device_id == I40E_DEV_ID_SFP_I_X722)
|
||||
pf->flags |= I40E_FLAG_HAVE_CRT_RETIMER;
|
||||
/* print a string summarizing features */
|
||||
|
|
|
@ -373,6 +373,10 @@ i40e_status i40e_read_phy_register_clause45(struct i40e_hw *hw,
|
|||
u8 page, u16 reg, u8 phy_addr, u16 *value);
|
||||
i40e_status i40e_write_phy_register_clause45(struct i40e_hw *hw,
|
||||
u8 page, u16 reg, u8 phy_addr, u16 value);
|
||||
i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
|
||||
u8 phy_addr, u16 *value);
|
||||
i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
|
||||
u8 phy_addr, u16 value);
|
||||
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
|
||||
i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
|
||||
u32 time, u32 interval);
|
||||
|
|
|
@ -521,6 +521,8 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
|
|||
case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
|
||||
if (!(pf->flags & I40E_FLAG_PTP_L4_CAPABLE))
|
||||
return -ERANGE;
|
||||
pf->ptp_rx = true;
|
||||
tsyntype = I40E_PRTTSYN_CTL1_V1MESSTYPE0_MASK |
|
||||
I40E_PRTTSYN_CTL1_TSYNTYPE_V1 |
|
||||
|
@ -528,19 +530,26 @@ static int i40e_ptp_set_timestamp_mode(struct i40e_pf *pf,
|
|||
config->rx_filter = HWTSTAMP_FILTER_PTP_V1_L4_EVENT;
|
||||
break;
|
||||
case HWTSTAMP_FILTER_PTP_V2_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
|
||||
if (!(pf->flags & I40E_FLAG_PTP_L4_CAPABLE))
|
||||
return -ERANGE;
|
||||
/* fall through */
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
|
||||
case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
|
||||
pf->ptp_rx = true;
|
||||
tsyntype = I40E_PRTTSYN_CTL1_V2MESSTYPE0_MASK |
|
||||
I40E_PRTTSYN_CTL1_TSYNTYPE_V2 |
|
||||
I40E_PRTTSYN_CTL1_UDP_ENA_MASK;
|
||||
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||
I40E_PRTTSYN_CTL1_TSYNTYPE_V2;
|
||||
if (pf->flags & I40E_FLAG_PTP_L4_CAPABLE) {
|
||||
tsyntype |= I40E_PRTTSYN_CTL1_UDP_ENA_MASK;
|
||||
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
|
||||
} else {
|
||||
config->rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
|
||||
}
|
||||
break;
|
||||
case HWTSTAMP_FILTER_ALL:
|
||||
default:
|
||||
|
|
|
@ -2027,7 +2027,7 @@ tx_only:
|
|||
else
|
||||
i40e_update_enable_itr(vsi, q_vector);
|
||||
|
||||
return 0;
|
||||
return min(work_done, budget - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,26 +173,37 @@ static inline bool i40e_test_staterr(union i40e_rx_desc *rx_desc,
|
|||
#define I40E_MAX_DATA_PER_TXD_ALIGNED \
|
||||
(I40E_MAX_DATA_PER_TXD & ~(I40E_MAX_READ_REQ_SIZE - 1))
|
||||
|
||||
/* This ugly bit of math is equivalent to DIV_ROUNDUP(size, X) where X is
|
||||
* the value I40E_MAX_DATA_PER_TXD_ALIGNED. It is needed due to the fact
|
||||
* that 12K is not a power of 2 and division is expensive. It is used to
|
||||
* approximate the number of descriptors used per linear buffer. Note
|
||||
* that this will overestimate in some cases as it doesn't account for the
|
||||
* fact that we will add up to 4K - 1 in aligning the 12K buffer, however
|
||||
* the error should not impact things much as large buffers usually mean
|
||||
* we will use fewer descriptors then there are frags in an skb.
|
||||
/**
|
||||
* i40e_txd_use_count - estimate the number of descriptors needed for Tx
|
||||
* @size: transmit request size in bytes
|
||||
*
|
||||
* Due to hardware alignment restrictions (4K alignment), we need to
|
||||
* assume that we can have no more than 12K of data per descriptor, even
|
||||
* though each descriptor can take up to 16K - 1 bytes of aligned memory.
|
||||
* Thus, we need to divide by 12K. But division is slow! Instead,
|
||||
* we decompose the operation into shifts and one relatively cheap
|
||||
* multiply operation.
|
||||
*
|
||||
* To divide by 12K, we first divide by 4K, then divide by 3:
|
||||
* To divide by 4K, shift right by 12 bits
|
||||
* To divide by 3, multiply by 85, then divide by 256
|
||||
* (Divide by 256 is done by shifting right by 8 bits)
|
||||
* Finally, we add one to round up. Because 256 isn't an exact multiple of
|
||||
* 3, we'll underestimate near each multiple of 12K. This is actually more
|
||||
* accurate as we have 4K - 1 of wiggle room that we can fit into the last
|
||||
* segment. For our purposes this is accurate out to 1M which is orders of
|
||||
* magnitude greater than our largest possible GSO size.
|
||||
*
|
||||
* This would then be implemented as:
|
||||
* return (((size >> 12) * 85) >> 8) + 1;
|
||||
*
|
||||
* Since multiplication and division are commutative, we can reorder
|
||||
* operations into:
|
||||
* return ((size * 85) >> 20) + 1;
|
||||
*/
|
||||
static inline unsigned int i40e_txd_use_count(unsigned int size)
|
||||
{
|
||||
const unsigned int max = I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||
const unsigned int reciprocal = ((1ull << 32) - 1 + (max / 2)) / max;
|
||||
unsigned int adjust = ~(u32)0;
|
||||
|
||||
/* if we rounded up on the reciprocal pull down the adjustment */
|
||||
if ((max * reciprocal) > adjust)
|
||||
adjust = ~(u32)(reciprocal - 1);
|
||||
|
||||
return (u32)((((u64)size * reciprocal) + adjust) >> 32);
|
||||
return ((size * 85) >> 20) + 1;
|
||||
}
|
||||
|
||||
/* Tx Descriptors needed, worst case */
|
||||
|
|
|
@ -213,47 +213,59 @@ struct i40e_link_status {
|
|||
#define I40E_MODULE_TYPE_1000BASE_T 0x08
|
||||
};
|
||||
|
||||
enum i40e_aq_capabilities_phy_type {
|
||||
I40E_CAP_PHY_TYPE_SGMII = BIT(I40E_PHY_TYPE_SGMII),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_KX = BIT(I40E_PHY_TYPE_1000BASE_KX),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_KX4 = BIT(I40E_PHY_TYPE_10GBASE_KX4),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_KR = BIT(I40E_PHY_TYPE_10GBASE_KR),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_KR4 = BIT(I40E_PHY_TYPE_40GBASE_KR4),
|
||||
I40E_CAP_PHY_TYPE_XAUI = BIT(I40E_PHY_TYPE_XAUI),
|
||||
I40E_CAP_PHY_TYPE_XFI = BIT(I40E_PHY_TYPE_XFI),
|
||||
I40E_CAP_PHY_TYPE_SFI = BIT(I40E_PHY_TYPE_SFI),
|
||||
I40E_CAP_PHY_TYPE_XLAUI = BIT(I40E_PHY_TYPE_XLAUI),
|
||||
I40E_CAP_PHY_TYPE_XLPPI = BIT(I40E_PHY_TYPE_XLPPI),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_CR4_CU = BIT(I40E_PHY_TYPE_40GBASE_CR4_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_CR1_CU = BIT(I40E_PHY_TYPE_10GBASE_CR1_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_AOC = BIT(I40E_PHY_TYPE_10GBASE_AOC),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_AOC = BIT(I40E_PHY_TYPE_40GBASE_AOC),
|
||||
I40E_CAP_PHY_TYPE_100BASE_TX = BIT(I40E_PHY_TYPE_100BASE_TX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_T = BIT(I40E_PHY_TYPE_1000BASE_T),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_T = BIT(I40E_PHY_TYPE_10GBASE_T),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_SR = BIT(I40E_PHY_TYPE_10GBASE_SR),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_LR = BIT(I40E_PHY_TYPE_10GBASE_LR),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU = BIT(I40E_PHY_TYPE_10GBASE_SFPP_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_CR1 = BIT(I40E_PHY_TYPE_10GBASE_CR1),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_CR4 = BIT(I40E_PHY_TYPE_40GBASE_CR4),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_SR4 = BIT(I40E_PHY_TYPE_40GBASE_SR4),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_LR4 = BIT(I40E_PHY_TYPE_40GBASE_LR4),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_SX = BIT(I40E_PHY_TYPE_1000BASE_SX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_LX = BIT(I40E_PHY_TYPE_1000BASE_LX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL =
|
||||
BIT(I40E_PHY_TYPE_1000BASE_T_OPTICAL),
|
||||
I40E_CAP_PHY_TYPE_20GBASE_KR2 = BIT(I40E_PHY_TYPE_20GBASE_KR2)
|
||||
};
|
||||
|
||||
struct i40e_phy_info {
|
||||
struct i40e_link_status link_info;
|
||||
struct i40e_link_status link_info_old;
|
||||
bool get_link_info;
|
||||
enum i40e_media_type media_type;
|
||||
/* all the phy types the NVM is capable of */
|
||||
enum i40e_aq_capabilities_phy_type phy_types;
|
||||
u64 phy_types;
|
||||
};
|
||||
|
||||
#define I40E_CAP_PHY_TYPE_SGMII BIT_ULL(I40E_PHY_TYPE_SGMII)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_KX BIT_ULL(I40E_PHY_TYPE_1000BASE_KX)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_KX4 BIT_ULL(I40E_PHY_TYPE_10GBASE_KX4)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_KR BIT_ULL(I40E_PHY_TYPE_10GBASE_KR)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_KR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_KR4)
|
||||
#define I40E_CAP_PHY_TYPE_XAUI BIT_ULL(I40E_PHY_TYPE_XAUI)
|
||||
#define I40E_CAP_PHY_TYPE_XFI BIT_ULL(I40E_PHY_TYPE_XFI)
|
||||
#define I40E_CAP_PHY_TYPE_SFI BIT_ULL(I40E_PHY_TYPE_SFI)
|
||||
#define I40E_CAP_PHY_TYPE_XLAUI BIT_ULL(I40E_PHY_TYPE_XLAUI)
|
||||
#define I40E_CAP_PHY_TYPE_XLPPI BIT_ULL(I40E_PHY_TYPE_XLPPI)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_CR4_CU BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_CR1_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_AOC BIT_ULL(I40E_PHY_TYPE_10GBASE_AOC)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_AOC BIT_ULL(I40E_PHY_TYPE_40GBASE_AOC)
|
||||
#define I40E_CAP_PHY_TYPE_100BASE_TX BIT_ULL(I40E_PHY_TYPE_100BASE_TX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_T BIT_ULL(I40E_PHY_TYPE_1000BASE_T)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_T BIT_ULL(I40E_PHY_TYPE_10GBASE_T)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_SR BIT_ULL(I40E_PHY_TYPE_10GBASE_SR)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_LR BIT_ULL(I40E_PHY_TYPE_10GBASE_LR)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_SFPP_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_CR1 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_CR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_SR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_SR4)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_LR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_LR4)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_SX BIT_ULL(I40E_PHY_TYPE_1000BASE_SX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_LX BIT_ULL(I40E_PHY_TYPE_1000BASE_LX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL \
|
||||
BIT_ULL(I40E_PHY_TYPE_1000BASE_T_OPTICAL)
|
||||
#define I40E_CAP_PHY_TYPE_20GBASE_KR2 BIT_ULL(I40E_PHY_TYPE_20GBASE_KR2)
|
||||
/* Defining the macro I40E_TYPE_OFFSET to implement a bit shift for some
|
||||
* PHY types. There is an unused bit (31) in the I40E_CAP_PHY_TYPE_* bit
|
||||
* fields but no corresponding gap in the i40e_aq_phy_type enumeration. So,
|
||||
* a shift is needed to adjust for this with values larger than 31. The
|
||||
* only affected values are I40E_PHY_TYPE_25GBASE_*.
|
||||
*/
|
||||
#define I40E_PHY_TYPE_OFFSET 1
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_KR BIT_ULL(I40E_PHY_TYPE_25GBASE_KR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_CR BIT_ULL(I40E_PHY_TYPE_25GBASE_CR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_SR BIT_ULL(I40E_PHY_TYPE_25GBASE_SR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_LR BIT_ULL(I40E_PHY_TYPE_25GBASE_LR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_HW_CAP_MAX_GPIO 30
|
||||
/* Capabilities of a PF or a VF or the whole device */
|
||||
struct i40e_hw_capabilities {
|
||||
|
|
|
@ -2766,7 +2766,6 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
|
|||
u16 vlanprio = vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT);
|
||||
struct i40e_netdev_priv *np = netdev_priv(netdev);
|
||||
struct i40e_pf *pf = np->vsi->back;
|
||||
bool is_vsi_in_vlan = false;
|
||||
struct i40e_vsi *vsi;
|
||||
struct i40e_vf *vf;
|
||||
int ret = 0;
|
||||
|
@ -2803,11 +2802,10 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
|
|||
/* duplicate request, so just return success */
|
||||
goto error_pvid;
|
||||
|
||||
/* Locked once because multiple functions below iterate list */
|
||||
spin_lock_bh(&vsi->mac_filter_hash_lock);
|
||||
is_vsi_in_vlan = i40e_is_vsi_in_vlan(vsi);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
if (le16_to_cpu(vsi->info.pvid) == 0 && is_vsi_in_vlan) {
|
||||
if (le16_to_cpu(vsi->info.pvid) == 0 && i40e_is_vsi_in_vlan(vsi)) {
|
||||
dev_err(&pf->pdev->dev,
|
||||
"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
|
||||
vf_id);
|
||||
|
@ -2830,14 +2828,23 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
|
|||
*/
|
||||
if ((!(vlan_id || qos) ||
|
||||
vlanprio != le16_to_cpu(vsi->info.pvid)) &&
|
||||
vsi->info.pvid)
|
||||
ret = i40e_vsi_add_vlan(vsi, I40E_VLAN_ANY);
|
||||
vsi->info.pvid) {
|
||||
ret = i40e_add_vlan_all_mac(vsi, I40E_VLAN_ANY);
|
||||
if (ret) {
|
||||
dev_info(&vsi->back->pdev->dev,
|
||||
"add VF VLAN failed, ret=%d aq_err=%d\n", ret,
|
||||
vsi->back->hw.aq.asq_last_status);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
goto error_pvid;
|
||||
}
|
||||
}
|
||||
|
||||
if (vsi->info.pvid) {
|
||||
/* kill old VLAN */
|
||||
i40e_vsi_kill_vlan(vsi, (le16_to_cpu(vsi->info.pvid) &
|
||||
VLAN_VID_MASK));
|
||||
/* remove all filters on the old VLAN */
|
||||
i40e_rm_vlan_all_mac(vsi, (le16_to_cpu(vsi->info.pvid) &
|
||||
VLAN_VID_MASK));
|
||||
}
|
||||
|
||||
if (vlan_id || qos)
|
||||
ret = i40e_vsi_add_pvid(vsi, vlanprio);
|
||||
else
|
||||
|
@ -2847,24 +2854,30 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id,
|
|||
dev_info(&pf->pdev->dev, "Setting VLAN %d, QOS 0x%x on VF %d\n",
|
||||
vlan_id, qos, vf_id);
|
||||
|
||||
/* add new VLAN filter */
|
||||
ret = i40e_vsi_add_vlan(vsi, vlan_id);
|
||||
/* add new VLAN filter for each MAC */
|
||||
ret = i40e_add_vlan_all_mac(vsi, vlan_id);
|
||||
if (ret) {
|
||||
dev_info(&vsi->back->pdev->dev,
|
||||
"add VF VLAN failed, ret=%d aq_err=%d\n", ret,
|
||||
vsi->back->hw.aq.asq_last_status);
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
goto error_pvid;
|
||||
}
|
||||
/* Kill non-vlan MAC filters - ignore error return since
|
||||
* there might not be any non-vlan MAC filters.
|
||||
*/
|
||||
i40e_vsi_kill_vlan(vsi, I40E_VLAN_ANY);
|
||||
|
||||
/* remove the previously added non-VLAN MAC filters */
|
||||
i40e_rm_vlan_all_mac(vsi, I40E_VLAN_ANY);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&vsi->mac_filter_hash_lock);
|
||||
|
||||
/* Schedule the worker thread to take care of applying changes */
|
||||
i40e_service_event_schedule(vsi->back);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pf->pdev->dev, "Unable to update VF vsi context\n");
|
||||
goto error_pvid;
|
||||
}
|
||||
|
||||
/* The Port VLAN needs to be saved across resets the same as the
|
||||
* default LAN MAC address.
|
||||
*/
|
||||
|
@ -2921,6 +2934,9 @@ int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int min_tx_rate,
|
|||
case I40E_LINK_SPEED_40GB:
|
||||
speed = 40000;
|
||||
break;
|
||||
case I40E_LINK_SPEED_25GB:
|
||||
speed = 25000;
|
||||
break;
|
||||
case I40E_LINK_SPEED_20GB:
|
||||
speed = 20000;
|
||||
break;
|
||||
|
|
|
@ -1639,6 +1639,10 @@ enum i40e_aq_phy_type {
|
|||
I40E_PHY_TYPE_1000BASE_LX = 0x1C,
|
||||
I40E_PHY_TYPE_1000BASE_T_OPTICAL = 0x1D,
|
||||
I40E_PHY_TYPE_20GBASE_KR2 = 0x1E,
|
||||
I40E_PHY_TYPE_25GBASE_KR = 0x1F,
|
||||
I40E_PHY_TYPE_25GBASE_CR = 0x20,
|
||||
I40E_PHY_TYPE_25GBASE_SR = 0x21,
|
||||
I40E_PHY_TYPE_25GBASE_LR = 0x22,
|
||||
I40E_PHY_TYPE_MAX
|
||||
};
|
||||
|
||||
|
@ -1647,6 +1651,7 @@ enum i40e_aq_phy_type {
|
|||
#define I40E_LINK_SPEED_10GB_SHIFT 0x3
|
||||
#define I40E_LINK_SPEED_40GB_SHIFT 0x4
|
||||
#define I40E_LINK_SPEED_20GB_SHIFT 0x5
|
||||
#define I40E_LINK_SPEED_25GB_SHIFT 0x6
|
||||
|
||||
enum i40e_aq_link_speed {
|
||||
I40E_LINK_SPEED_UNKNOWN = 0,
|
||||
|
@ -1654,7 +1659,8 @@ enum i40e_aq_link_speed {
|
|||
I40E_LINK_SPEED_1GB = BIT(I40E_LINK_SPEED_1000MB_SHIFT),
|
||||
I40E_LINK_SPEED_10GB = BIT(I40E_LINK_SPEED_10GB_SHIFT),
|
||||
I40E_LINK_SPEED_40GB = BIT(I40E_LINK_SPEED_40GB_SHIFT),
|
||||
I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT)
|
||||
I40E_LINK_SPEED_20GB = BIT(I40E_LINK_SPEED_20GB_SHIFT),
|
||||
I40E_LINK_SPEED_25GB = BIT(I40E_LINK_SPEED_25GB_SHIFT),
|
||||
};
|
||||
|
||||
struct i40e_aqc_module_desc {
|
||||
|
@ -1677,6 +1683,8 @@ struct i40e_aq_get_phy_abilities_resp {
|
|||
#define I40E_AQ_PHY_LINK_ENABLED 0x08
|
||||
#define I40E_AQ_PHY_AN_ENABLED 0x10
|
||||
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
|
||||
#define I40E_AQ_PHY_FEC_ABILITY_KR 0x40
|
||||
#define I40E_AQ_PHY_FEC_ABILITY_RS 0x80
|
||||
__le16 eee_capability;
|
||||
#define I40E_AQ_EEE_100BASE_TX 0x0002
|
||||
#define I40E_AQ_EEE_1000BASE_T 0x0004
|
||||
|
@ -1687,7 +1695,22 @@ struct i40e_aq_get_phy_abilities_resp {
|
|||
__le32 eeer_val;
|
||||
u8 d3_lpan;
|
||||
#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
|
||||
u8 reserved[3];
|
||||
u8 phy_type_ext;
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
|
||||
u8 fec_cfg_curr_mod_ext_info;
|
||||
#define I40E_AQ_ENABLE_FEC_KR 0x01
|
||||
#define I40E_AQ_ENABLE_FEC_RS 0x02
|
||||
#define I40E_AQ_REQUEST_FEC_KR 0x04
|
||||
#define I40E_AQ_REQUEST_FEC_RS 0x08
|
||||
#define I40E_AQ_ENABLE_FEC_AUTO 0x10
|
||||
#define I40E_AQ_FEC
|
||||
#define I40E_AQ_MODULE_TYPE_EXT_MASK 0xE0
|
||||
#define I40E_AQ_MODULE_TYPE_EXT_SHIFT 5
|
||||
|
||||
u8 ext_comp_code;
|
||||
u8 phy_id[4];
|
||||
u8 module_type[3];
|
||||
u8 qualified_module_count;
|
||||
|
@ -1709,7 +1732,20 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
|
|||
__le16 eee_capability;
|
||||
__le32 eeer;
|
||||
u8 low_power_ctrl;
|
||||
u8 reserved[3];
|
||||
u8 phy_type_ext;
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_KR 0X01
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_CR 0X02
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_SR 0x04
|
||||
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
|
||||
u8 fec_config;
|
||||
#define I40E_AQ_SET_FEC_ABILITY_KR BIT(0)
|
||||
#define I40E_AQ_SET_FEC_ABILITY_RS BIT(1)
|
||||
#define I40E_AQ_SET_FEC_REQUEST_KR BIT(2)
|
||||
#define I40E_AQ_SET_FEC_REQUEST_RS BIT(3)
|
||||
#define I40E_AQ_SET_FEC_AUTO BIT(4)
|
||||
#define I40E_AQ_PHY_FEC_CONFIG_SHIFT 0x0
|
||||
#define I40E_AQ_PHY_FEC_CONFIG_MASK (0x1F << I40E_AQ_PHY_FEC_CONFIG_SHIFT)
|
||||
u8 reserved;
|
||||
};
|
||||
|
||||
I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config);
|
||||
|
@ -1789,9 +1825,18 @@ struct i40e_aqc_get_link_status {
|
|||
#define I40E_AQ_LINK_TX_DRAINED 0x01
|
||||
#define I40E_AQ_LINK_TX_FLUSHED 0x03
|
||||
#define I40E_AQ_LINK_FORCED_40G 0x10
|
||||
/* 25G Error Codes */
|
||||
#define I40E_AQ_25G_NO_ERR 0X00
|
||||
#define I40E_AQ_25G_NOT_PRESENT 0X01
|
||||
#define I40E_AQ_25G_NVM_CRC_ERR 0X02
|
||||
#define I40E_AQ_25G_SBUS_UCODE_ERR 0X03
|
||||
#define I40E_AQ_25G_SERDES_UCODE_ERR 0X04
|
||||
#define I40E_AQ_25G_NIMB_UCODE_ERR 0X05
|
||||
u8 loopback; /* use defines from i40e_aqc_set_lb_mode */
|
||||
__le16 max_frame_size;
|
||||
u8 config;
|
||||
#define I40E_AQ_CONFIG_FEC_KR_ENA 0x01
|
||||
#define I40E_AQ_CONFIG_FEC_RS_ENA 0x02
|
||||
#define I40E_AQ_CONFIG_CRC_ENA 0x04
|
||||
#define I40E_AQ_CONFIG_PACING_MASK 0x78
|
||||
u8 external_power_ability;
|
||||
|
|
|
@ -53,6 +53,8 @@ i40e_status i40e_set_mac_type(struct i40e_hw *hw)
|
|||
case I40E_DEV_ID_10G_BASE_T4:
|
||||
case I40E_DEV_ID_20G_KR2:
|
||||
case I40E_DEV_ID_20G_KR2_A:
|
||||
case I40E_DEV_ID_25G_B:
|
||||
case I40E_DEV_ID_25G_SFP28:
|
||||
hw->mac.type = I40E_MAC_XL710;
|
||||
break;
|
||||
case I40E_DEV_ID_SFP_X722:
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
#define I40E_DEV_ID_20G_KR2 0x1587
|
||||
#define I40E_DEV_ID_20G_KR2_A 0x1588
|
||||
#define I40E_DEV_ID_10G_BASE_T4 0x1589
|
||||
#define I40E_DEV_ID_25G_B 0x158A
|
||||
#define I40E_DEV_ID_25G_SFP28 0x158B
|
||||
#define I40E_DEV_ID_VF 0x154C
|
||||
#define I40E_DEV_ID_VF_HV 0x1571
|
||||
#define I40E_DEV_ID_SFP_X722 0x37D0
|
||||
|
|
|
@ -115,6 +115,10 @@ i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page,
|
|||
u16 reg, u8 phy_addr, u16 *value);
|
||||
i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page,
|
||||
u16 reg, u8 phy_addr, u16 value);
|
||||
i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
|
||||
u8 phy_addr, u16 *value);
|
||||
i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page, u16 reg,
|
||||
u8 phy_addr, u16 value);
|
||||
u8 i40e_get_phy_address(struct i40e_hw *hw, u8 dev_num);
|
||||
i40e_status i40e_blink_phy_link_led(struct i40e_hw *hw,
|
||||
u32 time, u32 interval);
|
||||
|
|
|
@ -1490,7 +1490,7 @@ tx_only:
|
|||
else
|
||||
i40e_update_enable_itr(vsi, q_vector);
|
||||
|
||||
return 0;
|
||||
return min(work_done, budget - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -173,26 +173,37 @@ static inline bool i40e_test_staterr(union i40e_rx_desc *rx_desc,
|
|||
#define I40E_MAX_DATA_PER_TXD_ALIGNED \
|
||||
(I40E_MAX_DATA_PER_TXD & ~(I40E_MAX_READ_REQ_SIZE - 1))
|
||||
|
||||
/* This ugly bit of math is equivalent to DIV_ROUNDUP(size, X) where X is
|
||||
* the value I40E_MAX_DATA_PER_TXD_ALIGNED. It is needed due to the fact
|
||||
* that 12K is not a power of 2 and division is expensive. It is used to
|
||||
* approximate the number of descriptors used per linear buffer. Note
|
||||
* that this will overestimate in some cases as it doesn't account for the
|
||||
* fact that we will add up to 4K - 1 in aligning the 12K buffer, however
|
||||
* the error should not impact things much as large buffers usually mean
|
||||
* we will use fewer descriptors then there are frags in an skb.
|
||||
/**
|
||||
* i40e_txd_use_count - estimate the number of descriptors needed for Tx
|
||||
* @size: transmit request size in bytes
|
||||
*
|
||||
* Due to hardware alignment restrictions (4K alignment), we need to
|
||||
* assume that we can have no more than 12K of data per descriptor, even
|
||||
* though each descriptor can take up to 16K - 1 bytes of aligned memory.
|
||||
* Thus, we need to divide by 12K. But division is slow! Instead,
|
||||
* we decompose the operation into shifts and one relatively cheap
|
||||
* multiply operation.
|
||||
*
|
||||
* To divide by 12K, we first divide by 4K, then divide by 3:
|
||||
* To divide by 4K, shift right by 12 bits
|
||||
* To divide by 3, multiply by 85, then divide by 256
|
||||
* (Divide by 256 is done by shifting right by 8 bits)
|
||||
* Finally, we add one to round up. Because 256 isn't an exact multiple of
|
||||
* 3, we'll underestimate near each multiple of 12K. This is actually more
|
||||
* accurate as we have 4K - 1 of wiggle room that we can fit into the last
|
||||
* segment. For our purposes this is accurate out to 1M which is orders of
|
||||
* magnitude greater than our largest possible GSO size.
|
||||
*
|
||||
* This would then be implemented as:
|
||||
* return (((size >> 12) * 85) >> 8) + 1;
|
||||
*
|
||||
* Since multiplication and division are commutative, we can reorder
|
||||
* operations into:
|
||||
* return ((size * 85) >> 20) + 1;
|
||||
*/
|
||||
static inline unsigned int i40e_txd_use_count(unsigned int size)
|
||||
{
|
||||
const unsigned int max = I40E_MAX_DATA_PER_TXD_ALIGNED;
|
||||
const unsigned int reciprocal = ((1ull << 32) - 1 + (max / 2)) / max;
|
||||
unsigned int adjust = ~(u32)0;
|
||||
|
||||
/* if we rounded up on the reciprocal pull down the adjustment */
|
||||
if ((max * reciprocal) > adjust)
|
||||
adjust = ~(u32)(reciprocal - 1);
|
||||
|
||||
return (u32)((((u64)size * reciprocal) + adjust) >> 32);
|
||||
return ((size * 85) >> 20) + 1;
|
||||
}
|
||||
|
||||
/* Tx Descriptors needed, worst case */
|
||||
|
|
|
@ -187,47 +187,59 @@ struct i40e_link_status {
|
|||
#define I40E_MODULE_TYPE_1000BASE_T 0x08
|
||||
};
|
||||
|
||||
enum i40e_aq_capabilities_phy_type {
|
||||
I40E_CAP_PHY_TYPE_SGMII = BIT(I40E_PHY_TYPE_SGMII),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_KX = BIT(I40E_PHY_TYPE_1000BASE_KX),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_KX4 = BIT(I40E_PHY_TYPE_10GBASE_KX4),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_KR = BIT(I40E_PHY_TYPE_10GBASE_KR),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_KR4 = BIT(I40E_PHY_TYPE_40GBASE_KR4),
|
||||
I40E_CAP_PHY_TYPE_XAUI = BIT(I40E_PHY_TYPE_XAUI),
|
||||
I40E_CAP_PHY_TYPE_XFI = BIT(I40E_PHY_TYPE_XFI),
|
||||
I40E_CAP_PHY_TYPE_SFI = BIT(I40E_PHY_TYPE_SFI),
|
||||
I40E_CAP_PHY_TYPE_XLAUI = BIT(I40E_PHY_TYPE_XLAUI),
|
||||
I40E_CAP_PHY_TYPE_XLPPI = BIT(I40E_PHY_TYPE_XLPPI),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_CR4_CU = BIT(I40E_PHY_TYPE_40GBASE_CR4_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_CR1_CU = BIT(I40E_PHY_TYPE_10GBASE_CR1_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_AOC = BIT(I40E_PHY_TYPE_10GBASE_AOC),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_AOC = BIT(I40E_PHY_TYPE_40GBASE_AOC),
|
||||
I40E_CAP_PHY_TYPE_100BASE_TX = BIT(I40E_PHY_TYPE_100BASE_TX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_T = BIT(I40E_PHY_TYPE_1000BASE_T),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_T = BIT(I40E_PHY_TYPE_10GBASE_T),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_SR = BIT(I40E_PHY_TYPE_10GBASE_SR),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_LR = BIT(I40E_PHY_TYPE_10GBASE_LR),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU = BIT(I40E_PHY_TYPE_10GBASE_SFPP_CU),
|
||||
I40E_CAP_PHY_TYPE_10GBASE_CR1 = BIT(I40E_PHY_TYPE_10GBASE_CR1),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_CR4 = BIT(I40E_PHY_TYPE_40GBASE_CR4),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_SR4 = BIT(I40E_PHY_TYPE_40GBASE_SR4),
|
||||
I40E_CAP_PHY_TYPE_40GBASE_LR4 = BIT(I40E_PHY_TYPE_40GBASE_LR4),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_SX = BIT(I40E_PHY_TYPE_1000BASE_SX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_LX = BIT(I40E_PHY_TYPE_1000BASE_LX),
|
||||
I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL =
|
||||
BIT(I40E_PHY_TYPE_1000BASE_T_OPTICAL),
|
||||
I40E_CAP_PHY_TYPE_20GBASE_KR2 = BIT(I40E_PHY_TYPE_20GBASE_KR2)
|
||||
};
|
||||
|
||||
struct i40e_phy_info {
|
||||
struct i40e_link_status link_info;
|
||||
struct i40e_link_status link_info_old;
|
||||
bool get_link_info;
|
||||
enum i40e_media_type media_type;
|
||||
/* all the phy types the NVM is capable of */
|
||||
enum i40e_aq_capabilities_phy_type phy_types;
|
||||
u64 phy_types;
|
||||
};
|
||||
|
||||
#define I40E_CAP_PHY_TYPE_SGMII BIT_ULL(I40E_PHY_TYPE_SGMII)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_KX BIT_ULL(I40E_PHY_TYPE_1000BASE_KX)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_KX4 BIT_ULL(I40E_PHY_TYPE_10GBASE_KX4)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_KR BIT_ULL(I40E_PHY_TYPE_10GBASE_KR)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_KR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_KR4)
|
||||
#define I40E_CAP_PHY_TYPE_XAUI BIT_ULL(I40E_PHY_TYPE_XAUI)
|
||||
#define I40E_CAP_PHY_TYPE_XFI BIT_ULL(I40E_PHY_TYPE_XFI)
|
||||
#define I40E_CAP_PHY_TYPE_SFI BIT_ULL(I40E_PHY_TYPE_SFI)
|
||||
#define I40E_CAP_PHY_TYPE_XLAUI BIT_ULL(I40E_PHY_TYPE_XLAUI)
|
||||
#define I40E_CAP_PHY_TYPE_XLPPI BIT_ULL(I40E_PHY_TYPE_XLPPI)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_CR4_CU BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_CR1_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_AOC BIT_ULL(I40E_PHY_TYPE_10GBASE_AOC)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_AOC BIT_ULL(I40E_PHY_TYPE_40GBASE_AOC)
|
||||
#define I40E_CAP_PHY_TYPE_100BASE_TX BIT_ULL(I40E_PHY_TYPE_100BASE_TX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_T BIT_ULL(I40E_PHY_TYPE_1000BASE_T)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_T BIT_ULL(I40E_PHY_TYPE_10GBASE_T)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_SR BIT_ULL(I40E_PHY_TYPE_10GBASE_SR)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_LR BIT_ULL(I40E_PHY_TYPE_10GBASE_LR)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU BIT_ULL(I40E_PHY_TYPE_10GBASE_SFPP_CU)
|
||||
#define I40E_CAP_PHY_TYPE_10GBASE_CR1 BIT_ULL(I40E_PHY_TYPE_10GBASE_CR1)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_CR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_CR4)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_SR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_SR4)
|
||||
#define I40E_CAP_PHY_TYPE_40GBASE_LR4 BIT_ULL(I40E_PHY_TYPE_40GBASE_LR4)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_SX BIT_ULL(I40E_PHY_TYPE_1000BASE_SX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_LX BIT_ULL(I40E_PHY_TYPE_1000BASE_LX)
|
||||
#define I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL \
|
||||
BIT_ULL(I40E_PHY_TYPE_1000BASE_T_OPTICAL)
|
||||
#define I40E_CAP_PHY_TYPE_20GBASE_KR2 BIT_ULL(I40E_PHY_TYPE_20GBASE_KR2)
|
||||
/* Defining the macro I40E_TYPE_OFFSET to implement a bit shift for some
|
||||
* PHY types. There is an unused bit (31) in the I40E_CAP_PHY_TYPE_* bit
|
||||
* fields but no corresponding gap in the i40e_aq_phy_type enumeration. So,
|
||||
* a shift is needed to adjust for this with values larger than 31. The
|
||||
* only affected values are I40E_PHY_TYPE_25GBASE_*.
|
||||
*/
|
||||
#define I40E_PHY_TYPE_OFFSET 1
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_KR BIT_ULL(I40E_PHY_TYPE_25GBASE_KR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_CR BIT_ULL(I40E_PHY_TYPE_25GBASE_CR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_SR BIT_ULL(I40E_PHY_TYPE_25GBASE_SR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_CAP_PHY_TYPE_25GBASE_LR BIT_ULL(I40E_PHY_TYPE_25GBASE_LR + \
|
||||
I40E_PHY_TYPE_OFFSET)
|
||||
#define I40E_HW_CAP_MAX_GPIO 30
|
||||
/* Capabilities of a PF or a VF or the whole device */
|
||||
struct i40e_hw_capabilities {
|
||||
|
|
|
@ -85,6 +85,14 @@ static int i40evf_get_settings(struct net_device *netdev,
|
|||
case I40E_LINK_SPEED_40GB:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_40000);
|
||||
break;
|
||||
case I40E_LINK_SPEED_25GB:
|
||||
#ifdef SPEED_25000
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_25000);
|
||||
#else
|
||||
netdev_info(netdev,
|
||||
"Speed is 25G, display not supported by this version of ethtool.\n");
|
||||
#endif
|
||||
break;
|
||||
case I40E_LINK_SPEED_20GB:
|
||||
ethtool_cmd_speed_set(ecmd, SPEED_20000);
|
||||
break;
|
||||
|
|
|
@ -38,7 +38,7 @@ static const char i40evf_driver_string[] =
|
|||
|
||||
#define DRV_VERSION_MAJOR 1
|
||||
#define DRV_VERSION_MINOR 6
|
||||
#define DRV_VERSION_BUILD 21
|
||||
#define DRV_VERSION_BUILD 25
|
||||
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
|
||||
__stringify(DRV_VERSION_MINOR) "." \
|
||||
__stringify(DRV_VERSION_BUILD) \
|
||||
|
|
|
@ -836,6 +836,9 @@ static void i40evf_print_link_message(struct i40evf_adapter *adapter)
|
|||
case I40E_LINK_SPEED_40GB:
|
||||
speed = "40 G";
|
||||
break;
|
||||
case I40E_LINK_SPEED_25GB:
|
||||
speed = "25 G";
|
||||
break;
|
||||
case I40E_LINK_SPEED_20GB:
|
||||
speed = "20 G";
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue