All of lore.kernel.org
 help / color / mirror / Atom feed
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 6/12] net: atlantic: fix AQC113 HW init: ART, L2 filter slot, MAC address
Date: Wed, 10 Jun 2026 17:24:42 +0530	[thread overview]
Message-ID: <20260610115448.272-7-sukhdeeps@marvell.com> (raw)
In-Reply-To: <20260610115448.272-1-sukhdeeps@marvell.com>

From: Sukhdeep Singh <sukhdeeps@marvell.com>

Fix initialization issues in hw_atl2 to correctly support AQC113:

- hw_atl2_hw_reset: replace unconditional priv memset with selective
  field clears so that l3l4_filters[].l3_index and l4_index can be
  initialized to -1 (not allocated) rather than 0; 0 is a valid filter
  index and would incorrectly appear as an occupied slot after a reset.

- hw_atl2_hw_init_new_rx_filters: use firmware-reported ART section
  base and count (clamped to 16) instead of hardcoded 0xFFFF mask;
  enable simultaneous IPv4/IPv6 L3 filter mode (rpf_l3_v6_v4_select);
  tag the UC MAC slot using firmware-supplied l2_filters_base_index
  instead of hardcoded HW_ATL2_MAC_UC.

- hw_atl2_hw_init_rx_path: enable only the firmware-assigned MAC slot
  (priv->l2_filters_base_index) instead of always slot 0.

- Add hw_atl2_hw_mac_addr_set() that programs the MAC address into
  the firmware-assigned L2 filter slot.  Wire into hw_atl2_ops
  replacing the A1 hw_atl_b0_hw_mac_addr_set; call it from hw_init.

- Wire .hw_get_regs into hw_atl2_ops.

Signed-off-by: Sukhdeep Singh <sukhdeeps@marvell.com>
---
 .../aquantia/atlantic/hw_atl2/hw_atl2.c       | 81 ++++++++++++++++---
 .../atlantic/hw_atl2/hw_atl2_utils_fw.c       |  2 +
 2 files changed, 72 insertions(+), 11 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 ba9555fb8f11..ec5b2a03fd6f 100644
--- a/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
+++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl2/hw_atl2.c
@@ -11,6 +11,7 @@
 #include "hw_atl/hw_atl_utils.h"
 #include "hw_atl/hw_atl_llh.h"
 #include "hw_atl/hw_atl_llh_internal.h"
+#include "hw_atl2.h"
 #include "hw_atl2_utils.h"
 #include "hw_atl2_llh.h"
 #include "hw_atl2_internal.h"
@@ -95,12 +96,21 @@ static int hw_atl2_hw_reset(struct aq_hw_s *self)
 {
 	struct hw_atl2_priv *priv = self->priv;
 	int err;
+	int i;
 
 	err = hw_atl2_utils_soft_reset(self);
 	if (err)
 		return err;
 
-	memset(priv, 0, sizeof(*priv));
+	memset(&priv->last_stats, 0, sizeof(priv->last_stats));
+	memset(priv->l3_v4_filters, 0, sizeof(priv->l3_v4_filters));
+	memset(priv->l3_v6_filters, 0, sizeof(priv->l3_v6_filters));
+	memset(priv->l4_filters, 0, sizeof(priv->l4_filters));
+	memset(priv->etype_policy, 0, sizeof(priv->etype_policy));
+	for (i = 0; i < HW_ATL2_RPF_L3L4_FILTERS; i++) {
+		priv->l3l4_filters[i].l3_index = -1;
+		priv->l3l4_filters[i].l4_index = -1;
+	}
 
 	self->aq_fw_ops->set_state(self, MPI_RESET);
 
@@ -380,6 +390,9 @@ static void hw_atl2_hw_init_new_rx_filters(struct aq_hw_s *self)
 {
 	u8 *prio_tc_map = self->aq_nic_cfg->prio_tc_map;
 	struct hw_atl2_priv *priv = self->priv;
+	u32 art_first_sec, art_last_sec;
+	u32 art_sections;
+	u32 art_mask;
 	u16 action;
 	u8 index;
 	int i;
@@ -394,9 +407,20 @@ static void hw_atl2_hw_init_new_rx_filters(struct aq_hw_s *self)
 	 * REC entry is used for further processing. If multiple entries match,
 	 * the lowest REC entry, Action field will be selected.
 	 */
-	hw_atl2_rpf_act_rslvr_section_en_set(self, 0xFFFF);
+	art_last_sec = min_t(u32,
+			     priv->art_base_index / 8 + priv->art_count / 8,
+			     16U);
+	art_first_sec = min_t(u32, priv->art_base_index / 8, 16U);
+	art_mask = (BIT(art_last_sec) - 1) - (BIT(art_first_sec) - 1);
+	if (!art_mask) {
+		/* ART base index is out of range, enabling all sections */
+		art_mask = 0xFFFF;
+	}
+	art_sections = hw_atl2_rpf_act_rslvr_section_en_get(self) | art_mask;
+	hw_atl2_rpf_act_rslvr_section_en_set(self, art_sections);
+	hw_atl2_rpf_l3_v6_v4_select_set(self, 1);
 	hw_atl2_rpfl2_uc_flr_tag_set(self, HW_ATL2_RPF_TAG_BASE_UC,
-				     HW_ATL2_MAC_UC);
+				     priv->l2_filters_base_index);
 	hw_atl2_rpfl2_bc_flr_tag_set(self, HW_ATL2_RPF_TAG_BASE_UC);
 
 	/* FW reserves the beginning of ART, thus all driver entries must
@@ -484,6 +508,7 @@ static int hw_atl2_act_rslvr_table_set(struct aq_hw_s *self, u8 location,
 static int hw_atl2_hw_init_rx_path(struct aq_hw_s *self)
 {
 	struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
+	struct hw_atl2_priv *priv = self->priv;
 	int i;
 
 	/* Rx TC/RSS number config */
@@ -499,7 +524,9 @@ static int hw_atl2_hw_init_rx_path(struct aq_hw_s *self)
 
 	/* Multicast filters */
 	for (i = HW_ATL2_MAC_MAX; i--;) {
-		hw_atl_rpfl2_uc_flr_en_set(self, (i == 0U) ? 1U : 0U, i);
+		hw_atl_rpfl2_uc_flr_en_set(self,
+					   (i == priv->l2_filters_base_index) ?
+					   1U : 0U, i);
 		hw_atl_rpfl2unicast_flr_act_set(self, 1U, i);
 	}
 
@@ -530,6 +557,35 @@ static int hw_atl2_hw_init_rx_path(struct aq_hw_s *self)
 	return aq_hw_err_from_flags(self);
 }
 
+static int hw_atl2_hw_mac_addr_set(struct aq_hw_s *self, const u8 *mac_addr)
+{
+	struct hw_atl2_priv *priv = self->priv;
+	u32 location = priv->l2_filters_base_index;
+	unsigned int h;
+	unsigned int l;
+	int err;
+
+	if (!mac_addr) {
+		err = -EINVAL;
+		goto err_exit;
+	}
+	h = (mac_addr[0] << 8) | (mac_addr[1]);
+	l = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
+		(mac_addr[4] << 8) | mac_addr[5];
+
+	hw_atl_rpfl2_uc_flr_en_set(self, 0U, location);
+	hw_atl_rpfl2unicast_dest_addresslsw_set(self, l, location);
+	hw_atl_rpfl2unicast_dest_addressmsw_set(self, h, location);
+	hw_atl_rpfl2unicast_flr_act_set(self, 1U, location);
+	hw_atl2_rpfl2_uc_flr_tag_set(self, HW_ATL2_RPF_TAG_BASE_UC, location);
+	hw_atl_rpfl2_uc_flr_en_set(self, 1U, location);
+
+	err = aq_hw_err_from_flags(self);
+
+err_exit:
+	return err;
+}
+
 static int hw_atl2_hw_init(struct aq_hw_s *self, const u8 *mac_addr)
 {
 	static u32 aq_hw_atl2_igcr_table_[4][2] = {
@@ -547,7 +603,7 @@ static int hw_atl2_hw_init(struct aq_hw_s *self, const u8 *mac_addr)
 	hw_atl2_hw_init_tx_path(self);
 	hw_atl2_hw_init_rx_path(self);
 
-	hw_atl_b0_hw_mac_addr_set(self, mac_addr);
+	hw_atl2_hw_mac_addr_set(self, mac_addr);
 
 	self->aq_fw_ops->set_link_speed(self, aq_nic_cfg->link_speed_msk);
 	self->aq_fw_ops->set_state(self, MPI_INIT);
@@ -619,6 +675,8 @@ static int hw_atl2_hw_multicast_list_set(struct aq_hw_s *self,
 					 [ETH_ALEN],
 					 u32 count)
 {
+	struct hw_atl2_priv *priv = self->priv;
+	u32 base_location = priv->l2_filters_base_index + 1;
 	struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
 	int err = 0;
 
@@ -634,18 +692,18 @@ static int hw_atl2_hw_multicast_list_set(struct aq_hw_s *self,
 		u32 l = (ar_mac[i][2] << 24) | (ar_mac[i][3] << 16) |
 					(ar_mac[i][4] << 8) | ar_mac[i][5];
 
-		hw_atl_rpfl2_uc_flr_en_set(self, 0U, HW_ATL2_MAC_MIN + i);
+		hw_atl_rpfl2_uc_flr_en_set(self, 0U, base_location + i);
 
 		hw_atl_rpfl2unicast_dest_addresslsw_set(self, l,
-							HW_ATL2_MAC_MIN + i);
+							base_location + i);
 
 		hw_atl_rpfl2unicast_dest_addressmsw_set(self, h,
-							HW_ATL2_MAC_MIN + i);
+							base_location + i);
 
-		hw_atl2_rpfl2_uc_flr_tag_set(self, 1, HW_ATL2_MAC_MIN + i);
+		hw_atl2_rpfl2_uc_flr_tag_set(self, 1, base_location + i);
 
 		hw_atl_rpfl2_uc_flr_en_set(self, (cfg->is_mc_list_enabled),
-					   HW_ATL2_MAC_MIN + i);
+					   base_location + i);
 	}
 
 	err = aq_hw_err_from_flags(self);
@@ -816,7 +874,7 @@ static int hw_atl2_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
 const struct aq_hw_ops hw_atl2_ops = {
 	.hw_soft_reset        = hw_atl2_utils_soft_reset,
 	.hw_prepare           = hw_atl2_utils_initfw,
-	.hw_set_mac_address   = hw_atl_b0_hw_mac_addr_set,
+	.hw_set_mac_address   = hw_atl2_hw_mac_addr_set,
 	.hw_init              = hw_atl2_hw_init,
 	.hw_reset             = hw_atl2_hw_reset,
 	.hw_start             = hw_atl_b0_hw_start,
@@ -846,6 +904,7 @@ const struct aq_hw_ops hw_atl2_ops = {
 	.hw_rss_set                  = hw_atl2_hw_rss_set,
 	.hw_rss_hash_set             = hw_atl_b0_hw_rss_hash_set,
 	.hw_tc_rate_limit_set        = hw_atl2_hw_init_tx_tc_rate_limit,
+	.hw_get_regs                 = hw_atl2_utils_hw_get_regs,
 	.hw_get_hw_stats             = hw_atl2_utils_get_hw_stats,
 	.hw_get_fw_version           = hw_atl2_utils_get_fw_version,
 	.hw_set_offload              = hw_atl_b0_hw_offload_set,
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 12c3f42ab611..dc9b2ef4640b 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
@@ -626,6 +626,8 @@ int hw_atl2_utils_get_filter_caps(struct aq_hw_s *self)
 	if (priv->art_count == 0)
 		priv->art_count = HW_ATL2_ART_TOTAL_ENTRIES;
 	priv->l2_filters_base_index = filter_caps.l2_filters_base_index;
+	if (priv->l2_filters_base_index >= HW_ATL2_MAC_MAX)
+		priv->l2_filters_base_index = HW_ATL2_MAC_UC;
 	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;
-- 
2.43.0


  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 ` [PATCH net-next v5 5/12] net: atlantic: add AQC113 filter data structures, firmware query and register dump sukhdeeps
2026-06-10 11:54 ` sukhdeeps [this message]
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-7-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.