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;
}
-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);
struct hns3_nic_priv *priv = netdev_priv(netdev);
int ret;
+ hns3_remove_hw_addr(netdev);
+
if (netdev->reg_state != NETREG_UNINITIALIZED)
unregister_netdev(netdev);
priv->ring_data = NULL;
- hns3_uninit_mac_addr(netdev);
-
free_netdev(netdev);
}
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) {
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;
}