Skip to contentSkip to conversation

bnxt_en: Bug fixes.

PATCH In review Michael Chan 2 participants 8 messages Nov 15, 2018 – Nov 16, 2018

Subsystems (3)
lore
Share & tools
lore

Michael Chan

author maintainer
#0 lore raw

cover bnxt_en: Bug fixes.

Most of the bug fixes are related to the new 57500 chips, including some initialization and counter fixes, disabling RDMA support, and a workaround for occasional missing interrupts. The last patch from Vasundhara fixes the year/month parameters for firmware coredump.

Michael Chan (5):
bnxt_en: Fix RSS context allocation.
bnxt_en: Fix rx_l4_csum_errors counter on 57500 devices.
bnxt_en: Disable RDMA support on the 57500 chips.
bnxt_en: Workaround occasional TX timeout on 57500 A0.
bnxt_en: Add software "missed_irqs" counter.

Vasundhara Volam (1):
bnxt_en: Fix filling time in bnxt_fill_coredump_record()

 drivers/net/ethernet/broadcom/bnxt/bnxt.c         | 70 ++++++++++++++++++++++-
 drivers/net/ethernet/broadcom/bnxt/bnxt.h         |  4 ++
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |  9 ++-
 drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c     |  3 +
 4 files changed, 81 insertions(+), 5 deletions(-)
Signature · 1 line
2.5.1
author maintainer
#1 lore raw

PATCH 1/6 bnxt_en: Fix RSS context allocation.

Recent commit has added the reservation of RSS context. This requires bnxt_hwrm_vnic_qcaps() to be called before allocating any RSS contexts. The bnxt_hwrm_vnic_qcaps() call sets up proper flags that will determine how many RSS contexts to allocate to support NTUPLE.

This causes a regression that too many RSS contexts are being reserved and causing resource shortage when enabling many VFs. Fix it by calling bnxt_hwrm_vnic_qcaps() earlier.

Fixes 41e8d7983752 ("bnxt_en: Modify the ring reservation functions for 57500 series chips.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
index dd85d79..4a45a2b 100644
@@ -10087,6 +10087,7 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	}
 
 	bnxt_hwrm_func_qcfg(bp);
+	bnxt_hwrm_vnic_qcaps(bp);
 	bnxt_hwrm_port_led_qcaps(bp);
 	bnxt_ethtool_init(bp);
 	bnxt_dcb_init(bp);
@@ -10120,7 +10121,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 				    VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV6;
 	}
 
-	bnxt_hwrm_vnic_qcaps(bp);
 	if (bnxt_rfs_supported(bp)) {
 		dev->hw_features |= NETIF_F_NTUPLE;
 		if (bnxt_rfs_capable(bp)) {
Signature · 1 line
2.5.1
author maintainer
#2 lore raw

PATCH 2/6 bnxt_en: Fix rx_l4_csum_errors counter on 57500 devices.

In reply to Michael Chan

The software counter structure is defined in both the CP ring's structure and the NQ ring's structure on the new devices. The legacy code adds the counter to the CP ring's structure and the counter won't get displayed since the ethtool code is looking at the NQ ring's structure.

Since all other counters are contained in the NQ ring's structure, it makes more sense to count rx_l4_csum_errors in the NQ.

Fixes 50e3ab7836b5 ("bnxt_en: Allocate completion ring structures for 57500 series chips.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
index 4a45a2b..5856099 100644
@@ -1675,7 +1675,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	} else {
 		if (rxcmp1->rx_cmp_cfa_code_errors_v2 & RX_CMP_L4_CS_ERR_BITS) {
 			if (dev->features & NETIF_F_RXCSUM)
-				cpr->rx_l4_csum_errors++;
+				bnapi->cp_ring.rx_l4_csum_errors++;
 		}
 	}
 
Signature · 1 line
2.5.1
author maintainer
#3 lore raw

PATCH 3/6 bnxt_en: Disable RDMA support on the 57500 chips.

In reply to Michael Chan

There is no RDMA support on 57500 chips yet, so prevent bnxt_re from registering on these chips. There is intermittent failure if bnxt_re is allowed to register and proceed with RDMA operations.

Fixes 1ab968d2f1d6 ("bnxt_en: Add PCI ID for BCM57508 device.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +3 -0
index beee612..b59b382 100644
@@ -43,6 +43,9 @@ static int bnxt_register_dev(struct bnxt_en_dev *edev, int ulp_id,
 	if (ulp_id == BNXT_ROCE_ULP) {
 		unsigned int max_stat_ctxs;
 
+		if (bp->flags & BNXT_FLAG_CHIP_P5)
+			return -EOPNOTSUPP;
+
 		max_stat_ctxs = bnxt_get_max_func_stat_ctxs(bp);
 		if (max_stat_ctxs <= BNXT_MIN_ROCE_STAT_CTXS ||
 		    bp->num_stat_ctxs == max_stat_ctxs)
Signature · 1 line
2.5.1
author maintainer
#4 lore raw

PATCH 4/6 bnxt_en: Workaround occasional TX timeout on 57500 A0.

In reply to Michael Chan

Hardware can sometimes not generate NQ MSIX with a single pending CP ring entry. This seems to always happen at the last entry of the CP ring before it wraps. Add logic to check all the CP rings for pending entries without the CP ring consumer index advancing. Calling HWRM_DBG_RING_INFO_GET to read the context of the CP ring will flush out the NQ entry and MSIX.

---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c | 65 +++++++++++++++++++++++++++++++
 drivers/net/ethernet/broadcom/bnxt/bnxt.h |  3 ++
 2 files changed, 68 insertions(+)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +65 -0
index 5856099..5d4147a 100644
@@ -8714,6 +8714,26 @@ static int bnxt_set_features(struct net_device *dev, netdev_features_t features)
 	return rc;
 }
 
+static int bnxt_dbg_hwrm_ring_info_get(struct bnxt *bp, u8 ring_type,
+				       u32 ring_id, u32 *prod, u32 *cons)
+{
+	struct hwrm_dbg_ring_info_get_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_dbg_ring_info_get_input req = {0};
+	int rc;
+
+	bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_DBG_RING_INFO_GET, -1, -1);
+	req.ring_type = ring_type;
+	req.fw_ring_id = cpu_to_le32(ring_id);
+	mutex_lock(&bp->hwrm_cmd_lock);
+	rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
+	if (!rc) {
+		*prod = le32_to_cpu(resp->producer_index);
+		*cons = le32_to_cpu(resp->consumer_index);
+	}
+	mutex_unlock(&bp->hwrm_cmd_lock);
+	return rc;
+}
+
 static void bnxt_dump_tx_sw_state(struct bnxt_napi *bnapi)
 {
 	struct bnxt_tx_ring_info *txr = bnapi->tx_ring;
@@ -8821,6 +8841,11 @@ static void bnxt_timer(struct timer_list *t)
 			bnxt_queue_sp_work(bp);
 		}
 	}
+
+	if ((bp->flags & BNXT_FLAG_CHIP_P5) && netif_carrier_ok(dev)) {
+		set_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event);
+		bnxt_queue_sp_work(bp);
+	}
 bnxt_restart_timer:
 	mod_timer(&bp->timer, jiffies + bp->current_interval);
 }
@@ -8851,6 +8876,43 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
 	bnxt_rtnl_unlock_sp(bp);
 }
 
+static void bnxt_chk_missed_irq(struct bnxt *bp)
+{
+	int i;
+
+	if (!(bp->flags & BNXT_FLAG_CHIP_P5))
+		return;
+
+	for (i = 0; i < bp->cp_nr_rings; i++) {
+		struct bnxt_napi *bnapi = bp->bnapi[i];
+		struct bnxt_cp_ring_info *cpr;
+		u32 fw_ring_id;
+		int j;
+
+		if (!bnapi)
+			continue;
+
+		cpr = &bnapi->cp_ring;
+		for (j = 0; j < 2; j++) {
+			struct bnxt_cp_ring_info *cpr2 = cpr->cp_ring_arr[j];
+			u32 val[2];
+
+			if (!cpr2 || cpr2->has_more_work ||
+			    !bnxt_has_work(bp, cpr2))
+				continue;
+
+			if (cpr2->cp_raw_cons != cpr2->last_cp_raw_cons) {
+				cpr2->last_cp_raw_cons = cpr2->cp_raw_cons;
+				continue;
+			}
+			fw_ring_id = cpr2->cp_ring_struct.fw_ring_id;
+			bnxt_dbg_hwrm_ring_info_get(bp,
+				DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL,
+				fw_ring_id, &val[0], &val[1]);
+		}
+	}
+}
+
 static void bnxt_cfg_ntp_filters(struct bnxt *);
 
 static void bnxt_sp_task(struct work_struct *work)
@@ -8930,6 +8992,9 @@ static void bnxt_sp_task(struct work_struct *work)
 	if (test_and_clear_bit(BNXT_FLOW_STATS_SP_EVENT, &bp->sp_event))
 		bnxt_tc_flow_stats_work(bp);
 
+	if (test_and_clear_bit(BNXT_RING_COAL_NOW_SP_EVENT, &bp->sp_event))
+		bnxt_chk_missed_irq(bp);
+
 	/* These functions below will clear BNXT_STATE_IN_SP_TASK.  They
 	 * must be the last functions to be called before exiting.
 	 */
drivers/net/ethernet/broadcom/bnxt/bnxt.h +3 -0
index 498b373..00bd17e 100644
@@ -798,6 +798,8 @@ struct bnxt_cp_ring_info {
 	u8			had_work_done:1;
 	u8			has_more_work:1;
 
+	u32			last_cp_raw_cons;
+
 	struct bnxt_coal	rx_ring_coal;
 	u64			rx_packets;
 	u64			rx_bytes;
@@ -1527,6 +1529,7 @@ struct bnxt {
 #define BNXT_LINK_SPEED_CHNG_SP_EVENT	14
 #define BNXT_FLOW_STATS_SP_EVENT	15
 #define BNXT_UPDATE_PHY_SP_EVENT	16
+#define BNXT_RING_COAL_NOW_SP_EVENT	17
 
 	struct bnxt_hw_resc	hw_resc;
 	struct bnxt_pf_info	pf;
Signature · 1 line
2.5.1
author maintainer
#5 lore raw

PATCH 5/6 bnxt_en: Add software "missed_irqs" counter.

In reply to Michael Chan

To keep track of the number of times the workaround code for 57500 A0 has been triggered. This is a per NQ counter.

---
 drivers/net/ethernet/broadcom/bnxt/bnxt.c         | 1 +
 drivers/net/ethernet/broadcom/bnxt/bnxt.h         | 1 +
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 ++++-
 3 files changed, 6 insertions(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -0
index 5d4147a..d4c3001 100644
@@ -8909,6 +8909,7 @@ static void bnxt_chk_missed_irq(struct bnxt *bp)
 			bnxt_dbg_hwrm_ring_info_get(bp,
 				DBG_RING_INFO_GET_REQ_RING_TYPE_L2_CMPL,
 				fw_ring_id, &val[0], &val[1]);
+			cpr->missed_irqs++;
 		}
 	}
 }
drivers/net/ethernet/broadcom/bnxt/bnxt.h +1 -0
index 00bd17e..9e99d4a 100644
@@ -818,6 +818,7 @@ struct bnxt_cp_ring_info {
 	dma_addr_t		hw_stats_map;
 	u32			hw_stats_ctx_id;
 	u64			rx_l4_csum_errors;
+	u64			missed_irqs;
 
 	struct bnxt_ring_struct	cp_ring_struct;
 
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +4 -1
index 4807856..4b734cd 100644
@@ -137,7 +137,7 @@ static int bnxt_set_coalesce(struct net_device *dev,
 	return rc;
 }
 
-#define BNXT_NUM_STATS	21
+#define BNXT_NUM_STATS	22
 
 #define BNXT_RX_STATS_ENTRY(counter)	\
 	{ BNXT_RX_STATS_OFFSET(counter), __stringify(counter) }
@@ -384,6 +384,7 @@ static void bnxt_get_ethtool_stats(struct net_device *dev,
 		for (k = 0; k < stat_fields; j++, k++)
 			buf[j] = le64_to_cpu(hw_stats[k]);
 		buf[j++] = cpr->rx_l4_csum_errors;
+		buf[j++] = cpr->missed_irqs;
 
 		bnxt_sw_func_stats[RX_TOTAL_DISCARDS].counter +=
 			le64_to_cpu(cpr->hw_stats->rx_discard_pkts);
@@ -468,6 +469,8 @@ static void bnxt_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
 			buf += ETH_GSTRING_LEN;
 			sprintf(buf, "[%d]: rx_l4_csum_errors", i);
 			buf += ETH_GSTRING_LEN;
+			sprintf(buf, "[%d]: missed_irqs", i);
+			buf += ETH_GSTRING_LEN;
 		}
 		for (i = 0; i < BNXT_NUM_SW_FUNC_STATS; i++) {
 			strcpy(buf, bnxt_sw_func_stats[i].string);
Signature · 1 line
2.5.1
author maintainer
#6 lore raw

PATCH 6/6 bnxt_en: Fix filling time in bnxt_fill_coredump_record()

In reply to Michael Chan

From: Vasundhara Volam <[email protected]>

Fix the year and month offset while storing it in
bnxt_fill_coredump_record().

Fixes 6c5657d085ae ("bnxt_en: Add support for ethtool get dump.")
---
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +2 -2
index 4b734cd..6cc69a5 100644
@@ -2945,8 +2945,8 @@ bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record,
 	record->asic_state = 0;
 	strlcpy(record->system_name, utsname()->nodename,
 		sizeof(record->system_name));
-	record->year = cpu_to_le16(tm.tm_year);
-	record->month = cpu_to_le16(tm.tm_mon);
+	record->year = cpu_to_le16(tm.tm_year + 1900);
+	record->month = cpu_to_le16(tm.tm_mon + 1);
 	record->day = cpu_to_le16(tm.tm_mday);
 	record->hour = cpu_to_le16(tm.tm_hour);
 	record->minute = cpu_to_le16(tm.tm_min);
Signature · 1 line
2.5.1
maintainer
#7 lore raw
In reply to Michael Chan

From: Michael Chan <[email protected]>
Date: Thu, 15 Nov 2018 03:25:36 -0500

Quoted 4 lines

Most of the bug fixes are related to the new 57500 chips, including some initialization and counter fixes, disabling RDMA support, and a workaround for occasional missing interrupts. The last patch from Vasundhara fixes the year/month parameters for firmware coredump.

Series applied, thanks Michael.