net: hns3: fix for vlan table lost problem when resetting
The vlan table in hardware is clear after PF/Core/IMP/Global reset, which will cause vlan tagged packets not being received problem. This patch fixes it by restoring the vlan table after reset. Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> Signed-off-by: Peng Li <lipeng321@huawei.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
1a426f8b40
commit
681ec3999b
2 changed files with 29 additions and 0 deletions
|
@ -1404,11 +1404,15 @@ static int hns3_vlan_rx_add_vid(struct net_device *netdev,
|
||||||
__be16 proto, u16 vid)
|
__be16 proto, u16 vid)
|
||||||
{
|
{
|
||||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||||
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
if (h->ae_algo->ops->set_vlan_filter)
|
if (h->ae_algo->ops->set_vlan_filter)
|
||||||
ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, false);
|
ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, false);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
set_bit(vid, priv->active_vlans);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1416,14 +1420,32 @@ static int hns3_vlan_rx_kill_vid(struct net_device *netdev,
|
||||||
__be16 proto, u16 vid)
|
__be16 proto, u16 vid)
|
||||||
{
|
{
|
||||||
struct hnae3_handle *h = hns3_get_handle(netdev);
|
struct hnae3_handle *h = hns3_get_handle(netdev);
|
||||||
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
if (h->ae_algo->ops->set_vlan_filter)
|
if (h->ae_algo->ops->set_vlan_filter)
|
||||||
ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, true);
|
ret = h->ae_algo->ops->set_vlan_filter(h, proto, vid, true);
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
|
clear_bit(vid, priv->active_vlans);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void hns3_restore_vlan(struct net_device *netdev)
|
||||||
|
{
|
||||||
|
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||||
|
u16 vid;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for_each_set_bit(vid, priv->active_vlans, VLAN_N_VID) {
|
||||||
|
ret = hns3_vlan_rx_add_vid(netdev, htons(ETH_P_8021Q), vid);
|
||||||
|
if (ret)
|
||||||
|
netdev_warn(netdev, "Restore vlan: %d filter, ret:%d\n",
|
||||||
|
vid, ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
|
static int hns3_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan,
|
||||||
u8 qos, __be16 vlan_proto)
|
u8 qos, __be16 vlan_proto)
|
||||||
{
|
{
|
||||||
|
@ -3341,6 +3363,10 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
|
||||||
hns3_nic_set_rx_mode(netdev);
|
hns3_nic_set_rx_mode(netdev);
|
||||||
hns3_recover_hw_addr(netdev);
|
hns3_recover_hw_addr(netdev);
|
||||||
|
|
||||||
|
/* Hardware table is only clear when pf resets */
|
||||||
|
if (!(handle->flags & HNAE3_SUPPORT_VF))
|
||||||
|
hns3_restore_vlan(netdev);
|
||||||
|
|
||||||
/* Carrier off reporting is important to ethtool even BEFORE open */
|
/* Carrier off reporting is important to ethtool even BEFORE open */
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef __HNS3_ENET_H
|
#ifndef __HNS3_ENET_H
|
||||||
#define __HNS3_ENET_H
|
#define __HNS3_ENET_H
|
||||||
|
|
||||||
|
#include <linux/if_vlan.h>
|
||||||
|
|
||||||
#include "hnae3.h"
|
#include "hnae3.h"
|
||||||
|
|
||||||
extern const char hns3_driver_version[];
|
extern const char hns3_driver_version[];
|
||||||
|
@ -539,6 +541,7 @@ struct hns3_nic_priv {
|
||||||
struct notifier_block notifier_block;
|
struct notifier_block notifier_block;
|
||||||
/* Vxlan/Geneve information */
|
/* Vxlan/Geneve information */
|
||||||
struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX];
|
struct hns3_udp_tunnel udp_tnl[HNS3_UDP_TNL_MAX];
|
||||||
|
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
|
||||||
};
|
};
|
||||||
|
|
||||||
union l3_hdr_info {
|
union l3_hdr_info {
|
||||||
|
|
Loading…
Add table
Reference in a new issue