aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index ec62fa7418f4..b837e8e27a35 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6226,6 +6226,13 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
features &= ~NETIF_F_CSUM_MASK;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC) {
+ if (features & NETIF_F_HW_VLAN_CTAG_RX)
+ features |= NETIF_F_HW_VLAN_STAG_RX;
+ else
+ features &= ~NETIF_F_HW_VLAN_STAG_RX;
+ }
+
return features;
}
@@ -6850,32 +6857,21 @@ static u32 stmmac_vid_crc32_le(__le16 vid_le)
return crc;
}
-static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double)
+static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_svlan)
{
u32 crc, hash = 0;
- u16 pmatch = 0;
- int count = 0;
u16 vid = 0;
for_each_set_bit(vid, priv->active_vlans, VLAN_N_VID) {
__le16 vid_le = cpu_to_le16(vid);
crc = bitrev32(~stmmac_vid_crc32_le(vid_le)) >> 28;
hash |= (1 << crc);
- count++;
- }
-
- if (!priv->dma_cap.vlhash) {
- if (count > 2) /* VID = 0 always passes filter */
- return -EOPNOTSUPP;
-
- pmatch = vid;
- hash = 0;
}
if (!netif_running(priv->dev))
return 0;
- return stmmac_update_vlan_hash(priv, priv->hw, hash, pmatch, is_double);
+ return stmmac_update_vlan_hash(priv, priv->hw, hash, is_svlan);
}
/* FIXME: This may need RXC to be running, but it may be called with BH
@@ -6884,8 +6880,8 @@ static int stmmac_vlan_update(struct stmmac_priv *priv, bool is_double)
static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid)
{
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned int num_double_vlans;
- bool is_double = false;
+ unsigned int num_svlans;
+ bool is_svlan = false;
int ret;
ret = pm_runtime_resume_and_get(priv->device);
@@ -6893,11 +6889,11 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
return ret;
if (be16_to_cpu(proto) == ETH_P_8021AD)
- is_double = true;
+ is_svlan = true;
set_bit(vid, priv->active_vlans);
- num_double_vlans = priv->num_double_vlans + is_double;
- ret = stmmac_vlan_update(priv, num_double_vlans);
+ num_svlans = priv->num_svlans + is_svlan;
+ ret = stmmac_vlan_update(priv, num_svlans);
if (ret) {
clear_bit(vid, priv->active_vlans);
goto err_pm_put;
@@ -6907,12 +6903,12 @@ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid
ret = stmmac_add_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
if (ret) {
clear_bit(vid, priv->active_vlans);
- stmmac_vlan_update(priv, priv->num_double_vlans);
+ stmmac_vlan_update(priv, priv->num_svlans);
goto err_pm_put;
}
}
- priv->num_double_vlans = num_double_vlans;
+ priv->num_svlans = num_svlans;
err_pm_put:
pm_runtime_put(priv->device);
@@ -6926,8 +6922,8 @@ err_pm_put:
static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid)
{
struct stmmac_priv *priv = netdev_priv(ndev);
- unsigned int num_double_vlans;
- bool is_double = false;
+ unsigned int num_svlans;
+ bool is_svlan = false;
int ret;
ret = pm_runtime_resume_and_get(priv->device);
@@ -6935,11 +6931,11 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi
return ret;
if (be16_to_cpu(proto) == ETH_P_8021AD)
- is_double = true;
+ is_svlan = true;
clear_bit(vid, priv->active_vlans);
- num_double_vlans = priv->num_double_vlans - is_double;
- ret = stmmac_vlan_update(priv, num_double_vlans);
+ num_svlans = priv->num_svlans - is_svlan;
+ ret = stmmac_vlan_update(priv, num_svlans);
if (ret) {
set_bit(vid, priv->active_vlans);
goto del_vlan_error;
@@ -6949,12 +6945,12 @@ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vi
ret = stmmac_del_hw_vlan_rx_fltr(priv, ndev, priv->hw, proto, vid);
if (ret) {
set_bit(vid, priv->active_vlans);
- stmmac_vlan_update(priv, priv->num_double_vlans);
+ stmmac_vlan_update(priv, priv->num_svlans);
goto del_vlan_error;
}
}
- priv->num_double_vlans = num_double_vlans;
+ priv->num_svlans = num_svlans;
del_vlan_error:
pm_runtime_put(priv->device);
@@ -6970,7 +6966,7 @@ static void stmmac_vlan_restore(struct stmmac_priv *priv)
if (priv->hw->num_vlan)
stmmac_restore_hw_vlan_rx_fltr(priv, priv->dev, priv->hw);
- stmmac_vlan_update(priv, priv->num_double_vlans);
+ stmmac_vlan_update(priv, priv->num_svlans);
}
static int stmmac_bpf(struct net_device *dev, struct netdev_bpf *bpf)
@@ -8009,14 +8005,18 @@ static int __stmmac_dvr_probe(struct device *device,
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
#ifdef STMMAC_VLAN_TAG_USED
/* Both mac100 and gmac support receive VLAN tag detection */
- ndev->features |= NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_STAG_RX;
+ ndev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ ndev->features |= NETIF_F_HW_VLAN_STAG_RX;
+
if (dwmac_is_xmac(priv->plat->core_type)) {
ndev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
priv->hw->hw_vlan_en = true;
}
if (priv->dma_cap.vlhash) {
ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER;
- ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
+ if (priv->plat->core_type == DWMAC_CORE_XGMAC)
+ ndev->features |= NETIF_F_HW_VLAN_STAG_FILTER;
}
if (priv->dma_cap.vlins)
ndev->features |= NETIF_F_HW_VLAN_CTAG_TX;