Page MenuHomeFreeBSD

D58937.id189529.diff
No OneTemporary

D58937.id189529.diff

diff --git a/share/man/man4/aq.4 b/share/man/man4/aq.4
--- a/share/man/man4/aq.4
+++ b/share/man/man4/aq.4
@@ -3,7 +3,7 @@
.\"
.\" SPDX-License-Identifier: BSD-2-Clause
.\"
-.Dd September 13, 2026
+.Dd September 19, 2026
.Dt AQ 4
.Os
.Sh NAME
@@ -33,6 +33,19 @@
.Pp
For more information on configuring this device, see
.Xr ifconfig 8 .
+.Pp
+The receive-side scaling hash key and indirection table can be read and
+programmed with
+.Xr ifconfig 8 ,
+and a programmed key or table is reapplied every time the interface is
+initialised.
+First generation adapters deliver UDP to receive queue 0 through a flow
+filter, regardless of the table, unless the kernel enables UDP hashing
+with the
+.Va net.inet.rss.udp_4tuple
+tunable under
+.Cd "options RSS" ;
+second generation adapters hash UDP through the table.
.Sh HARDWARE
The
.Nm
diff --git a/sys/dev/aq/aq_main.c b/sys/dev/aq/aq_main.c
--- a/sys/dev/aq/aq_main.c
+++ b/sys/dev/aq/aq_main.c
@@ -202,6 +202,13 @@
static void aq_if_led_func(if_ctx_t ctx, int onoff);
static int aq_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req);
+/* RSS */
+static int aq_if_get_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk);
+static int aq_if_set_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk);
+static int aq_if_get_rss_hash(if_ctx_t ctx, struct ifrsshash *ifrh);
+static int aq_if_get_rss_table(if_ctx_t ctx, struct ifrsstable *ifrt);
+static int aq_if_set_rss_table(if_ctx_t ctx, struct ifrsstable *ifrt);
+
static device_method_t aq_methods[] = {
DEVMETHOD(device_register, aq_register),
DEVMETHOD(device_probe, iflib_device_probe),
@@ -269,6 +276,13 @@
DEVMETHOD(ifdi_led_func, aq_if_led_func),
DEVMETHOD(ifdi_i2c_req, aq_if_i2c_req),
+ /* RSS */
+ DEVMETHOD(ifdi_get_rss_key, aq_if_get_rss_key),
+ DEVMETHOD(ifdi_set_rss_key, aq_if_set_rss_key),
+ DEVMETHOD(ifdi_get_rss_hash, aq_if_get_rss_hash),
+ DEVMETHOD(ifdi_get_rss_table, aq_if_get_rss_table),
+ DEVMETHOD(ifdi_set_rss_table, aq_if_set_rss_table),
+
DEVMETHOD_END
};
@@ -445,6 +459,7 @@
scctx->isc_ntxqsets_max = HW_ATL_B0_RINGS_MAX;
scctx->isc_nrxqsets_max = HW_ATL_RSS_INDIRECTION_QUEUES_MAX;
+ scctx->isc_rss_table_size = HW_ATL_RSS_INDIRECTION_TABLE_MAX;
/* iflib will map and release this bar */
scctx->isc_msix_bar = pci_msix_table_bar(softc->dev);
@@ -1280,6 +1295,118 @@
AQ_DBG_EXIT(0);
}
+static uint32_t
+aq_rss_iftypes(struct aq_dev *softc)
+{
+ u_int hashconfig = aq_rss_hashconfig();
+ uint32_t types;
+
+ if (IS_CHIP_FEATURE(&softc->hw, ATLANTIC2))
+ return (rss_hashconfig_to_iftypes(hashconfig));
+
+ types = RSS_TYPE_IPV4 | RSS_TYPE_TCP_IPV4 | RSS_TYPE_IPV6 |
+ RSS_TYPE_TCP_IPV6;
+ if ((hashconfig & (RSS_HASHTYPE_RSS_UDP_IPV4 |
+ RSS_HASHTYPE_RSS_UDP_IPV6 | RSS_HASHTYPE_RSS_UDP_IPV6_EX)) != 0)
+ types |= RSS_TYPE_UDP_IPV4 | RSS_TYPE_UDP_IPV6;
+
+ return (types);
+}
+
+static int
+aq_if_get_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk)
+{
+ struct aq_dev *softc = iflib_get_softc(ctx);
+
+ _Static_assert(sizeof(ifrk->ifrk_key) >= HW_ATL_RSS_HASHKEY_SIZE,
+ "RSS key buffer too small");
+
+ ifrk->ifrk_func = RSS_FUNC_TOEPLITZ;
+ ifrk->ifrk_keylen = HW_ATL_RSS_HASHKEY_SIZE;
+ memcpy(ifrk->ifrk_key, softc->rss_key, HW_ATL_RSS_HASHKEY_SIZE);
+
+ return (0);
+}
+
+static int
+aq_if_get_rss_hash(if_ctx_t ctx, struct ifrsshash *ifrh)
+{
+ struct aq_dev *softc = iflib_get_softc(ctx);
+
+ ifrh->ifrh_func = RSS_FUNC_TOEPLITZ;
+ ifrh->ifrh_types = aq_rss_iftypes(softc);
+
+ return (0);
+}
+
+static int
+aq_rss_hw_failed(if_ctx_t ctx, struct aq_dev *softc, int err)
+{
+
+ device_printf(softc->dev, "could not program RSS: %d\n", err);
+ softc->reset_pending = true;
+ iflib_request_reset_if_up(ctx);
+ iflib_admin_intr_deferred(ctx);
+
+ return (err);
+}
+
+static int
+aq_if_set_rss_key(if_ctx_t ctx, struct ifrsskey *ifrk)
+{
+ struct aq_dev *softc = iflib_get_softc(ctx);
+ int err;
+
+ if (ifrk->ifrk_keylen != HW_ATL_RSS_HASHKEY_SIZE)
+ return (EINVAL);
+
+ if (iflib_is_running(ctx) && !softc->reset_pending) {
+ err = aq_hw_rss_hash_set(&softc->hw, ifrk->ifrk_key);
+ if (err != 0)
+ return (aq_rss_hw_failed(ctx, softc, err));
+ }
+ memcpy(softc->rss_key, ifrk->ifrk_key, HW_ATL_RSS_HASHKEY_SIZE);
+
+ return (0);
+}
+
+static int
+aq_if_get_rss_table(if_ctx_t ctx, struct ifrsstable *ifrt)
+{
+ struct aq_dev *softc = iflib_get_softc(ctx);
+ uint16_t i;
+
+ _Static_assert(RSS_TABLELEN >= HW_ATL_RSS_INDIRECTION_TABLE_MAX,
+ "RSS table buffer too small");
+
+ ifrt->ifrt_nentries = HW_ATL_RSS_INDIRECTION_TABLE_MAX;
+ for (i = 0; i < HW_ATL_RSS_INDIRECTION_TABLE_MAX; i++)
+ ifrt->ifrt_table[i] = softc->rss_table[i];
+
+ return (0);
+}
+
+static int
+aq_if_set_rss_table(if_ctx_t ctx, struct ifrsstable *ifrt)
+{
+ struct aq_dev *softc = iflib_get_softc(ctx);
+ uint8_t table[HW_ATL_RSS_INDIRECTION_TABLE_MAX];
+ uint16_t i;
+ int err;
+
+ for (i = 0; i < HW_ATL_RSS_INDIRECTION_TABLE_MAX; i++)
+ table[i] = (uint8_t)ifrt->ifrt_table[i];
+
+ if (iflib_is_running(ctx) && !softc->reset_pending) {
+ err = aq_hw_rss_set(&softc->hw, table);
+ if (err != 0)
+ return (aq_rss_hw_failed(ctx, softc, err));
+ }
+ memcpy(softc->rss_table, table, sizeof(table));
+
+ return (0);
+}
+
static int
aq_if_i2c_req(if_ctx_t ctx, struct ifi2creq *req)
{
diff --git a/sys/net/rss_config.h b/sys/net/rss_config.h
--- a/sys/net/rss_config.h
+++ b/sys/net/rss_config.h
@@ -130,6 +130,7 @@
void rss_getkey(uint8_t *key);
u_int rss_gethashalgo(void);
u_int rss_gethashconfig(void);
+uint32_t rss_hashconfig_to_iftypes(u_int hashconfig);
/*
* Hash calculation functions.
*/
diff --git a/sys/net/rss_config.c b/sys/net/rss_config.c
--- a/sys/net/rss_config.c
+++ b/sys/net/rss_config.c
@@ -517,6 +517,38 @@
return (config);
}
+/*
+ * Translate an RSS_HASHTYPE_ mask to the RSS_TYPE_ mask reported by
+ * SIOCGIFRSSHASH.
+ */
+uint32_t
+rss_hashconfig_to_iftypes(u_int hashconfig)
+{
+ static const struct {
+ u_int hashtype;
+ uint32_t iftype;
+ } map[] = {
+ { RSS_HASHTYPE_RSS_IPV4, RSS_TYPE_IPV4 },
+ { RSS_HASHTYPE_RSS_TCP_IPV4, RSS_TYPE_TCP_IPV4 },
+ { RSS_HASHTYPE_RSS_IPV6, RSS_TYPE_IPV6 },
+ { RSS_HASHTYPE_RSS_IPV6_EX, RSS_TYPE_IPV6_EX },
+ { RSS_HASHTYPE_RSS_TCP_IPV6, RSS_TYPE_TCP_IPV6 },
+ { RSS_HASHTYPE_RSS_TCP_IPV6_EX, RSS_TYPE_TCP_IPV6_EX },
+ { RSS_HASHTYPE_RSS_UDP_IPV4, RSS_TYPE_UDP_IPV4 },
+ { RSS_HASHTYPE_RSS_UDP_IPV6, RSS_TYPE_UDP_IPV6 },
+ { RSS_HASHTYPE_RSS_UDP_IPV6_EX, RSS_TYPE_UDP_IPV6_EX },
+ };
+ uint32_t iftypes;
+ u_int i;
+
+ iftypes = 0;
+ for (i = 0; i < nitems(map); i++) {
+ if ((hashconfig & map[i].hashtype) != 0)
+ iftypes |= map[i].iftype;
+ }
+ return (iftypes);
+}
+
/*
* XXXRW: Confirm that sysctl -a won't dump this keying material, don't want
* it appearing in debugging output unnecessarily.

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 21, 3:44 AM (6 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41148103
Default Alt Text
D58937.id189529.diff (6 KB)

Event Timeline