From 398a4f5f9e8f53b55286b3bbda1853b26846d74b Mon Sep 17 00:00:00 2001 From: Selvin Xavier Date: Sun, 24 Sep 2017 09:00:44 -0700 Subject: [PATCH] bnxt_en: Misc bug fixes Add new device ids. Fixes the rtnl_lock issue while loading bnxt_re driver on some of the systems. Signed-off-by: Selvin Xavier --- ...Fix-bnxt_reset-in-the-slow-path-task.patch | 96 +++++++++++++++++++ ...-RTNL-lock-usage-on-bnxt_update_link.patch | 94 ++++++++++++++++++ ...-lock-usage-on-bnxt_get_port_module_.patch | 45 +++++++++ ...I-IDs-for-BCM57452-and-BCM57454-ASIC.patch | 46 +++++++++ 4 files changed, 281 insertions(+) create mode 100644 linux-next-cherry-picks/0059-bnxt_en-Fix-bnxt_reset-in-the-slow-path-task.patch create mode 100644 linux-next-cherry-picks/0060-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_update_link.patch create mode 100644 linux-next-cherry-picks/0061-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_get_port_module_.patch create mode 100644 linux-next-cherry-picks/0062-bnxt_en-Added-PCI-IDs-for-BCM57452-and-BCM57454-ASIC.patch diff --git a/linux-next-cherry-picks/0059-bnxt_en-Fix-bnxt_reset-in-the-slow-path-task.patch b/linux-next-cherry-picks/0059-bnxt_en-Fix-bnxt_reset-in-the-slow-path-task.patch new file mode 100644 index 0000000..31d2496 --- /dev/null +++ b/linux-next-cherry-picks/0059-bnxt_en-Fix-bnxt_reset-in-the-slow-path-task.patch @@ -0,0 +1,96 @@ +From a551ee94ea723b4af9b827c7460f108bc13425ee Mon Sep 17 00:00:00 2001 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:07 -0500 +Subject: [PATCH 1/2] bnxt_en: Fix bnxt_reset() in the slow path task. + +In bnxt_sp_task(), we set a bit BNXT_STATE_IN_SP_TASK so that bnxt_close() +will synchronize and wait for bnxt_sp_task() to finish. Some functions +in bnxt_sp_task() require us to clear BNXT_STATE_IN_SP_TASK and then +acquire rtnl_lock() to prevent race conditions. + +There are some bugs related to this logic. This patch refactors the code +to have common bnxt_rtnl_lock_sp() and bnxt_rtnl_unlock_sp() to handle +the RTNL and the clearing/setting of the bit. Multiple functions will +need the same logic. We also need to move bnxt_reset() to the end of +bnxt_sp_task(). Functions that clear BNXT_STATE_IN_SP_TASK must be the +last functions to be called in bnxt_sp_task(). The common scheme will +handle the condition properly. + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 53e686f..30d7d64 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -6200,23 +6200,32 @@ static void bnxt_timer(unsigned long data) + mod_timer(&bp->timer, jiffies + bp->current_interval); + } + +-/* Only called from bnxt_sp_task() */ +-static void bnxt_reset(struct bnxt *bp, bool silent) ++static void bnxt_rtnl_lock_sp(struct bnxt *bp) + { +- /* bnxt_reset_task() calls bnxt_close_nic() which waits +- * for BNXT_STATE_IN_SP_TASK to clear. +- * If there is a parallel dev_close(), bnxt_close() may be holding ++ /* We are called from bnxt_sp_task which has BNXT_STATE_IN_SP_TASK ++ * set. If the device is being closed, bnxt_close() may be holding + * rtnl() and waiting for BNXT_STATE_IN_SP_TASK to clear. So we + * must clear BNXT_STATE_IN_SP_TASK before holding rtnl(). + */ + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_lock(); +- if (test_bit(BNXT_STATE_OPEN, &bp->state)) +- bnxt_reset_task(bp, silent); ++} ++ ++static void bnxt_rtnl_unlock_sp(struct bnxt *bp) ++{ + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + rtnl_unlock(); + } + ++/* Only called from bnxt_sp_task() */ ++static void bnxt_reset(struct bnxt *bp, bool silent) ++{ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_reset_task(bp, silent); ++ bnxt_rtnl_unlock_sp(bp); ++} ++ + static void bnxt_cfg_ntp_filters(struct bnxt *); + + static void bnxt_sp_task(struct work_struct *work) +@@ -6266,18 +6275,21 @@ static void bnxt_sp_task(struct work_struct *work) + bnxt_hwrm_tunnel_dst_port_free( + bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE); + } +- if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) +- bnxt_reset(bp, false); +- +- if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) +- bnxt_reset(bp, true); +- + if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) + bnxt_get_port_module_status(bp); + + if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_port_qstats(bp); + ++ /* These functions below will clear BNXT_STATE_IN_SP_TASK. They ++ * must be the last functions to be called before exiting. ++ */ ++ if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) ++ bnxt_reset(bp, false); ++ ++ if (test_and_clear_bit(BNXT_RESET_TASK_SILENT_SP_EVENT, &bp->sp_event)) ++ bnxt_reset(bp, true); ++ + smp_mb__before_atomic(); + clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + } +-- +2.5.5 + diff --git a/linux-next-cherry-picks/0060-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_update_link.patch b/linux-next-cherry-picks/0060-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_update_link.patch new file mode 100644 index 0000000..0d18377 --- /dev/null +++ b/linux-next-cherry-picks/0060-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_update_link.patch @@ -0,0 +1,94 @@ +From 0eaa24b971ae251ae9d3be23f77662a655532063 Mon Sep 17 00:00:00 2001 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:08 -0500 +Subject: [PATCH 2/2] bnxt_en: Fix RTNL lock usage on bnxt_update_link(). + +bnxt_update_link() is called from multiple code paths. Most callers, +such as open, ethtool, already hold RTNL. Only the caller bnxt_sp_task() +does not. So it is a bug to take RTNL inside bnxt_update_link(). + +Fix it by removing the RTNL inside bnxt_update_link(). The function +now expects the caller to always hold RTNL. + +In bnxt_sp_task(), call bnxt_rtnl_lock_sp() before calling +bnxt_update_link(). We also need to move the call to the end of +bnxt_sp_task() since it will be clearing the BNXT_STATE_IN_SP_TASK bit. + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 30d7d64..69b0fce 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -5314,17 +5314,12 @@ static int bnxt_update_link(struct bnxt *bp, bool chng_link_state) + if ((link_info->support_auto_speeds | diff) != + link_info->support_auto_speeds) { + /* An advertised speed is no longer supported, so we need to +- * update the advertisement settings. See bnxt_reset() for +- * comments about the rtnl_lock() sequence below. ++ * update the advertisement settings. Caller holds RTNL ++ * so we can modify link settings. + */ +- clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); +- rtnl_lock(); + link_info->advertising = link_info->support_auto_speeds; +- if (test_bit(BNXT_STATE_OPEN, &bp->state) && +- (link_info->autoneg & BNXT_AUTONEG_SPEED)) ++ if (link_info->autoneg & BNXT_AUTONEG_SPEED) + bnxt_hwrm_set_link_setting(bp, true, false); +- set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); +- rtnl_unlock(); + } + return 0; + } +@@ -6231,7 +6226,6 @@ static void bnxt_cfg_ntp_filters(struct bnxt *); + static void bnxt_sp_task(struct work_struct *work) + { + struct bnxt *bp = container_of(work, struct bnxt, sp_task); +- int rc; + + set_bit(BNXT_STATE_IN_SP_TASK, &bp->state); + smp_mb__after_atomic(); +@@ -6245,16 +6239,6 @@ static void bnxt_sp_task(struct work_struct *work) + + if (test_and_clear_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event)) + bnxt_cfg_ntp_filters(bp); +- if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { +- if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, +- &bp->sp_event)) +- bnxt_hwrm_phy_qcaps(bp); +- +- rc = bnxt_update_link(bp, true); +- if (rc) +- netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", +- rc); +- } + if (test_and_clear_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_exec_fwd_req(bp); + if (test_and_clear_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event)) { +@@ -6284,6 +6268,21 @@ static void bnxt_sp_task(struct work_struct *work) + /* These functions below will clear BNXT_STATE_IN_SP_TASK. They + * must be the last functions to be called before exiting. + */ ++ if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { ++ int rc = 0; ++ ++ if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, ++ &bp->sp_event)) ++ bnxt_hwrm_phy_qcaps(bp); ++ ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ rc = bnxt_update_link(bp, true); ++ bnxt_rtnl_unlock_sp(bp); ++ if (rc) ++ netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", ++ rc); ++ } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, false); + +-- +2.5.5 + diff --git a/linux-next-cherry-picks/0061-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_get_port_module_.patch b/linux-next-cherry-picks/0061-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_get_port_module_.patch new file mode 100644 index 0000000..f48e8b5 --- /dev/null +++ b/linux-next-cherry-picks/0061-bnxt_en-Fix-RTNL-lock-usage-on-bnxt_get_port_module_.patch @@ -0,0 +1,45 @@ +From 90c694bb71819fb5bd3501ac397307d7e41ddeca Mon Sep 17 00:00:00 2001 +From: Michael Chan +Date: Wed, 25 Jan 2017 02:55:09 -0500 +Subject: [PATCH 3/3] bnxt_en: Fix RTNL lock usage on + bnxt_get_port_module_status(). + +bnxt_get_port_module_status() calls bnxt_update_link() which expects +RTNL to be held. In bnxt_sp_task() that does not hold RTNL, we need to +call it with a prior call to bnxt_rtnl_lock_sp() and the call needs to +be moved to the end of bnxt_sp_task(). + +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +Signed-off-by: Selvin Xavier + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index 69b0fce..4fcc6a8 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -6259,9 +6259,6 @@ static void bnxt_sp_task(struct work_struct *work) + bnxt_hwrm_tunnel_dst_port_free( + bp, TUNNEL_DST_PORT_FREE_REQ_TUNNEL_TYPE_GENEVE); + } +- if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) +- bnxt_get_port_module_status(bp); +- + if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) + bnxt_hwrm_port_qstats(bp); + +@@ -6283,6 +6280,12 @@ static void bnxt_sp_task(struct work_struct *work) + netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", + rc); + } ++ if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) { ++ bnxt_rtnl_lock_sp(bp); ++ if (test_bit(BNXT_STATE_OPEN, &bp->state)) ++ bnxt_get_port_module_status(bp); ++ bnxt_rtnl_unlock_sp(bp); ++ } + if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) + bnxt_reset(bp, false); + +-- +2.5.5 + diff --git a/linux-next-cherry-picks/0062-bnxt_en-Added-PCI-IDs-for-BCM57452-and-BCM57454-ASIC.patch b/linux-next-cherry-picks/0062-bnxt_en-Added-PCI-IDs-for-BCM57452-and-BCM57454-ASIC.patch new file mode 100644 index 0000000..5bad3f5 --- /dev/null +++ b/linux-next-cherry-picks/0062-bnxt_en-Added-PCI-IDs-for-BCM57452-and-BCM57454-ASIC.patch @@ -0,0 +1,46 @@ +From 32b40798c1b40343641f04cdfd09652af70ea0e9 Mon Sep 17 00:00:00 2001 +From: Deepak Khungar +Date: Sun, 12 Feb 2017 19:18:18 -0500 +Subject: [PATCH] bnxt_en: Added PCI IDs for BCM57452 and BCM57454 ASICs + +Signed-off-by: Deepak Khungar +Signed-off-by: Michael Chan +Signed-off-by: David S. Miller +--- + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +index c899d61..71f9a18 100644 +--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c ++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c +@@ -99,6 +99,8 @@ enum board_idx { + BCM57407_NPAR, + BCM57414_NPAR, + BCM57416_NPAR, ++ BCM57452, ++ BCM57454, + NETXTREME_E_VF, + NETXTREME_C_VF, + }; +@@ -133,6 +135,8 @@ static const struct { + { "Broadcom BCM57407 NetXtreme-E Ethernet Partition" }, + { "Broadcom BCM57414 NetXtreme-E Ethernet Partition" }, + { "Broadcom BCM57416 NetXtreme-E Ethernet Partition" }, ++ { "Broadcom BCM57452 NetXtreme-E 10Gb/25Gb/40Gb/50Gb Ethernet" }, ++ { "Broadcom BCM57454 NetXtreme-E 10Gb/25Gb/40Gb/50Gb/100Gb Ethernet" }, + { "Broadcom NetXtreme-E Ethernet Virtual Function" }, + { "Broadcom NetXtreme-C Ethernet Virtual Function" }, + }; +@@ -168,6 +172,8 @@ static const struct pci_device_id bnxt_pci_tbl[] = { + { PCI_VDEVICE(BROADCOM, 0x16ed), .driver_data = BCM57414_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x16ee), .driver_data = BCM57416_NPAR }, + { PCI_VDEVICE(BROADCOM, 0x16ef), .driver_data = BCM57416_NPAR }, ++ { PCI_VDEVICE(BROADCOM, 0x16f1), .driver_data = BCM57452 }, ++ { PCI_VDEVICE(BROADCOM, 0x1614), .driver_data = BCM57454 }, + #ifdef CONFIG_BNXT_SRIOV + { PCI_VDEVICE(BROADCOM, 0x16c1), .driver_data = NETXTREME_E_VF }, + { PCI_VDEVICE(BROADCOM, 0x16cb), .driver_data = NETXTREME_C_VF }, +-- +2.5.5 + -- 2.46.0