Skip to content

Commit

Permalink
net: hns3: Clear mac vlan table entries when unload driver or functio…
Browse files Browse the repository at this point in the history
…n reset

In original codes, the mac vlan table entries are not cleared when
unload hns3 driver. The dirty mac vlan table entries will make the
result of looking up mac vlan table being unexpected.

When doing core reset or global reset, the firmware will clear all
the tables for driver, and driver shouldn't send any commands to
firmware during reset. But when doing function reset, the driver
needs to clear the tables itself.

This patch clears the mac vlan table entries for each client when
unload driver or reset.

Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: Salil Mehta <salil.mehta@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Jian Shen authored and David S. Miller committed Oct 5, 2018
1 parent dd2b6ef commit f05e210
Showing 1 changed file with 28 additions and 17 deletions.
45 changes: 28 additions & 17 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

static void hns3_clear_all_ring(struct hnae3_handle *h);
static void hns3_force_clear_all_rx_ring(struct hnae3_handle *h);
static void hns3_remove_hw_addr(struct net_device *netdev);

static const char hns3_driver_name[] = "hns3";
const char hns3_driver_version[] = VERMAGIC_STRING;
Expand Down Expand Up @@ -3155,15 +3156,6 @@ static void hns3_init_mac_addr(struct net_device *netdev, bool init)

}

static void hns3_uninit_mac_addr(struct net_device *netdev)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;

if (h->ae_algo->ops->rm_uc_addr)
h->ae_algo->ops->rm_uc_addr(h, netdev->dev_addr);
}

static int hns3_restore_fd_rules(struct net_device *netdev)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
Expand Down Expand Up @@ -3296,6 +3288,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
struct hns3_nic_priv *priv = netdev_priv(netdev);
int ret;

hns3_remove_hw_addr(netdev);

if (netdev->reg_state != NETREG_UNINITIALIZED)
unregister_netdev(netdev);

Expand All @@ -3319,8 +3313,6 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)

priv->ring_data = NULL;

hns3_uninit_mac_addr(netdev);

free_netdev(netdev);
}

Expand Down Expand Up @@ -3392,6 +3384,25 @@ static void hns3_recover_hw_addr(struct net_device *ndev)
hns3_nic_mc_sync(ndev, ha->addr);
}

static void hns3_remove_hw_addr(struct net_device *netdev)
{
struct netdev_hw_addr_list *list;
struct netdev_hw_addr *ha, *tmp;

hns3_nic_uc_unsync(netdev, netdev->dev_addr);

/* go through and unsync uc_addr entries to the device */
list = &netdev->uc;
list_for_each_entry_safe(ha, tmp, &list->list, list)
hns3_nic_uc_unsync(netdev, ha->addr);

/* go through and unsync mc_addr entries to the device */
list = &netdev->mc;
list_for_each_entry_safe(ha, tmp, &list->list, list)
if (ha->refcount > 1)
hns3_nic_mc_unsync(netdev, ha->addr);
}

static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
{
while (ring->next_to_clean != ring->next_to_use) {
Expand Down Expand Up @@ -3637,14 +3648,14 @@ static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
if (ret)
netdev_err(netdev, "uninit ring error\n");

hns3_uninit_mac_addr(netdev);

/* it is cumbersome for hardware to pick-and-choose rules for deletion
* from TCAM. Hence, for function reset software intervention is
* required to delete the rules
/* it is cumbersome for hardware to pick-and-choose entries for deletion
* from table space. Hence, for function reset software intervention is
* required to delete the entries
*/
if (hns3_dev_ongoing_func_reset(ae_dev))
if (hns3_dev_ongoing_func_reset(ae_dev)) {
hns3_remove_hw_addr(netdev);
hns3_del_all_fd_rules(netdev, false);
}

return ret;
}
Expand Down

0 comments on commit f05e210

Please sign in to comment.