Skip to content

Commit d59e3cb

Browse files
committed
Merge branch 'bnxt_en-updates'
Michael Chan says: ==================== bnxt_en: Updates. This patch series contains mainly NVRAM related features. More NVRAM error checking and logging are added when installing firmware packages. A new devlink hw health report is now added to report and diagnose NVRAM issues. Other miscellaneous patches include reporting correctly cards that don't support link pause, adding an internal unknown link state, and avoiding unnecessary link toggle during firmware reset. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 2057b8b + 22f5dba commit d59e3cb

File tree

7 files changed

+367
-74
lines changed

7 files changed

+367
-74
lines changed

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

+43-18
Original file line numberDiff line numberDiff line change
@@ -2061,6 +2061,22 @@ static void bnxt_event_error_report(struct bnxt *bp, u32 data1, u32 data2)
20612061
case ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DOORBELL_DROP_THRESHOLD:
20622062
netdev_warn(bp->dev, "One or more MMIO doorbells dropped by the device!\n");
20632063
break;
2064+
case ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_NVM: {
2065+
struct bnxt_hw_health *hw_health = &bp->hw_health;
2066+
2067+
hw_health->nvm_err_address = EVENT_DATA2_NVM_ERR_ADDR(data2);
2068+
if (EVENT_DATA1_NVM_ERR_TYPE_WRITE(data1)) {
2069+
hw_health->synd = BNXT_HW_STATUS_NVM_WRITE_ERR;
2070+
hw_health->nvm_write_errors++;
2071+
} else if (EVENT_DATA1_NVM_ERR_TYPE_ERASE(data1)) {
2072+
hw_health->synd = BNXT_HW_STATUS_NVM_ERASE_ERR;
2073+
hw_health->nvm_erase_errors++;
2074+
} else {
2075+
hw_health->synd = BNXT_HW_STATUS_NVM_UNKNOWN_ERR;
2076+
}
2077+
set_bit(BNXT_FW_NVM_ERR_SP_EVENT, &bp->sp_event);
2078+
break;
2079+
}
20642080
default:
20652081
netdev_err(bp->dev, "FW reported unknown error type %u\n",
20662082
err_type);
@@ -9300,7 +9316,7 @@ void bnxt_tx_enable(struct bnxt *bp)
93009316
/* Make sure napi polls see @dev_state change */
93019317
synchronize_net();
93029318
netif_tx_wake_all_queues(bp->dev);
9303-
if (bp->link_info.link_up)
9319+
if (BNXT_LINK_IS_UP(bp))
93049320
netif_carrier_on(bp->dev);
93059321
}
93069322

@@ -9330,7 +9346,7 @@ static char *bnxt_report_fec(struct bnxt_link_info *link_info)
93309346

93319347
void bnxt_report_link(struct bnxt *bp)
93329348
{
9333-
if (bp->link_info.link_up) {
9349+
if (BNXT_LINK_IS_UP(bp)) {
93349350
const char *signal = "";
93359351
const char *flow_ctrl;
93369352
const char *duplex;
@@ -9416,7 +9432,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
94169432
if (rc)
94179433
goto hwrm_phy_qcaps_exit;
94189434

9419-
bp->phy_flags = resp->flags;
9435+
bp->phy_flags = resp->flags | (le16_to_cpu(resp->flags2) << 8);
94209436
if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED) {
94219437
struct ethtool_eee *eee = &bp->eee;
94229438
u16 fw_speeds = le16_to_cpu(resp->supported_speeds_eee_mode);
@@ -9466,7 +9482,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
94669482
struct bnxt_link_info *link_info = &bp->link_info;
94679483
struct hwrm_port_phy_qcfg_output *resp;
94689484
struct hwrm_port_phy_qcfg_input *req;
9469-
u8 link_up = link_info->link_up;
9485+
u8 link_state = link_info->link_state;
94709486
bool support_changed = false;
94719487
int rc;
94729488

@@ -9567,14 +9583,14 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
95679583
/* TODO: need to add more logic to report VF link */
95689584
if (chng_link_state) {
95699585
if (link_info->phy_link_status == BNXT_LINK_LINK)
9570-
link_info->link_up = 1;
9586+
link_info->link_state = BNXT_LINK_STATE_UP;
95719587
else
9572-
link_info->link_up = 0;
9573-
if (link_up != link_info->link_up)
9588+
link_info->link_state = BNXT_LINK_STATE_DOWN;
9589+
if (link_state != link_info->link_state)
95749590
bnxt_report_link(bp);
95759591
} else {
9576-
/* alwasy link down if not require to update link state */
9577-
link_info->link_up = 0;
9592+
/* always link down if not require to update link state */
9593+
link_info->link_state = BNXT_LINK_STATE_DOWN;
95789594
}
95799595
hwrm_req_drop(bp, req);
95809596

@@ -9774,7 +9790,18 @@ static int bnxt_hwrm_shutdown_link(struct bnxt *bp)
97749790
return rc;
97759791

97769792
req->flags = cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN);
9777-
return hwrm_req_send(bp, req);
9793+
rc = hwrm_req_send(bp, req);
9794+
if (!rc) {
9795+
mutex_lock(&bp->link_lock);
9796+
/* Device is not obliged link down in certain scenarios, even
9797+
* when forced. Setting the state unknown is consistent with
9798+
* driver startup and will force link state to be reported
9799+
* during subsequent open based on PORT_PHY_QCFG.
9800+
*/
9801+
bp->link_info.link_state = BNXT_LINK_STATE_UNKNOWN;
9802+
mutex_unlock(&bp->link_lock);
9803+
}
9804+
return rc;
97789805
}
97799806

97809807
static int bnxt_fw_reset_via_optee(struct bnxt *bp)
@@ -10205,7 +10232,7 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
1020510232
/* The last close may have shutdown the link, so need to call
1020610233
* PHY_CFG to bring it back up.
1020710234
*/
10208-
if (!bp->link_info.link_up)
10235+
if (!BNXT_LINK_IS_UP(bp))
1020910236
update_link = true;
1021010237

1021110238
if (!bnxt_eee_config_ok(bp))
@@ -11437,7 +11464,7 @@ static void bnxt_timer(struct timer_list *t)
1143711464
if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
1143811465
bnxt_fw_health_check(bp);
1143911466

11440-
if (bp->link_info.link_up && bp->stats_coal_ticks) {
11467+
if (BNXT_LINK_IS_UP(bp) && bp->stats_coal_ticks) {
1144111468
set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event);
1144211469
bnxt_queue_sp_work(bp);
1144311470
}
@@ -11876,6 +11903,9 @@ static void bnxt_sp_task(struct work_struct *work)
1187611903
if (test_and_clear_bit(BNXT_FW_ECHO_REQUEST_SP_EVENT, &bp->sp_event))
1187711904
bnxt_fw_echo_reply(bp);
1187811905

11906+
if (test_and_clear_bit(BNXT_FW_NVM_ERR_SP_EVENT, &bp->sp_event))
11907+
bnxt_devlink_health_hw_report(bp);
11908+
1187911909
/* These functions below will clear BNXT_STATE_IN_SP_TASK. They
1188011910
* must be the last functions to be called before exiting.
1188111911
*/
@@ -12138,11 +12168,6 @@ int bnxt_fw_init_one(struct bnxt *bp)
1213812168
if (rc)
1213912169
return rc;
1214012170

12141-
/* In case fw capabilities have changed, destroy the unneeded
12142-
* reporters and create newly capable ones.
12143-
*/
12144-
bnxt_dl_fw_reporters_destroy(bp, false);
12145-
bnxt_dl_fw_reporters_create(bp);
1214612171
bnxt_fw_init_one_p3(bp);
1214712172
return 0;
1214812173
}
@@ -12971,7 +12996,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
1297112996
cancel_delayed_work_sync(&bp->fw_reset_task);
1297212997
bp->sp_event = 0;
1297312998

12974-
bnxt_dl_fw_reporters_destroy(bp, true);
12999+
bnxt_dl_fw_reporters_destroy(bp);
1297513000
bnxt_dl_unregister(bp);
1297613001
bnxt_shutdown_tc(bp);
1297713002

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

+54-3
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,21 @@ struct rx_tpa_end_cmp_ext {
516516
ASYNC_EVENT_CMPL_ERROR_REPORT_INVALID_SIGNAL_EVENT_DATA2_PIN_ID_MASK) >>\
517517
ASYNC_EVENT_CMPL_ERROR_REPORT_INVALID_SIGNAL_EVENT_DATA2_PIN_ID_SFT)
518518

519+
#define EVENT_DATA2_NVM_ERR_ADDR(data2) \
520+
(((data2) & \
521+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA2_ERR_ADDR_MASK) >>\
522+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA2_ERR_ADDR_SFT)
523+
524+
#define EVENT_DATA1_NVM_ERR_TYPE_WRITE(data1) \
525+
(((data1) & \
526+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_MASK) ==\
527+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_WRITE)
528+
529+
#define EVENT_DATA1_NVM_ERR_TYPE_ERASE(data1) \
530+
(((data1) & \
531+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_MASK) ==\
532+
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_ERASE)
533+
519534
struct nqe_cn {
520535
__le16 type;
521536
#define NQ_CN_TYPE_MASK 0x3fUL
@@ -1175,7 +1190,11 @@ struct bnxt_link_info {
11751190
#define BNXT_PHY_STATE_ENABLED 0
11761191
#define BNXT_PHY_STATE_DISABLED 1
11771192

1178-
u8 link_up;
1193+
u8 link_state;
1194+
#define BNXT_LINK_STATE_UNKNOWN 0
1195+
#define BNXT_LINK_STATE_DOWN 1
1196+
#define BNXT_LINK_STATE_UP 2
1197+
#define BNXT_LINK_IS_UP(bp) ((bp)->link_info.link_state == BNXT_LINK_STATE_UP)
11791198
u8 duplex;
11801199
#define BNXT_LINK_DUPLEX_HALF PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF
11811200
#define BNXT_LINK_DUPLEX_FULL PORT_PHY_QCFG_RESP_DUPLEX_STATE_FULL
@@ -1524,6 +1543,33 @@ struct bnxt_ctx_mem_info {
15241543
struct bnxt_mem_init mem_init[BNXT_CTX_MEM_INIT_MAX];
15251544
};
15261545

1546+
enum bnxt_hw_err {
1547+
BNXT_HW_STATUS_HEALTHY = 0x0,
1548+
BNXT_HW_STATUS_NVM_WRITE_ERR = 0x1,
1549+
BNXT_HW_STATUS_NVM_ERASE_ERR = 0x2,
1550+
BNXT_HW_STATUS_NVM_UNKNOWN_ERR = 0x3,
1551+
BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR = 0x4,
1552+
BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR = 0x5,
1553+
BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR = 0x6,
1554+
BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR = 0x7,
1555+
};
1556+
1557+
struct bnxt_hw_health {
1558+
u32 nvm_err_address;
1559+
u32 nvm_write_errors;
1560+
u32 nvm_erase_errors;
1561+
u32 nvm_test_vpd_ent_errors;
1562+
u32 nvm_test_vpd_read_errors;
1563+
u32 nvm_test_vpd_write_errors;
1564+
u32 nvm_test_incmpl_errors;
1565+
u8 synd;
1566+
/* max a test in a day if previous test was successful */
1567+
#define HW_RETEST_MIN_TIME (1000 * 3600 * 24)
1568+
u8 nvm_test_result;
1569+
unsigned long nvm_test_timestamp;
1570+
struct devlink_health_reporter *hw_reporter;
1571+
};
1572+
15271573
enum bnxt_health_severity {
15281574
SEVERITY_NORMAL = 0,
15291575
SEVERITY_WARNING,
@@ -2041,6 +2087,7 @@ struct bnxt {
20412087
#define BNXT_FW_EXCEPTION_SP_EVENT 19
20422088
#define BNXT_LINK_CFG_CHANGE_SP_EVENT 21
20432089
#define BNXT_FW_ECHO_REQUEST_SP_EVENT 23
2090+
#define BNXT_FW_NVM_ERR_SP_EVENT 25
20442091

20452092
struct delayed_work fw_reset_task;
20462093
int fw_reset_state;
@@ -2100,8 +2147,8 @@ struct bnxt {
21002147
u32 lpi_tmr_lo;
21012148
u32 lpi_tmr_hi;
21022149

2103-
/* copied from flags in hwrm_port_phy_qcaps_output */
2104-
u8 phy_flags;
2150+
/* copied from flags and flags2 in hwrm_port_phy_qcaps_output */
2151+
u32 phy_flags;
21052152
#define BNXT_PHY_FL_EEE_CAP PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED
21062153
#define BNXT_PHY_FL_EXT_LPBK PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED
21072154
#define BNXT_PHY_FL_AN_PHY_LPBK PORT_PHY_QCAPS_RESP_FLAGS_AUTONEG_LPBK_SUPPORTED
@@ -2110,6 +2157,8 @@ struct bnxt {
21102157
#define BNXT_PHY_FL_NO_PHY_LPBK PORT_PHY_QCAPS_RESP_FLAGS_LOCAL_LPBK_NOT_SUPPORTED
21112158
#define BNXT_PHY_FL_FW_MANAGED_LKDN PORT_PHY_QCAPS_RESP_FLAGS_FW_MANAGED_LINK_DOWN
21122159
#define BNXT_PHY_FL_NO_FCS PORT_PHY_QCAPS_RESP_FLAGS_NO_FCS
2160+
#define BNXT_PHY_FL_NO_PAUSE (PORT_PHY_QCAPS_RESP_FLAGS2_PAUSE_UNSUPPORTED << 8)
2161+
#define BNXT_PHY_FL_NO_PFC (PORT_PHY_QCAPS_RESP_FLAGS2_PFC_UNSUPPORTED << 8)
21132162

21142163
u8 num_tests;
21152164
struct bnxt_test_info *test_info;
@@ -2139,6 +2188,8 @@ struct bnxt {
21392188
struct dentry *debugfs_pdev;
21402189
struct device *hwmon_dev;
21412190
enum board_idx board_idx;
2191+
2192+
struct bnxt_hw_health hw_health;
21422193
};
21432194

21442195
#define BNXT_NUM_RX_RING_STATS 8

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,8 @@ static int bnxt_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc)
627627
int rc;
628628

629629
if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
630-
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
630+
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST) ||
631+
(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE))
631632
return -EINVAL;
632633

633634
if (!my_pfc) {

0 commit comments

Comments
 (0)