From 937f599a1126545ec68f13b6c799231a5ee631b5 Mon Sep 17 00:00:00 2001 From: Grzegorz Siwik Date: Fri, 29 Mar 2019 15:08:30 -0700 Subject: i40e: VF's promiscuous attribute is not kept This patch fixes a bug where the promiscuous mode was not being kept when the VF switched to a new VLAN. Now we are config two times a promiscuous mode when we switch VLAN. Without this change when we change VF VLAN we still receive all the packets from previous VLAN and only unicast from new VLAN. Signed-off-by: Grzegorz Siwik Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 8a6fb9c03955..00345bbf68ec 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -4016,6 +4016,7 @@ 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); + bool allmulti = false, alluni = false; struct i40e_pf *pf = np->vsi->back; struct i40e_vsi *vsi; struct i40e_vf *vf; @@ -4100,6 +4101,15 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, } spin_unlock_bh(&vsi->mac_filter_hash_lock); + + /* disable promisc modes in case they were enabled */ + ret = i40e_config_vf_promiscuous_mode(vf, vf->lan_vsi_id, + allmulti, alluni); + if (ret) { + dev_err(&pf->pdev->dev, "Unable to config VF promiscuous mode\n"); + goto error_pvid; + } + if (vlan_id || qos) ret = i40e_vsi_add_pvid(vsi, vlanprio); else @@ -4126,6 +4136,12 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, spin_unlock_bh(&vsi->mac_filter_hash_lock); + if (test_bit(I40E_VF_STATE_UC_PROMISC, &vf->vf_states)) + alluni = true; + + if (test_bit(I40E_VF_STATE_MC_PROMISC, &vf->vf_states)) + allmulti = true; + /* Schedule the worker thread to take care of applying changes */ i40e_service_event_schedule(vsi->back); @@ -4138,6 +4154,13 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev, int vf_id, * default LAN MAC address. */ vf->port_vlan_id = le16_to_cpu(vsi->info.pvid); + + ret = i40e_config_vf_promiscuous_mode(vf, vsi->id, allmulti, alluni); + if (ret) { + dev_err(&pf->pdev->dev, "Unable to config vf promiscuous mode\n"); + goto error_pvid; + } + ret = 0; error_pvid: -- cgit v1.2.3-59-g8ed1b From e576e769663c7dfa5a40c8eac1f79b7ec2a22482 Mon Sep 17 00:00:00 2001 From: Aleksandr Loktionov Date: Fri, 29 Mar 2019 15:08:31 -0700 Subject: i40e: add new pci id for X710/XXV710 N3000 cards New device ids are created to support X710/XXV710 N3000 cards. Signed-off-by: Aleksandr Loktionov Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_common.c | 2 ++ drivers/net/ethernet/intel/i40e/i40e_devids.h | 2 ++ drivers/net/ethernet/intel/i40e/i40e_main.c | 2 ++ 3 files changed, 6 insertions(+) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index e7d500f92a90..8de6e007b4a0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -32,6 +32,8 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_20G_KR2_A: case I40E_DEV_ID_25G_B: case I40E_DEV_ID_25G_SFP28: + case I40E_DEV_ID_X710_N3000: + case I40E_DEV_ID_XXV710_N3000: hw->mac.type = I40E_MAC_XL710; break; case I40E_DEV_ID_KX_X722: diff --git a/drivers/net/ethernet/intel/i40e/i40e_devids.h b/drivers/net/ethernet/intel/i40e/i40e_devids.h index 334b05ff685a..16be4d5286bd 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_devids.h +++ b/drivers/net/ethernet/intel/i40e/i40e_devids.h @@ -5,6 +5,8 @@ #define _I40E_DEVIDS_H_ /* Device IDs */ +#define I40E_DEV_ID_X710_N3000 0x0CF8 +#define I40E_DEV_ID_XXV710_N3000 0x0D58 #define I40E_DEV_ID_SFP_XL710 0x1572 #define I40E_DEV_ID_QEMU 0x1574 #define I40E_DEV_ID_KX_B 0x1580 diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index fa1b2cfd359e..7d0183c67cff 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -81,6 +81,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_X710_N3000), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_XXV710_N3000), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_B), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_25G_SFP28), 0}, /* required last entry */ -- cgit v1.2.3-59-g8ed1b From 40a23040d82595acf819d4e7902331ecbbd17744 Mon Sep 17 00:00:00 2001 From: Grzegorz Siwik Date: Fri, 29 Mar 2019 15:08:32 -0700 Subject: i40e: Setting VF to VLAN 0 requires restart This patch fixes a bug where changing VLAN to 0 was not set until VF restart. Now we are setting pvid info to 0 when we have to change VLAN to 0. Without this change when VF VLAN was changed to 0 nothing happened until VF restart. For changing to VLAN different than 0 it worked correctly. Signed-off-by: Grzegorz Siwik Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 7d0183c67cff..7116207320fb 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -2975,9 +2975,9 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid) **/ void i40e_vsi_remove_pvid(struct i40e_vsi *vsi) { - i40e_vlan_stripping_disable(vsi); - vsi->info.pvid = 0; + + i40e_vlan_stripping_disable(vsi); } /** -- cgit v1.2.3-59-g8ed1b From 1aa874b42ee8958c737e282ebcf87f653b6c80dc Mon Sep 17 00:00:00 2001 From: Grzegorz Siwik Date: Fri, 29 Mar 2019 15:08:35 -0700 Subject: i40e: Fix the typo in adding 40GE KR4 mode This patch fixes the typo in I40E_CAP_PHY_TYPE mode link code. It was fixed by changing 40000baseLR4_Full to 40000baseKR4_Full Signed-off-by: Grzegorz Siwik Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 2c81afbd7c58..d440778f2dc7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -549,9 +549,9 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, } if (phy_types & I40E_CAP_PHY_TYPE_40GBASE_KR4) { ethtool_link_ksettings_add_link_mode(ks, supported, - 40000baseLR4_Full); + 40000baseKR4_Full); ethtool_link_ksettings_add_link_mode(ks, advertising, - 40000baseLR4_Full); + 40000baseKR4_Full); } if (phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2) { ethtool_link_ksettings_add_link_mode(ks, supported, -- cgit v1.2.3-59-g8ed1b From 7015ca3df965378bcef072cca9cd63ed098665b5 Mon Sep 17 00:00:00 2001 From: Sergey Nemov Date: Fri, 29 Mar 2019 15:08:36 -0700 Subject: i40e: add num_vectors checker in iwarp handler Field num_vectors from struct virtchnl_iwarp_qvlist_info should not be larger than num_msix_vectors_vf in the hw struct. The iwarp uses the same set of vectors as the LAN VF driver. Signed-off-by: Sergey Nemov Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 00345bbf68ec..25490cfb06fc 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -442,6 +442,16 @@ static int i40e_config_iwarp_qvlist(struct i40e_vf *vf, u32 next_q_idx, next_q_type; u32 msix_vf, size; + msix_vf = pf->hw.func_caps.num_msix_vectors_vf; + + if (qvlist_info->num_vectors > msix_vf) { + dev_warn(&pf->pdev->dev, + "Incorrect number of iwarp vectors %u. Maximum %u allowed.\n", + qvlist_info->num_vectors, + msix_vf); + goto err; + } + size = sizeof(struct virtchnl_iwarp_qvlist_info) + (sizeof(struct virtchnl_iwarp_qv_info) * (qvlist_info->num_vectors - 1)); -- cgit v1.2.3-59-g8ed1b From c004804dceee9ca384d97d9857ea2e2795c2651d Mon Sep 17 00:00:00 2001 From: Grzegorz Siwik Date: Fri, 29 Mar 2019 15:08:37 -0700 Subject: i40e: Wrong truncation from u16 to u8 In this patch fixed wrong truncation method from u16 to u8 during validation. It was changed by changing u8 to u32 parameter in method declaration and arguments were changed to u32. Signed-off-by: Grzegorz Siwik Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 25490cfb06fc..d0e3677b7dc8 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -196,7 +196,7 @@ static inline bool i40e_vc_isvalid_queue_id(struct i40e_vf *vf, u16 vsi_id, * * check for the valid vector id **/ -static inline bool i40e_vc_isvalid_vector_id(struct i40e_vf *vf, u8 vector_id) +static inline bool i40e_vc_isvalid_vector_id(struct i40e_vf *vf, u32 vector_id) { struct i40e_pf *pf = vf->pf; -- cgit v1.2.3-59-g8ed1b From 2e45d3f4677ae7cd83f97b6039208979e88a7a84 Mon Sep 17 00:00:00 2001 From: Aleksandr Loktionov Date: Fri, 29 Mar 2019 15:08:38 -0700 Subject: i40e: Add support for X710 B/P & SFP+ cards New device ids are created to support X710 backplane and SFP+ cards. This patch adds in i40e driver support for 2.5GbaseT and 5GbaseT speed. It's implemented by checking I40E_CAP_PHY_TYPE_2_5GBASE_T, I40E_CAP_PHY_TYPE_5GBASE_T bits from f/w and setting corresponding bits in ethtool link ksettings supported and advertising masks. Signed-off-by: Aleksandr Loktionov Signed-off-by: Alice Michael Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 12 ++++++- drivers/net/ethernet/intel/i40e/i40e_common.c | 5 +++ drivers/net/ethernet/intel/i40e/i40e_devids.h | 3 ++ drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 42 ++++++++++++++++++++++- drivers/net/ethernet/intel/i40e/i40e_main.c | 8 +++++ drivers/net/ethernet/intel/i40e/i40e_type.h | 6 ++++ 6 files changed, 74 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index abcf79eb3261..6536023fa074 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -1888,6 +1888,8 @@ enum i40e_aq_phy_type { I40E_PHY_TYPE_25GBASE_LR = 0x22, I40E_PHY_TYPE_25GBASE_AOC = 0x23, I40E_PHY_TYPE_25GBASE_ACC = 0x24, + I40E_PHY_TYPE_2_5GBASE_T = 0x30, + I40E_PHY_TYPE_5GBASE_T = 0x31, I40E_PHY_TYPE_MAX, I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD, I40E_PHY_TYPE_EMPTY = 0xFE, @@ -1929,19 +1931,25 @@ enum i40e_aq_phy_type { BIT_ULL(I40E_PHY_TYPE_25GBASE_SR) | \ BIT_ULL(I40E_PHY_TYPE_25GBASE_LR) | \ BIT_ULL(I40E_PHY_TYPE_25GBASE_AOC) | \ - BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC)) + BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC) | \ + BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T) | \ + BIT_ULL(I40E_PHY_TYPE_5GBASE_T)) +#define I40E_LINK_SPEED_2_5GB_SHIFT 0x0 #define I40E_LINK_SPEED_100MB_SHIFT 0x1 #define I40E_LINK_SPEED_1000MB_SHIFT 0x2 #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 +#define I40E_LINK_SPEED_5GB_SHIFT 0x7 enum i40e_aq_link_speed { I40E_LINK_SPEED_UNKNOWN = 0, I40E_LINK_SPEED_100MB = BIT(I40E_LINK_SPEED_100MB_SHIFT), I40E_LINK_SPEED_1GB = BIT(I40E_LINK_SPEED_1000MB_SHIFT), + I40E_LINK_SPEED_2_5GB = (1 << I40E_LINK_SPEED_2_5GB_SHIFT), + I40E_LINK_SPEED_5GB = (1 << I40E_LINK_SPEED_5GB_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), @@ -1987,6 +1995,8 @@ struct i40e_aq_get_phy_abilities_resp { #define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08 #define I40E_AQ_PHY_TYPE_EXT_25G_AOC 0x10 #define I40E_AQ_PHY_TYPE_EXT_25G_ACC 0x20 +#define I40E_AQ_PHY_TYPE_EXT_2_5GBASE_T 0x40 +#define I40E_AQ_PHY_TYPE_EXT_5GBASE_T 0x80 u8 fec_cfg_curr_mod_ext_info; #define I40E_AQ_ENABLE_FEC_KR 0x01 #define I40E_AQ_ENABLE_FEC_RS 0x02 diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 8de6e007b4a0..ecb1adaa54ec 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -28,6 +28,8 @@ static i40e_status i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_QSFP_C: case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: + case I40E_DEV_ID_10G_B: + case I40E_DEV_ID_10G_SFP: case I40E_DEV_ID_20G_KR2: case I40E_DEV_ID_20G_KR2_A: case I40E_DEV_ID_25G_B: @@ -1151,6 +1153,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) break; case I40E_PHY_TYPE_100BASE_TX: case I40E_PHY_TYPE_1000BASE_T: + case I40E_PHY_TYPE_2_5GBASE_T: + case I40E_PHY_TYPE_5GBASE_T: case I40E_PHY_TYPE_10GBASE_T: media = I40E_MEDIA_TYPE_BASET; break; @@ -4900,6 +4904,7 @@ i40e_status i40e_read_phy_register(struct i40e_hw *hw, break; case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: + case I40E_DEV_ID_10G_BASE_T_BC: case I40E_DEV_ID_10G_BASE_T_X722: case I40E_DEV_ID_25G_B: case I40E_DEV_ID_25G_SFP28: diff --git a/drivers/net/ethernet/intel/i40e/i40e_devids.h b/drivers/net/ethernet/intel/i40e/i40e_devids.h index 16be4d5286bd..bac4da031f9b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_devids.h +++ b/drivers/net/ethernet/intel/i40e/i40e_devids.h @@ -20,6 +20,9 @@ #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_10G_BASE_T_BC 0x15FF +#define I40E_DEV_ID_10G_B 0x104F +#define I40E_DEV_ID_10G_SFP 0x104E #define I40E_DEV_ID_KX_X722 0x37CE #define I40E_DEV_ID_QSFP_X722 0x37CF #define I40E_DEV_ID_SFP_X722 0x37D0 diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index d440778f2dc7..7545b21bee3c 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -508,6 +508,20 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, ethtool_link_ksettings_add_link_mode(ks, advertising, 10000baseT_Full); } + if (phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T) { + ethtool_link_ksettings_add_link_mode(ks, supported, + 2500baseT_Full); + if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB) + ethtool_link_ksettings_add_link_mode(ks, advertising, + 2500baseT_Full); + } + if (phy_types & I40E_CAP_PHY_TYPE_5GBASE_T) { + ethtool_link_ksettings_add_link_mode(ks, supported, + 5000baseT_Full); + if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB) + ethtool_link_ksettings_add_link_mode(ks, advertising, + 5000baseT_Full); + } if (phy_types & I40E_CAP_PHY_TYPE_XLAUI || phy_types & I40E_CAP_PHY_TYPE_XLPPI || phy_types & I40E_CAP_PHY_TYPE_40GBASE_AOC) @@ -674,13 +688,15 @@ static void i40e_phy_type_to_ethtool(struct i40e_pf *pf, phy_types & I40E_CAP_PHY_TYPE_25GBASE_KR || phy_types & I40E_CAP_PHY_TYPE_25GBASE_CR || phy_types & I40E_CAP_PHY_TYPE_20GBASE_KR2 || - phy_types & I40E_CAP_PHY_TYPE_10GBASE_T || phy_types & I40E_CAP_PHY_TYPE_10GBASE_SR || phy_types & I40E_CAP_PHY_TYPE_10GBASE_LR || phy_types & I40E_CAP_PHY_TYPE_10GBASE_KX4 || phy_types & I40E_CAP_PHY_TYPE_10GBASE_KR || phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1_CU || phy_types & I40E_CAP_PHY_TYPE_10GBASE_CR1 || + phy_types & I40E_CAP_PHY_TYPE_10GBASE_T || + phy_types & I40E_CAP_PHY_TYPE_5GBASE_T || + phy_types & I40E_CAP_PHY_TYPE_2_5GBASE_T || phy_types & I40E_CAP_PHY_TYPE_1000BASE_T_OPTICAL || phy_types & I40E_CAP_PHY_TYPE_1000BASE_T || phy_types & I40E_CAP_PHY_TYPE_1000BASE_SX || @@ -790,11 +806,17 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, 10000baseT_Full); break; case I40E_PHY_TYPE_10GBASE_T: + case I40E_PHY_TYPE_5GBASE_T: + case I40E_PHY_TYPE_2_5GBASE_T: case I40E_PHY_TYPE_1000BASE_T: case I40E_PHY_TYPE_100BASE_TX: ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg); ethtool_link_ksettings_add_link_mode(ks, supported, 10000baseT_Full); + ethtool_link_ksettings_add_link_mode(ks, supported, + 5000baseT_Full); + ethtool_link_ksettings_add_link_mode(ks, supported, + 2500baseT_Full); ethtool_link_ksettings_add_link_mode(ks, supported, 1000baseT_Full); ethtool_link_ksettings_add_link_mode(ks, supported, @@ -803,6 +825,12 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, if (hw_link_info->requested_speeds & I40E_LINK_SPEED_10GB) ethtool_link_ksettings_add_link_mode(ks, advertising, 10000baseT_Full); + if (hw_link_info->requested_speeds & I40E_LINK_SPEED_5GB) + ethtool_link_ksettings_add_link_mode(ks, advertising, + 5000baseT_Full); + if (hw_link_info->requested_speeds & I40E_LINK_SPEED_2_5GB) + ethtool_link_ksettings_add_link_mode(ks, advertising, + 2500baseT_Full); if (hw_link_info->requested_speeds & I40E_LINK_SPEED_1GB) ethtool_link_ksettings_add_link_mode(ks, advertising, 1000baseT_Full); @@ -958,6 +986,12 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw, case I40E_LINK_SPEED_10GB: ks->base.speed = SPEED_10000; break; + case I40E_LINK_SPEED_5GB: + ks->base.speed = SPEED_5000; + break; + case I40E_LINK_SPEED_2_5GB: + ks->base.speed = SPEED_2500; + break; case I40E_LINK_SPEED_1GB: ks->base.speed = SPEED_1000; break; @@ -1243,6 +1277,12 @@ static int i40e_set_link_ksettings(struct net_device *netdev, ethtool_link_ksettings_test_link_mode(ks, advertising, 10000baseLR_Full)) config.link_speed |= I40E_LINK_SPEED_10GB; + if (ethtool_link_ksettings_test_link_mode(ks, advertising, + 2500baseT_Full)) + config.link_speed |= I40E_LINK_SPEED_2_5GB; + if (ethtool_link_ksettings_test_link_mode(ks, advertising, + 5000baseT_Full)) + config.link_speed |= I40E_LINK_SPEED_5GB; if (ethtool_link_ksettings_test_link_mode(ks, advertising, 20000baseKR2_Full)) config.link_speed |= I40E_LINK_SPEED_20GB; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 7116207320fb..320562b39686 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -73,6 +73,8 @@ static const struct pci_device_id i40e_pci_tbl[] = { {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_C), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_BASE_T4), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_SFP), 0}, + {PCI_VDEVICE(INTEL, I40E_DEV_ID_10G_B), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_KX_X722), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_QSFP_X722), 0}, {PCI_VDEVICE(INTEL, I40E_DEV_ID_SFP_X722), 0}, @@ -6520,6 +6522,12 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup) case I40E_LINK_SPEED_10GB: speed = "10 G"; break; + case I40E_LINK_SPEED_5GB: + speed = "5 G"; + break; + case I40E_LINK_SPEED_2_5GB: + speed = "2.5 G"; + break; case I40E_LINK_SPEED_1GB: speed = "1000 M"; break; diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 820af0043cc8..8f43aa47c263 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -252,6 +252,12 @@ struct i40e_phy_info { I40E_PHY_TYPE_OFFSET) #define I40E_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC + \ I40E_PHY_TYPE_OFFSET) +/* Offset for 2.5G/5G PHY Types value to bit number conversion */ +#define I40E_PHY_TYPE_OFFSET2 (-10) +#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T + \ + I40E_PHY_TYPE_OFFSET2) +#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T + \ + I40E_PHY_TYPE_OFFSET2) #define I40E_HW_CAP_MAX_GPIO 30 /* Capabilities of a PF or a VF or the whole device */ struct i40e_hw_capabilities { -- cgit v1.2.3-59-g8ed1b From d29e0d233e0d25ac680cb77662fca1193732c4a5 Mon Sep 17 00:00:00 2001 From: Martyna Szapar Date: Fri, 29 Mar 2019 15:08:39 -0700 Subject: i40e: missing input validation on VF message handling by the PF Patch is adding missing input validation on VF message handling by the PF to the functions with opcodes: VIRTCHNL_OP_CONFIG_VSI_QUEUES = 6 VIRTCHNL_OP_CONFIG_IRQ_MAP = 7, VIRTCHNL_OP_DISABLE_QUEUES = 9, VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE = 14, Signed-off-by: Martyna Szapar Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 58 ++++++++++++++++------ drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h | 2 + 2 files changed, 46 insertions(+), 14 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index d0e3677b7dc8..6a812eeaba8d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -2014,6 +2014,16 @@ static int i40e_vc_config_promiscuous_mode_msg(struct i40e_vf *vf, u8 *msg) goto err_out; } + if (info->flags > I40E_MAX_VF_PROMISC_FLAGS) { + aq_ret = I40E_ERR_PARAM; + goto err_out; + } + + if (!i40e_vc_isvalid_vsi_id(vf, info->vsi_id)) { + aq_ret = I40E_ERR_PARAM; + goto err_out; + } + /* Multicast promiscuous handling*/ if (info->flags & FLAG_VF_MULTICAST_PROMISC) allmulti = true; @@ -2068,17 +2078,16 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) struct virtchnl_queue_pair_info *qpi; struct i40e_pf *pf = vf->pf; u16 vsi_id, vsi_queue_id = 0; + u16 num_qps_all = 0; i40e_status aq_ret = 0; int i, j = 0, idx = 0; - vsi_id = qci->vsi_id; - if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { aq_ret = I40E_ERR_PARAM; goto error_param; } - if (!i40e_vc_isvalid_vsi_id(vf, vsi_id)) { + if (!i40e_vc_isvalid_vsi_id(vf, qci->vsi_id)) { aq_ret = I40E_ERR_PARAM; goto error_param; } @@ -2088,10 +2097,27 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) goto error_param; } + if (vf->adq_enabled) { + for (i = 0; i < I40E_MAX_VF_VSI; i++) + num_qps_all += vf->ch[i].num_qps; + if (num_qps_all != qci->num_queue_pairs) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } + } + + vsi_id = qci->vsi_id; + for (i = 0; i < qci->num_queue_pairs; i++) { qpi = &qci->qpair[i]; if (!vf->adq_enabled) { + if (!i40e_vc_isvalid_queue_id(vf, vsi_id, + qpi->txq.queue_id)) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } + vsi_queue_id = qpi->txq.queue_id; if (qpi->txq.vsi_id != qci->vsi_id || @@ -2102,10 +2128,8 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) } } - if (!i40e_vc_isvalid_queue_id(vf, vsi_id, vsi_queue_id)) { - aq_ret = I40E_ERR_PARAM; - goto error_param; - } + if (vf->adq_enabled) + vsi_id = vf->ch[idx].vsi_id; if (i40e_config_vsi_rx_queue(vf, vsi_id, vsi_queue_id, &qpi->rxq) || @@ -2129,7 +2153,6 @@ static int i40e_vc_config_queues_msg(struct i40e_vf *vf, u8 *msg) j++; vsi_queue_id++; } - vsi_id = vf->ch[idx].vsi_id; } } /* set vsi num_queue_pairs in use to num configured by VF */ @@ -2188,7 +2211,7 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg) struct virtchnl_irq_map_info *irqmap_info = (struct virtchnl_irq_map_info *)msg; struct virtchnl_vector_map *map; - u16 vsi_id, vector_id; + u16 vsi_id; i40e_status aq_ret = 0; int i; @@ -2197,16 +2220,21 @@ static int i40e_vc_config_irq_map_msg(struct i40e_vf *vf, u8 *msg) goto error_param; } + if (irqmap_info->num_vectors > + vf->pf->hw.func_caps.num_msix_vectors_vf) { + aq_ret = I40E_ERR_PARAM; + goto error_param; + } + for (i = 0; i < irqmap_info->num_vectors; i++) { map = &irqmap_info->vecmap[i]; - vector_id = map->vector_id; - vsi_id = map->vsi_id; /* validate msg params */ - if (!i40e_vc_isvalid_vector_id(vf, vector_id) || - !i40e_vc_isvalid_vsi_id(vf, vsi_id)) { + if (!i40e_vc_isvalid_vector_id(vf, map->vector_id) || + !i40e_vc_isvalid_vsi_id(vf, map->vsi_id)) { aq_ret = I40E_ERR_PARAM; goto error_param; } + vsi_id = map->vsi_id; if (i40e_validate_queue_map(vf, vsi_id, map->rxq_map)) { aq_ret = I40E_ERR_PARAM; @@ -2354,7 +2382,9 @@ static int i40e_vc_disable_queues_msg(struct i40e_vf *vf, u8 *msg) goto error_param; } - if ((0 == vqs->rx_queues) && (0 == vqs->tx_queues)) { + if ((vqs->rx_queues == 0 && vqs->tx_queues == 0) || + vqs->rx_queues > I40E_MAX_VF_QUEUES || + vqs->tx_queues > I40E_MAX_VF_QUEUES) { aq_ret = I40E_ERR_PARAM; goto error_param; } diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h index f9621026beef..f65cc0c16550 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h @@ -17,6 +17,8 @@ #define I40E_VLAN_MASK 0xFFF #define I40E_PRIORITY_MASK 0xE000 +#define I40E_MAX_VF_PROMISC_FLAGS 3 + /* Various queue ctrls */ enum i40e_queue_ctrl { I40E_QUEUE_CTRL_UNKNOWN = 0, -- cgit v1.2.3-59-g8ed1b From 0a92892c69bd01b1a9481ef49587f60e97c64042 Mon Sep 17 00:00:00 2001 From: Maciej Paczkowski Date: Fri, 29 Mar 2019 15:08:40 -0700 Subject: i40e: Revert ShadowRAM checksum calculation change The reason of this revert is unexpected issue found in NVM Update tool during NVM image downgrade. The implementation is no longer needed since the QV tools are already aware of new FW double ShadowRAM dump mechanism. This patch reverts ShadowRAM checksum calculation change introduced in commit 9d12f0c4e436 ("i40e: Revert ShadowRAM checksum calculation change") Signed-off-by: Maciej Paczkowski Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_nvm.c | 28 +++------------------------- 1 file changed, 3 insertions(+), 25 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index ee89779a9a6f..c508b75c3c09 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c @@ -574,36 +574,14 @@ i40e_calc_nvm_checksum_exit: i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw) { i40e_status ret_code; - u16 checksum, checksum_sr; + u16 checksum; __le16 le_sum; ret_code = i40e_calc_nvm_checksum(hw, &checksum); - if (ret_code) - return ret_code; - le_sum = cpu_to_le16(checksum); - ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, - 1, &le_sum, true); - if (ret_code) - return ret_code; - - /* Due to changes in FW the SW is required to perform double SR-dump - * in some cases. SR-dump is the process when internal shadow RAM is - * dumped into flash bank. It is triggered by setting "last_command" - * argument in i40e_write_nvm_aq function call. - * Since FW 1.8 we need to calculate SR checksum again and update it - * in flash if it is not equal to previously computed checksum. - * This situation would occur only in FW >= 1.8 - */ - ret_code = i40e_calc_nvm_checksum(hw, &checksum_sr); - if (ret_code) - return ret_code; - if (checksum_sr != checksum) { - le_sum = cpu_to_le16(checksum_sr); - ret_code = i40e_write_nvm_aq(hw, 0x00, - I40E_SR_SW_CHECKSUM_WORD, + if (!ret_code) + ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD, 1, &le_sum, true); - } return ret_code; } -- cgit v1.2.3-59-g8ed1b From 825f0a4eb7fa9106a64ca8a2e62c37cc9766fdb9 Mon Sep 17 00:00:00 2001 From: "Gustavo A. R. Silva" Date: Fri, 29 Mar 2019 16:38:49 -0700 Subject: i40e: Use struct_size() in kzalloc() One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example: struct foo { int stuff; struct boo entry[]; }; size = sizeof(struct foo) + count * sizeof(struct boo); instance = kzalloc(size, GFP_KERNEL) Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper: instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL) Notice that, in this case, variable size is not necessary, hence it is removed. This code was detected with the help of Coccinelle. Signed-off-by: "Gustavo A. R. Silva" Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_client.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c index 5f3b8b9ff511..e81530ca08d0 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_client.c +++ b/drivers/net/ethernet/intel/i40e/i40e_client.c @@ -578,11 +578,9 @@ static int i40e_client_setup_qvlist(struct i40e_info *ldev, struct i40e_hw *hw = &pf->hw; struct i40e_qv_info *qv_info; u32 v_idx, i, reg_idx, reg; - u32 size; - size = sizeof(struct i40e_qvlist_info) + - (sizeof(struct i40e_qv_info) * (qvlist_info->num_vectors - 1)); - ldev->qvlist_info = kzalloc(size, GFP_KERNEL); + ldev->qvlist_info = kzalloc(struct_size(ldev->qvlist_info, qv_info, + qvlist_info->num_vectors - 1), GFP_KERNEL); if (!ldev->qvlist_info) return -ENOMEM; ldev->qvlist_info->num_vectors = qvlist_info->num_vectors; -- cgit v1.2.3-59-g8ed1b From 24474f2709af6729b9b1da1c5e160ab62e25e3a4 Mon Sep 17 00:00:00 2001 From: Martyna Szapar Date: Mon, 15 Apr 2019 14:43:07 -0700 Subject: i40e: Fix of memory leak and integer truncation in i40e_virtchnl.c Fixed possible memory leak in i40e_vc_add_cloud_filter function: cfilter is being allocated and in some error conditions the function returns without freeing the memory. Fix of integer truncation from u16 (type of queue_id value) to u8 when calling i40e_vc_isvalid_queue_id function. Signed-off-by: Martyna Szapar Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index 6a812eeaba8d..ebe18276cea1 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -181,7 +181,7 @@ static inline bool i40e_vc_isvalid_vsi_id(struct i40e_vf *vf, u16 vsi_id) * check for the valid queue id **/ static inline bool i40e_vc_isvalid_queue_id(struct i40e_vf *vf, u16 vsi_id, - u8 qid) + u16 qid) { struct i40e_pf *pf = vf->pf; struct i40e_vsi *vsi = i40e_find_vsi_from_id(pf, vsi_id); @@ -3421,7 +3421,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) if (!test_bit(I40E_VF_STATE_ACTIVE, &vf->vf_states)) { aq_ret = I40E_ERR_PARAM; - goto err; + goto err_out; } if (!vf->adq_enabled) { @@ -3429,7 +3429,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) "VF %d: ADq is not enabled, can't apply cloud filter\n", vf->vf_id); aq_ret = I40E_ERR_PARAM; - goto err; + goto err_out; } if (i40e_validate_cloud_filter(vf, vcf)) { @@ -3437,7 +3437,7 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) "VF %d: Invalid input/s, can't apply cloud filter\n", vf->vf_id); aq_ret = I40E_ERR_PARAM; - goto err; + goto err_out; } cfilter = kzalloc(sizeof(*cfilter), GFP_KERNEL); @@ -3498,13 +3498,17 @@ static int i40e_vc_add_cloud_filter(struct i40e_vf *vf, u8 *msg) "VF %d: Failed to add cloud filter, err %s aq_err %s\n", vf->vf_id, i40e_stat_str(&pf->hw, ret), i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status)); - goto err; + goto err_free; } INIT_HLIST_NODE(&cfilter->cloud_node); hlist_add_head(&cfilter->cloud_node, &vf->cloud_filter_list); + /* release the pointer passing it to the collection */ + cfilter = NULL; vf->num_cloud_filters++; -err: +err_free: + kfree(cfilter); +err_out: return i40e_vc_send_resp_to_vf(vf, VIRTCHNL_OP_ADD_CLOUD_FILTER, aq_ret); } -- cgit v1.2.3-59-g8ed1b From 0b63644602cfcbac849f7ea49272a39e90fa95eb Mon Sep 17 00:00:00 2001 From: Martyna Szapar Date: Thu, 18 Apr 2019 13:31:53 -0700 Subject: i40e: Memory leak in i40e_config_iwarp_qvlist Added freeing the old allocation of vf->qvlist_info in function i40e_config_iwarp_qvlist before overwriting it with the new allocation. Signed-off-by: Martyna Szapar Tested-by: Andrew Bowers Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'drivers/net/ethernet') diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index ebe18276cea1..479bc60c8f71 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -441,6 +441,7 @@ static int i40e_config_iwarp_qvlist(struct i40e_vf *vf, u32 v_idx, i, reg_idx, reg; u32 next_q_idx, next_q_type; u32 msix_vf, size; + int ret = 0; msix_vf = pf->hw.func_caps.num_msix_vectors_vf; @@ -449,16 +450,19 @@ static int i40e_config_iwarp_qvlist(struct i40e_vf *vf, "Incorrect number of iwarp vectors %u. Maximum %u allowed.\n", qvlist_info->num_vectors, msix_vf); - goto err; + ret = -EINVAL; + goto err_out; } size = sizeof(struct virtchnl_iwarp_qvlist_info) + (sizeof(struct virtchnl_iwarp_qv_info) * (qvlist_info->num_vectors - 1)); + kfree(vf->qvlist_info); vf->qvlist_info = kzalloc(size, GFP_KERNEL); - if (!vf->qvlist_info) - return -ENOMEM; - + if (!vf->qvlist_info) { + ret = -ENOMEM; + goto err_out; + } vf->qvlist_info->num_vectors = qvlist_info->num_vectors; msix_vf = pf->hw.func_caps.num_msix_vectors_vf; @@ -469,8 +473,10 @@ static int i40e_config_iwarp_qvlist(struct i40e_vf *vf, v_idx = qv_info->v_idx; /* Validate vector id belongs to this vf */ - if (!i40e_vc_isvalid_vector_id(vf, v_idx)) - goto err; + if (!i40e_vc_isvalid_vector_id(vf, v_idx)) { + ret = -EINVAL; + goto err_free; + } vf->qvlist_info->qv_info[i] = *qv_info; @@ -512,10 +518,11 @@ static int i40e_config_iwarp_qvlist(struct i40e_vf *vf, } return 0; -err: +err_free: kfree(vf->qvlist_info); vf->qvlist_info = NULL; - return -EINVAL; +err_out: + return ret; } /** -- cgit v1.2.3-59-g8ed1b