i40evf: increase messaging wait time
[dpdk.git] / drivers / net / i40e / i40e_ethdev_vf.c
index 9f92a2f..90d1cbb 100644 (file)
@@ -298,8 +298,8 @@ i40evf_wait_cmd_done(struct rte_eth_dev *dev,
        int i = 0;
        enum i40evf_aq_result ret;
 
-#define MAX_TRY_TIMES 10
-#define ASQ_DELAY_MS  50
+#define MAX_TRY_TIMES 20
+#define ASQ_DELAY_MS  100
        do {
                /* Delay some time first */
                rte_delay_ms(ASQ_DELAY_MS);
@@ -1145,6 +1145,22 @@ err:
        return -1;
 }
 
+static int
+i40evf_uninit_vf(struct rte_eth_dev *dev)
+{
+       struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       PMD_INIT_FUNC_TRACE();
+
+       if (hw->adapter_stopped == 0)
+               i40evf_dev_close(dev);
+       rte_free(vf->vf_res);
+       vf->vf_res = NULL;
+
+       return 0;
+}
+
 static int
 i40evf_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1175,6 +1191,7 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
        hw->bus.device = eth_dev->pci_dev->addr.devid;
        hw->bus.func = eth_dev->pci_dev->addr.function;
        hw->hw_addr = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+       hw->adapter_stopped = 0;
 
        if(i40evf_init_vf(eth_dev) != 0) {
                PMD_INIT_LOG(ERR, "Init vf failed");
@@ -1195,16 +1212,39 @@ i40evf_dev_init(struct rte_eth_dev *eth_dev)
        return 0;
 }
 
+static int
+i40evf_dev_uninit(struct rte_eth_dev *eth_dev)
+{
+       PMD_INIT_FUNC_TRACE();
+
+       if (rte_eal_process_type() != RTE_PROC_PRIMARY)
+               return -EPERM;
+
+       eth_dev->dev_ops = NULL;
+       eth_dev->rx_pkt_burst = NULL;
+       eth_dev->tx_pkt_burst = NULL;
+
+       if (i40evf_uninit_vf(eth_dev) != 0) {
+               PMD_INIT_LOG(ERR, "i40evf_uninit_vf failed");
+               return -1;
+       }
+
+       rte_free(eth_dev->data->mac_addrs);
+       eth_dev->data->mac_addrs = NULL;
+
+       return 0;
+}
 /*
  * virtual function driver struct
  */
 static struct eth_driver rte_i40evf_pmd = {
-       {
+       .pci_drv = {
                .name = "rte_i40evf_pmd",
                .id_table = pci_id_i40evf_map,
-               .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+               .drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
        },
        .eth_dev_init = i40evf_dev_init,
+       .eth_dev_uninit = i40evf_dev_uninit,
        .dev_private_size = sizeof(struct i40e_vf),
 };
 
@@ -1416,6 +1456,61 @@ i40evf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
        return ret;
 }
 
+static int
+i40evf_rxq_init(struct rte_eth_dev *dev, struct i40e_rx_queue *rxq)
+{
+       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct rte_eth_dev_data *dev_data = dev->data;
+       struct rte_pktmbuf_pool_private *mbp_priv;
+       uint16_t buf_size, len;
+
+       rxq->qrx_tail = hw->hw_addr + I40E_QRX_TAIL1(rxq->queue_id);
+       I40E_PCI_REG_WRITE(rxq->qrx_tail, rxq->nb_rx_desc - 1);
+       I40EVF_WRITE_FLUSH(hw);
+
+       /* Calculate the maximum packet length allowed */
+       mbp_priv = rte_mempool_get_priv(rxq->mp);
+       buf_size = (uint16_t)(mbp_priv->mbuf_data_room_size -
+                                       RTE_PKTMBUF_HEADROOM);
+       rxq->hs_mode = i40e_header_split_none;
+       rxq->rx_hdr_len = 0;
+       rxq->rx_buf_len = RTE_ALIGN(buf_size, (1 << I40E_RXQ_CTX_DBUFF_SHIFT));
+       len = rxq->rx_buf_len * I40E_MAX_CHAINED_RX_BUFFERS;
+       rxq->max_pkt_len = RTE_MIN(len,
+               dev_data->dev_conf.rxmode.max_rx_pkt_len);
+
+       /**
+        * Check if the jumbo frame and maximum packet length are set correctly
+        */
+       if (dev_data->dev_conf.rxmode.jumbo_frame == 1) {
+               if (rxq->max_pkt_len <= ETHER_MAX_LEN ||
+                   rxq->max_pkt_len > I40E_FRAME_SIZE_MAX) {
+                       PMD_DRV_LOG(ERR, "maximum packet length must be "
+                               "larger than %u and smaller than %u, as jumbo "
+                               "frame is enabled", (uint32_t)ETHER_MAX_LEN,
+                                       (uint32_t)I40E_FRAME_SIZE_MAX);
+                       return I40E_ERR_CONFIG;
+               }
+       } else {
+               if (rxq->max_pkt_len < ETHER_MIN_LEN ||
+                   rxq->max_pkt_len > ETHER_MAX_LEN) {
+                       PMD_DRV_LOG(ERR, "maximum packet length must be "
+                               "larger than %u and smaller than %u, as jumbo "
+                               "frame is disabled", (uint32_t)ETHER_MIN_LEN,
+                                               (uint32_t)ETHER_MAX_LEN);
+                       return I40E_ERR_CONFIG;
+               }
+       }
+
+       if (dev_data->dev_conf.rxmode.enable_scatter ||
+           (rxq->max_pkt_len + 2 * I40E_VLAN_TAG_SIZE) > buf_size) {
+               dev_data->scattered_rx = 1;
+               dev->rx_pkt_burst = i40e_recv_scattered_pkts;
+       }
+
+       return 0;
+}
+
 static int
 i40evf_rx_init(struct rte_eth_dev *dev)
 {
@@ -1423,17 +1518,13 @@ i40evf_rx_init(struct rte_eth_dev *dev)
        uint16_t i;
        struct i40e_rx_queue **rxq =
                (struct i40e_rx_queue **)dev->data->rx_queues;
-       struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        i40evf_config_rss(vf);
        for (i = 0; i < dev->data->nb_rx_queues; i++) {
-               rxq[i]->qrx_tail = hw->hw_addr + I40E_QRX_TAIL1(i);
-               I40E_PCI_REG_WRITE(rxq[i]->qrx_tail, rxq[i]->nb_rx_desc - 1);
+               if (i40evf_rxq_init(dev, rxq[i]) < 0)
+                       return -EFAULT;
        }
 
-       /* Flush the operation to write registers */
-       I40EVF_WRITE_FLUSH(hw);
-
        return 0;
 }
 
@@ -1473,29 +1564,9 @@ i40evf_dev_start(struct rte_eth_dev *dev)
 
        PMD_INIT_FUNC_TRACE();
 
-       vf->max_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
-       if (dev->data->dev_conf.rxmode.jumbo_frame == 1) {
-               if (vf->max_pkt_len <= ETHER_MAX_LEN ||
-                       vf->max_pkt_len > I40E_FRAME_SIZE_MAX) {
-                       PMD_DRV_LOG(ERR, "maximum packet length must "
-                                   "be larger than %u and smaller than %u,"
-                                   "as jumbo frame is enabled",
-                                   (uint32_t)ETHER_MAX_LEN,
-                                   (uint32_t)I40E_FRAME_SIZE_MAX);
-                       return I40E_ERR_CONFIG;
-               }
-       } else {
-               if (vf->max_pkt_len < ETHER_MIN_LEN ||
-                       vf->max_pkt_len > ETHER_MAX_LEN) {
-                       PMD_DRV_LOG(ERR, "maximum packet length must be "
-                                   "larger than %u and smaller than %u, "
-                                   "as jumbo frame is disabled",
-                                   (uint32_t)ETHER_MIN_LEN,
-                                   (uint32_t)ETHER_MAX_LEN);
-                       return I40E_ERR_CONFIG;
-               }
-       }
+       hw->adapter_stopped = 0;
 
+       vf->max_pkt_len = dev->data->dev_conf.rxmode.max_rx_pkt_len;
        vf->num_queue_pairs = RTE_MAX(dev->data->nb_rx_queues,
                                        dev->data->nb_tx_queues);
 
@@ -1641,8 +1712,22 @@ i40evf_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
        dev_info->max_tx_queues = vf->vsi_res->num_queue_pairs;
        dev_info->min_rx_bufsize = I40E_BUF_SIZE_MIN;
        dev_info->max_rx_pktlen = I40E_FRAME_SIZE_MAX;
+       dev_info->hash_key_size = (I40E_VFQF_HKEY_MAX_INDEX + 1) * sizeof(uint32_t);
        dev_info->reta_size = ETH_RSS_RETA_SIZE_64;
        dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL;
+       dev_info->rx_offload_capa =
+               DEV_RX_OFFLOAD_VLAN_STRIP |
+               DEV_RX_OFFLOAD_QINQ_STRIP |
+               DEV_RX_OFFLOAD_IPV4_CKSUM |
+               DEV_RX_OFFLOAD_UDP_CKSUM |
+               DEV_RX_OFFLOAD_TCP_CKSUM;
+       dev_info->tx_offload_capa =
+               DEV_TX_OFFLOAD_VLAN_INSERT |
+               DEV_TX_OFFLOAD_QINQ_INSERT |
+               DEV_TX_OFFLOAD_IPV4_CKSUM |
+               DEV_TX_OFFLOAD_UDP_CKSUM |
+               DEV_TX_OFFLOAD_TCP_CKSUM |
+               DEV_TX_OFFLOAD_SCTP_CKSUM;
 
        dev_info->default_rxconf = (struct rte_eth_rxconf) {
                .rx_thresh = {
@@ -1680,6 +1765,7 @@ i40evf_dev_close(struct rte_eth_dev *dev)
        struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
        i40evf_dev_stop(dev);
+       hw->adapter_stopped = 1;
        i40evf_reset_vf(hw);
        i40e_shutdown_adminq(hw);
 }