Merge branch 'bnxt_en-updates-for-net-next'

Michael Chan says:

====================
bnxt_en: Updates for net-next

This series includes some code clean-ups and optimizations.  New features
include 2 new backing store memory types to collect FW logs for core
dumps, dynamic SRIOV resource allocations for RoCE, and ethtool tunable
for PFC watchdog.

v2: Drop patch #4.  The patch makes the code different from the original
bnxt_hwrm_func_backing_store_cfg_v2() that allows instance_bmap to have
bits that are not contiguous.  It is safer to keep the original code.

v1: https://lore.kernel.org/netdev/20250915030505.1803478-1-michael.chan@broadcom.com/
====================

Link: https://patch.msgid.link/20250917040839.1924698-1-michael.chan@broadcom.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni 2025-09-18 13:09:44 +02:00
commit 7b712146cb
9 changed files with 180 additions and 34 deletions

View file

@ -265,6 +265,8 @@ const u16 bnxt_bstore_to_trace[] = {
[BNXT_CTX_CA1] = DBG_LOG_BUFFER_FLUSH_REQ_TYPE_CA1_TRACE,
[BNXT_CTX_CA2] = DBG_LOG_BUFFER_FLUSH_REQ_TYPE_CA2_TRACE,
[BNXT_CTX_RIGP1] = DBG_LOG_BUFFER_FLUSH_REQ_TYPE_RIGP1_TRACE,
[BNXT_CTX_KONG] = DBG_LOG_BUFFER_FLUSH_REQ_TYPE_AFM_KONG_HWRM_TRACE,
[BNXT_CTX_QPC] = DBG_LOG_BUFFER_FLUSH_REQ_TYPE_ERR_QPC_TRACE,
};
static struct workqueue_struct *bnxt_pf_wq;
@ -6836,7 +6838,7 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
req->dflt_ring_grp = cpu_to_le16(bp->grp_info[grp_idx].fw_grp_id);
req->lb_rule = cpu_to_le16(0xffff);
vnic_mru:
vnic->mru = bp->dev->mtu + ETH_HLEN + VLAN_HLEN;
vnic->mru = bp->dev->mtu + VLAN_ETH_HLEN;
req->mru = cpu_to_le16(vnic->mru);
req->vnic_id = cpu_to_le16(vnic->fw_vnic_id);
@ -9150,7 +9152,7 @@ static int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt *bp,
return rc;
}
static int bnxt_backing_store_cfg_v2(struct bnxt *bp, u32 ena)
static int bnxt_backing_store_cfg_v2(struct bnxt *bp)
{
struct bnxt_ctx_mem_info *ctx = bp->ctx;
struct bnxt_ctx_mem_type *ctxm;
@ -9158,7 +9160,7 @@ static int bnxt_backing_store_cfg_v2(struct bnxt *bp, u32 ena)
int rc = 0;
u16 type;
for (type = BNXT_CTX_SRT; type <= BNXT_CTX_RIGP1; type++) {
for (type = BNXT_CTX_SRT; type <= BNXT_CTX_QPC; type++) {
ctxm = &ctx->ctx_arr[type];
if (!bnxt_bs_trace_avail(bp, type))
continue;
@ -9176,12 +9178,13 @@ static int bnxt_backing_store_cfg_v2(struct bnxt *bp, u32 ena)
}
if (last_type == BNXT_CTX_INV) {
if (!ena)
for (type = 0; type < BNXT_CTX_MAX; type++) {
ctxm = &ctx->ctx_arr[type];
if (ctxm->mem_valid)
last_type = type;
}
if (last_type == BNXT_CTX_INV)
return 0;
else if (ena & FUNC_BACKING_STORE_CFG_REQ_ENABLES_TIM)
last_type = BNXT_CTX_MAX - 1;
else
last_type = BNXT_CTX_L2_MAX - 1;
}
ctx->ctx_arr[last_type].last = 1;
@ -9308,6 +9311,10 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp)
if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED))
return 0;
ena = 0;
if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS))
goto skip_legacy;
ctxm = &ctx->ctx_arr[BNXT_CTX_QP];
l2_qps = ctxm->qp_l2_entries;
qp1_qps = ctxm->qp_qp1_entries;
@ -9316,7 +9323,6 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp)
ctxm = &ctx->ctx_arr[BNXT_CTX_SRQ];
srqs = ctxm->srq_l2_entries;
max_srqs = ctxm->max_entries;
ena = 0;
if ((bp->flags & BNXT_FLAG_ROCE_CAP) && !is_kdump_kernel()) {
pg_lvl = 2;
if (BNXT_SW_RES_LMT(bp)) {
@ -9410,8 +9416,9 @@ skip_rdma:
ena |= FUNC_BACKING_STORE_CFG_REQ_ENABLES_TQM_SP << i;
ena |= FUNC_BACKING_STORE_CFG_REQ_DFLT_ENABLES;
skip_legacy:
if (bp->fw_cap & BNXT_FW_CAP_BACKING_STORE_V2)
rc = bnxt_backing_store_cfg_v2(bp, ena);
rc = bnxt_backing_store_cfg_v2(bp);
else
rc = bnxt_hwrm_func_backing_store_cfg(bp, ena);
if (rc) {
@ -9625,10 +9632,10 @@ no_ptp:
static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
{
u32 flags, flags_ext, flags_ext2, flags_ext3;
struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
struct hwrm_func_qcaps_output *resp;
struct hwrm_func_qcaps_input *req;
struct bnxt_hw_resc *hw_resc = &bp->hw_resc;
u32 flags, flags_ext, flags_ext2;
int rc;
rc = hwrm_req_init(bp, req, HWRM_FUNC_QCAPS);
@ -9695,6 +9702,10 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
(flags_ext2 & FUNC_QCAPS_RESP_FLAGS_EXT2_ROCE_VF_RESOURCE_MGMT_SUPPORTED))
bp->fw_cap |= BNXT_FW_CAP_ROCE_VF_RESC_MGMT_SUPPORTED;
flags_ext3 = le32_to_cpu(resp->flags_ext3);
if (flags_ext3 & FUNC_QCAPS_RESP_FLAGS_EXT3_ROCE_VF_DYN_ALLOC_SUPPORT)
bp->fw_cap |= BNXT_FW_CAP_ROCE_VF_DYN_ALLOC_SUPPORT;
bp->tx_push_thresh = 0;
if ((flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED) &&
BNXT_FW_MAJ(bp) > 217)
@ -14737,6 +14748,23 @@ static bool bnxt_fw_pre_resv_vnics(struct bnxt *bp)
return false;
}
static void bnxt_hwrm_pfcwd_qcaps(struct bnxt *bp)
{
struct hwrm_queue_pfcwd_timeout_qcaps_output *resp;
struct hwrm_queue_pfcwd_timeout_qcaps_input *req;
int rc;
bp->max_pfcwd_tmo_ms = 0;
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCWD_TIMEOUT_QCAPS);
if (rc)
return;
resp = hwrm_req_hold(bp, req);
rc = hwrm_req_send_silent(bp, req);
if (!rc)
bp->max_pfcwd_tmo_ms = le16_to_cpu(resp->max_pfcwd_timeout);
hwrm_req_drop(bp, req);
}
static int bnxt_fw_init_one_p1(struct bnxt *bp)
{
int rc;
@ -14814,6 +14842,7 @@ static int bnxt_fw_init_one_p2(struct bnxt *bp)
if (bnxt_fw_pre_resv_vnics(bp))
bp->fw_cap |= BNXT_FW_CAP_PRE_RESV_VNICS;
bnxt_hwrm_pfcwd_qcaps(bp);
bnxt_hwrm_func_qcfg(bp);
bnxt_hwrm_vnic_qcaps(bp);
bnxt_hwrm_port_led_qcaps(bp);
@ -16075,7 +16104,7 @@ static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
napi_enable_locked(&bnapi->napi);
bnxt_db_nq_arm(bp, &cpr->cp_db, cpr->cp_raw_cons);
mru = bp->dev->mtu + ETH_HLEN + VLAN_HLEN;
mru = bp->dev->mtu + VLAN_ETH_HLEN;
for (i = 0; i < bp->nr_vnics; i++) {
vnic = &bp->vnic_info[i];
@ -16156,7 +16185,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
struct bnxt *bp = netdev_priv(dev);
if (BNXT_PF(bp))
bnxt_sriov_disable(bp);
__bnxt_sriov_disable(bp);
bnxt_rdma_aux_device_del(bp);

View file

@ -1968,10 +1968,12 @@ struct bnxt_ctx_mem_type {
#define BNXT_CTX_CA1 FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CA1_TRACE
#define BNXT_CTX_CA2 FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_CA2_TRACE
#define BNXT_CTX_RIGP1 FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_RIGP1_TRACE
#define BNXT_CTX_KONG FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_AFM_KONG_HWRM_TRACE
#define BNXT_CTX_QPC FUNC_BACKING_STORE_QCAPS_V2_REQ_TYPE_ERR_QPC_TRACE
#define BNXT_CTX_MAX (BNXT_CTX_TIM + 1)
#define BNXT_CTX_L2_MAX (BNXT_CTX_FTQM + 1)
#define BNXT_CTX_V2_MAX (BNXT_CTX_RIGP1 + 1)
#define BNXT_CTX_V2_MAX (BNXT_CTX_QPC + 1)
#define BNXT_CTX_INV ((u16)-1)
struct bnxt_ctx_mem_info {
@ -2424,6 +2426,8 @@ struct bnxt {
u8 max_q;
u8 num_tc;
u16 max_pfcwd_tmo_ms;
u8 tph_mode;
unsigned int current_interval;
@ -2477,6 +2481,7 @@ struct bnxt {
#define BNXT_FW_CAP_ENABLE_RDMA_SRIOV BIT_ULL(5)
#define BNXT_FW_CAP_ROCE_VF_RESC_MGMT_SUPPORTED BIT_ULL(6)
#define BNXT_FW_CAP_KONG_MB_CHNL BIT_ULL(7)
#define BNXT_FW_CAP_ROCE_VF_DYN_ALLOC_SUPPORT BIT_ULL(8)
#define BNXT_FW_CAP_OVS_64BIT_HANDLE BIT_ULL(10)
#define BNXT_FW_CAP_TRUSTED_VF BIT_ULL(11)
#define BNXT_FW_CAP_ERROR_RECOVERY BIT_ULL(13)
@ -2521,6 +2526,8 @@ struct bnxt {
#define BNXT_SUPPORTS_MULTI_RSS_CTX(bp) \
(BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) && \
((bp)->rss_cap & BNXT_RSS_CAP_MULTI_RSS_CTX))
#define BNXT_ROCE_VF_DYN_ALLOC_CAP(bp) \
((bp)->fw_cap & BNXT_FW_CAP_ROCE_VF_DYN_ALLOC_SUPPORT)
#define BNXT_SUPPORTS_QUEUE_API(bp) \
(BNXT_PF(bp) && BNXT_SUPPORTS_NTUPLE_VNIC(bp) && \
((bp)->fw_cap & BNXT_FW_CAP_VNIC_RE_FLUSH))

View file

@ -36,6 +36,8 @@ static const u16 bnxt_bstore_to_seg_id[] = {
[BNXT_CTX_CA1] = BNXT_CTX_MEM_SEG_CA1,
[BNXT_CTX_CA2] = BNXT_CTX_MEM_SEG_CA2,
[BNXT_CTX_RIGP1] = BNXT_CTX_MEM_SEG_RIGP1,
[BNXT_CTX_KONG] = BNXT_CTX_MEM_SEG_KONG,
[BNXT_CTX_QPC] = BNXT_CTX_MEM_SEG_QPC,
};
static int bnxt_dbg_hwrm_log_buffer_flush(struct bnxt *bp, u16 type, u32 flags,
@ -359,7 +361,7 @@ static u32 bnxt_get_ctx_coredump(struct bnxt *bp, void *buf, u32 offset,
if (buf)
buf += offset;
for (type = 0 ; type <= BNXT_CTX_RIGP1; type++) {
for (type = 0; type < BNXT_CTX_V2_MAX; type++) {
struct bnxt_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
bool trace = bnxt_bs_trace_avail(bp, type);
u32 seg_id = bnxt_bstore_to_seg_id[type];

View file

@ -102,6 +102,8 @@ struct bnxt_driver_segment_record {
#define BNXT_CTX_MEM_SEG_CA1 0x9
#define BNXT_CTX_MEM_SEG_CA2 0xa
#define BNXT_CTX_MEM_SEG_RIGP1 0xb
#define BNXT_CTX_MEM_SEG_QPC 0xc
#define BNXT_CTX_MEM_SEG_KONG 0xd
#define BNXT_CRASH_DUMP_LEN (8 << 20)

View file

@ -40,12 +40,6 @@ bnxt_dl_flash_update(struct devlink *dl,
struct bnxt *bp = bnxt_get_bp_from_dl(dl);
int rc;
if (!BNXT_PF(bp)) {
NL_SET_ERR_MSG_MOD(extack,
"flash update not supported from a VF");
return -EPERM;
}
devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0, extack);
if (!rc)
@ -1080,16 +1074,9 @@ static int __bnxt_hwrm_nvm_req(struct bnxt *bp,
static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
union devlink_param_value *val)
{
struct hwrm_nvm_get_variable_input *req = msg;
const struct bnxt_dl_nvm_param *nvm_param;
int i;
/* Get/Set NVM CFG parameter is supported only on PFs */
if (BNXT_VF(bp)) {
hwrm_req_drop(bp, req);
return -EPERM;
}
for (i = 0; i < ARRAY_SIZE(nvm_params); i++) {
nvm_param = &nvm_params[i];
if (nvm_param->id == param_id)

View file

@ -4399,12 +4399,42 @@ static int bnxt_get_eee(struct net_device *dev, struct ethtool_keee *edata)
return 0;
}
static int bnxt_hwrm_pfcwd_qcfg(struct bnxt *bp, u16 *val)
{
struct hwrm_queue_pfcwd_timeout_qcfg_output *resp;
struct hwrm_queue_pfcwd_timeout_qcfg_input *req;
int rc;
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCWD_TIMEOUT_QCFG);
if (rc)
return rc;
resp = hwrm_req_hold(bp, req);
rc = hwrm_req_send(bp, req);
if (!rc)
*val = le16_to_cpu(resp->pfcwd_timeout_value);
hwrm_req_drop(bp, req);
return rc;
}
static int bnxt_hwrm_pfcwd_cfg(struct bnxt *bp, u16 val)
{
struct hwrm_queue_pfcwd_timeout_cfg_input *req;
int rc;
rc = hwrm_req_init(bp, req, HWRM_QUEUE_PFCWD_TIMEOUT_CFG);
if (rc)
return rc;
req->pfcwd_timeout_value = cpu_to_le16(val);
rc = hwrm_req_send(bp, req);
return rc;
}
static int bnxt_set_tunable(struct net_device *dev,
const struct ethtool_tunable *tuna,
const void *data)
{
struct bnxt *bp = netdev_priv(dev);
u32 rx_copybreak;
u32 rx_copybreak, val;
switch (tuna->id) {
case ETHTOOL_RX_COPYBREAK:
@ -4417,6 +4447,15 @@ static int bnxt_set_tunable(struct net_device *dev,
bp->rx_copybreak = rx_copybreak;
}
return 0;
case ETHTOOL_PFC_PREVENTION_TOUT:
if (BNXT_VF(bp) || !bp->max_pfcwd_tmo_ms)
return -EOPNOTSUPP;
val = *(u16 *)data;
if (val > bp->max_pfcwd_tmo_ms &&
val != PFC_STORM_PREVENTION_AUTO)
return -EINVAL;
return bnxt_hwrm_pfcwd_cfg(bp, val);
default:
return -EOPNOTSUPP;
}
@ -4431,6 +4470,10 @@ static int bnxt_get_tunable(struct net_device *dev,
case ETHTOOL_RX_COPYBREAK:
*(u32 *)data = bp->rx_copybreak;
break;
case ETHTOOL_PFC_PREVENTION_TOUT:
if (!bp->max_pfcwd_tmo_ms)
return -EOPNOTSUPP;
return bnxt_hwrm_pfcwd_qcfg(bp, data);
default:
return -EOPNOTSUPP;
}

View file

@ -541,6 +541,13 @@ static void bnxt_hwrm_roce_sriov_cfg(struct bnxt *bp, int num_vfs)
if (rc)
goto err;
/* In case of VF Dynamic resource allocation, driver will provision
* maximum resources to all the VFs. FW will dynamically allocate
* resources to VFs on the fly, so always divide the resources by 1.
*/
if (BNXT_ROCE_VF_DYN_ALLOC_CAP(bp))
num_vfs = 1;
cfg_req->fid = cpu_to_le16(0xffff);
cfg_req->enables2 =
cpu_to_le32(FUNC_CFG_REQ_ENABLES2_ROCE_MAX_AV_PER_VF |
@ -734,7 +741,7 @@ static int bnxt_hwrm_func_cfg(struct bnxt *bp, int num_vfs)
FUNC_CFG_REQ_ENABLES_NUM_VNICS |
FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS);
mtu = bp->dev->mtu + ETH_HLEN + VLAN_HLEN;
mtu = bp->dev->mtu + VLAN_ETH_HLEN;
req->mru = cpu_to_le16(mtu);
req->admin_mtu = cpu_to_le16(mtu);
@ -919,7 +926,7 @@ err_out1:
return rc;
}
void bnxt_sriov_disable(struct bnxt *bp)
void __bnxt_sriov_disable(struct bnxt *bp)
{
u16 num_vfs = pci_num_vf(bp->pdev);
@ -943,6 +950,14 @@ void bnxt_sriov_disable(struct bnxt *bp)
devl_unlock(bp->dl);
bnxt_free_vf_resources(bp);
}
static void bnxt_sriov_disable(struct bnxt *bp)
{
if (!pci_num_vf(bp->pdev))
return;
__bnxt_sriov_disable(bp);
/* Reclaim all resources for the PF. */
rtnl_lock();
@ -1321,7 +1336,7 @@ int bnxt_cfg_hw_sriov(struct bnxt *bp, int *num_vfs, bool reset)
return 0;
}
void bnxt_sriov_disable(struct bnxt *bp)
void __bnxt_sriov_disable(struct bnxt *bp)
{
}

View file

@ -38,7 +38,7 @@ bool bnxt_is_trusted_vf(struct bnxt *bp, struct bnxt_vf_info *vf);
int bnxt_set_vf_trust(struct net_device *dev, int vf_id, bool trust);
int bnxt_sriov_configure(struct pci_dev *pdev, int num_vfs);
int bnxt_cfg_hw_sriov(struct bnxt *bp, int *num_vfs, bool reset);
void bnxt_sriov_disable(struct bnxt *);
void __bnxt_sriov_disable(struct bnxt *bp);
void bnxt_hwrm_exec_fwd_req(struct bnxt *);
void bnxt_update_vf_mac(struct bnxt *);
int bnxt_approve_mac(struct bnxt *, const u8 *, bool);

View file

@ -6751,6 +6751,67 @@ struct hwrm_queue_dscp2pri_cfg_output {
u8 valid;
};
/* hwrm_queue_pfcwd_timeout_qcaps_input (size:128b/16B) */
struct hwrm_queue_pfcwd_timeout_qcaps_input {
__le16 req_type;
__le16 cmpl_ring;
__le16 seq_id;
__le16 target_id;
__le64 resp_addr;
};
/* hwrm_queue_pfcwd_timeout_qcaps_output (size:128b/16B) */
struct hwrm_queue_pfcwd_timeout_qcaps_output {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
__le16 max_pfcwd_timeout;
u8 unused_0[5];
u8 valid;
};
/* hwrm_queue_pfcwd_timeout_cfg_input (size:192b/24B) */
struct hwrm_queue_pfcwd_timeout_cfg_input {
__le16 req_type;
__le16 cmpl_ring;
__le16 seq_id;
__le16 target_id;
__le64 resp_addr;
__le16 pfcwd_timeout_value;
u8 unused_0[6];
};
/* hwrm_queue_pfcwd_timeout_cfg_output (size:128b/16B) */
struct hwrm_queue_pfcwd_timeout_cfg_output {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
u8 unused_0[7];
u8 valid;
};
/* hwrm_queue_pfcwd_timeout_qcfg_input (size:128b/16B) */
struct hwrm_queue_pfcwd_timeout_qcfg_input {
__le16 req_type;
__le16 cmpl_ring;
__le16 seq_id;
__le16 target_id;
__le64 resp_addr;
};
/* hwrm_queue_pfcwd_timeout_qcfg_output (size:128b/16B) */
struct hwrm_queue_pfcwd_timeout_qcfg_output {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
__le16 pfcwd_timeout_value;
u8 unused_0[5];
u8 valid;
};
/* hwrm_vnic_alloc_input (size:192b/24B) */
struct hwrm_vnic_alloc_input {
__le16 req_type;