Skip to content

Commit

Permalink
net: aquantia: fix vlans not working over bridged network
Browse files Browse the repository at this point in the history
In configuration of vlan over bridge over aquantia device
it was found that vlan tagged traffic is dropped on chip.

The reason is that bridge device enables promisc mode,
but in atlantic chip vlan filters will still apply.
So we have to corellate promisc settings with vlan configuration.

The solution is to track in a separate state variable the
need of vlan forced promisc. And also consider generic
promisc configuration when doing vlan filter config.

Fixes: 7975d2a ("net: aquantia: add support of rx-vlan-filter offload")
Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Dmitry Bogdanov authored and David S. Miller committed Jun 26, 2019
1 parent 5b18f12 commit 48dd73d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 8 deletions.
10 changes: 8 additions & 2 deletions drivers/net/ethernet/aquantia/atlantic/aq_filters.c
Original file line number Diff line number Diff line change
Expand Up @@ -843,9 +843,14 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic)
return err;

if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
if (hweight < AQ_VLAN_MAX_FILTERS)
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, true);
if (hweight < AQ_VLAN_MAX_FILTERS && hweight > 0) {
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw,
!(aq_nic->packet_filter & IFF_PROMISC));
aq_nic->aq_nic_cfg.is_vlan_force_promisc = false;
} else {
/* otherwise left in promiscue mode */
aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
}
}

return err;
Expand All @@ -866,6 +871,7 @@ int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic)
if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl))
return -EOPNOTSUPP;

aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false);
if (err)
return err;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)

cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
cfg->features = cfg->aq_hw_caps->hw_features;
cfg->is_vlan_force_promisc = true;
}

static int aq_nic_update_link_status(struct aq_nic_s *self)
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/aquantia/atlantic/aq_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct aq_nic_cfg_s {
u32 flow_control;
u32 link_speed_msk;
u32 wol;
bool is_vlan_force_promisc;
u16 is_mc_list_enabled;
u16 mc_list_count;
bool is_autoneg;
Expand Down
19 changes: 13 additions & 6 deletions drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
unsigned int packet_filter)
{
unsigned int i = 0U;
struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;

hw_atl_rpfl2promiscuous_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC));

hw_atl_rpf_vlan_prom_mode_en_set(self,
IS_FILTER_ENABLED(IFF_PROMISC) ||
cfg->is_vlan_force_promisc);

hw_atl_rpfl2promiscuous_mode_en_set(self, IS_FILTER_ENABLED(IFF_PROMISC));
hw_atl_rpfl2multicast_flr_en_set(self,
IS_FILTER_ENABLED(IFF_ALLMULTI), 0);

Expand All @@ -788,13 +795,13 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,

hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));

self->aq_nic_cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);

for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i)
hw_atl_rpfl2_uc_flr_en_set(self,
(self->aq_nic_cfg->is_mc_list_enabled &&
(i <= self->aq_nic_cfg->mc_list_count)) ?
1U : 0U, i);
(cfg->is_mc_list_enabled &&
(i <= cfg->mc_list_count)) ?
1U : 0U, i);

return aq_hw_err_from_flags(self);
}
Expand Down Expand Up @@ -1086,7 +1093,7 @@ static int hw_atl_b0_hw_vlan_set(struct aq_hw_s *self,
static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
{
/* set promisc in case of disabing the vland filter */
hw_atl_rpf_vlan_prom_mode_en_set(self, !!!enable);
hw_atl_rpf_vlan_prom_mode_en_set(self, !enable);

return aq_hw_err_from_flags(self);
}
Expand Down

0 comments on commit 48dd73d

Please sign in to comment.