Updated the Broadcom bnxt driver with new features and improvements, including:
* Added support for 200G PAM4 link speed.
+ * Added support for RSS hash level selection.
* **Updated Cisco enic driver.**
ETH_RSS_NONFRAG_IPV4_UDP | \
ETH_RSS_IPV6 | \
ETH_RSS_NONFRAG_IPV6_TCP | \
- ETH_RSS_NONFRAG_IPV6_UDP)
+ ETH_RSS_NONFRAG_IPV6_UDP | \
+ ETH_RSS_LEVEL_MASK)
#define BNXT_DEV_TX_OFFLOAD_SUPPORT (DEV_TX_OFFLOAD_VLAN_INSERT | \
DEV_TX_OFFLOAD_IPV4_CKSUM | \
uint32_t vnic_cap_flags;
#define BNXT_VNIC_CAP_COS_CLASSIFY BIT(0)
+#define BNXT_VNIC_CAP_OUTER_RSS BIT(1)
unsigned int rx_nr_rings;
unsigned int rx_cp_nr_rings;
unsigned int rx_num_qs_per_vnic;
/* Update the default RSS VNIC(s) */
vnic = BNXT_GET_DEFAULT_VNIC(bp);
vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
+ vnic->hash_mode =
+ bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,
+ ETH_RSS_LEVEL(rss_conf->rss_hf));
/*
* If hashkey is not specified, use the previously configured
hash_types &=
~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
}
+
+ rss_conf->rss_hf |=
+ bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
+
if (hash_types) {
PMD_DRV_LOG(ERR,
"Unknown RSS config from firmware (%08x), RSS disabled",
if (vnic->rx_queue_cnt > 1) {
vnic->hash_type =
bnxt_rte_to_hwrm_hash_types(rss->types);
+ vnic->hash_mode =
+ bnxt_rte_to_hwrm_hash_level(bp, rss->types, rss->level);
if (!rss->key_len) {
/* If hash key has not been specified,
int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
{
int rc = 0;
+ uint32_t flags;
struct hwrm_vnic_qcaps_input req = {.req_type = 0 };
struct hwrm_vnic_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
HWRM_CHECK_RESULT();
- if (rte_le_to_cpu_32(resp->flags) &
- HWRM_VNIC_QCAPS_OUTPUT_FLAGS_COS_ASSIGNMENT_CAP) {
+ flags = rte_le_to_cpu_32(resp->flags);
+
+ if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_COS_ASSIGNMENT_CAP) {
bp->vnic_cap_flags |= BNXT_VNIC_CAP_COS_CLASSIFY;
PMD_DRV_LOG(INFO, "CoS assignment capability enabled\n");
}
+ if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_CAP)
+ bp->vnic_cap_flags |= BNXT_VNIC_CAP_OUTER_RSS;
+
bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
HWRM_UNLOCK();
bp->flags &= ~BNXT_FLAG_UPDATE_HASH;
for (i = 0; i < bp->nr_vnics; i++) {
+ uint32_t lvl = ETH_RSS_LEVEL(rss->rss_hf);
+
vnic = &bp->vnic_info[i];
vnic->hash_type =
bnxt_rte_to_hwrm_hash_types(rss->rss_hf);
+ vnic->hash_mode =
+ bnxt_rte_to_hwrm_hash_level(bp,
+ rss->rss_hf,
+ lvl);
/*
* Use the supplied key if the key length is
return hwrm_type;
}
+
+int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)
+{
+ uint32_t mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
+ bool l3 = (hash_f & (ETH_RSS_IPV4 | ETH_RSS_IPV6));
+ bool l4 = (hash_f & (ETH_RSS_NONFRAG_IPV4_UDP |
+ ETH_RSS_NONFRAG_IPV6_UDP |
+ ETH_RSS_NONFRAG_IPV4_TCP |
+ ETH_RSS_NONFRAG_IPV6_TCP));
+ bool l3_only = l3 && !l4;
+ bool l3_and_l4 = l3 && l4;
+
+ /* If FW has not advertised capability to configure outer/inner
+ * RSS hashing , just log a message. HW will work in default RSS mode.
+ */
+ if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS)) {
+ PMD_DRV_LOG(ERR, "RSS hash level cannot be configured\n");
+ return mode;
+ }
+
+ switch (lvl) {
+ case BNXT_RSS_LEVEL_INNERMOST:
+ if (l3_and_l4 || l4)
+ mode =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4;
+ else if (l3_only)
+ mode =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2;
+ break;
+ case BNXT_RSS_LEVEL_OUTERMOST:
+ if (l3_and_l4 || l4)
+ mode =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4;
+ else if (l3_only)
+ mode =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2;
+ break;
+ default:
+ mode = HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_DEFAULT;
+ break;
+ }
+
+ return mode;
+}
+
+uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode)
+{
+ uint64_t rss_level = 0;
+
+ /* If FW has not advertised capability to configure inner/outer RSS
+ * return default hash mode.
+ */
+ if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS))
+ return ETH_RSS_LEVEL_PMD_DEFAULT;
+
+ if (mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_2 ||
+ mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_OUTERMOST_4)
+ rss_level |= ETH_RSS_LEVEL_OUTERMOST;
+ else if (mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_2 ||
+ mode == HWRM_VNIC_RSS_CFG_INPUT_HASH_MODE_FLAGS_INNERMOST_4)
+ rss_level |= ETH_RSS_LEVEL_INNERMOST;
+ else
+ rss_level |= ETH_RSS_LEVEL_PMD_DEFAULT;
+
+ return rss_level;
+}
#define INVALID_VNIC_ID ((uint16_t)-1)
+#define BNXT_RSS_LEVEL_INNERMOST 0x2
+#define BNXT_RSS_LEVEL_OUTERMOST 0x1
+
struct bnxt_vnic_info {
STAILQ_ENTRY(bnxt_vnic_info) next;
uint8_t ff_pool_idx;
int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
void prandom_bytes(void *dest_ptr, size_t len);
uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
+int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl);
+uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode);
#endif