From ae4393dfd472b194c90d75d2123105fb5ed59b04 Mon Sep 17 00:00:00 2001 From: Magnus Karlsson Date: Mon, 26 Apr 2021 13:14:01 +0200 Subject: [PATCH 1/5] i40e: fix broken XDP support Commit 12738ac4754e ("i40e: Fix sparse errors in i40e_txrx.c") broke XDP support in the i40e driver. That commit was fixing a sparse error in the code by introducing a new variable xdp_res instead of overloading this into the skb pointer. The problem is that the code later uses the skb pointer in if statements and these where not extended to also test for the new xdp_res variable. Fix this by adding the correct tests for xdp_res in these places. The skb pointer was used to store the result of the XDP program by overloading the results in the error pointer ERR_PTR(-result). Therefore, the allocation failure test that used to only test for !skb now need to be extended to also consider !xdp_res. i40e_cleanup_headers() had a check that based on the skb value being an error pointer, i.e. a result from the XDP program != XDP_PASS, and if so start to process a new packet immediately, instead of populating skb fields and sending the skb to the stack. This check is not needed anymore, since we have added an explicit test for xdp_res being set and if so just do continue to pick the next packet from the NIC. Fixes: 12738ac4754e ("i40e: Fix sparse errors in i40e_txrx.c") Acked-by: Jesper Dangaard Brouer Tested-by: Jesper Dangaard Brouer Reported-by: Jesper Dangaard Brouer Reviewed-by: Maciej Fijalkowski Signed-off-by: Magnus Karlsson Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 121cd99fdeff..de70c16ef619 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c @@ -1961,10 +1961,6 @@ static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb, union i40e_rx_desc *rx_desc) { - /* XDP packets use error pointer so abort at this point */ - if (IS_ERR(skb)) - return true; - /* ERR_MASK will only have valid bits if EOP set, and * what we are doing here is actually checking * I40E_RX_DESC_ERROR_RXE_SHIFT, since it is the zeroth bit in @@ -2534,7 +2530,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) } /* exit if we failed to retrieve a buffer */ - if (!skb) { + if (!xdp_res && !skb) { rx_ring->rx_stats.alloc_buff_failed++; rx_buffer->pagecnt_bias++; break; @@ -2547,7 +2543,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget) if (i40e_is_non_eop(rx_ring, rx_desc)) continue; - if (i40e_cleanup_headers(rx_ring, skb, rx_desc)) { + if (xdp_res || i40e_cleanup_headers(rx_ring, skb, rx_desc)) { skb = NULL; continue; } From 38318f23a7ef86a8b1862e5e8078c4de121960c3 Mon Sep 17 00:00:00 2001 From: Yunjian Wang Date: Mon, 12 Apr 2021 22:41:18 +0800 Subject: [PATCH 2/5] i40e: Fix use-after-free in i40e_client_subtask() Currently the call to i40e_client_del_instance frees the object pf->cinst, however pf->cinst->lan_info is being accessed after the free. Fix this by adding the missing return. Addresses-Coverity: ("Read from pointer after free") Fixes: 7b0b1a6d0ac9 ("i40e: Disable iWARP VSI PETCP_ENA flag on netdev down events") Signed-off-by: Yunjian Wang Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c index a2dba32383f6..32f3facbed1a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_client.c +++ b/drivers/net/ethernet/intel/i40e/i40e_client.c @@ -375,6 +375,7 @@ void i40e_client_subtask(struct i40e_pf *pf) clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state); i40e_client_del_instance(pf); + return; } } } From 61343e6da7810de81d6b826698946ae4f9070819 Mon Sep 17 00:00:00 2001 From: Jaroslaw Gawin Date: Tue, 13 Apr 2021 14:19:40 +0000 Subject: [PATCH 3/5] i40e: fix the restart auto-negotiation after FEC modified When FEC mode was changed the link didn't know it because the link was not reset and new parameters were not negotiated. Set a flag 'I40E_AQ_PHY_ENABLE_ATOMIC_LINK' in 'abilities' to restart the link and make it run with the new settings. Fixes: 1d96340196f1 ("i40e: Add support FEC configuration for Fortville 25G") Signed-off-by: Jaroslaw Gawin Signed-off-by: Mateusz Palczewski Tested-by: Dave Switzer Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 040a01400b85..53416787fb7b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -1409,7 +1409,8 @@ static int i40e_set_fec_cfg(struct net_device *netdev, u8 fec_cfg) memset(&config, 0, sizeof(config)); config.phy_type = abilities.phy_type; - config.abilities = abilities.abilities; + config.abilities = abilities.abilities | + I40E_AQ_PHY_ENABLE_ATOMIC_LINK; config.phy_type_ext = abilities.phy_type_ext; config.link_speed = abilities.link_speed; config.eee_capability = abilities.eee_capability; From 15395ec4685bd45a43d1b54b8fd9846b87e2c621 Mon Sep 17 00:00:00 2001 From: Mateusz Palczewski Date: Tue, 13 Apr 2021 14:43:07 +0000 Subject: [PATCH 4/5] i40e: Fix PHY type identifiers for 2.5G and 5G adapters Unlike other supported adapters, 2.5G and 5G use different PHY type identifiers for reading/writing PHY settings and for reading link status. This commit introduces separate PHY identifiers for these two operation types. Fixes: 2e45d3f4677a ("i40e: Add support for X710 B/P & SFP+ cards") Signed-off-by: Dawid Lukwinski Signed-off-by: Mateusz Palczewski Reviewed-by: Aleksandr Loktionov Tested-by: Dave Switzer Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 6 ++++-- drivers/net/ethernet/intel/i40e/i40e_common.c | 4 ++-- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 4 ++-- drivers/net/ethernet/intel/i40e/i40e_type.h | 7 ++----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h index ce626eace692..140b677f114d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h @@ -1566,8 +1566,10 @@ 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_2_5GBASE_T = 0x26, + I40E_PHY_TYPE_5GBASE_T = 0x27, + I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS = 0x30, + I40E_PHY_TYPE_5GBASE_T_LINK_STATUS = 0x31, I40E_PHY_TYPE_MAX, I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD, I40E_PHY_TYPE_EMPTY = 0xFE, diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 41b813fe07a5..67cb0b47416a 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c @@ -1154,8 +1154,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_2_5GBASE_T_LINK_STATUS: + case I40E_PHY_TYPE_5GBASE_T_LINK_STATUS: case I40E_PHY_TYPE_10GBASE_T: media = I40E_MEDIA_TYPE_BASET; break; diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 53416787fb7b..bd527eab002b 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -841,8 +841,8 @@ 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_5GBASE_T_LINK_STATUS: + case I40E_PHY_TYPE_2_5GBASE_T_LINK_STATUS: case I40E_PHY_TYPE_1000BASE_T: case I40E_PHY_TYPE_100BASE_TX: ethtool_link_ksettings_add_link_mode(ks, supported, Autoneg); diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h index 5c10faaca790..c81109a63e90 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_type.h +++ b/drivers/net/ethernet/intel/i40e/i40e_type.h @@ -239,11 +239,8 @@ struct i40e_phy_info { #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_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T) +#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T) #define I40E_HW_CAP_MAX_GPIO 30 /* Capabilities of a PF or a VF or the whole device */ struct i40e_hw_capabilities { From 8085a36db71f54d2592426eb76bdf71b82479140 Mon Sep 17 00:00:00 2001 From: Arkadiusz Kubalewski Date: Fri, 16 Apr 2021 23:43:57 +0200 Subject: [PATCH 5/5] i40e: Remove LLDP frame filters Remove filters from being setup in case of software DCB and allow the LLDP frames to be properly transmitted to the wire. It is not possible to transmit the LLDP frame out of the port, if they are filtered by control VSI. This prohibits software LLDP agent properly communicate its DCB capabilities to the neighbors. Fixes: 4b208eaa8078 ("i40e: Add init and default config of software based DCB") Signed-off-by: Arkadiusz Kubalewski Tested-by: Imam Hassan Reza Biswas Signed-off-by: Tony Nguyen --- drivers/net/ethernet/intel/i40e/i40e.h | 1 - .../net/ethernet/intel/i40e/i40e_ethtool.c | 1 - drivers/net/ethernet/intel/i40e/i40e_main.c | 42 ------------------- 3 files changed, 44 deletions(-) diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 9067cd3ce243..85d3dd3a3339 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h @@ -1144,7 +1144,6 @@ static inline bool i40e_is_sw_dcb(struct i40e_pf *pf) return !!(pf->flags & I40E_FLAG_DISABLE_FW_LLDP); } -void i40e_set_lldp_forwarding(struct i40e_pf *pf, bool enable); #ifdef CONFIG_I40E_DCB void i40e_dcbnl_flush_apps(struct i40e_pf *pf, struct i40e_dcbx_config *old_cfg, diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index bd527eab002b..ccd5b9486ea9 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c @@ -5282,7 +5282,6 @@ flags_complete: i40e_aq_cfg_lldp_mib_change_event(&pf->hw, false, NULL); i40e_aq_stop_lldp(&pf->hw, true, false, NULL); } else { - i40e_set_lldp_forwarding(pf, false); status = i40e_aq_start_lldp(&pf->hw, false, NULL); if (status) { adq_err = pf->hw.aq.asq_last_status; diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c2d145a56b5e..704e474879c5 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -6879,40 +6879,6 @@ out: } #endif /* CONFIG_I40E_DCB */ -/** - * i40e_set_lldp_forwarding - set forwarding of lldp frames - * @pf: PF being configured - * @enable: if forwarding to OS shall be enabled - * - * Toggle forwarding of lldp frames behavior, - * When passing DCB control from firmware to software - * lldp frames must be forwarded to the software based - * lldp agent. - */ -void i40e_set_lldp_forwarding(struct i40e_pf *pf, bool enable) -{ - if (pf->lan_vsi == I40E_NO_VSI) - return; - - if (!pf->vsi[pf->lan_vsi]) - return; - - /* No need to check the outcome, commands may fail - * if desired value is already set - */ - i40e_aq_add_rem_control_packet_filter(&pf->hw, NULL, ETH_P_LLDP, - I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX | - I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC, - pf->vsi[pf->lan_vsi]->seid, 0, - enable, NULL, NULL); - - i40e_aq_add_rem_control_packet_filter(&pf->hw, NULL, ETH_P_LLDP, - I40E_AQC_ADD_CONTROL_PACKET_FLAGS_RX | - I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC, - pf->vsi[pf->lan_vsi]->seid, 0, - enable, NULL, NULL); -} - /** * i40e_print_link_message - print link up or down * @vsi: the VSI for which link needs a message @@ -10736,10 +10702,6 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired) */ i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw, pf->main_vsi_seid); -#ifdef CONFIG_I40E_DCB - if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) - i40e_set_lldp_forwarding(pf, true); -#endif /* CONFIG_I40E_DCB */ /* restart the VSIs that were rebuilt and running before the reset */ i40e_pf_unquiesce_all_vsi(pf); @@ -15772,10 +15734,6 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw, pf->main_vsi_seid); -#ifdef CONFIG_I40E_DCB - if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) - i40e_set_lldp_forwarding(pf, true); -#endif /* CONFIG_I40E_DCB */ if ((pf->hw.device_id == I40E_DEV_ID_10G_BASE_T) || (pf->hw.device_id == I40E_DEV_ID_10G_BASE_T4))