Skip to content

Commit 7070eea

Browse files
vladimirolteandavem330
authored andcommitted
enetc: permit configuration of rx-vlan-filter with ethtool
Each ENETC station interface (SI) has a VLAN filter list and a port flag (PSIPVMR) by which it can be put in "VLAN promiscuous" mode, which enables the reception of VLAN-tagged traffic even if it is not in the VLAN filtering list. Currently the handling of this setting works like this: the port starts off as VLAN promiscuous, then it switches to enabling VLAN filtering as soon as the first VLAN is installed in its filter via .ndo_vlan_rx_add_vid. In practice that does not work out very well, because more often than not, the first VLAN to be installed is out of the control of the user: the 8021q module, if loaded, adds its rule for 802.1p (VID 0) traffic upon bringing the interface up. What the user is currently seeing in ethtool is this: ethtool -k eno2 rx-vlan-filter: on [fixed] which doesn't match the intention of the code, but the practical reality of having the 8021q module install its VID which has the side-effect of turning on VLAN filtering in this driver. All in all, a slightly confusing experience. So instead of letting this driver switch the VLAN filtering state by itself, just wire it up with the rx-vlan-filter feature from ethtool, and let it be user-configurable just through that knob, except for one case, see below. In promiscuous mode, it is more intuitive that all traffic is received, including VLAN tagged traffic. It appears that it is necessary to set the flag in PSIPVMR for that to be the case, so VLAN promiscuous mode is also temporarily enabled. On exit from promiscuous mode, the setting made by ethtool is restored. Signed-off-by: Vladimir Oltean <[email protected]> Reviewed-by: Claudiu Manoil <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 89f9ffd commit 7070eea

File tree

1 file changed

+16
-28
lines changed

1 file changed

+16
-28
lines changed

drivers/net/ethernet/freescale/enetc/enetc_pf.c

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -50,21 +50,6 @@ static void enetc_set_vlan_promisc(struct enetc_hw *hw, char si_map)
5050
enetc_port_wr(hw, ENETC_PSIPVMR, ENETC_PSIPVMR_SET_VP(si_map) | val);
5151
}
5252

53-
static bool enetc_si_vlan_promisc_is_on(struct enetc_pf *pf, int si_idx)
54-
{
55-
return pf->vlan_promisc_simap & BIT(si_idx);
56-
}
57-
58-
static bool enetc_vlan_filter_is_on(struct enetc_pf *pf)
59-
{
60-
int i;
61-
62-
for_each_set_bit(i, pf->active_vlans, VLAN_N_VID)
63-
return true;
64-
65-
return false;
66-
}
67-
6853
static void enetc_enable_si_vlan_promisc(struct enetc_pf *pf, int si_idx)
6954
{
7055
pf->vlan_promisc_simap |= BIT(si_idx);
@@ -204,6 +189,7 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
204189
{
205190
struct enetc_ndev_priv *priv = netdev_priv(ndev);
206191
struct enetc_pf *pf = enetc_si_priv(priv->si);
192+
char vlan_promisc_simap = pf->vlan_promisc_simap;
207193
struct enetc_hw *hw = &priv->si->hw;
208194
bool uprom = false, mprom = false;
209195
struct enetc_mac_filter *filter;
@@ -216,16 +202,16 @@ static void enetc_pf_set_rx_mode(struct net_device *ndev)
216202
psipmr = ENETC_PSIPMR_SET_UP(0) | ENETC_PSIPMR_SET_MP(0);
217203
uprom = true;
218204
mprom = true;
219-
/* enable VLAN promisc mode for SI0 */
220-
if (!enetc_si_vlan_promisc_is_on(pf, 0))
221-
enetc_enable_si_vlan_promisc(pf, 0);
222-
205+
/* Enable VLAN promiscuous mode for SI0 (PF) */
206+
vlan_promisc_simap |= BIT(0);
223207
} else if (ndev->flags & IFF_ALLMULTI) {
224208
/* enable multi cast promisc mode for SI0 (PF) */
225209
psipmr = ENETC_PSIPMR_SET_MP(0);
226210
mprom = true;
227211
}
228212

213+
enetc_set_vlan_promisc(&pf->si->hw, vlan_promisc_simap);
214+
229215
/* first 2 filter entries belong to PF */
230216
if (!uprom) {
231217
/* Update unicast filters */
@@ -306,9 +292,6 @@ static int enetc_vlan_rx_add_vid(struct net_device *ndev, __be16 prot, u16 vid)
306292
struct enetc_pf *pf = enetc_si_priv(priv->si);
307293
int idx;
308294

309-
if (enetc_si_vlan_promisc_is_on(pf, 0))
310-
enetc_disable_si_vlan_promisc(pf, 0);
311-
312295
__set_bit(vid, pf->active_vlans);
313296

314297
idx = enetc_vid_hash_idx(vid);
@@ -326,9 +309,6 @@ static int enetc_vlan_rx_del_vid(struct net_device *ndev, __be16 prot, u16 vid)
326309
__clear_bit(vid, pf->active_vlans);
327310
enetc_sync_vlan_ht_filter(pf, true);
328311

329-
if (!enetc_vlan_filter_is_on(pf))
330-
enetc_enable_si_vlan_promisc(pf, 0);
331-
332312
return 0;
333313
}
334314

@@ -677,6 +657,15 @@ static int enetc_pf_set_features(struct net_device *ndev,
677657
enetc_enable_txvlan(&priv->si->hw, 0,
678658
!!(features & NETIF_F_HW_VLAN_CTAG_TX));
679659

660+
if (changed & NETIF_F_HW_VLAN_CTAG_FILTER) {
661+
struct enetc_pf *pf = enetc_si_priv(priv->si);
662+
663+
if (!!(features & NETIF_F_HW_VLAN_CTAG_FILTER))
664+
enetc_disable_si_vlan_promisc(pf, 0);
665+
else
666+
enetc_enable_si_vlan_promisc(pf, 0);
667+
}
668+
680669
if (changed & NETIF_F_LOOPBACK)
681670
enetc_set_loopback(ndev, !!(features & NETIF_F_LOOPBACK));
682671

@@ -719,12 +708,11 @@ static void enetc_pf_netdev_setup(struct enetc_si *si, struct net_device *ndev,
719708

720709
ndev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
721710
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_RX |
722-
NETIF_F_LOOPBACK;
711+
NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_LOOPBACK;
723712
ndev->features = NETIF_F_HIGHDMA | NETIF_F_SG |
724713
NETIF_F_RXCSUM | NETIF_F_HW_CSUM |
725714
NETIF_F_HW_VLAN_CTAG_TX |
726-
NETIF_F_HW_VLAN_CTAG_RX |
727-
NETIF_F_HW_VLAN_CTAG_FILTER;
715+
NETIF_F_HW_VLAN_CTAG_RX;
728716

729717
if (si->num_rss)
730718
ndev->hw_features |= NETIF_F_RXHASH;

0 commit comments

Comments
 (0)