diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/stmmac_main.c')
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 60 |
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; |
