Commit 0a3445b8 authored by David S. Miller's avatar David S. Miller

Merge branch 'bnxt_en-Bug-fixes'

Michael Chan says:

====================
bnxt_en: Bug fixes.

This set of driver patches include bug fixes for ethtool get channels,
ethtool statistics, ethtool NVRAM, AER recovery, a firmware reset issue
that could potentially crash, hwmon temperature reporting issue on VF,
and 2 fixes for regressions introduced by the recent user-defined RSS
map feature.

Please queue patches 1 to 6 for -stable.  Thanks.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2e1ec861 b43b9f53
...@@ -1141,6 +1141,9 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, ...@@ -1141,6 +1141,9 @@ static int bnxt_discard_rx(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
static void bnxt_queue_fw_reset_work(struct bnxt *bp, unsigned long delay) static void bnxt_queue_fw_reset_work(struct bnxt *bp, unsigned long delay)
{ {
if (!(test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)))
return;
if (BNXT_PF(bp)) if (BNXT_PF(bp))
queue_delayed_work(bnxt_pf_wq, &bp->fw_reset_task, delay); queue_delayed_work(bnxt_pf_wq, &bp->fw_reset_task, delay);
else else
...@@ -1157,10 +1160,12 @@ static void bnxt_queue_sp_work(struct bnxt *bp) ...@@ -1157,10 +1160,12 @@ static void bnxt_queue_sp_work(struct bnxt *bp)
static void bnxt_cancel_sp_work(struct bnxt *bp) static void bnxt_cancel_sp_work(struct bnxt *bp)
{ {
if (BNXT_PF(bp)) if (BNXT_PF(bp)) {
flush_workqueue(bnxt_pf_wq); flush_workqueue(bnxt_pf_wq);
else } else {
cancel_work_sync(&bp->sp_task); cancel_work_sync(&bp->sp_task);
cancel_delayed_work_sync(&bp->fw_reset_task);
}
} }
static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr)
...@@ -6102,6 +6107,21 @@ static int bnxt_get_func_stat_ctxs(struct bnxt *bp) ...@@ -6102,6 +6107,21 @@ static int bnxt_get_func_stat_ctxs(struct bnxt *bp)
return cp + ulp_stat; return cp + ulp_stat;
} }
/* Check if a default RSS map needs to be setup. This function is only
* used on older firmware that does not require reserving RX rings.
*/
static void bnxt_check_rss_tbl_no_rmgr(struct bnxt *bp)
{
struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
/* The RSS map is valid for RX rings set to resv_rx_rings */
if (hw_resc->resv_rx_rings != bp->rx_nr_rings) {
hw_resc->resv_rx_rings = bp->rx_nr_rings;
if (!netif_is_rxfh_configured(bp->dev))
bnxt_set_dflt_rss_indir_tbl(bp);
}
}
static bool bnxt_need_reserve_rings(struct bnxt *bp) static bool bnxt_need_reserve_rings(struct bnxt *bp)
{ {
struct bnxt_hw_resc *hw_resc = &bp->hw_resc; struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
...@@ -6110,22 +6130,28 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp) ...@@ -6110,22 +6130,28 @@ static bool bnxt_need_reserve_rings(struct bnxt *bp)
int rx = bp->rx_nr_rings, stat; int rx = bp->rx_nr_rings, stat;
int vnic = 1, grp = rx; int vnic = 1, grp = rx;
if (bp->hwrm_spec_code < 0x10601) if (hw_resc->resv_tx_rings != bp->tx_nr_rings &&
return false; bp->hwrm_spec_code >= 0x10601)
if (hw_resc->resv_tx_rings != bp->tx_nr_rings)
return true; return true;
/* Old firmware does not need RX ring reservations but we still
* need to setup a default RSS map when needed. With new firmware
* we go through RX ring reservations first and then set up the
* RSS map for the successfully reserved RX rings when needed.
*/
if (!BNXT_NEW_RM(bp)) {
bnxt_check_rss_tbl_no_rmgr(bp);
return false;
}
if ((bp->flags & BNXT_FLAG_RFS) && !(bp->flags & BNXT_FLAG_CHIP_P5)) if ((bp->flags & BNXT_FLAG_RFS) && !(bp->flags & BNXT_FLAG_CHIP_P5))
vnic = rx + 1; vnic = rx + 1;
if (bp->flags & BNXT_FLAG_AGG_RINGS) if (bp->flags & BNXT_FLAG_AGG_RINGS)
rx <<= 1; rx <<= 1;
stat = bnxt_get_func_stat_ctxs(bp); stat = bnxt_get_func_stat_ctxs(bp);
if (BNXT_NEW_RM(bp) && if (hw_resc->resv_rx_rings != rx || hw_resc->resv_cp_rings != cp ||
(hw_resc->resv_rx_rings != rx || hw_resc->resv_cp_rings != cp || hw_resc->resv_vnics != vnic || hw_resc->resv_stat_ctxs != stat ||
hw_resc->resv_vnics != vnic || hw_resc->resv_stat_ctxs != stat || (hw_resc->resv_hw_ring_grps != grp &&
(hw_resc->resv_hw_ring_grps != grp && !(bp->flags & BNXT_FLAG_CHIP_P5)))
!(bp->flags & BNXT_FLAG_CHIP_P5))))
return true; return true;
if ((bp->flags & BNXT_FLAG_CHIP_P5) && BNXT_PF(bp) && if ((bp->flags & BNXT_FLAG_CHIP_P5) && BNXT_PF(bp) &&
hw_resc->resv_irqs != nq) hw_resc->resv_irqs != nq)
...@@ -6214,6 +6240,9 @@ static int __bnxt_reserve_rings(struct bnxt *bp) ...@@ -6214,6 +6240,9 @@ static int __bnxt_reserve_rings(struct bnxt *bp)
if (!tx || !rx || !cp || !grp || !vnic || !stat) if (!tx || !rx || !cp || !grp || !vnic || !stat)
return -ENOMEM; return -ENOMEM;
if (!netif_is_rxfh_configured(bp->dev))
bnxt_set_dflt_rss_indir_tbl(bp);
return rc; return rc;
} }
...@@ -8495,9 +8524,6 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) ...@@ -8495,9 +8524,6 @@ int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init)
rc = bnxt_init_int_mode(bp); rc = bnxt_init_int_mode(bp);
bnxt_ulp_irq_restart(bp, rc); bnxt_ulp_irq_restart(bp, rc);
} }
if (!netif_is_rxfh_configured(bp->dev))
bnxt_set_dflt_rss_indir_tbl(bp);
if (rc) { if (rc) {
netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc); netdev_err(bp->dev, "ring reservation/IRQ init failure rc: %d\n", rc);
return rc; return rc;
...@@ -9284,16 +9310,19 @@ static ssize_t bnxt_show_temp(struct device *dev, ...@@ -9284,16 +9310,19 @@ static ssize_t bnxt_show_temp(struct device *dev,
struct hwrm_temp_monitor_query_input req = {0}; struct hwrm_temp_monitor_query_input req = {0};
struct hwrm_temp_monitor_query_output *resp; struct hwrm_temp_monitor_query_output *resp;
struct bnxt *bp = dev_get_drvdata(dev); struct bnxt *bp = dev_get_drvdata(dev);
u32 temp = 0; u32 len = 0;
resp = bp->hwrm_cmd_resp_addr; resp = bp->hwrm_cmd_resp_addr;
bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1); bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_TEMP_MONITOR_QUERY, -1, -1);
mutex_lock(&bp->hwrm_cmd_lock); mutex_lock(&bp->hwrm_cmd_lock);
if (!_hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT)) if (!_hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT))
temp = resp->temp * 1000; /* display millidegree */ len = sprintf(buf, "%u\n", resp->temp * 1000); /* display millidegree */
mutex_unlock(&bp->hwrm_cmd_lock); mutex_unlock(&bp->hwrm_cmd_lock);
return sprintf(buf, "%u\n", temp); if (len)
return len;
return sprintf(buf, "unknown\n");
} }
static SENSOR_DEVICE_ATTR(temp1_input, 0444, bnxt_show_temp, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_input, 0444, bnxt_show_temp, NULL, 0);
...@@ -11761,6 +11790,7 @@ static void bnxt_remove_one(struct pci_dev *pdev) ...@@ -11761,6 +11790,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
unregister_netdev(dev); unregister_netdev(dev);
bnxt_dl_unregister(bp); bnxt_dl_unregister(bp);
bnxt_shutdown_tc(bp); bnxt_shutdown_tc(bp);
clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
bnxt_cancel_sp_work(bp); bnxt_cancel_sp_work(bp);
bp->sp_event = 0; bp->sp_event = 0;
...@@ -12200,6 +12230,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -12200,6 +12230,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (BNXT_CHIP_P5(bp)) if (BNXT_CHIP_P5(bp))
bp->flags |= BNXT_FLAG_CHIP_P5; bp->flags |= BNXT_FLAG_CHIP_P5;
rc = bnxt_alloc_rss_indir_tbl(bp);
if (rc)
goto init_err_pci_clean;
rc = bnxt_fw_init_one_p2(bp); rc = bnxt_fw_init_one_p2(bp);
if (rc) if (rc)
goto init_err_pci_clean; goto init_err_pci_clean;
...@@ -12304,11 +12338,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -12304,11 +12338,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
*/ */
bp->tx_nr_rings_per_tc = bp->tx_nr_rings; bp->tx_nr_rings_per_tc = bp->tx_nr_rings;
rc = bnxt_alloc_rss_indir_tbl(bp);
if (rc)
goto init_err_pci_clean;
bnxt_set_dflt_rss_indir_tbl(bp);
if (BNXT_PF(bp)) { if (BNXT_PF(bp)) {
if (!bnxt_pf_wq) { if (!bnxt_pf_wq) {
bnxt_pf_wq = bnxt_pf_wq =
...@@ -12339,6 +12368,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -12339,6 +12368,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
(long)pci_resource_start(pdev, 0), dev->dev_addr); (long)pci_resource_start(pdev, 0), dev->dev_addr);
pcie_print_link_status(pdev); pcie_print_link_status(pdev);
pci_save_state(pdev);
return 0; return 0;
init_err_cleanup: init_err_cleanup:
...@@ -12536,6 +12566,8 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev) ...@@ -12536,6 +12566,8 @@ static pci_ers_result_t bnxt_io_slot_reset(struct pci_dev *pdev)
"Cannot re-enable PCI device after reset.\n"); "Cannot re-enable PCI device after reset.\n");
} else { } else {
pci_set_master(pdev); pci_set_master(pdev);
pci_restore_state(pdev);
pci_save_state(pdev);
err = bnxt_hwrm_func_reset(bp); err = bnxt_hwrm_func_reset(bp);
if (!err) { if (!err) {
......
...@@ -472,20 +472,13 @@ static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp) ...@@ -472,20 +472,13 @@ static int bnxt_get_num_tpa_ring_stats(struct bnxt *bp)
static int bnxt_get_num_ring_stats(struct bnxt *bp) static int bnxt_get_num_ring_stats(struct bnxt *bp)
{ {
int rx, tx, cmn; int rx, tx, cmn;
bool sh = false;
if (bp->flags & BNXT_FLAG_SHARED_RINGS)
sh = true;
rx = NUM_RING_RX_HW_STATS + NUM_RING_RX_SW_STATS + rx = NUM_RING_RX_HW_STATS + NUM_RING_RX_SW_STATS +
bnxt_get_num_tpa_ring_stats(bp); bnxt_get_num_tpa_ring_stats(bp);
tx = NUM_RING_TX_HW_STATS; tx = NUM_RING_TX_HW_STATS;
cmn = NUM_RING_CMN_SW_STATS; cmn = NUM_RING_CMN_SW_STATS;
if (sh) return rx * bp->rx_nr_rings + tx * bp->tx_nr_rings +
return (rx + tx + cmn) * bp->cp_nr_rings; cmn * bp->cp_nr_rings;
else
return rx * bp->rx_nr_rings + tx * bp->tx_nr_rings +
cmn * bp->cp_nr_rings;
} }
static int bnxt_get_num_stats(struct bnxt *bp) static int bnxt_get_num_stats(struct bnxt *bp)
...@@ -806,7 +799,7 @@ static void bnxt_get_channels(struct net_device *dev, ...@@ -806,7 +799,7 @@ static void bnxt_get_channels(struct net_device *dev,
int max_tx_sch_inputs; int max_tx_sch_inputs;
/* Get the most up-to-date max_tx_sch_inputs. */ /* Get the most up-to-date max_tx_sch_inputs. */
if (BNXT_NEW_RM(bp)) if (netif_running(dev) && BNXT_NEW_RM(bp))
bnxt_hwrm_func_resc_qcaps(bp, false); bnxt_hwrm_func_resc_qcaps(bp, false);
max_tx_sch_inputs = hw_resc->max_tx_sch_inputs; max_tx_sch_inputs = hw_resc->max_tx_sch_inputs;
...@@ -2323,6 +2316,9 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data) ...@@ -2323,6 +2316,9 @@ static int bnxt_get_nvram_directory(struct net_device *dev, u32 len, u8 *data)
if (rc != 0) if (rc != 0)
return rc; return rc;
if (!dir_entries || !entry_length)
return -EIO;
/* Insert 2 bytes of directory info (count and size of entries) */ /* Insert 2 bytes of directory info (count and size of entries) */
if (len < 2) if (len < 2)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment