Commit 681ec399 authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller

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: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarPeng Li <lipeng321@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a426f8b
...@@ -1404,11 +1404,15 @@ static int hns3_vlan_rx_add_vid(struct net_device *netdev, ...@@ -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, ...@@ -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) ...@@ -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 @@ ...@@ -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 { ...@@ -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 {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment