From: <sukhdeeps@marvell.com>
To: <netdev@vger.kernel.org>
Cc: <andrew+netdev@lunn.ch>, <davem@davemloft.net>,
<edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>,
<linux-kernel@vger.kernel.org>, <horms@kernel.org>,
<vadim.fedorenko@linux.dev>,
Sukhdeep Singh <sukhdeeps@marvell.com>
Subject: [PATCH net-next v5 5/12] net: atlantic: add AQC113 filter data structures, firmware query and register dump
Date: Wed, 10 Jun 2026 17:24:41 +0530 [thread overview]
Message-ID: <20260610115448.272-6-sukhdeeps@marvell.com> (raw)
In-Reply-To: <20260610115448.272-1-sukhdeeps@marvell.com>
From: Sukhdeep Singh <sukhdeeps@marvell.com>
Add filter infrastructure for AQC113 hardware:
- Define L3 (IPv4/IPv6), L4 (TCP/UDP/SCTP), and combined L3L4 filter
structures with serialized usage counter for filter sharing.
- Define tag policy structure for ethertype filter management.
- Add RPF L3/L4 command bit definitions for filter programming.
- Add filter count constants for L3L4, L3V4, L4, VLAN, and ethertype.
- Extend hw_atl2_priv with filter arrays, base indices, and counts
discovered from firmware.
Query filter capabilities from firmware shared memory at init time
to discover available L2/L3/L4/VLAN/ethertype filter resources and
ART (Action Resolver Table) configuration.
Add hardware register dump utility for AQC113 debug support.
Signed-off-by: Sukhdeep Singh <sukhdeeps@marvell.com>
---
.../aquantia/atlantic/hw_atl2/hw_atl2.c | 9 ---
.../atlantic/hw_atl2/hw_atl2_internal.h | 65 +++++++++++++++++
.../aquantia/atlantic/hw_atl2/hw_atl2_utils.c | 34 +++++++++
.../aquantia/atlantic/hw_atl2/hw_atl2_utils.h | 7 +-
.../atlantic/hw_atl2/hw_atl2_utils_fw.c | 69 +++++++++++++++++--
5 files changed, 169 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
index 0ce9caae8799..ba9555fb8f11 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
@@ -540,17 +540,8 @@ static int hw_atl2_hw_init(struct aq_hw_s *self, const u8 *mac_addr)
};
struct aq_nic_cfg_s *aq_nic_cfg = self->aq_nic_cfg;
- struct hw_atl2_priv *priv = self->priv;
- u8 base_index, count;
int err;
- err = hw_atl2_utils_get_action_resolve_table_caps(self, &base_index,
- &count);
- if (err)
- return err;
-
- priv->art_base_index = 8 * base_index;
-
hw_atl2_init_launchtime(self);
hw_atl2_hw_init_tx_path(self);
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h
index 5a89bb8722f9..6b608918ec33 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_internal.h
@@ -84,6 +84,19 @@ enum HW_ATL2_RPF_ART_INDEX {
HW_ATL_VLAN_MAX_FILTERS,
};
+#define HW_ATL2_RPF_L3_CMD_EN BIT(0)
+#define HW_ATL2_RPF_L3_CMD_SA_EN BIT(1)
+#define HW_ATL2_RPF_L3_CMD_DA_EN BIT(2)
+#define HW_ATL2_RPF_L3_CMD_PROTO_EN BIT(3)
+#define HW_ATL2_RPF_L3_V6_CMD_EN BIT(0x10)
+#define HW_ATL2_RPF_L3_V6_CMD_SA_EN BIT(0x11)
+#define HW_ATL2_RPF_L3_V6_CMD_DA_EN BIT(0x12)
+#define HW_ATL2_RPF_L3_V6_CMD_PROTO_EN BIT(0x13)
+#define HW_ATL2_RPF_L4_CMD_EN BIT(0)
+#define HW_ATL2_RPF_L4_CMD_DP_EN BIT(1)
+#define HW_ATL2_RPF_L4_CMD_SP_EN BIT(2)
+#define HW_ATL2_ART_TOTAL_ENTRIES 128
+
#define HW_ATL2_ACTION(ACTION, RSS, INDEX, VALID) \
((((ACTION) & 0x3U) << 8) | \
(((RSS) & 0x1U) << 7) | \
@@ -94,6 +107,13 @@ enum HW_ATL2_RPF_ART_INDEX {
#define HW_ATL2_ACTION_DISABLE HW_ATL2_ACTION(0, 0, 0, 0)
#define HW_ATL2_ACTION_ASSIGN_QUEUE(QUEUE) HW_ATL2_ACTION(1, 0, (QUEUE), 1)
#define HW_ATL2_ACTION_ASSIGN_TC(TC) HW_ATL2_ACTION(1, 1, (TC), 1)
+#define HW_ATL2_RPF_L3L4_FILTERS 8
+#define HW_ATL2_RPF_L3V4_FILTERS 8
+#define HW_ATL2_RPF_L3V6_FILTERS 6
+#define HW_ATL2_RPF_L4_FILTERS 8
+#define HW_ATL2_RPF_VLAN_FILTERS 16
+#define HW_ATL2_RPF_ETYPE_FILTERS 16
+#define HW_ATL2_RPF_ETYPE_TAGS 7
enum HW_ATL2_RPF_RSS_HASH_TYPE {
HW_ATL2_RPF_RSS_HASH_TYPE_NONE = 0,
@@ -119,9 +139,54 @@ enum HW_ATL2_RPF_RSS_HASH_TYPE {
#define HW_ATL_MCAST_FLT_ANY_TO_HOST 0x00010FFFU
+struct hw_atl2_l3_filter {
+ u8 proto;
+ u8 usage;
+ u32 cmd;
+ u32 srcip[4];
+ u32 dstip[4];
+};
+
+struct hw_atl2_l4_filter {
+ u8 usage;
+ u32 cmd;
+ u16 sport;
+ u16 dport;
+};
+
+struct hw_atl2_l3l4_filter {
+ s8 l3_index;
+ s8 l4_index;
+ u8 ipv6;
+};
+
+struct hw_atl2_tag_policy {
+ u16 action;
+ u16 usage;
+};
+
struct hw_atl2_priv {
+ struct hw_atl2_l3_filter l3_v4_filters[HW_ATL2_RPF_L3L4_FILTERS];
+ struct hw_atl2_l3_filter l3_v6_filters[HW_ATL2_RPF_L3L4_FILTERS];
+ struct hw_atl2_l4_filter l4_filters[HW_ATL2_RPF_L3L4_FILTERS];
+ struct hw_atl2_l3l4_filter l3l4_filters[HW_ATL2_RPF_L3L4_FILTERS];
+ struct hw_atl2_tag_policy etype_policy[HW_ATL2_RPF_ETYPE_FILTERS];
struct statistics_s last_stats;
unsigned int art_base_index;
+ unsigned int art_count;
+ unsigned int l2_filters_base_index;
+ unsigned int l2_filter_count;
+ unsigned int etype_filter_base_index;
+ unsigned int etype_filter_count;
+ unsigned int etype_filter_tag_top;
+ unsigned int vlan_filter_base_index;
+ unsigned int vlan_filter_count;
+ unsigned int l3_v4_filter_base_index;
+ unsigned int l3_v4_filter_count;
+ unsigned int l3_v6_filter_base_index;
+ unsigned int l3_v6_filter_count;
+ unsigned int l4_filter_base_index;
+ unsigned int l4_filter_count;
};
#endif /* HW_ATL2_INTERNAL_H */
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
index 0fe6257d9c08..ef549e172dd9 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.c
@@ -128,3 +128,37 @@ int hw_atl2_utils_soft_reset(struct aq_hw_s *self)
err_exit:
return err;
}
+
+static const u32 hw_atl2_utils_hw_mac_regs[] = {
+ 0x00005580U, 0x00005590U, 0x000055B0U, 0x000055B4U,
+ 0x000055C0U, 0x00005B00U, 0x00005B04U, 0x00005B08U,
+ 0x00005B0CU, 0x00005B10U, 0x00005B14U, 0x00005B18U,
+ 0x00005B1CU, 0x00005B20U, 0x00005B24U, 0x00005B28U,
+ 0x00005B2CU, 0x00005B30U, 0x00005B34U, 0x00005B38U,
+ 0x00005B3CU, 0x00005B40U, 0x00005B44U, 0x00005B48U,
+ 0x00005B4CU, 0x00005B50U, 0x00005B54U, 0x00005B58U,
+ 0x00005B5CU, 0x00005B60U, 0x00005B64U, 0x00005B68U,
+ 0x00005B6CU, 0x00005B70U, 0x00005B74U, 0x00005B78U,
+ 0x00005B7CU, 0x00007C00U, 0x00007C04U, 0x00007C08U,
+ 0x00007C0CU, 0x00007C10U, 0x00007C14U, 0x00007C18U,
+ 0x00007C1CU, 0x00007C20U, 0x00007C40U, 0x00007C44U,
+ 0x00007C48U, 0x00007C4CU, 0x00007C50U, 0x00007C54U,
+ 0x00007C58U, 0x00007C5CU, 0x00007C60U, 0x00007C80U,
+ 0x00007C84U, 0x00007C88U, 0x00007C8CU, 0x00007C90U,
+ 0x00007C94U, 0x00007C98U, 0x00007C9CU, 0x00007CA0U,
+ 0x00007CC0U, 0x00007CC4U, 0x00007CC8U, 0x00007CCCU,
+ 0x00007CD0U, 0x00007CD4U, 0x00007CD8U, 0x00007CDCU,
+};
+
+int hw_atl2_utils_hw_get_regs(struct aq_hw_s *self,
+ const struct aq_hw_caps_s *aq_hw_caps,
+ u32 *regs_buff)
+{
+ unsigned int i;
+
+ for (i = 0; i < min_t(u32, aq_hw_caps->mac_regs_count,
+ ARRAY_SIZE(hw_atl2_utils_hw_mac_regs)); i++)
+ regs_buff[i] = aq_hw_read_reg(self,
+ hw_atl2_utils_hw_mac_regs[i]);
+ return 0;
+}
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.h
index 6bad64c77b87..bae18c32365b 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.h
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils.h
@@ -626,10 +626,13 @@ int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops);
int hw_atl2_utils_soft_reset(struct aq_hw_s *self);
+int hw_atl2_utils_hw_get_regs(struct aq_hw_s *self,
+ const struct aq_hw_caps_s *aq_hw_caps,
+ u32 *regs_buff);
+
u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self);
-int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self,
- u8 *base_index, u8 *count);
+int hw_atl2_utils_get_filter_caps(struct aq_hw_s *self);
extern const struct aq_fw_ops aq_a2_fw_ops;
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
index 7370e3f76b62..12c3f42ab611 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2_utils_fw.c
@@ -121,6 +121,10 @@ static int aq_a2_fw_init(struct aq_hw_s *self)
u32 val;
int err;
+ err = hw_atl2_utils_get_filter_caps(self);
+ if (err)
+ return err;
+
hw_atl2_shared_buffer_get(self, link_control, link_control);
link_control.mode = AQ_HOST_MODE_ACTIVE;
hw_atl2_shared_buffer_write(self, link_control, link_control);
@@ -606,18 +610,75 @@ u32 hw_atl2_utils_get_fw_version(struct aq_hw_s *self)
version.bundle.build;
}
-int hw_atl2_utils_get_action_resolve_table_caps(struct aq_hw_s *self,
- u8 *base_index, u8 *count)
+int hw_atl2_utils_get_filter_caps(struct aq_hw_s *self)
{
+ struct hw_atl2_priv *priv = self->priv;
struct filter_caps_s filter_caps;
+ u32 tag_top;
int err;
err = hw_atl2_shared_buffer_read_safe(self, filter_caps, &filter_caps);
if (err)
return err;
- *base_index = filter_caps.rslv_tbl_base_index;
- *count = filter_caps.rslv_tbl_count;
+ priv->art_base_index = filter_caps.rslv_tbl_base_index * 8;
+ priv->art_count = filter_caps.rslv_tbl_count * 8;
+ if (priv->art_count == 0)
+ priv->art_count = HW_ATL2_ART_TOTAL_ENTRIES;
+ priv->l2_filters_base_index = filter_caps.l2_filters_base_index;
+ priv->l2_filter_count = filter_caps.l2_filter_count;
+ priv->etype_filter_base_index = filter_caps.ethertype_filter_base_index;
+ priv->etype_filter_count = filter_caps.ethertype_filter_count;
+ priv->etype_filter_tag_top =
+ (priv->etype_filter_count >= HW_ATL2_RPF_ETYPE_TAGS) ?
+ (HW_ATL2_RPF_ETYPE_TAGS) : (HW_ATL2_RPF_ETYPE_TAGS >> 1);
+ priv->vlan_filter_base_index = filter_caps.vlan_filter_base_index;
+ /* 0 - no tag, 1 - reserved for vlan-filter-offload filters */
+ tag_top =
+ (filter_caps.vlan_filter_count == HW_ATL2_RPF_VLAN_FILTERS) ?
+ (HW_ATL2_RPF_VLAN_FILTERS - 2) :
+ (HW_ATL2_RPF_VLAN_FILTERS / 2 - 2);
+
+ if (filter_caps.vlan_filter_count > 2) {
+ priv->vlan_filter_count = min_t(u32,
+ filter_caps.vlan_filter_count - 2,
+ tag_top);
+ } else {
+ pr_debug("atlantic: FW vlan_filter_count=%u <= 2, no usable VLAN filters\n",
+ filter_caps.vlan_filter_count);
+ priv->vlan_filter_count = 0;
+ }
+
+ priv->l3_v4_filter_base_index = filter_caps.l3_ip4_filter_base_index;
+ if (priv->l3_v4_filter_base_index >= HW_ATL2_RPF_L3V4_FILTERS) {
+ priv->l3_v4_filter_base_index = 0;
+ priv->l3_v4_filter_count = 0;
+ } else {
+ priv->l3_v4_filter_count = min_t(u32,
+ filter_caps.l3_ip4_filter_count,
+ HW_ATL2_RPF_L3V4_FILTERS - 1);
+ }
+
+ priv->l3_v6_filter_base_index = filter_caps.l3_ip6_filter_base_index;
+ if (priv->l3_v6_filter_base_index >= HW_ATL2_RPF_L3V6_FILTERS) {
+ priv->l3_v6_filter_base_index = 0;
+ priv->l3_v6_filter_count = 0;
+ } else {
+ priv->l3_v6_filter_count = min_t(u32,
+ filter_caps.l3_ip6_filter_count,
+ HW_ATL2_RPF_L3V6_FILTERS - 1);
+ }
+
+ priv->l4_filter_base_index = filter_caps.l4_filter_base_index;
+ if (priv->l4_filter_base_index >= HW_ATL2_RPF_L4_FILTERS) {
+ priv->l4_filter_base_index = 0;
+ priv->l4_filter_count = 0;
+ } else {
+ priv->l4_filter_count = min_t(u32,
+ filter_caps.l4_filter_count,
+ HW_ATL2_RPF_L4_FILTERS - 1);
+ }
+
return 0;
}
--
2.43.0
next prev parent reply other threads:[~2026-06-10 11:55 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-10 11:54 [PATCH net-next v5 0/12] net: atlantic: add PTP support for AQC113 (Antigua) sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 1/12] net: atlantic: correct L3L4 filter flow_type masking and IPv6 handling sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 2/12] net: atlantic: move active_ipv4/ipv6 bitmap updates after HW write sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 3/12] net: atlantic: decouple aq_set_data_fl3l4() from driver internals sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 4/12] net: atlantic: add AQC113 hardware register definitions and accessors sukhdeeps
2026-06-10 11:54 ` sukhdeeps [this message]
2026-06-10 11:54 ` [PATCH net-next v5 6/12] net: atlantic: fix AQC113 HW init: ART, L2 filter slot, MAC address sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 7/12] net: atlantic: implement AQC113 L2/L3/L4 RX filter ops sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 8/12] net: atlantic: add AQC113 PTP traffic class and TX path setup sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 9/12] net: atlantic: extend hw_ops and TX descriptor for AQC113 PTP sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 10/12] net: atlantic: add AQC113 PTP hardware ops in hw_atl2 sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 11/12] net: atlantic: add AQC113 TX timestamp polling and PTP TX classification sukhdeeps
2026-06-10 11:54 ` [PATCH net-next v5 12/12] net: atlantic: add AQC113 PTP support in aq_ptp and driver core sukhdeeps
2026-06-15 22:50 ` [PATCH net-next v5 0/12] net: atlantic: add PTP support for AQC113 (Antigua) patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260610115448.272-6-sukhdeeps@marvell.com \
--to=sukhdeeps@marvell.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.