Skip to content

Commit

Permalink
Merge branch 'bnxt_en-updates'
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David S. Miller committed Mar 5, 2022
2 parents 2057b8b + 22f5dba commit d59e3cb
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 74 deletions.
61 changes: 43 additions & 18 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2061,6 +2061,22 @@ static void bnxt_event_error_report(struct bnxt *bp, u32 data1, u32 data2)
case ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DOORBELL_DROP_THRESHOLD:
netdev_warn(bp->dev, "One or more MMIO doorbells dropped by the device!\n");
break;
case ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_NVM: {
struct bnxt_hw_health *hw_health = &bp->hw_health;

hw_health->nvm_err_address = EVENT_DATA2_NVM_ERR_ADDR(data2);
if (EVENT_DATA1_NVM_ERR_TYPE_WRITE(data1)) {
hw_health->synd = BNXT_HW_STATUS_NVM_WRITE_ERR;
hw_health->nvm_write_errors++;
} else if (EVENT_DATA1_NVM_ERR_TYPE_ERASE(data1)) {
hw_health->synd = BNXT_HW_STATUS_NVM_ERASE_ERR;
hw_health->nvm_erase_errors++;
} else {
hw_health->synd = BNXT_HW_STATUS_NVM_UNKNOWN_ERR;
}
set_bit(BNXT_FW_NVM_ERR_SP_EVENT, &bp->sp_event);
break;
}
default:
netdev_err(bp->dev, "FW reported unknown error type %u\n",
err_type);
Expand Down Expand Up @@ -9300,7 +9316,7 @@ void bnxt_tx_enable(struct bnxt *bp)
/* Make sure napi polls see @dev_state change */
synchronize_net();
netif_tx_wake_all_queues(bp->dev);
if (bp->link_info.link_up)
if (BNXT_LINK_IS_UP(bp))
netif_carrier_on(bp->dev);
}

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

void bnxt_report_link(struct bnxt *bp)
{
if (bp->link_info.link_up) {
if (BNXT_LINK_IS_UP(bp)) {
const char *signal = "";
const char *flow_ctrl;
const char *duplex;
Expand Down Expand Up @@ -9416,7 +9432,7 @@ static int bnxt_hwrm_phy_qcaps(struct bnxt *bp)
if (rc)
goto hwrm_phy_qcaps_exit;

bp->phy_flags = resp->flags;
bp->phy_flags = resp->flags | (le16_to_cpu(resp->flags2) << 8);
if (resp->flags & PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED) {
struct ethtool_eee *eee = &bp->eee;
u16 fw_speeds = le16_to_cpu(resp->supported_speeds_eee_mode);
Expand Down Expand Up @@ -9466,7 +9482,7 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
struct bnxt_link_info *link_info = &bp->link_info;
struct hwrm_port_phy_qcfg_output *resp;
struct hwrm_port_phy_qcfg_input *req;
u8 link_up = link_info->link_up;
u8 link_state = link_info->link_state;
bool support_changed = false;
int rc;

Expand Down Expand Up @@ -9567,14 +9583,14 @@ int bnxt_update_link(struct bnxt *bp, bool chng_link_state)
/* TODO: need to add more logic to report VF link */
if (chng_link_state) {
if (link_info->phy_link_status == BNXT_LINK_LINK)
link_info->link_up = 1;
link_info->link_state = BNXT_LINK_STATE_UP;
else
link_info->link_up = 0;
if (link_up != link_info->link_up)
link_info->link_state = BNXT_LINK_STATE_DOWN;
if (link_state != link_info->link_state)
bnxt_report_link(bp);
} else {
/* alwasy link down if not require to update link state */
link_info->link_up = 0;
/* always link down if not require to update link state */
link_info->link_state = BNXT_LINK_STATE_DOWN;
}
hwrm_req_drop(bp, req);

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

req->flags = cpu_to_le32(PORT_PHY_CFG_REQ_FLAGS_FORCE_LINK_DWN);
return hwrm_req_send(bp, req);
rc = hwrm_req_send(bp, req);
if (!rc) {
mutex_lock(&bp->link_lock);
/* Device is not obliged link down in certain scenarios, even
* when forced. Setting the state unknown is consistent with
* driver startup and will force link state to be reported
* during subsequent open based on PORT_PHY_QCFG.
*/
bp->link_info.link_state = BNXT_LINK_STATE_UNKNOWN;
mutex_unlock(&bp->link_lock);
}
return rc;
}

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

if (!bnxt_eee_config_ok(bp))
Expand Down Expand Up @@ -11437,7 +11464,7 @@ static void bnxt_timer(struct timer_list *t)
if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
bnxt_fw_health_check(bp);

if (bp->link_info.link_up && bp->stats_coal_ticks) {
if (BNXT_LINK_IS_UP(bp) && bp->stats_coal_ticks) {
set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event);
bnxt_queue_sp_work(bp);
}
Expand Down Expand Up @@ -11876,6 +11903,9 @@ static void bnxt_sp_task(struct work_struct *work)
if (test_and_clear_bit(BNXT_FW_ECHO_REQUEST_SP_EVENT, &bp->sp_event))
bnxt_fw_echo_reply(bp);

if (test_and_clear_bit(BNXT_FW_NVM_ERR_SP_EVENT, &bp->sp_event))
bnxt_devlink_health_hw_report(bp);

/* These functions below will clear BNXT_STATE_IN_SP_TASK. They
* must be the last functions to be called before exiting.
*/
Expand Down Expand Up @@ -12138,11 +12168,6 @@ int bnxt_fw_init_one(struct bnxt *bp)
if (rc)
return rc;

/* In case fw capabilities have changed, destroy the unneeded
* reporters and create newly capable ones.
*/
bnxt_dl_fw_reporters_destroy(bp, false);
bnxt_dl_fw_reporters_create(bp);
bnxt_fw_init_one_p3(bp);
return 0;
}
Expand Down Expand Up @@ -12971,7 +12996,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
cancel_delayed_work_sync(&bp->fw_reset_task);
bp->sp_event = 0;

bnxt_dl_fw_reporters_destroy(bp, true);
bnxt_dl_fw_reporters_destroy(bp);
bnxt_dl_unregister(bp);
bnxt_shutdown_tc(bp);

Expand Down
57 changes: 54 additions & 3 deletions drivers/net/ethernet/broadcom/bnxt/bnxt.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,21 @@ struct rx_tpa_end_cmp_ext {
ASYNC_EVENT_CMPL_ERROR_REPORT_INVALID_SIGNAL_EVENT_DATA2_PIN_ID_MASK) >>\
ASYNC_EVENT_CMPL_ERROR_REPORT_INVALID_SIGNAL_EVENT_DATA2_PIN_ID_SFT)

#define EVENT_DATA2_NVM_ERR_ADDR(data2) \
(((data2) & \
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA2_ERR_ADDR_MASK) >>\
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA2_ERR_ADDR_SFT)

#define EVENT_DATA1_NVM_ERR_TYPE_WRITE(data1) \
(((data1) & \
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_MASK) ==\
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_WRITE)

#define EVENT_DATA1_NVM_ERR_TYPE_ERASE(data1) \
(((data1) & \
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_MASK) ==\
ASYNC_EVENT_CMPL_ERROR_REPORT_NVM_EVENT_DATA1_NVM_ERR_TYPE_ERASE)

struct nqe_cn {
__le16 type;
#define NQ_CN_TYPE_MASK 0x3fUL
Expand Down Expand Up @@ -1175,7 +1190,11 @@ struct bnxt_link_info {
#define BNXT_PHY_STATE_ENABLED 0
#define BNXT_PHY_STATE_DISABLED 1

u8 link_up;
u8 link_state;
#define BNXT_LINK_STATE_UNKNOWN 0
#define BNXT_LINK_STATE_DOWN 1
#define BNXT_LINK_STATE_UP 2
#define BNXT_LINK_IS_UP(bp) ((bp)->link_info.link_state == BNXT_LINK_STATE_UP)
u8 duplex;
#define BNXT_LINK_DUPLEX_HALF PORT_PHY_QCFG_RESP_DUPLEX_STATE_HALF
#define BNXT_LINK_DUPLEX_FULL PORT_PHY_QCFG_RESP_DUPLEX_STATE_FULL
Expand Down Expand Up @@ -1524,6 +1543,33 @@ struct bnxt_ctx_mem_info {
struct bnxt_mem_init mem_init[BNXT_CTX_MEM_INIT_MAX];
};

enum bnxt_hw_err {
BNXT_HW_STATUS_HEALTHY = 0x0,
BNXT_HW_STATUS_NVM_WRITE_ERR = 0x1,
BNXT_HW_STATUS_NVM_ERASE_ERR = 0x2,
BNXT_HW_STATUS_NVM_UNKNOWN_ERR = 0x3,
BNXT_HW_STATUS_NVM_TEST_VPD_ENT_ERR = 0x4,
BNXT_HW_STATUS_NVM_TEST_VPD_READ_ERR = 0x5,
BNXT_HW_STATUS_NVM_TEST_VPD_WRITE_ERR = 0x6,
BNXT_HW_STATUS_NVM_TEST_INCMPL_ERR = 0x7,
};

struct bnxt_hw_health {
u32 nvm_err_address;
u32 nvm_write_errors;
u32 nvm_erase_errors;
u32 nvm_test_vpd_ent_errors;
u32 nvm_test_vpd_read_errors;
u32 nvm_test_vpd_write_errors;
u32 nvm_test_incmpl_errors;
u8 synd;
/* max a test in a day if previous test was successful */
#define HW_RETEST_MIN_TIME (1000 * 3600 * 24)
u8 nvm_test_result;
unsigned long nvm_test_timestamp;
struct devlink_health_reporter *hw_reporter;
};

enum bnxt_health_severity {
SEVERITY_NORMAL = 0,
SEVERITY_WARNING,
Expand Down Expand Up @@ -2041,6 +2087,7 @@ struct bnxt {
#define BNXT_FW_EXCEPTION_SP_EVENT 19
#define BNXT_LINK_CFG_CHANGE_SP_EVENT 21
#define BNXT_FW_ECHO_REQUEST_SP_EVENT 23
#define BNXT_FW_NVM_ERR_SP_EVENT 25

struct delayed_work fw_reset_task;
int fw_reset_state;
Expand Down Expand Up @@ -2100,8 +2147,8 @@ struct bnxt {
u32 lpi_tmr_lo;
u32 lpi_tmr_hi;

/* copied from flags in hwrm_port_phy_qcaps_output */
u8 phy_flags;
/* copied from flags and flags2 in hwrm_port_phy_qcaps_output */
u32 phy_flags;
#define BNXT_PHY_FL_EEE_CAP PORT_PHY_QCAPS_RESP_FLAGS_EEE_SUPPORTED
#define BNXT_PHY_FL_EXT_LPBK PORT_PHY_QCAPS_RESP_FLAGS_EXTERNAL_LPBK_SUPPORTED
#define BNXT_PHY_FL_AN_PHY_LPBK PORT_PHY_QCAPS_RESP_FLAGS_AUTONEG_LPBK_SUPPORTED
Expand All @@ -2110,6 +2157,8 @@ struct bnxt {
#define BNXT_PHY_FL_NO_PHY_LPBK PORT_PHY_QCAPS_RESP_FLAGS_LOCAL_LPBK_NOT_SUPPORTED
#define BNXT_PHY_FL_FW_MANAGED_LKDN PORT_PHY_QCAPS_RESP_FLAGS_FW_MANAGED_LINK_DOWN
#define BNXT_PHY_FL_NO_FCS PORT_PHY_QCAPS_RESP_FLAGS_NO_FCS
#define BNXT_PHY_FL_NO_PAUSE (PORT_PHY_QCAPS_RESP_FLAGS2_PAUSE_UNSUPPORTED << 8)
#define BNXT_PHY_FL_NO_PFC (PORT_PHY_QCAPS_RESP_FLAGS2_PFC_UNSUPPORTED << 8)

u8 num_tests;
struct bnxt_test_info *test_info;
Expand Down Expand Up @@ -2139,6 +2188,8 @@ struct bnxt {
struct dentry *debugfs_pdev;
struct device *hwmon_dev;
enum board_idx board_idx;

struct bnxt_hw_health hw_health;
};

#define BNXT_NUM_RX_RING_STATS 8
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,8 @@ static int bnxt_dcbnl_ieee_setpfc(struct net_device *dev, struct ieee_pfc *pfc)
int rc;

if (!(bp->dcbx_cap & DCB_CAP_DCBX_VER_IEEE) ||
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST))
!(bp->dcbx_cap & DCB_CAP_DCBX_HOST) ||
(bp->phy_flags & BNXT_PHY_FL_NO_PAUSE))
return -EINVAL;

if (!my_pfc) {
Expand Down
Loading

0 comments on commit d59e3cb

Please sign in to comment.