net: hns3: fix error handling for desc filling
[linux-2.6-microblaze.git] / drivers / net / ethernet / hisilicon / hns3 / hns3_enet.c
index da98fd7..33c481d 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/aer.h>
 #include <linux/skbuff.h>
 #include <linux/sctp.h>
-#include <linux/vermagic.h>
 #include <net/gre.h>
 #include <net/ip6_checksum.h>
 #include <net/pkt_cls.h>
        } while (0)
 
 static void hns3_clear_all_ring(struct hnae3_handle *h, bool force);
-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 const char hns3_driver_string[] =
                        "Hisilicon Ethernet Network Driver for Hip08 Family";
 static const char hns3_copyright[] = "Copyright (c) 2017 Huawei Corporation.";
@@ -550,6 +547,13 @@ static int hns3_nic_uc_unsync(struct net_device *netdev,
 {
        struct hnae3_handle *h = hns3_get_handle(netdev);
 
+       /* need ignore the request of removing device address, because
+        * we store the device address and other addresses of uc list
+        * in the function's mac filter list.
+        */
+       if (ether_addr_equal(addr, netdev->dev_addr))
+               return 0;
+
        if (h->ae_algo->ops->rm_uc_addr)
                return h->ae_algo->ops->rm_uc_addr(h, addr);
 
@@ -597,34 +601,25 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
 {
        struct hnae3_handle *h = hns3_get_handle(netdev);
        u8 new_flags;
-       int ret;
 
        new_flags = hns3_get_netdev_flags(netdev);
 
-       ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
-       if (ret) {
-               netdev_err(netdev, "sync uc address fail\n");
-               if (ret == -ENOSPC)
-                       new_flags |= HNAE3_OVERFLOW_UPE;
-       }
-
-       if (netdev->flags & IFF_MULTICAST) {
-               ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
-                                   hns3_nic_mc_unsync);
-               if (ret) {
-                       netdev_err(netdev, "sync mc address fail\n");
-                       if (ret == -ENOSPC)
-                               new_flags |= HNAE3_OVERFLOW_MPE;
-               }
-       }
+       __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
+       __dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync);
 
        /* User mode Promisc mode enable and vlan filtering is disabled to
-        * let all packets in. MAC-VLAN Table overflow Promisc enabled and
-        * vlan fitering is enabled
+        * let all packets in.
         */
-       hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
        h->netdev_flags = new_flags;
-       hns3_update_promisc_mode(netdev, new_flags);
+       hns3_request_update_promisc_mode(h);
+}
+
+void hns3_request_update_promisc_mode(struct hnae3_handle *handle)
+{
+       const struct hnae3_ae_ops *ops = handle->ae_algo->ops;
+
+       if (ops->request_update_promisc_mode)
+               ops->request_update_promisc_mode(handle);
 }
 
 int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
@@ -1123,12 +1118,12 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
                return -ENOMEM;
        }
 
+       desc_cb->priv = priv;
        desc_cb->length = size;
+       desc_cb->dma = dma;
+       desc_cb->type = type;
 
        if (likely(size <= HNS3_MAX_BD_SIZE)) {
-               desc_cb->priv = priv;
-               desc_cb->dma = dma;
-               desc_cb->type = type;
                desc->addr = cpu_to_le64(dma);
                desc->tx.send_size = cpu_to_le16(size);
                desc->tx.bdtp_fe_sc_vld_ra_ri =
@@ -1140,18 +1135,11 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
        }
 
        frag_buf_num = hns3_tx_bd_count(size);
-       sizeoflast = size & HNS3_TX_LAST_SIZE_M;
+       sizeoflast = size % HNS3_MAX_BD_SIZE;
        sizeoflast = sizeoflast ? sizeoflast : HNS3_MAX_BD_SIZE;
 
        /* When frag size is bigger than hardware limit, split this frag */
        for (k = 0; k < frag_buf_num; k++) {
-               /* The txbd's baseinfo of DESC_TYPE_PAGE & DESC_TYPE_SKB */
-               desc_cb->priv = priv;
-               desc_cb->dma = dma + HNS3_MAX_BD_SIZE * k;
-               desc_cb->type = ((type == DESC_TYPE_FRAGLIST_SKB ||
-                                 type == DESC_TYPE_SKB) && !k) ?
-                               type : DESC_TYPE_PAGE;
-
                /* now, fill the descriptor */
                desc->addr = cpu_to_le64(dma + HNS3_MAX_BD_SIZE * k);
                desc->tx.send_size = cpu_to_le16((k == frag_buf_num - 1) ?
@@ -1163,7 +1151,6 @@ static int hns3_fill_desc(struct hns3_enet_ring *ring, void *priv,
                /* move ring pointer to next */
                ring_ptr_move_fw(ring, next_to_use);
 
-               desc_cb = &ring->desc_cb[ring->next_to_use];
                desc = &ring->desc[ring->next_to_use];
        }
 
@@ -1351,6 +1338,10 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
        unsigned int i;
 
        for (i = 0; i < ring->desc_num; i++) {
+               struct hns3_desc *desc = &ring->desc[ring->next_to_use];
+
+               memset(desc, 0, sizeof(*desc));
+
                /* check if this is where we started */
                if (ring->next_to_use == next_to_use_orig)
                        break;
@@ -1358,6 +1349,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
                /* rollback one */
                ring_ptr_move_bw(ring, next_to_use);
 
+               if (!ring->desc_cb[ring->next_to_use].dma)
+                       continue;
+
                /* unmap the descriptor dma address */
                if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB ||
                    ring->desc_cb[ring->next_to_use].type ==
@@ -1374,6 +1368,7 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
 
                ring->desc_cb[ring->next_to_use].length = 0;
                ring->desc_cb[ring->next_to_use].dma = 0;
+               ring->desc_cb[ring->next_to_use].type = DESC_TYPE_UNKNOWN;
        }
 }
 
@@ -1450,9 +1445,6 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 
        bd_num += ret;
 
-       if (!skb_has_frag_list(skb))
-               goto out;
-
        skb_walk_frags(skb, frag_skb) {
                ret = hns3_fill_skb_to_desc(ring, frag_skb,
                                            DESC_TYPE_FRAGLIST_SKB);
@@ -1461,7 +1453,7 @@ netdev_tx_t hns3_nic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 
                bd_num += ret;
        }
-out:
+
        pre_ntu = ring->next_to_use ? (ring->next_to_use - 1) :
                                        (ring->desc_num - 1);
        ring->desc[pre_ntu].tx.bdtp_fe_sc_vld_ra_ri |=
@@ -1552,12 +1544,6 @@ static int hns3_nic_set_features(struct net_device *netdev,
                        return ret;
        }
 
-       if ((changed & NETIF_F_HW_VLAN_CTAG_FILTER) &&
-           h->ae_algo->ops->enable_vlan_filter) {
-               enable = !!(features & NETIF_F_HW_VLAN_CTAG_FILTER);
-               h->ae_algo->ops->enable_vlan_filter(h, enable);
-       }
-
        if ((changed & NETIF_F_HW_VLAN_CTAG_RX) &&
            h->ae_algo->ops->enable_hw_strip_rxvtag) {
                enable = !!(features & NETIF_F_HW_VLAN_CTAG_RX);
@@ -2107,7 +2093,6 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        ae_dev->pdev = pdev;
        ae_dev->flag = ent->driver_data;
-       ae_dev->reset_type = HNAE3_NONE_RESET;
        hns3_get_dev_capability(pdev, ae_dev);
        pci_set_drvdata(pdev, ae_dev);
 
@@ -3909,9 +3894,11 @@ static int hns3_init_mac_addr(struct net_device *netdev)
                eth_hw_addr_random(netdev);
                dev_warn(priv->dev, "using random MAC address %pM\n",
                         netdev->dev_addr);
-       } else {
+       } else if (!ether_addr_equal(netdev->dev_addr, mac_addr_temp)) {
                ether_addr_copy(netdev->dev_addr, mac_addr_temp);
                ether_addr_copy(netdev->perm_addr, mac_addr_temp);
+       } else {
+               return 0;
        }
 
        if (h->ae_algo->ops->set_mac_addr)
@@ -3939,17 +3926,6 @@ static void hns3_uninit_phy(struct net_device *netdev)
                h->ae_algo->ops->mac_disconnect_phy(h);
 }
 
-static int hns3_restore_fd_rules(struct net_device *netdev)
-{
-       struct hnae3_handle *h = hns3_get_handle(netdev);
-       int ret = 0;
-
-       if (h->ae_algo->ops->restore_fd_rules)
-               ret = h->ae_algo->ops->restore_fd_rules(h);
-
-       return ret;
-}
-
 static void hns3_del_all_fd_rules(struct net_device *netdev, bool clear_list)
 {
        struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -4121,8 +4097,6 @@ 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);
 
@@ -4153,9 +4127,8 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
 
        hns3_put_ring_config(priv);
 
-       hns3_dbg_uninit(handle);
-
 out_netdev_free:
+       hns3_dbg_uninit(handle);
        free_netdev(netdev);
 }
 
@@ -4193,56 +4166,6 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
        return hns3_nic_set_real_num_queue(ndev);
 }
 
-static int hns3_recover_hw_addr(struct net_device *ndev)
-{
-       struct netdev_hw_addr_list *list;
-       struct netdev_hw_addr *ha, *tmp;
-       int ret = 0;
-
-       netif_addr_lock_bh(ndev);
-       /* go through and sync uc_addr entries to the device */
-       list = &ndev->uc;
-       list_for_each_entry_safe(ha, tmp, &list->list, list) {
-               ret = hns3_nic_uc_sync(ndev, ha->addr);
-               if (ret)
-                       goto out;
-       }
-
-       /* go through and sync mc_addr entries to the device */
-       list = &ndev->mc;
-       list_for_each_entry_safe(ha, tmp, &list->list, list) {
-               ret = hns3_nic_mc_sync(ndev, ha->addr);
-               if (ret)
-                       goto out;
-       }
-
-out:
-       netif_addr_unlock_bh(ndev);
-       return ret;
-}
-
-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);
-
-       netif_addr_lock_bh(netdev);
-       /* 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);
-
-       netif_addr_unlock_bh(netdev);
-}
-
 static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
 {
        while (ring->next_to_clean != ring->next_to_use) {
@@ -4401,7 +4324,6 @@ static void hns3_restore_coal(struct hns3_nic_priv *priv)
 
 static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
 {
-       struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
        struct hnae3_knic_private_info *kinfo = &handle->kinfo;
        struct net_device *ndev = kinfo->netdev;
        struct hns3_nic_priv *priv = netdev_priv(ndev);
@@ -4409,15 +4331,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
        if (test_and_set_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
                return 0;
 
-       /* 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)) {
-               hns3_remove_hw_addr(ndev);
-               hns3_del_all_fd_rules(ndev, false);
-       }
-
        if (!netif_running(ndev))
                return 0;
 
@@ -4484,6 +4397,9 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
                goto err_init_irq_fail;
        }
 
+       if (!hns3_is_phys_func(handle->pdev))
+               hns3_init_mac_addr(netdev);
+
        ret = hns3_client_start(handle);
        if (ret) {
                dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
@@ -4509,33 +4425,6 @@ err_put_ring:
        return ret;
 }
 
-static int hns3_reset_notify_restore_enet(struct hnae3_handle *handle)
-{
-       struct net_device *netdev = handle->kinfo.netdev;
-       bool vlan_filter_enable;
-       int ret;
-
-       ret = hns3_init_mac_addr(netdev);
-       if (ret)
-               return ret;
-
-       ret = hns3_recover_hw_addr(netdev);
-       if (ret)
-               return ret;
-
-       ret = hns3_update_promisc_mode(netdev, handle->netdev_flags);
-       if (ret)
-               return ret;
-
-       vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
-       hns3_enable_vlan_filter(netdev, vlan_filter_enable);
-
-       if (handle->ae_algo->ops->restore_vlan_table)
-               handle->ae_algo->ops->restore_vlan_table(handle);
-
-       return hns3_restore_fd_rules(netdev);
-}
-
 static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
 {
        struct net_device *netdev = handle->kinfo.netdev;
@@ -4585,9 +4474,6 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
        case HNAE3_UNINIT_CLIENT:
                ret = hns3_reset_notify_uninit_enet(handle);
                break;
-       case HNAE3_RESTORE_CLIENT:
-               ret = hns3_reset_notify_restore_enet(handle);
-               break;
        default:
                break;
        }
@@ -4765,4 +4651,3 @@ MODULE_DESCRIPTION("HNS3: Hisilicon Ethernet Driver");
 MODULE_AUTHOR("Huawei Tech. Co., Ltd.");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("pci:hns-nic");
-MODULE_VERSION(HNS3_MOD_VERSION);