|
Jiri Slaby |
ba7816 |
From: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
Jiri Slaby |
ba7816 |
Date: Sat, 25 Mar 2023 13:28:15 +0200
|
|
Jiri Slaby |
ba7816 |
Subject: [PATCH] net: stmmac: don't reject VLANs when IFF_PROMISC is set
|
|
Jiri Slaby |
ba7816 |
References: bsc#1012628
|
|
Jiri Slaby |
ba7816 |
Patch-mainline: 6.2.10
|
|
Jiri Slaby |
ba7816 |
Git-commit: a7602e7332b97cfbec7bacb0f1ade99a575fe104
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
[ Upstream commit a7602e7332b97cfbec7bacb0f1ade99a575fe104 ]
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
The blamed commit has introduced the following tests to
|
|
Jiri Slaby |
ba7816 |
dwmac4_add_hw_vlan_rx_fltr(), called from stmmac_vlan_rx_add_vid():
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
if (hw->promisc) {
|
|
Jiri Slaby |
ba7816 |
netdev_err(dev,
|
|
Jiri Slaby |
ba7816 |
"Adding VLAN in promisc mode not supported\n");
|
|
Jiri Slaby |
ba7816 |
return -EPERM;
|
|
Jiri Slaby |
ba7816 |
}
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
"VLAN promiscuous" mode is keyed in this driver to IFF_PROMISC, and so,
|
|
Jiri Slaby |
ba7816 |
vlan_vid_add() and vlan_vid_del() calls cannot take place in IFF_PROMISC
|
|
Jiri Slaby |
ba7816 |
mode. I have the following 2 arguments that this restriction is.... hm,
|
|
Jiri Slaby |
ba7816 |
how shall I put it nicely... unproductive :)
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
First, take the case of a Linux bridge. If the kernel is compiled with
|
|
Jiri Slaby |
ba7816 |
CONFIG_BRIDGE_VLAN_FILTERING=y, then this bridge shall have a VLAN
|
|
Jiri Slaby |
ba7816 |
database. The bridge shall try to call vlan_add_vid() on its bridge
|
|
Jiri Slaby |
ba7816 |
ports for each VLAN in the VLAN table. It will do this irrespectively of
|
|
Jiri Slaby |
ba7816 |
whether that port is *currently* VLAN-aware or not. So it will do this
|
|
Jiri Slaby |
ba7816 |
even when the bridge was created with vlan_filtering 0.
|
|
Jiri Slaby |
ba7816 |
But the Linux bridge, in VLAN-unaware mode, configures its ports in
|
|
Jiri Slaby |
ba7816 |
promiscuous (IFF_PROMISC) mode, so that they accept packets with any
|
|
Jiri Slaby |
ba7816 |
MAC DA (a switch must do this in order to forward those packets which
|
|
Jiri Slaby |
ba7816 |
are not directly targeted to its MAC address).
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
As a result, the stmmac driver does not work as a bridge port, when the
|
|
Jiri Slaby |
ba7816 |
kernel is compiled with CONFIG_BRIDGE_VLAN_FILTERING=y.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
$ ip link add br0 type bridge && ip link set br0 up
|
|
Jiri Slaby |
ba7816 |
$ ip link set eth0 master br0 && ip link set eth0 up
|
|
Jiri Slaby |
ba7816 |
[ 2333.943296] br0: port 1(eth0) entered blocking state
|
|
Jiri Slaby |
ba7816 |
[ 2333.943381] br0: port 1(eth0) entered disabled state
|
|
Jiri Slaby |
ba7816 |
[ 2333.943782] device eth0 entered promiscuous mode
|
|
Jiri Slaby |
ba7816 |
[ 2333.944080] 4033c000.ethernet eth0: Adding VLAN in promisc mode not supported
|
|
Jiri Slaby |
ba7816 |
[ 2333.976509] 4033c000.ethernet eth0: failed to initialize vlan filtering on this port
|
|
Jiri Slaby |
ba7816 |
RTNETLINK answers: Operation not permitted
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
Secondly, take the case of stmmac as DSA master. Some switch tagging
|
|
Jiri Slaby |
ba7816 |
protocols are based on 802.1Q VLANs (tag_sja1105.c), and as such,
|
|
Jiri Slaby |
ba7816 |
tag_8021q.c uses vlan_vid_add() to work with VLAN-filtering DSA masters.
|
|
Jiri Slaby |
ba7816 |
But also, when a DSA port becomes promiscuous (for example when it joins
|
|
Jiri Slaby |
ba7816 |
a bridge), the DSA framework also makes the DSA master promiscuous.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
Moreover, for every VLAN that a DSA switch sends to the CPU, DSA also
|
|
Jiri Slaby |
ba7816 |
programs a VLAN filter on the DSA master, because if the the DSA switch
|
|
Jiri Slaby |
ba7816 |
uses a tail tag, then the hardware frame parser of the DSA master will
|
|
Jiri Slaby |
ba7816 |
see VLAN as VLAN, and might filter them out, for being unknown.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
Due to the above 2 reasons, my belief is that the stmmac driver does not
|
|
Jiri Slaby |
ba7816 |
get to choose to not accept vlan_vid_add() calls while IFF_PROMISC is
|
|
Jiri Slaby |
ba7816 |
enabled, because the 2 are completely independent and there are code
|
|
Jiri Slaby |
ba7816 |
paths in the network stack which directly lead to this situation
|
|
Jiri Slaby |
ba7816 |
occurring, without the user's direct input.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
In fact, my belief is that "VLAN promiscuous" mode should have never
|
|
Jiri Slaby |
ba7816 |
been keyed on IFF_PROMISC in the first place, but rather, on the
|
|
Jiri Slaby |
ba7816 |
NETIF_F_HW_VLAN_CTAG_FILTER feature flag which can be toggled by the
|
|
Jiri Slaby |
ba7816 |
user through ethtool -k, when present in netdev->hw_features.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
In the stmmac driver, NETIF_F_HW_VLAN_CTAG_FILTER is only present in
|
|
Jiri Slaby |
ba7816 |
"features", making this feature "on [fixed]".
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
I have this belief because I am unaware of any definition of promiscuity
|
|
Jiri Slaby |
ba7816 |
which implies having an effect on anything other than MAC DA (therefore
|
|
Jiri Slaby |
ba7816 |
not VLAN). However, I seem to be rather alone in having this opinion,
|
|
Jiri Slaby |
ba7816 |
looking back at the disagreements from this discussion:
|
|
Jiri Slaby |
ba7816 |
https://lore.kernel.org/netdev/20201110153958.ci5ekor3o2ekg3ky@ipetronik.com/
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
In any case, to remove the vlan_vid_add() dependency on !IFF_PROMISC,
|
|
Jiri Slaby |
ba7816 |
one would need to remove the check and see what fails. I guess the test
|
|
Jiri Slaby |
ba7816 |
was there because of the way in which dwmac4_vlan_promisc_enable() is
|
|
Jiri Slaby |
ba7816 |
implemented.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
For context, the dwmac4 supports Perfect Filtering for a limited number
|
|
Jiri Slaby |
ba7816 |
of VLANs - dwmac4_get_num_vlan(), priv->hw->num_vlan, with a fallback on
|
|
Jiri Slaby |
ba7816 |
Hash Filtering - priv->dma_cap.vlhash - see stmmac_vlan_update(), also
|
|
Jiri Slaby |
ba7816 |
visible in cat /sys/kernel/debug/stmmaceth/eth0/dma_cap | grep 'VLAN
|
|
Jiri Slaby |
ba7816 |
Hash Filtering'.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
The perfect filtering is based on MAC_VLAN_Tag_Filter/MAC_VLAN_Tag_Data
|
|
Jiri Slaby |
ba7816 |
registers, accessed in the driver through dwmac4_write_vlan_filter().
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
The hash filtering is based on the MAC_VLAN_Hash_Table register, named
|
|
Jiri Slaby |
ba7816 |
GMAC_VLAN_HASH_TABLE in the driver and accessed by dwmac4_update_vlan_hash().
|
|
Jiri Slaby |
ba7816 |
The control bit for enabling hash filtering is GMAC_VLAN_VTHM
|
|
Jiri Slaby |
ba7816 |
(MAC_VLAN_Tag_Ctrl bit VTHM: VLAN Tag Hash Table Match Enable).
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
Now, the description of dwmac4_vlan_promisc_enable() is that it iterates
|
|
Jiri Slaby |
ba7816 |
through the driver's cache of perfect filter entries (hw->vlan_filter[i],
|
|
Jiri Slaby |
ba7816 |
added by dwmac4_add_hw_vlan_rx_fltr()), and evicts them from hardware by
|
|
Jiri Slaby |
ba7816 |
unsetting their GMAC_VLAN_TAG_DATA_VEN (MAC_VLAN_Tag_Data bit VEN - VLAN
|
|
Jiri Slaby |
ba7816 |
Tag Enable) bit. Then it unsets the GMAC_VLAN_VTHM bit, which disables
|
|
Jiri Slaby |
ba7816 |
hash matching.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
This leaves the MAC, according to table "VLAN Match Status" from the
|
|
Jiri Slaby |
ba7816 |
documentation, to always enter these data paths:
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
VID |VLAN Perfect Filter |VTHM Bit |VLAN Hash Filter |Final VLAN Match
|
|
Jiri Slaby |
ba7816 |
|Match Result | |Match Result |Status
|
|
Jiri Slaby |
ba7816 |
-------|--------------------|---------|-----------------|----------------
|
|
Jiri Slaby |
ba7816 |
VID!=0 |Fail |0 |don't care |Pass
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
So, dwmac4_vlan_promisc_enable() does its job, but by unsetting
|
|
Jiri Slaby |
ba7816 |
GMAC_VLAN_VTHM, it conflicts with the other code path which controls
|
|
Jiri Slaby |
ba7816 |
this bit: dwmac4_update_vlan_hash(), called through stmmac_update_vlan_hash()
|
|
Jiri Slaby |
ba7816 |
from stmmac_vlan_rx_add_vid() and from stmmac_vlan_rx_kill_vid().
|
|
Jiri Slaby |
ba7816 |
This is, I guess, why dwmac4_add_hw_vlan_rx_fltr() is not allowed to run
|
|
Jiri Slaby |
ba7816 |
after dwmac4_vlan_promisc_enable() has unset GMAC_VLAN_VTHM: because if
|
|
Jiri Slaby |
ba7816 |
it did, then dwmac4_update_vlan_hash() would set GMAC_VLAN_VTHM again,
|
|
Jiri Slaby |
ba7816 |
breaking the "VLAN promiscuity".
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
It turns out that dwmac4_vlan_promisc_enable() is way too complicated
|
|
Jiri Slaby |
ba7816 |
for what needs to be done. The MAC_Packet_Filter register also has the
|
|
Jiri Slaby |
ba7816 |
VTFE bit (VLAN Tag Filter Enable), which simply controls whether VLAN
|
|
Jiri Slaby |
ba7816 |
tagged packets which don't match the filtering tables (either perfect or
|
|
Jiri Slaby |
ba7816 |
hash) are dropped or not. At the moment, this driver unconditionally
|
|
Jiri Slaby |
ba7816 |
sets GMAC_PACKET_FILTER_VTFE if NETIF_F_HW_VLAN_CTAG_FILTER was detected
|
|
Jiri Slaby |
ba7816 |
through the priv->dma_cap.vlhash capability bits of the device, in
|
|
Jiri Slaby |
ba7816 |
stmmac_dvr_probe().
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
I would suggest deleting the unnecessarily complex logic from
|
|
Jiri Slaby |
ba7816 |
dwmac4_vlan_promisc_enable(), and simply unsetting GMAC_PACKET_FILTER_VTFE
|
|
Jiri Slaby |
ba7816 |
when becoming IFF_PROMISC, which has the same effect of allowing packets
|
|
Jiri Slaby |
ba7816 |
with any VLAN tags, but has the additional benefit of being able to run
|
|
Jiri Slaby |
ba7816 |
concurrently with stmmac_vlan_rx_add_vid() and stmmac_vlan_rx_kill_vid().
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
As much as I believe that the VTFE bit should have been exclusively
|
|
Jiri Slaby |
ba7816 |
controlled by NETIF_F_HW_VLAN_CTAG_FILTER through ethtool, and not by
|
|
Jiri Slaby |
ba7816 |
IFF_PROMISC, changing that is not a punctual fix to the problem, and it
|
|
Jiri Slaby |
ba7816 |
would probably break the VFFQ feature added by the later commit
|
|
Jiri Slaby |
ba7816 |
e0f9956a3862 ("net: stmmac: Add option for VLAN filter fail queue
|
|
Jiri Slaby |
ba7816 |
enable"). From the commit description, VFFQ needs IFF_PROMISC=on and
|
|
Jiri Slaby |
ba7816 |
VTFE=off in order to work (and this change respects that). But if VTFE
|
|
Jiri Slaby |
ba7816 |
was changed to be controlled through ethtool -k, then a user-visible
|
|
Jiri Slaby |
ba7816 |
change would have been introduced in Intel's scripts (a need to run
|
|
Jiri Slaby |
ba7816 |
"ethtool -k eth0 rx-vlan-filter off" which did not exist before).
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
The patch was tested with this set of commands:
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
ip link set eth0 up
|
|
Jiri Slaby |
ba7816 |
ip link add link eth0 name eth0.100 type vlan id 100
|
|
Jiri Slaby |
ba7816 |
ip addr add 192.168.100.2/24 dev eth0.100 && ip link set eth0.100 up
|
|
Jiri Slaby |
ba7816 |
ip link set eth0 promisc on
|
|
Jiri Slaby |
ba7816 |
ip link add link eth0 name eth0.101 type vlan id 101
|
|
Jiri Slaby |
ba7816 |
ip addr add 192.168.101.2/24 dev eth0.101 && ip link set eth0.101 up
|
|
Jiri Slaby |
ba7816 |
ip link set eth0 promisc off
|
|
Jiri Slaby |
ba7816 |
ping -c 5 192.168.100.1
|
|
Jiri Slaby |
ba7816 |
ping -c 5 192.168.101.1
|
|
Jiri Slaby |
ba7816 |
ip link set eth0 promisc on
|
|
Jiri Slaby |
ba7816 |
ping -c 5 192.168.100.1
|
|
Jiri Slaby |
ba7816 |
ping -c 5 192.168.101.1
|
|
Jiri Slaby |
ba7816 |
ip link del eth0.100
|
|
Jiri Slaby |
ba7816 |
ip link del eth0.101
|
|
Jiri Slaby |
ba7816 |
# Wait for VLAN-tagged pings from the other end...
|
|
Jiri Slaby |
ba7816 |
# Check with "tcpdump -i eth0 -e -n -p" and we should see them
|
|
Jiri Slaby |
ba7816 |
ip link set eth0 promisc off
|
|
Jiri Slaby |
ba7816 |
# Wait for VLAN-tagged pings from the other end...
|
|
Jiri Slaby |
ba7816 |
# Check with "tcpdump -i eth0 -e -n -p" and we shouldn't see them
|
|
Jiri Slaby |
ba7816 |
# anymore, but remove the "-p" argument from tcpdump and they're there.
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
Fixes: c89f44ff10fd ("net: stmmac: Add support for VLAN promiscuous mode")
|
|
Jiri Slaby |
ba7816 |
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
|
|
Jiri Slaby |
ba7816 |
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Jiri Slaby |
ba7816 |
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
|
Jiri Slaby |
ba7816 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
ba7816 |
---
|
|
Jiri Slaby |
ba7816 |
drivers/net/ethernet/stmicro/stmmac/common.h | 1 -
|
|
Jiri Slaby |
ba7816 |
.../net/ethernet/stmicro/stmmac/dwmac4_core.c | 61 +------------------
|
|
Jiri Slaby |
ba7816 |
2 files changed, 3 insertions(+), 59 deletions(-)
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
|
|
Jiri Slaby |
ba7816 |
index ec9c1302..54bb072a 100644
|
|
Jiri Slaby |
ba7816 |
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
|
|
Jiri Slaby |
ba7816 |
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
|
|
Jiri Slaby |
ba7816 |
@@ -532,7 +532,6 @@ struct mac_device_info {
|
|
Jiri Slaby |
ba7816 |
unsigned int xlgmac;
|
|
Jiri Slaby |
ba7816 |
unsigned int num_vlan;
|
|
Jiri Slaby |
ba7816 |
u32 vlan_filter[32];
|
|
Jiri Slaby |
ba7816 |
- unsigned int promisc;
|
|
Jiri Slaby |
ba7816 |
bool vlan_fail_q_en;
|
|
Jiri Slaby |
ba7816 |
u8 vlan_fail_q;
|
|
Jiri Slaby |
ba7816 |
};
|
|
Jiri Slaby |
ba7816 |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
|
|
Jiri Slaby |
ba7816 |
index 8c7a0b7c..36251ec2 100644
|
|
Jiri Slaby |
ba7816 |
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
|
|
Jiri Slaby |
ba7816 |
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
|
|
Jiri Slaby |
ba7816 |
@@ -472,12 +472,6 @@ static int dwmac4_add_hw_vlan_rx_fltr(struct net_device *dev,
|
|
Jiri Slaby |
ba7816 |
if (vid > 4095)
|
|
Jiri Slaby |
ba7816 |
return -EINVAL;
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
- if (hw->promisc) {
|
|
Jiri Slaby |
ba7816 |
- netdev_err(dev,
|
|
Jiri Slaby |
ba7816 |
- "Adding VLAN in promisc mode not supported\n");
|
|
Jiri Slaby |
ba7816 |
- return -EPERM;
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
/* Single Rx VLAN Filter */
|
|
Jiri Slaby |
ba7816 |
if (hw->num_vlan == 1) {
|
|
Jiri Slaby |
ba7816 |
/* For single VLAN filter, VID 0 means VLAN promiscuous */
|
|
Jiri Slaby |
ba7816 |
@@ -527,12 +521,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
|
|
Jiri Slaby |
ba7816 |
{
|
|
Jiri Slaby |
ba7816 |
int i, ret = 0;
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
- if (hw->promisc) {
|
|
Jiri Slaby |
ba7816 |
- netdev_err(dev,
|
|
Jiri Slaby |
ba7816 |
- "Deleting VLAN in promisc mode not supported\n");
|
|
Jiri Slaby |
ba7816 |
- return -EPERM;
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
/* Single Rx VLAN Filter */
|
|
Jiri Slaby |
ba7816 |
if (hw->num_vlan == 1) {
|
|
Jiri Slaby |
ba7816 |
if ((hw->vlan_filter[0] & GMAC_VLAN_TAG_VID) == vid) {
|
|
Jiri Slaby |
ba7816 |
@@ -557,39 +545,6 @@ static int dwmac4_del_hw_vlan_rx_fltr(struct net_device *dev,
|
|
Jiri Slaby |
ba7816 |
return ret;
|
|
Jiri Slaby |
ba7816 |
}
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
-static void dwmac4_vlan_promisc_enable(struct net_device *dev,
|
|
Jiri Slaby |
ba7816 |
- struct mac_device_info *hw)
|
|
Jiri Slaby |
ba7816 |
-{
|
|
Jiri Slaby |
ba7816 |
- void __iomem *ioaddr = hw->pcsr;
|
|
Jiri Slaby |
ba7816 |
- u32 value;
|
|
Jiri Slaby |
ba7816 |
- u32 hash;
|
|
Jiri Slaby |
ba7816 |
- u32 val;
|
|
Jiri Slaby |
ba7816 |
- int i;
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
- /* Single Rx VLAN Filter */
|
|
Jiri Slaby |
ba7816 |
- if (hw->num_vlan == 1) {
|
|
Jiri Slaby |
ba7816 |
- dwmac4_write_single_vlan(dev, 0);
|
|
Jiri Slaby |
ba7816 |
- return;
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
- /* Extended Rx VLAN Filter Enable */
|
|
Jiri Slaby |
ba7816 |
- for (i = 0; i < hw->num_vlan; i++) {
|
|
Jiri Slaby |
ba7816 |
- if (hw->vlan_filter[i] & GMAC_VLAN_TAG_DATA_VEN) {
|
|
Jiri Slaby |
ba7816 |
- val = hw->vlan_filter[i] & ~GMAC_VLAN_TAG_DATA_VEN;
|
|
Jiri Slaby |
ba7816 |
- dwmac4_write_vlan_filter(dev, hw, i, val);
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
- hash = readl(ioaddr + GMAC_VLAN_HASH_TABLE);
|
|
Jiri Slaby |
ba7816 |
- if (hash & GMAC_VLAN_VLHT) {
|
|
Jiri Slaby |
ba7816 |
- value = readl(ioaddr + GMAC_VLAN_TAG);
|
|
Jiri Slaby |
ba7816 |
- if (value & GMAC_VLAN_VTHM) {
|
|
Jiri Slaby |
ba7816 |
- value &= ~GMAC_VLAN_VTHM;
|
|
Jiri Slaby |
ba7816 |
- writel(value, ioaddr + GMAC_VLAN_TAG);
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
-}
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
static void dwmac4_restore_hw_vlan_rx_fltr(struct net_device *dev,
|
|
Jiri Slaby |
ba7816 |
struct mac_device_info *hw)
|
|
Jiri Slaby |
ba7816 |
{
|
|
Jiri Slaby |
ba7816 |
@@ -709,22 +664,12 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
|
|
Jiri Slaby |
ba7816 |
}
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
/* VLAN filtering */
|
|
Jiri Slaby |
ba7816 |
- if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
|
Jiri Slaby |
ba7816 |
+ if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en)
|
|
Jiri Slaby |
ba7816 |
+ value &= ~GMAC_PACKET_FILTER_VTFE;
|
|
Jiri Slaby |
ba7816 |
+ else if (dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)
|
|
Jiri Slaby |
ba7816 |
value |= GMAC_PACKET_FILTER_VTFE;
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
writel(value, ioaddr + GMAC_PACKET_FILTER);
|
|
Jiri Slaby |
ba7816 |
-
|
|
Jiri Slaby |
ba7816 |
- if (dev->flags & IFF_PROMISC && !hw->vlan_fail_q_en) {
|
|
Jiri Slaby |
ba7816 |
- if (!hw->promisc) {
|
|
Jiri Slaby |
ba7816 |
- hw->promisc = 1;
|
|
Jiri Slaby |
ba7816 |
- dwmac4_vlan_promisc_enable(dev, hw);
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
- } else {
|
|
Jiri Slaby |
ba7816 |
- if (hw->promisc) {
|
|
Jiri Slaby |
ba7816 |
- hw->promisc = 0;
|
|
Jiri Slaby |
ba7816 |
- dwmac4_restore_hw_vlan_rx_fltr(dev, hw);
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
- }
|
|
Jiri Slaby |
ba7816 |
}
|
|
Jiri Slaby |
ba7816 |
|
|
Jiri Slaby |
ba7816 |
static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
|
|
Jiri Slaby |
ba7816 |
--
|
|
Jiri Slaby |
ba7816 |
2.35.3
|
|
Jiri Slaby |
ba7816 |
|