From: Sukhdeep Singh Date: Wed, 10 Jun 2026 11:54:38 +0000 (+0530) Subject: net: atlantic: move active_ipv4/ipv6 bitmap updates after HW write X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dfb7a7468b94d9dec7744938b03e742dda41ca02;p=thirdparty%2Flinux.git net: atlantic: move active_ipv4/ipv6 bitmap updates after HW write Move active_ipv4/active_ipv6 bitmap updates from aq_set_data_fl3l4() into aq_add_del_fl3l4() after the hardware write succeeds. The bitmaps track which filter slots are actively programmed in hardware and must only be updated once the HW write is confirmed. The bitmap updates in aq_nic_reserve_filter() and aq_nic_release_filter() are intentionally retained: they guard the aq_check_approve_fl3l4() IPv4/IPv6 mixing validation for callers such as the AQC113 PTP path that program filters directly via hw_atl2_new_fl3l4_configure() without going through aq_add_del_fl3l4(). Signed-off-by: Sukhdeep Singh Link: https://patch.msgid.link/20260610115448.272-3-sukhdeeps@marvell.com Signed-off-by: Jakub Kicinski --- diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c index eef52f23166dd..150a0b1af26a3 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_filters.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_filters.c @@ -479,15 +479,8 @@ static int aq_set_data_fl3l4(struct aq_nic_s *aq_nic, data->is_ipv6 = rx_fltrs->fl3l4.is_ipv6; data->location = HW_ATL_GET_REG_LOCATION_FL3L4(fsp->location); - if (!add) { - if (!data->is_ipv6) - rx_fltrs->fl3l4.active_ipv4 &= ~BIT(data->location); - else - rx_fltrs->fl3l4.active_ipv6 &= - ~BIT((data->location) / 4); - + if (!add) return 0; - } data->cmd |= HW_ATL_RX_ENABLE_FLTR_L3L4; @@ -515,11 +508,9 @@ static int aq_set_data_fl3l4(struct aq_nic_s *aq_nic, ntohl(fsp->h_u.tcp_ip4_spec.ip4src); data->ip_dst[0] = ntohl(fsp->h_u.tcp_ip4_spec.ip4dst); - rx_fltrs->fl3l4.active_ipv4 |= BIT(data->location); } else { int i; - rx_fltrs->fl3l4.active_ipv6 |= BIT((data->location) / 4); for (i = 0; i < HW_ATL_RX_CNT_REG_ADDR_IPV6; ++i) { data->ip_dst[i] = ntohl(fsp->h_u.tcp_ip6_spec.ip6dst[i]); @@ -574,16 +565,35 @@ static int aq_set_fl3l4(struct aq_hw_s *aq_hw, static int aq_add_del_fl3l4(struct aq_nic_s *aq_nic, struct aq_rx_filter *aq_rx_fltr, bool add) { + struct aq_hw_rx_fltrs_s *rx_fltrs = aq_get_hw_rx_fltrs(aq_nic); const struct aq_hw_ops *aq_hw_ops = aq_nic->aq_hw_ops; struct aq_hw_s *aq_hw = aq_nic->aq_hw; struct aq_rx_filter_l3l4 data; + int err; if (unlikely(aq_rx_fltr->aq_fsp.location < AQ_RX_FIRST_LOC_FL3L4 || - aq_rx_fltr->aq_fsp.location > AQ_RX_LAST_LOC_FL3L4 || - aq_set_data_fl3l4(aq_nic, aq_rx_fltr, &data, add))) + aq_rx_fltr->aq_fsp.location > AQ_RX_LAST_LOC_FL3L4)) return -EINVAL; - return aq_set_fl3l4(aq_hw, aq_hw_ops, &data); + aq_set_data_fl3l4(aq_nic, aq_rx_fltr, &data, add); + + err = aq_set_fl3l4(aq_hw, aq_hw_ops, &data); + if (err) + return err; + + if (add) { + if (!data.is_ipv6) + rx_fltrs->fl3l4.active_ipv4 |= BIT(data.location); + else + rx_fltrs->fl3l4.active_ipv6 |= BIT(data.location / 4); + } else { + if (!data.is_ipv6) + rx_fltrs->fl3l4.active_ipv4 &= ~BIT(data.location); + else + rx_fltrs->fl3l4.active_ipv6 &= ~BIT(data.location / 4); + } + + return 0; } static int aq_add_del_rule(struct aq_nic_s *aq_nic,