spelling fixes
[dpdk.git] / lib / librte_pmd_ixgbe / ixgbe_ethdev.c
index 240106b..e78c208 100644 (file)
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  * 
- *   Copyright(c) 2010-2013 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -586,6 +586,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 +676,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 +739,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);
 
@@ -711,7 +747,8 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                        hw->mac.num_rar_entries, 0);
        if (eth_dev->data->mac_addrs == NULL) {
                PMD_INIT_LOG(ERR,
-                       "Failed to allocate %d bytes needed to store MAC addresses",
+                       "Failed to allocate %u bytes needed to store "
+                       "MAC addresses",
                        ETHER_ADDR_LEN * hw->mac.num_rar_entries);
                return -ENOMEM;
        }
@@ -771,6 +808,21 @@ eth_ixgbe_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
        return 0;
 }
 
+static void ixgbevf_get_queue_num(struct ixgbe_hw *hw)
+{
+       /* Traffic classes are not supported by now */
+       unsigned int tcs, tc;
+
+       /*
+        * 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);
+}
+
 /*
  * Virtual Function device init
  */
@@ -839,12 +891,16 @@ eth_ixgbevf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                return (diag);
        }
 
+       /* Get Rx/Tx queue count via mailbox, which is ready after reset_hw */
+       ixgbevf_get_queue_num(hw);
+
        /* Allocate memory for storing MAC addresses */
        eth_dev->data->mac_addrs = rte_zmalloc("ixgbevf", ETHER_ADDR_LEN *
                        hw->mac.num_rar_entries, 0);
        if (eth_dev->data->mac_addrs == NULL) {
                PMD_INIT_LOG(ERR,
-                       "Failed to allocate %d bytes needed to store MAC addresses",
+                       "Failed to allocate %u bytes needed to store "
+                       "MAC addresses",
                        ETHER_ADDR_LEN * hw->mac.num_rar_entries);
                return -ENOMEM;
        }
@@ -875,9 +931,7 @@ static struct eth_driver rte_ixgbe_pmd = {
        {
                .name = "rte_ixgbe_pmd",
                .id_table = pci_id_ixgbe_map,
-#ifdef RTE_EAL_UNBIND_PORTS
                .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
-#endif
        },
        .eth_dev_init = eth_ixgbe_dev_init,
        .dev_private_size = sizeof(struct ixgbe_adapter),
@@ -890,9 +944,7 @@ static struct eth_driver rte_ixgbevf_pmd = {
        {
                .name = "rte_ixgbevf_pmd",
                .id_table = pci_id_ixgbevf_map,
-#ifdef RTE_EAL_UNBIND_PORTS
                .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
-#endif
        },
        .eth_dev_init = eth_ixgbevf_dev_init,
        .dev_private_size = sizeof(struct ixgbe_adapter),
@@ -1245,7 +1297,7 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        /* IXGBE devices don't support half duplex */
        if ((dev->data->dev_conf.link_duplex != ETH_LINK_AUTONEG_DUPLEX) &&
                        (dev->data->dev_conf.link_duplex != ETH_LINK_FULL_DUPLEX)) {
-               PMD_INIT_LOG(ERR, "Invalid link_duplex (%u) for port %u\n",
+               PMD_INIT_LOG(ERR, "Invalid link_duplex (%hu) for port %hhu\n",
                                dev->data->dev_conf.link_duplex,
                                dev->data->port_id);
                return -EINVAL;
@@ -1286,6 +1338,11 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        /* Turn on the laser */
        ixgbe_enable_tx_laser(hw);
 
+       /* Skip link setup if loopback mode is enabled for 82599. */
+       if (hw->mac.type == ixgbe_mac_82599EB &&
+                       dev->data->dev_conf.lpbk_mode == IXGBE_LPBK_82599_TX_RX)
+               goto skip_link_setup;
+
        err = ixgbe_check_link(hw, &speed, &link_up, 0);
        if (err)
                goto error;
@@ -1313,8 +1370,9 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
                speed = IXGBE_LINK_SPEED_10GB_FULL;
                break;
        default:
-               PMD_INIT_LOG(ERR, "Invalid link_speed (%u) for port %u\n",
-                               dev->data->dev_conf.link_speed, dev->data->port_id);
+               PMD_INIT_LOG(ERR, "Invalid link_speed (%hu) for port %hhu\n",
+                               dev->data->dev_conf.link_speed,
+                               dev->data->port_id);
                goto error;
        }
 
@@ -1322,6 +1380,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
        if (err)
                goto error;
 
+skip_link_setup:
+
        /* check if lsc interrupt is enabled */
        if (dev->data->dev_conf.intr_conf.lsc != 0)
                ixgbe_dev_lsc_interrupt_setup(dev);
@@ -1366,6 +1426,9 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        struct rte_eth_link link;
        struct ixgbe_hw *hw =
                IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+       struct ixgbe_vf_info *vfinfo = 
+               *IXGBE_DEV_PRIVATE_TO_P_VFDATA(dev->data->dev_private);
+       int vf;
 
        PMD_INIT_FUNC_TRACE();
 
@@ -1379,6 +1442,10 @@ ixgbe_dev_stop(struct rte_eth_dev *dev)
        /* stop adapter */
        ixgbe_stop_adapter(hw);
 
+       for (vf = 0; vfinfo != NULL && 
+                    vf < dev->pci_dev->max_vfs; vf++)
+               vfinfo[vf].clear_to_send = false;
+
        /* Turn off the laser */
        ixgbe_disable_tx_laser(hw);
 
@@ -1576,6 +1643,12 @@ ixgbe_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
 
        stats->oerrors  = 0;
 
+       /* XON/XOFF pause frames */
+       stats->tx_pause_xon  = hw_stats->lxontxc;
+       stats->rx_pause_xon  = hw_stats->lxonrxc;
+       stats->tx_pause_xoff = hw_stats->lxofftxc;
+       stats->rx_pause_xoff = hw_stats->lxoffrxc;
+
        /* Flow Director Stats registers */
        hw_stats->fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
        hw_stats->fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
@@ -1668,6 +1741,17 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
                dev_info->max_vmdq_pools = ETH_16_POOLS;
        else
                dev_info->max_vmdq_pools = ETH_64_POOLS;
+       dev_info->rx_offload_capa =
+               DEV_RX_OFFLOAD_VLAN_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_IPV4_CKSUM  |
+               DEV_TX_OFFLOAD_UDP_CKSUM   |
+               DEV_TX_OFFLOAD_TCP_CKSUM   |
+               DEV_TX_OFFLOAD_SCTP_CKSUM;
 }
 
 /* return 0 means link status changed, -1 means not changed */
@@ -1882,7 +1966,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.