RE: [EXTERNAL] Re: [PATCH net-next 6/9] net: atlantic: implement AQC113 L2/L3/L4 RX filter management filter management management

From: Sukhdeep Soni [C]

Date: Fri May 08 2026 - 02:58:24 EST


On 06 May 2026, Vadim Fedorenko wrote:
> On 06/05/2026 14:57, sukhdeeps@xxxxxxxxxxx wrote:
> From: Sukhdeep Singh <sukhdeeps@xxxxxxxxxxx>
>
> Implement complete RX filter management for AQC113 hardware:
>
> - Add tag-based filter policy with reference-counted sharing, allowing
> multiple filter rules to share the same L3 or L4 hardware filter
> when their match criteria are identical.
> - Implement L3 (IPv4/IPv6 source/destination address and protocol)
> filter find, get (program HW and increment refcount), and put
> (decrement refcount and clear HW when last user releases).
> - Implement L4 (TCP/UDP/SCTP source/destination port) filter
> management with the same find/get/put pattern.
> - Add combined L3L4 filter configuration that translates legacy
> aq_rx_filter_l3l4 commands into AQC113 separate L3+L4 filter
> programming with Action Resolver Table (ART) entries.
> - Add L2 ethertype filter set/clear with tag-based ART integration.
> - Add MAC address setup using firmware-provided L2 filter base index.
>
> Update hardware initialization:
> - Use firmware-reported ART section base and count instead of
> hardcoded 0xFFFF section enable.
> - Enable L3 v6/v4 select mode for simultaneous IPv4/IPv6 filtering.
> - Initialize L3L4 filter indices to -1 on reset.
>
> Wire up hw_filter_l2_set, hw_filter_l2_clear, hw_filter_l3l4_set,
> hw_set_mac_address, hw_get_version, and hw_get_regs in hw_atl2_ops.
>
> Signed-off-by: Sukhdeep Singh <sukhdeeps@xxxxxxxxxxx>
> ---
> .../net/ethernet/aquantia/atlantic/aq_hw.h | 2 +
> .../aquantia/atlantic/hw_atl2/hw_atl2.c | 582 +++++++++++++++++-
> 2 files changed, 580 insertions(+), 4 deletions(-)

[...]

>
> @@ -380,6 +422,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 = 0;

> no need to init variable which is overwritten later ...

Agreed, will remove art_mask initialization in v2

> u16 action;
> u8 index;
> int i;
> @@ -394,9 +439,14 @@ 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 = priv->art_base_index / 8 + priv->art_count / 8;
> + art_first_sec = priv->art_base_index / 8;
> + art_mask = (BIT(art_last_sec) - 1) - (BIT(art_first_sec) - 1);

> ... here

> + 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
> @@ -530,6 +580,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 = 0U;
> + unsigned int l = 0U;
> + int err = 0;

> here again, h, l and err are not used with init values.

will remove initialization for h, l and err in v2. Thank you for the review.

> +
> + 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] = {

[...]