Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F176601766
D58937.id189529.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D58937.id189529.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D58937: aq: implement the RSS driver methods
Attached
Detach File
Event Timeline
Log In to Comment