Page MenuHomeFreeBSD

D12223.id32796.diff
No OneTemporary

D12223.id32796.diff

Index: sys/dev/bnxt/bnxt.h
===================================================================
--- sys/dev/bnxt/bnxt.h
+++ sys/dev/bnxt/bnxt.h
@@ -526,6 +526,14 @@
uint16_t alloc_vnics;
};
+struct bnxt_hw_lro {
+ uint16_t enable;
+ uint16_t is_mode_gro;
+ uint16_t max_agg_segs;
+ uint16_t max_aggs;
+ uint32_t min_agg_len;
+};
+
struct bnxt_softc {
device_t dev;
if_ctx_t ctx;
@@ -584,10 +592,13 @@
struct sysctl_ctx_list hw_stats;
struct sysctl_oid *hw_stats_oid;
+ struct sysctl_ctx_list hw_lro_ctx;
+ struct sysctl_oid *hw_lro_oid;
struct bnxt_ver_info *ver_info;
struct bnxt_nvram_info *nvm_info;
bool wol;
+ struct bnxt_hw_lro hw_lro;
uint8_t wol_filter_id;
uint16_t rx_coal_usecs;
uint16_t rx_coal_usecs_irq;
Index: sys/dev/bnxt/bnxt_hwrm.h
===================================================================
--- sys/dev/bnxt/bnxt_hwrm.h
+++ sys/dev/bnxt/bnxt_hwrm.h
@@ -61,8 +61,8 @@
int bnxt_hwrm_rss_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic,
uint32_t hash_type);
int bnxt_hwrm_func_cfg(struct bnxt_softc *softc);
-int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc,
- struct bnxt_vnic_info *vnic, uint32_t flags);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc);
+void bnxt_validate_hw_lro_settings(struct bnxt_softc *softc);
int bnxt_hwrm_nvm_find_dir_entry(struct bnxt_softc *softc, uint16_t type,
uint16_t *ordinal, uint16_t ext, uint16_t *index, bool use_index,
uint8_t search_opt, uint32_t *data_length, uint32_t *item_length,
Index: sys/dev/bnxt/bnxt_hwrm.c
===================================================================
--- sys/dev/bnxt/bnxt_hwrm.c
+++ sys/dev/bnxt/bnxt_hwrm.c
@@ -944,30 +944,76 @@
return hwrm_send_message(softc, &req, sizeof(req));
}
+void
+bnxt_validate_hw_lro_settings(struct bnxt_softc *softc)
+{
+ if (softc->hw_lro.enable)
+ softc->hw_lro.enable = 1;
+
+ if (softc->hw_lro.is_mode_gro)
+ softc->hw_lro.is_mode_gro = 1;
+
+ switch (softc->hw_lro.max_agg_segs) {
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX:
+ break;
+ default:
+ softc->hw_lro.max_agg_segs =
+ HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX;
+ }
+
+ switch (softc->hw_lro.max_aggs) {
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16:
+ case HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX:
+ break;
+ default:
+ softc->hw_lro.max_aggs =
+ HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX;
+ }
+
+ if (softc->hw_lro.min_agg_len > 9000)
+ softc->hw_lro.min_agg_len = 9000;
+}
+
int
-bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc, struct bnxt_vnic_info *vnic,
- uint32_t flags)
+bnxt_hwrm_vnic_tpa_cfg(struct bnxt_softc *softc)
{
struct hwrm_vnic_tpa_cfg_input req = {0};
+ uint32_t flags;
bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_VNIC_TPA_CFG);
- req.flags = htole32(flags);
- req.vnic_id = htole16(vnic->id);
- req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
- HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
- /* HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER | */
- HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
- /* TODO: Calculate this based on ring size? */
- req.max_agg_segs = htole16(3);
- /* Base this in the allocated TPA start size... */
- req.max_aggs = htole16(7);
- /*
- * TODO: max_agg_timer?
- * req.mag_agg_timer = htole32(XXX);
- */
- req.min_agg_len = htole32(0);
+ if (softc->hw_lro.enable) {
+ flags = HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+ HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ;
+
+ if (softc->hw_lro.is_mode_gro)
+ flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO;
+ else
+ flags |= HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE;
+
+ req.flags = htole32(flags);
+ req.enables = htole32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+ HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+ HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+
+ req.max_agg_segs = htole16(softc->hw_lro.max_agg_segs);
+ req.max_aggs = htole16(softc->hw_lro.max_aggs);
+ req.min_agg_len = htole32(softc->hw_lro.min_agg_len);
+ }
+
+ req.vnic_id = htole16(softc->vnic_info.id);
+
return hwrm_send_message(softc, &req, sizeof(req));
}
Index: sys/dev/bnxt/bnxt_sysctl.h
===================================================================
--- sys/dev/bnxt/bnxt_sysctl.h
+++ sys/dev/bnxt/bnxt_sysctl.h
@@ -39,3 +39,4 @@
int bnxt_create_nvram_sysctls(struct bnxt_nvram_info *ni);
int bnxt_create_config_sysctls_pre(struct bnxt_softc *softc);
int bnxt_create_config_sysctls_post(struct bnxt_softc *softc);
+int bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc);
Index: sys/dev/bnxt/bnxt_sysctl.c
===================================================================
--- sys/dev/bnxt/bnxt_sysctl.c
+++ sys/dev/bnxt/bnxt_sysctl.c
@@ -84,6 +84,16 @@
return ENOMEM;
}
+ sysctl_ctx_init(&softc->hw_lro_ctx);
+ ctx = device_get_sysctl_ctx(softc->dev);
+ softc->hw_lro_oid = SYSCTL_ADD_NODE(ctx,
+ SYSCTL_CHILDREN(device_get_sysctl_tree(softc->dev)), OID_AUTO,
+ "hw_lro", CTLFLAG_RD, 0, "hardware lro");
+ if (!softc->hw_lro_oid) {
+ sysctl_ctx_free(&softc->hw_lro_ctx);
+ return ENOMEM;
+ }
+
return 0;
}
@@ -114,6 +124,13 @@
else
softc->nvm_info->nvm_oid = NULL;
}
+ if (softc->hw_lro_oid != NULL) {
+ orc = sysctl_ctx_free(&softc->hw_lro_ctx);
+ if (orc)
+ rc = orc;
+ else
+ softc->hw_lro_oid = NULL;
+ }
return rc;
}
@@ -760,6 +777,70 @@
return 0;
}
+#define BNXT_HW_LRO_FN(fn_name, arg) \
+static int \
+fn_name(SYSCTL_HANDLER_ARGS) { \
+ struct bnxt_softc *softc = arg1; \
+ int rc; \
+ int val; \
+ \
+ if (softc == NULL) \
+ return EBUSY; \
+ \
+ val = softc->hw_lro.arg; \
+ rc = sysctl_handle_int(oidp, &val, 0, req); \
+ if (rc || !req->newptr) \
+ return rc; \
+ \
+ softc->hw_lro.arg = val; \
+ bnxt_validate_hw_lro_settings(softc); \
+ rc = bnxt_hwrm_vnic_tpa_cfg(softc); \
+ \
+ return rc; \
+}
+
+BNXT_HW_LRO_FN(bnxt_hw_lro_enable_disable, enable)
+BNXT_HW_LRO_FN(bnxt_hw_lro_set_mode, is_mode_gro)
+BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_agg_segs, max_agg_segs)
+BNXT_HW_LRO_FN(bnxt_hw_lro_set_max_aggs, max_aggs)
+BNXT_HW_LRO_FN(bnxt_hw_lro_set_min_agg_len, min_agg_len)
+
+int
+bnxt_create_hw_lro_sysctls(struct bnxt_softc *softc)
+{
+ struct sysctl_oid *oid = softc->hw_lro_oid;
+
+ if (!oid)
+ return ENOMEM;
+
+ SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "hw_lro_enable", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_hw_lro_enable_disable, "A",
+ "Enable or Disable HW LRO: 0 / 1");
+
+ SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "hw_lro_mode_gro", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_hw_lro_set_mode, "A",
+ "Set mode: 1 = GRO mode, 0 = RSC mode");
+
+ SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "max_agg_segs", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_hw_lro_set_max_agg_segs, "A",
+ "Set Max Agg Seg Value: 0 / 1 / 2 / 3 / 31");
+
+ SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "max_aggs", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_hw_lro_set_max_aggs, "A",
+ "Set Max Aggs Value: 0 / 1 / 2 / 3 / 4 / 7");
+
+ SYSCTL_ADD_PROC(&softc->hw_lro_ctx, SYSCTL_CHILDREN(oid), OID_AUTO,
+ "min_agg_len", CTLTYPE_INT|CTLFLAG_RWTUN, softc, 0,
+ bnxt_hw_lro_set_min_agg_len, "A",
+ "Min Agg Len: 1 to 9000");
+
+
+ return 0;
+}
static int
bnxt_vlan_only_sysctl(SYSCTL_HANDLER_ARGS) {
struct bnxt_softc *softc = arg1;
Index: sys/dev/bnxt/if_bnxt.c
===================================================================
--- sys/dev/bnxt/if_bnxt.c
+++ sys/dev/bnxt/if_bnxt.c
@@ -784,6 +784,13 @@
/* iflib will map and release this bar */
scctx->isc_msix_bar = pci_msix_table_bar(softc->dev);
+ /* Default settings for HW LRO (TPA) */
+ softc->hw_lro.enable = 1;
+ softc->hw_lro.is_mode_gro = 0;
+ softc->hw_lro.max_agg_segs = HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX;
+ softc->hw_lro.max_aggs = HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX;
+ softc->hw_lro.min_agg_len = 512;
+
/* Allocate the default completion ring */
softc->def_cp_ring.stats_ctx_id = HWRM_NA_SIGNATURE;
softc->def_cp_ring.ring.phys_id = (uint16_t)HWRM_NA_SIGNATURE;
@@ -819,6 +826,10 @@
if (rc)
goto failed;
+ rc = bnxt_create_hw_lro_sysctls(softc);
+ if (rc)
+ goto failed;
+
/* Initialize the vlan list */
SLIST_INIT(&softc->vnic_info.vlan_tags);
softc->vnic_info.vlan_tag_list.idi_vaddr = NULL;
@@ -1029,15 +1040,7 @@
if (rc)
goto fail;
- /*
- * Enable LRO/TPA/GRO
- * TBD:
- * Enable / Disable HW_LRO based on
- * ifconfig lro / ifconfig -lro setting
- */
- rc = bnxt_hwrm_vnic_tpa_cfg(softc, &softc->vnic_info,
- (if_getcapenable(iflib_get_ifp(ctx)) & IFCAP_LRO) ?
- HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA : 0);
+ rc = bnxt_hwrm_vnic_tpa_cfg(softc);
if (rc)
goto fail;

File Metadata

Mime Type
text/plain
Expires
Mon, Jul 6, 7:12 PM (9 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34765935
Default Alt Text
D12223.id32796.diff (9 KB)

Event Timeline