net/hns3: process MAC interrupt
[dpdk.git] / drivers / net / hns3 / hns3_ethdev_vf.c
index 4f9da4a..fd20c52 100644 (file)
@@ -778,6 +778,7 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
        uint16_t nb_rx_q = dev->data->nb_rx_queues;
        uint16_t nb_tx_q = dev->data->nb_tx_queues;
        struct rte_eth_rss_conf rss_conf;
+       uint32_t max_rx_pkt_len;
        uint16_t mtu;
        bool gro_en;
        int ret;
@@ -825,12 +826,18 @@ hns3vf_dev_configure(struct rte_eth_dev *dev)
         * according to the maximum RX packet length.
         */
        if (conf->rxmode.offloads & DEV_RX_OFFLOAD_JUMBO_FRAME) {
-               /*
-                * Security of max_rx_pkt_len is guaranteed in dpdk frame.
-                * Maximum value of max_rx_pkt_len is HNS3_MAX_FRAME_LEN, so it
-                * can safely assign to "uint16_t" type variable.
-                */
-               mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(conf->rxmode.max_rx_pkt_len);
+               max_rx_pkt_len = conf->rxmode.max_rx_pkt_len;
+               if (max_rx_pkt_len > HNS3_MAX_FRAME_LEN ||
+                   max_rx_pkt_len <= HNS3_DEFAULT_FRAME_LEN) {
+                       hns3_err(hw, "maximum Rx packet length must be greater "
+                                "than %u and less than %u when jumbo frame enabled.",
+                                (uint16_t)HNS3_DEFAULT_FRAME_LEN,
+                                (uint16_t)HNS3_MAX_FRAME_LEN);
+                       ret = -EINVAL;
+                       goto cfg_err;
+               }
+
+               mtu = (uint16_t)HNS3_PKTLEN_TO_MTU(max_rx_pkt_len);
                ret = hns3vf_dev_mtu_set(dev, mtu);
                if (ret)
                        goto cfg_err;
@@ -1934,6 +1941,17 @@ hns3vf_do_stop(struct hns3_adapter *hns)
 
        hw->mac.link_status = ETH_LINK_DOWN;
 
+       /*
+        * The "hns3vf_do_stop" function will also be called by .stop_service to
+        * prepare reset. At the time of global or IMP reset, the command cannot
+        * be sent to stop the tx/rx queues. The mbuf in Tx/Rx queues may be
+        * accessed during the reset process. So the mbuf can not be released
+        * during reset and is required to be released after the reset is
+        * completed.
+        */
+       if (__atomic_load_n(&hw->reset.resetting,  __ATOMIC_RELAXED) == 0)
+               hns3_dev_release_mbufs(hns);
+
        if (__atomic_load_n(&hw->reset.disable_cmd, __ATOMIC_RELAXED) == 0) {
                hns3vf_configure_mac_addr(hns, true);
                ret = hns3_reset_all_tqps(hns);
@@ -2003,7 +2021,6 @@ hns3vf_dev_stop(struct rte_eth_dev *dev)
                hns3_stop_tqps(hw);
                hns3vf_do_stop(hns);
                hns3vf_unmap_rx_interrupt(dev);
-               hns3_dev_release_mbufs(hns);
                hw->adapter_state = HNS3_NIC_CONFIGURED;
        }
        hns3_rx_scattered_reset(dev);
@@ -2118,6 +2135,8 @@ hns3vf_do_start(struct hns3_adapter *hns, bool reset_queue)
        if (ret)
                return ret;
 
+       hns3_enable_rxd_adv_layout(hw);
+
        ret = hns3_init_queues(hns, reset_queue);
        if (ret)
                hns3_err(hw, "failed to init queues, ret = %d.", ret);
@@ -2244,11 +2263,8 @@ hns3vf_dev_start(struct rte_eth_dev *dev)
                return ret;
        }
        ret = hns3vf_map_rx_interrupt(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        /*
         * There are three register used to control the status of a TQP
@@ -2262,19 +2278,12 @@ hns3vf_dev_start(struct rte_eth_dev *dev)
         * status of queue in the dpdk framework.
         */
        ret = hns3_start_all_txqs(dev);
-       if (ret) {
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto map_rx_inter_err;
 
        ret = hns3_start_all_rxqs(dev);
-       if (ret) {
-               hns3_stop_all_txqs(dev);
-               hw->adapter_state = HNS3_NIC_CONFIGURED;
-               rte_spinlock_unlock(&hw->lock);
-               return ret;
-       }
+       if (ret)
+               goto start_all_rxqs_fail;
 
        hw->adapter_state = HNS3_NIC_STARTED;
        rte_spinlock_unlock(&hw->lock);
@@ -2295,6 +2304,15 @@ hns3vf_dev_start(struct rte_eth_dev *dev)
         */
        hns3_start_tqps(hw);
 
+       return ret;
+
+start_all_rxqs_fail:
+       hns3_stop_all_txqs(dev);
+map_rx_inter_err:
+       (void)hns3vf_do_stop(hns);
+       hw->adapter_state = HNS3_NIC_CONFIGURED;
+       rte_spinlock_unlock(&hw->lock);
+
        return ret;
 }
 
@@ -2404,15 +2422,17 @@ static int
 hns3vf_prepare_reset(struct hns3_adapter *hns)
 {
        struct hns3_hw *hw = &hns->hw;
-       int ret = 0;
+       int ret;
 
        if (hw->reset.level == HNS3_VF_FUNC_RESET) {
                ret = hns3_send_mbx_msg(hw, HNS3_MBX_RESET, 0, NULL,
                                        0, true, NULL, 0);
+               if (ret)
+                       return ret;
        }
        __atomic_store_n(&hw->reset.disable_cmd, 1, __ATOMIC_RELAXED);
 
-       return ret;
+       return 0;
 }
 
 static int
@@ -2754,6 +2774,7 @@ static const struct eth_dev_ops hns3vf_eth_dev_ops = {
        .vlan_offload_set   = hns3vf_vlan_offload_set,
        .get_reg            = hns3_get_regs,
        .dev_supported_ptypes_get = hns3_dev_supported_ptypes_get,
+       .tx_done_cleanup    = hns3_tx_done_cleanup,
 };
 
 static const struct hns3_reset_ops hns3vf_reset_ops = {