Commit ee1bfbcc authored by Paolo Abeni's avatar Paolo Abeni
Browse files

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.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents b2140e97 85036aee
Loading
Loading
Loading
Loading
+53 −19
Original line number Diff line number Diff line
@@ -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,7 +5263,7 @@ 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,
static void bnxt_fill_hw_rss_tbl_p5(struct bnxt *bp,
				    struct bnxt_vnic_info *vnic)
{
	__le16 *ring_tbl = vnic->rss_table;
@@ -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 |
+2 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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);
+47 −0
Original line number Diff line number Diff line
@@ -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;
+33 −12
Original line number Diff line number Diff line
@@ -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,8 +211,26 @@ 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;

	if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
		int neg_adj = 0;
		u32 diff;
		u64 adj;

		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;
@@ -222,6 +241,7 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
		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)
Loading