Skip to content

Commit 7d9df38

Browse files
Michael Chankuba-moo
authored andcommitted
bnxt_en: Cap the size of HWRM_PORT_PHY_QCFG forwarded response
Firmware interface 1.10.2.118 has increased the size of HWRM_PORT_PHY_QCFG response beyond the maximum size that can be forwarded. When the VF's link state is not the default auto state, the PF will need to forward the response back to the VF to indicate the forced state. This regression may cause the VF to fail to initialize. Fix it by capping the HWRM_PORT_PHY_QCFG response to the maximum 96 bytes. The SPEEDS2_SUPPORTED flag needs to be cleared because the new speeds2 fields are beyond the legacy structure. Also modify bnxt_hwrm_fwd_resp() to print a warning if the message size exceeds 96 bytes to make this failure more obvious. Fixes: 84a911d ("bnxt_en: Update firmware interface to 1.10.2.118") Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com> Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Link: https://lore.kernel.org/r/20240612231736.57823-1-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 6f4d93b commit 7d9df38

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,57 @@ struct bnxt_l2_filter {
14341434
atomic_t refcnt;
14351435
};
14361436

1437+
/* Compat version of hwrm_port_phy_qcfg_output capped at 96 bytes. The
1438+
* first 95 bytes are identical to hwrm_port_phy_qcfg_output in bnxt_hsi.h.
1439+
* The last valid byte in the compat version is different.
1440+
*/
1441+
struct hwrm_port_phy_qcfg_output_compat {
1442+
__le16 error_code;
1443+
__le16 req_type;
1444+
__le16 seq_id;
1445+
__le16 resp_len;
1446+
u8 link;
1447+
u8 active_fec_signal_mode;
1448+
__le16 link_speed;
1449+
u8 duplex_cfg;
1450+
u8 pause;
1451+
__le16 support_speeds;
1452+
__le16 force_link_speed;
1453+
u8 auto_mode;
1454+
u8 auto_pause;
1455+
__le16 auto_link_speed;
1456+
__le16 auto_link_speed_mask;
1457+
u8 wirespeed;
1458+
u8 lpbk;
1459+
u8 force_pause;
1460+
u8 module_status;
1461+
__le32 preemphasis;
1462+
u8 phy_maj;
1463+
u8 phy_min;
1464+
u8 phy_bld;
1465+
u8 phy_type;
1466+
u8 media_type;
1467+
u8 xcvr_pkg_type;
1468+
u8 eee_config_phy_addr;
1469+
u8 parallel_detect;
1470+
__le16 link_partner_adv_speeds;
1471+
u8 link_partner_adv_auto_mode;
1472+
u8 link_partner_adv_pause;
1473+
__le16 adv_eee_link_speed_mask;
1474+
__le16 link_partner_adv_eee_link_speed_mask;
1475+
__le32 xcvr_identifier_type_tx_lpi_timer;
1476+
__le16 fec_cfg;
1477+
u8 duplex_state;
1478+
u8 option_flags;
1479+
char phy_vendor_name[16];
1480+
char phy_vendor_partnumber[16];
1481+
__le16 support_pam4_speeds;
1482+
__le16 force_pam4_link_speed;
1483+
__le16 auto_pam4_link_speed_mask;
1484+
u8 link_partner_pam4_adv_speeds;
1485+
u8 valid;
1486+
};
1487+
14371488
struct bnxt_link_info {
14381489
u8 phy_type;
14391490
u8 media_type;

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,8 +950,11 @@ static int bnxt_hwrm_fwd_resp(struct bnxt *bp, struct bnxt_vf_info *vf,
950950
struct hwrm_fwd_resp_input *req;
951951
int rc;
952952

953-
if (BNXT_FWD_RESP_SIZE_ERR(msg_size))
953+
if (BNXT_FWD_RESP_SIZE_ERR(msg_size)) {
954+
netdev_warn_once(bp->dev, "HWRM fwd response too big (%d bytes)\n",
955+
msg_size);
954956
return -EINVAL;
957+
}
955958

956959
rc = hwrm_req_init(bp, req, HWRM_FWD_RESP);
957960
if (!rc) {
@@ -1085,7 +1088,7 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
10851088
rc = bnxt_hwrm_exec_fwd_resp(
10861089
bp, vf, sizeof(struct hwrm_port_phy_qcfg_input));
10871090
} else {
1088-
struct hwrm_port_phy_qcfg_output phy_qcfg_resp = {0};
1091+
struct hwrm_port_phy_qcfg_output_compat phy_qcfg_resp = {};
10891092
struct hwrm_port_phy_qcfg_input *phy_qcfg_req;
10901093

10911094
phy_qcfg_req =
@@ -1096,6 +1099,11 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)
10961099
mutex_unlock(&bp->link_lock);
10971100
phy_qcfg_resp.resp_len = cpu_to_le16(sizeof(phy_qcfg_resp));
10981101
phy_qcfg_resp.seq_id = phy_qcfg_req->seq_id;
1102+
/* New SPEEDS2 fields are beyond the legacy structure, so
1103+
* clear the SPEEDS2_SUPPORTED flag.
1104+
*/
1105+
phy_qcfg_resp.option_flags &=
1106+
~PORT_PHY_QCAPS_RESP_FLAGS2_SPEEDS2_SUPPORTED;
10991107
phy_qcfg_resp.valid = 1;
11001108

11011109
if (vf->flags & BNXT_VF_LINK_UP) {

0 commit comments

Comments
 (0)