Skip to content

Commit 8d4bd96

Browse files
Michael Chandavem330
authored andcommitted
bnxt_en: Eliminate unnecessary RX resets.
Currently, the driver will schedule RX ring reset when we get a buffer error in the RX completion record. These RX buffer errors can be due to normal out-of-buffer conditions or a permanent error in the RX ring. Because the driver cannot distinguish between these 2 conditions, we assume all these buffer errors require reset. This is very disruptive when it is just a normal out-of-buffer condition. Newer firmware will now monitor the rings for the permanent failure and will send a notification to the driver when it happens. This allows the driver to reset only when such a notification is received. In environments where we have predominently out-of-buffer conditions, we now can avoid these unnecessary resets. Reviewed-by: Edwin Peer <[email protected]> Signed-off-by: Michael Chan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 1b5c8b6 commit 8d4bd96

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ static const u16 bnxt_async_events_arr[] = {
254254
ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE,
255255
ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY,
256256
ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY,
257+
ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG,
257258
};
258259

259260
static struct workqueue_struct *bnxt_pf_wq;
@@ -1777,7 +1778,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
17771778
rc = -EIO;
17781779
if (rx_err & RX_CMPL_ERRORS_BUFFER_ERROR_MASK) {
17791780
bnapi->cp_ring.sw_stats.rx.rx_buf_errors++;
1780-
if (!(bp->flags & BNXT_FLAG_CHIP_P5)) {
1781+
if (!(bp->flags & BNXT_FLAG_CHIP_P5) &&
1782+
!(bp->fw_cap & BNXT_FW_CAP_RING_MONITOR)) {
17811783
netdev_warn_once(bp->dev, "RX buffer error %x\n",
17821784
rx_err);
17831785
bnxt_sched_reset(bp, rxr);
@@ -1946,10 +1948,33 @@ u32 bnxt_fw_health_readl(struct bnxt *bp, int reg_idx)
19461948
return val;
19471949
}
19481950

1951+
static u16 bnxt_agg_ring_id_to_grp_idx(struct bnxt *bp, u16 ring_id)
1952+
{
1953+
int i;
1954+
1955+
for (i = 0; i < bp->rx_nr_rings; i++) {
1956+
u16 grp_idx = bp->rx_ring[i].bnapi->index;
1957+
struct bnxt_ring_grp_info *grp_info;
1958+
1959+
grp_info = &bp->grp_info[grp_idx];
1960+
if (grp_info->agg_fw_ring_id == ring_id)
1961+
return grp_idx;
1962+
}
1963+
return INVALID_HW_RING_ID;
1964+
}
1965+
19491966
#define BNXT_GET_EVENT_PORT(data) \
19501967
((data) & \
19511968
ASYNC_EVENT_CMPL_PORT_CONN_NOT_ALLOWED_EVENT_DATA1_PORT_ID_MASK)
19521969

1970+
#define BNXT_EVENT_RING_TYPE(data2) \
1971+
((data2) & \
1972+
ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_MASK)
1973+
1974+
#define BNXT_EVENT_RING_TYPE_RX(data2) \
1975+
(BNXT_EVENT_RING_TYPE(data2) == \
1976+
ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_RX)
1977+
19531978
static int bnxt_async_event_process(struct bnxt *bp,
19541979
struct hwrm_async_event_cmpl *cmpl)
19551980
{
@@ -2057,6 +2082,30 @@ static int bnxt_async_event_process(struct bnxt *bp,
20572082
bnxt_fw_health_readl(bp, BNXT_FW_RESET_CNT_REG);
20582083
goto async_event_process_exit;
20592084
}
2085+
case ASYNC_EVENT_CMPL_EVENT_ID_RING_MONITOR_MSG: {
2086+
u32 data1 = le32_to_cpu(cmpl->event_data1);
2087+
u32 data2 = le32_to_cpu(cmpl->event_data2);
2088+
struct bnxt_rx_ring_info *rxr;
2089+
u16 grp_idx;
2090+
2091+
if (bp->flags & BNXT_FLAG_CHIP_P5)
2092+
goto async_event_process_exit;
2093+
2094+
netdev_warn(bp->dev, "Ring monitor event, ring type %lu id 0x%x\n",
2095+
BNXT_EVENT_RING_TYPE(data2), data1);
2096+
if (!BNXT_EVENT_RING_TYPE_RX(data2))
2097+
goto async_event_process_exit;
2098+
2099+
grp_idx = bnxt_agg_ring_id_to_grp_idx(bp, data1);
2100+
if (grp_idx == INVALID_HW_RING_ID) {
2101+
netdev_warn(bp->dev, "Unknown RX agg ring id 0x%x\n",
2102+
data1);
2103+
goto async_event_process_exit;
2104+
}
2105+
rxr = bp->bnapi[grp_idx]->rx_ring;
2106+
bnxt_sched_reset(bp, rxr);
2107+
goto async_event_process_exit;
2108+
}
20602109
default:
20612110
goto async_event_process_exit;
20622111
}
@@ -6649,6 +6698,8 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
66496698
}
66506699
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
66516700
bp->flags |= BNXT_FLAG_MULTI_HOST;
6701+
if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
6702+
bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
66526703

66536704
switch (resp->port_partition_type) {
66546705
case FUNC_QCFG_RESP_PORT_PARTITION_TYPE_NPAR1_0:

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1822,6 +1822,7 @@ struct bnxt {
18221822
#define BNXT_FW_CAP_VLAN_TX_INSERT 0x02000000
18231823
#define BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED 0x04000000
18241824
#define BNXT_FW_CAP_PORT_STATS_NO_RESET 0x10000000
1825+
#define BNXT_FW_CAP_RING_MONITOR 0x40000000
18251826

18261827
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
18271828
u32 hwrm_spec_code;

0 commit comments

Comments
 (0)