ixgbevf: fix jumbo frame
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe_ethdev.c
index fdf6c1d..a50bce4 100644 (file)
@@ -58,6 +58,7 @@
 #include <rte_ethdev.h>
 #include <rte_atomic.h>
 #include <rte_malloc.h>
+#include <rte_dev.h>
 
 #include "ixgbe_logs.h"
 #include "ixgbe/ixgbe_api.h"
@@ -586,6 +587,39 @@ ixgbe_dcb_init(struct ixgbe_hw *hw,struct ixgbe_dcb_config *dcb_config)
        }
 } 
 
+/*
+ * Ensure that all locks are released before first NVM or PHY access
+ */
+static void
+ixgbe_swfw_lock_reset(struct ixgbe_hw *hw)
+{
+       uint16_t mask;
+
+       /*
+        * Phy lock should not fail in this early stage. If this is the case,
+        * it is due to an improper exit of the application.
+        * So force the release of the faulty lock. Release of common lock
+        * is done automatically by swfw_sync function.
+        */
+       mask = IXGBE_GSSR_PHY0_SM << hw->bus.func;
+       if (ixgbe_acquire_swfw_semaphore(hw, mask) < 0) {
+                  DEBUGOUT1("SWFW phy%d lock released", hw->bus.func);
+       }
+       ixgbe_release_swfw_semaphore(hw, mask);
+
+       /*
+        * These ones are more tricky since they are common to all ports; but
+        * swfw_sync retries last long enough (1s) to be almost sure that if
+        * lock can not be taken it is due to an improper lock of the
+        * semaphore.
+        */
+       mask = IXGBE_GSSR_EEP_SM | IXGBE_GSSR_MAC_CSR_SM | IXGBE_GSSR_SW_MNG_SM;
+       if (ixgbe_acquire_swfw_semaphore(hw, mask) < 0) {
+                  DEBUGOUT("SWFW common locks released");
+       }
+       ixgbe_release_swfw_semaphore(hw, mask);
+}
+
 /*
  * This function is based on code in ixgbe_attach() in ixgbe/ixgbe.c.
  * It returns 0 on success.
@@ -643,6 +677,12 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                return -EIO;
        }
 
+       /* pick up the PCI bus settings for reporting later */
+       ixgbe_get_bus_info(hw);
+
+       /* Unlock any pending hardware semaphore */
+       ixgbe_swfw_lock_reset(hw);
+
        /* Initialize DCB configuration*/
        memset(dcb_config, 0, sizeof(struct ixgbe_dcb_config));
        ixgbe_dcb_init(hw,dcb_config);
@@ -700,9 +740,6 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
        /* disable interrupt */
        ixgbe_disable_intr(hw);
 
-       /* pick up the PCI bus settings for reporting later */
-       ixgbe_get_bus_info(hw);
-
        /* reset mappings for queue statistics hw counters*/
        ixgbe_reset_qstat_mappings(hw);
 
@@ -772,19 +809,30 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
        return 0;
 }
 
-static void ixgbevf_get_queue_num(struct ixgbe_hw *hw)
+
+/*
+ * Negotiate mailbox API version with the PF.
+ * After reset API version is always set to the basic one (ixgbe_mbox_api_10).
+ * Then we try to negotiate starting with the most recent one.
+ * If all negotiation attempts fail, then we will proceed with
+ * the default one (ixgbe_mbox_api_10).
+ */
+static void
+ixgbevf_negotiate_api(struct ixgbe_hw *hw)
 {
-       /* Traffic classes are not supported by now */
-       unsigned int tcs, tc;
+       int32_t i;
 
-       /*
-        * Must let PF know we are at mailbox API version 1.1.
-        * Otherwise PF won't answer properly.
-        * In case that PF fails to provide Rx/Tx queue number,
-        * max_tx_queues and max_rx_queues remain to be 1.
-        */
-       if (!ixgbevf_negotiate_api_version(hw, ixgbe_mbox_api_11))
-               ixgbevf_get_queues(hw, &tcs, &tc);
+       /* start with highest supported, proceed down */
+       static const enum ixgbe_pfvf_api_rev sup_ver[] = {
+               ixgbe_mbox_api_11,
+               ixgbe_mbox_api_10,
+       };
+
+       for (i = 0;
+                       i != RTE_DIM(sup_ver) &&
+                       ixgbevf_negotiate_api_version(hw, sup_ver[i]) != 0;
+                       i++)
+               ;
 }
 
 /*
@@ -794,9 +842,11 @@ static int
 eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                     struct rte_eth_dev *eth_dev)
 {
-       struct rte_pci_device *pci_dev;
-       struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        int diag;
+       uint32_t tc, tcs;
+       struct rte_pci_device *pci_dev;
+       struct ixgbe_hw *hw =
+               IXGBE_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
        struct ixgbe_vfta * shadow_vfta =
                IXGBE_DEV_PRIVATE_TO_VFTA(eth_dev->data->dev_private);
        struct ixgbe_hwstrip *hwstrip = 
@@ -855,8 +905,11 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                return (diag);
        }
 
+       /* negotiate mailbox API version to use with the PF. */
+       ixgbevf_negotiate_api(hw);
+
        /* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */
-       ixgbevf_get_queue_num(hw);
+       ixgbevf_get_queues(hw, &tcs, &tc);
 
        /* Allocate memory for storing MAC addresses */
        eth_dev->data->mac_addrs = rte_zmalloc("ixgbevf", ETHER_ADDR_LEN *
@@ -919,8 +972,8 @@ static struct eth_driver rte_ixgbevf_pmd = {
  * Invoked once at EAL init time.
  * Register itself as the [Poll Mode] Driver of PCI IXGBE devices.
  */
-int
-rte_ixgbe_pmd_init(void)
+static int
+rte_ixgbe_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
 {
        PMD_INIT_FUNC_TRACE();
 
@@ -933,8 +986,8 @@ rte_ixgbe_pmd_init(void)
  * Invoked one at EAL init time.
  * Register itself as the [Virtual Poll Mode] Driver of PCI niantic devices.
  */
-int
-rte_ixgbevf_pmd_init(void)
+static int
+rte_ixgbevf_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
 {
        DEBUGFUNC("rte_ixgbevf_pmd_init");
 
@@ -1930,7 +1983,7 @@ ixgbe_dev_link_status_print(struct rte_eth_dev *dev)
 }
 
 /*
- * It executes link_update after knowing an interrupt occured.
+ * It executes link_update after knowing an interrupt occurred.
  *
  * @param dev
  *  Pointer to struct rte_eth_dev.
@@ -2482,6 +2535,9 @@ ixgbevf_dev_start(struct rte_eth_dev *dev)
 
        hw->mac.ops.reset_hw(hw);
 
+       /* negotiate mailbox API version to use with the PF. */
+       ixgbevf_negotiate_api(hw);
+
        ixgbevf_dev_tx_init(dev);
 
        /* This can fail when allocating mbufs for descriptor rings */
@@ -3024,3 +3080,16 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
 
        return 0;
 }
+
+static struct rte_driver rte_ixgbe_driver = {
+       .type = PMD_PDEV,
+       .init = rte_ixgbe_pmd_init,
+};
+
+static struct rte_driver rte_ixgbevf_driver = {
+       .type = PMD_PDEV,
+       .init = rte_ixgbevf_pmd_init,
+};
+
+PMD_REGISTER_DRIVER(rte_ixgbe_driver);
+PMD_REGISTER_DRIVER(rte_ixgbevf_driver);