Commit ee1bfbcc authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'bnxt_en-updates'

Michael Chan says:

====================
bnxt_en: Updates

This small patchset adds an improvement to the configuration of ethtool
RSS tuple hash and a PTP improvement when running in a multi-host
environment.
====================

Link: https://lore.kernel.org/r/1667780192-3700-1-git-send-email-michael.chan@broadcom.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents b2140e97 85036aee
......@@ -5250,7 +5250,7 @@ int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings)
return 1;
}
static void __bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
static void bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
{
bool no_rss = !(vnic->flags & BNXT_VNIC_RSS_FLAG);
u16 i, j;
......@@ -5263,8 +5263,8 @@ static void __bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
}
}
static void __bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
struct bnxt_vnic_info *vnic)
static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
struct bnxt_vnic_info *vnic)
{
__le16 *ring_tbl = vnic->rss_table;
struct bnxt_rx_ring_info *rxr;
......@@ -5285,12 +5285,27 @@ static void __bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
}
}
static void bnxt_fill_hw_rss_tbl(struct bnxt *bp, struct bnxt_vnic_info *vnic)
static void
__bnxt_hwrm_vnic_set_rss(struct bnxt *bp, struct hwrm_vnic_rss_cfg_input *req,
struct bnxt_vnic_info *vnic)
{
if (bp->flags & BNXT_FLAG_CHIP_P5)
__bnxt_fill_hw_rss_tbl_p5(bp, vnic);
bnxt_fill_hw_rss_tbl_p5(bp, vnic);
else
__bnxt_fill_hw_rss_tbl(bp, vnic);
bnxt_fill_hw_rss_tbl(bp, vnic);
if (bp->rss_hash_delta) {
req->hash_type = cpu_to_le32(bp->rss_hash_delta);
if (bp->rss_hash_cfg & bp->rss_hash_delta)
req->flags |= VNIC_RSS_CFG_REQ_FLAGS_HASH_TYPE_INCLUDE;
else
req->flags |= VNIC_RSS_CFG_REQ_FLAGS_HASH_TYPE_EXCLUDE;
} else {
req->hash_type = cpu_to_le32(bp->rss_hash_cfg);
}
req->hash_mode_flags = VNIC_RSS_CFG_REQ_HASH_MODE_FLAGS_DEFAULT;
req->ring_grp_tbl_addr = cpu_to_le64(vnic->rss_table_dma_addr);
req->hash_key_tbl_addr = cpu_to_le64(vnic->rss_hash_key_dma_addr);
}
static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
......@@ -5307,14 +5322,8 @@ static int bnxt_hwrm_vnic_set_rss(struct bnxt *bp, u16 vnic_id, bool set_rss)
if (rc)
return rc;
if (set_rss) {
bnxt_fill_hw_rss_tbl(bp, vnic);
req->hash_type = cpu_to_le32(bp->rss_hash_cfg);
req->hash_mode_flags = VNIC_RSS_CFG_REQ_HASH_MODE_FLAGS_DEFAULT;
req->ring_grp_tbl_addr = cpu_to_le64(vnic->rss_table_dma_addr);
req->hash_key_tbl_addr =
cpu_to_le64(vnic->rss_hash_key_dma_addr);
}
if (set_rss)
__bnxt_hwrm_vnic_set_rss(bp, req, vnic);
req->rss_ctx_idx = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[0]);
return hwrm_req_send(bp, req);
}
......@@ -5335,10 +5344,7 @@ static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, u16 vnic_id, bool set_rss)
if (!set_rss)
return hwrm_req_send(bp, req);
bnxt_fill_hw_rss_tbl(bp, vnic);
req->hash_type = cpu_to_le32(bp->rss_hash_cfg);
req->hash_mode_flags = VNIC_RSS_CFG_REQ_HASH_MODE_FLAGS_DEFAULT;
req->hash_key_tbl_addr = cpu_to_le64(vnic->rss_hash_key_dma_addr);
__bnxt_hwrm_vnic_set_rss(bp, req, vnic);
ring_tbl_map = vnic->rss_table_dma_addr;
nr_ctxs = bnxt_get_nr_rss_ctxs(bp, bp->rx_nr_rings);
......@@ -5357,6 +5363,25 @@ static int bnxt_hwrm_vnic_set_rss_p5(struct bnxt *bp, u16 vnic_id, bool set_rss)
return rc;
}
static void bnxt_hwrm_update_rss_hash_cfg(struct bnxt *bp)
{
struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
struct hwrm_vnic_rss_qcfg_output *resp;
struct hwrm_vnic_rss_qcfg_input *req;
if (hwrm_req_init(bp, req, HWRM_VNIC_RSS_QCFG))
return;
/* all contexts configured to same hash_type, zero always exists */
req->rss_ctx_idx = cpu_to_le16(vnic->fw_rss_cos_lb_ctx[0]);
resp = hwrm_req_hold(bp, req);
if (!hwrm_req_send(bp, req)) {
bp->rss_hash_cfg = le32_to_cpu(resp->hash_type) ?: bp->rss_hash_cfg;
bp->rss_hash_delta = 0;
}
hwrm_req_drop(bp, req);
}
static int bnxt_hwrm_vnic_set_hds(struct bnxt *bp, u16 vnic_id)
{
struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
......@@ -5614,6 +5639,8 @@ static int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
(BNXT_CHIP_P5_THOR(bp) &&
!(bp->fw_cap & BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED)))
bp->fw_cap |= BNXT_FW_CAP_VLAN_RX_STRIP;
if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_HASH_TYPE_DELTA_CAP)
bp->fw_cap |= BNXT_FW_CAP_RSS_HASH_TYPE_DELTA;
bp->max_tpa_v2 = le16_to_cpu(resp->max_aggs_supported);
if (bp->max_tpa_v2) {
if (BNXT_CHIP_P5_THOR(bp))
......@@ -6958,8 +6985,11 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
}
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) {
bp->flags |= BNXT_FLAG_MULTI_HOST;
if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
bp->fw_cap &= ~BNXT_FW_CAP_PTP_RTC;
}
if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
......@@ -8808,6 +8838,8 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
rc = bnxt_setup_vnic(bp, 0);
if (rc)
goto err_out;
if (bp->fw_cap & BNXT_FW_CAP_RSS_HASH_TYPE_DELTA)
bnxt_hwrm_update_rss_hash_cfg(bp);
if (bp->flags & BNXT_FLAG_RFS) {
rc = bnxt_alloc_rfs_vnics(bp);
......@@ -12243,6 +12275,8 @@ static void bnxt_set_dflt_rss_hash_type(struct bnxt *bp)
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV4 |
VNIC_RSS_CFG_REQ_HASH_TYPE_IPV6 |
VNIC_RSS_CFG_REQ_HASH_TYPE_TCP_IPV6;
if (bp->fw_cap & BNXT_FW_CAP_RSS_HASH_TYPE_DELTA)
bp->rss_hash_delta = bp->rss_hash_cfg;
if (BNXT_CHIP_P4_PLUS(bp) && bp->hwrm_spec_code >= 0x10501) {
bp->flags |= BNXT_FLAG_UDP_RSS_CAP;
bp->rss_hash_cfg |= VNIC_RSS_CFG_REQ_HASH_TYPE_UDP_IPV4 |
......
......@@ -1900,6 +1900,7 @@ struct bnxt {
u16 *rss_indir_tbl;
u16 rss_indir_tbl_entries;
u32 rss_hash_cfg;
u32 rss_hash_delta;
u16 max_mtu;
u8 max_tc;
......@@ -1965,6 +1966,7 @@ struct bnxt {
#define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX_V2 0x00010000
#define BNXT_FW_CAP_PCIE_STATS_SUPPORTED 0x00020000
#define BNXT_FW_CAP_EXT_STATS_SUPPORTED 0x00040000
#define BNXT_FW_CAP_RSS_HASH_TYPE_DELTA 0x00080000
#define BNXT_FW_CAP_ERR_RECOVER_RELOAD 0x00100000
#define BNXT_FW_CAP_HOT_RESET 0x00200000
#define BNXT_FW_CAP_PTP_RTC 0x00400000
......
......@@ -1234,6 +1234,8 @@ static int bnxt_srxfh(struct bnxt *bp, struct ethtool_rxnfc *cmd)
if (bp->rss_hash_cfg == rss_hash_cfg)
return 0;
if (bp->fw_cap & BNXT_FW_CAP_RSS_HASH_TYPE_DELTA)
bp->rss_hash_delta = bp->rss_hash_cfg ^ rss_hash_cfg;
bp->rss_hash_cfg = rss_hash_cfg;
if (netif_running(bp->dev)) {
bnxt_close_nic(bp, false, false);
......
......@@ -6768,6 +6768,53 @@ struct hwrm_vnic_rss_cfg_cmd_err {
u8 unused_0[7];
};
/* hwrm_vnic_rss_qcfg_input (size:192b/24B) */
struct hwrm_vnic_rss_qcfg_input {
__le16 req_type;
__le16 cmpl_ring;
__le16 seq_id;
__le16 target_id;
__le64 resp_addr;
__le16 rss_ctx_idx;
__le16 vnic_id;
u8 unused_0[4];
};
/* hwrm_vnic_rss_qcfg_output (size:512b/64B) */
struct hwrm_vnic_rss_qcfg_output {
__le16 error_code;
__le16 req_type;
__le16 seq_id;
__le16 resp_len;
__le32 hash_type;
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_IPV4 0x1UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_TCP_IPV4 0x2UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_UDP_IPV4 0x4UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_IPV6 0x8UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_TCP_IPV6 0x10UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_UDP_IPV6 0x20UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_IPV6_FLOW_LABEL 0x40UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_AH_SPI_IPV4 0x80UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_ESP_SPI_IPV4 0x100UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_AH_SPI_IPV6 0x200UL
#define VNIC_RSS_QCFG_RESP_HASH_TYPE_ESP_SPI_IPV6 0x400UL
u8 unused_0[4];
__le32 hash_key[10];
u8 hash_mode_flags;
#define VNIC_RSS_QCFG_RESP_HASH_MODE_FLAGS_DEFAULT 0x1UL
#define VNIC_RSS_QCFG_RESP_HASH_MODE_FLAGS_INNERMOST_4 0x2UL
#define VNIC_RSS_QCFG_RESP_HASH_MODE_FLAGS_INNERMOST_2 0x4UL
#define VNIC_RSS_QCFG_RESP_HASH_MODE_FLAGS_OUTERMOST_4 0x8UL
#define VNIC_RSS_QCFG_RESP_HASH_MODE_FLAGS_OUTERMOST_2 0x10UL
u8 ring_select_mode;
#define VNIC_RSS_QCFG_RESP_RING_SELECT_MODE_TOEPLITZ 0x0UL
#define VNIC_RSS_QCFG_RESP_RING_SELECT_MODE_XOR 0x1UL
#define VNIC_RSS_QCFG_RESP_RING_SELECT_MODE_TOEPLITZ_CHECKSUM 0x2UL
#define VNIC_RSS_QCFG_RESP_RING_SELECT_MODE_LAST VNIC_RSS_QCFG_RESP_RING_SELECT_MODE_TOEPLITZ_CHECKSUM
u8 unused_1[5];
u8 valid;
};
/* hwrm_vnic_plcmodes_cfg_input (size:320b/40B) */
struct hwrm_vnic_plcmodes_cfg_input {
__le16 req_type;
......
......@@ -14,6 +14,7 @@
#include <linux/net_tstamp.h>
#include <linux/timekeeping.h>
#include <linux/ptp_classify.h>
#include <linux/clocksource.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_hwrm.h"
......@@ -210,18 +211,37 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
ptp_info);
struct hwrm_port_mac_cfg_input *req;
struct bnxt *bp = ptp->bp;
int rc;
int rc = 0;
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
if (rc)
return rc;
if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
int neg_adj = 0;
u32 diff;
u64 adj;
req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
rc = hwrm_req_send(ptp->bp, req);
if (rc)
netdev_err(ptp->bp->dev,
"ptp adjfreq failed. rc = %d\n", rc);
if (ppb < 0) {
neg_adj = 1;
ppb = -ppb;
}
adj = ptp->cmult;
adj *= ppb;
diff = div_u64(adj, 1000000000ULL);
spin_lock_bh(&ptp->ptp_lock);
timecounter_read(&ptp->tc);
ptp->cc.mult = neg_adj ? ptp->cmult - diff : ptp->cmult + diff;
spin_unlock_bh(&ptp->ptp_lock);
} else {
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
if (rc)
return rc;
req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
rc = hwrm_req_send(ptp->bp, req);
if (rc)
netdev_err(ptp->bp->dev,
"ptp adjfreq failed. rc = %d\n", rc);
}
return rc;
}
......@@ -846,8 +866,9 @@ static void bnxt_ptp_timecounter_init(struct bnxt *bp, bool init_tc)
memset(&ptp->cc, 0, sizeof(ptp->cc));
ptp->cc.read = bnxt_cc_read;
ptp->cc.mask = CYCLECOUNTER_MASK(48);
ptp->cc.shift = 0;
ptp->cc.mult = 1;
ptp->cc.shift = BNXT_CYCLES_SHIFT;
ptp->cc.mult = clocksource_khz2mult(BNXT_DEVCLK_FREQ, ptp->cc.shift);
ptp->cmult = ptp->cc.mult;
ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD;
}
if (init_tc)
......
......@@ -17,6 +17,8 @@
#define BNXT_PTP_GRC_WIN_BASE 0x6000
#define BNXT_MAX_PHC_DRIFT 31000000
#define BNXT_CYCLES_SHIFT 23
#define BNXT_DEVCLK_FREQ 1000000
#define BNXT_LO_TIMER_MASK 0x0000ffffffffUL
#define BNXT_HI_TIMER_MASK 0xffff00000000UL
......@@ -88,8 +90,9 @@ struct bnxt_ptp_cfg {
u64 old_time;
unsigned long next_period;
unsigned long next_overflow_check;
/* 48-bit PHC overflows in 78 hours. Check overflow every 19 hours. */
#define BNXT_PHC_OVERFLOW_PERIOD (19 * 3600 * HZ)
u32 cmult;
/* a 23b shift cyclecounter will overflow in ~36 mins. Check overflow every 18 mins. */
#define BNXT_PHC_OVERFLOW_PERIOD (18 * 60 * HZ)
u16 tx_seqid;
u16 tx_hdr_off;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment