remove trailing whitespaces
[dpdk.git] / lib / librte_pmd_e1000 / igb_ethdev.c
index e485326..6e835c3 100644 (file)
@@ -1,13 +1,13 @@
 /*-
  *   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
  *   modification, are permitted provided that the following conditions
  *   are met:
- * 
+ *
  *     * Redistributions of source code must retain the above copyright
  *       notice, this list of conditions and the following disclaimer.
  *     * Redistributions in binary form must reproduce the above copyright
@@ -17,7 +17,7 @@
  *     * Neither the name of Intel Corporation nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
- * 
+ *
  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -51,6 +51,7 @@
 #include <rte_eal.h>
 #include <rte_atomic.h>
 #include <rte_malloc.h>
+#include <rte_dev.h>
 
 #include "e1000_logs.h"
 #include "e1000/e1000_api.h"
@@ -114,7 +115,7 @@ static void igbvf_dev_close(struct rte_eth_dev *dev);
 static int eth_igbvf_link_update(struct e1000_hw *hw);
 static void eth_igbvf_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats);
 static void eth_igbvf_stats_reset(struct rte_eth_dev *dev);
-static int igbvf_vlan_filter_set(struct rte_eth_dev *dev, 
+static int igbvf_vlan_filter_set(struct rte_eth_dev *dev,
                uint16_t vlan_id, int on);
 static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on);
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on);
@@ -193,6 +194,8 @@ static struct eth_dev_ops eth_igb_ops = {
        .mac_addr_remove      = eth_igb_rar_clear,
        .reta_update          = eth_igb_rss_reta_update,
        .reta_query           = eth_igb_rss_reta_query,
+       .rss_hash_update      = eth_igb_rss_hash_update,
+       .rss_hash_conf_get    = eth_igb_rss_hash_conf_get,
 };
 
 /*
@@ -274,7 +277,7 @@ igb_intr_enable(struct rte_eth_dev *dev)
                E1000_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
        struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
        E1000_WRITE_REG(hw, E1000_IMS, intr->mask);
        E1000_WRITE_FLUSH(hw);
 }
@@ -291,18 +294,18 @@ igb_pf_reset_hw(struct e1000_hw *hw)
 {
        uint32_t ctrl_ext;
        int32_t status;
+
        status = e1000_reset_hw(hw);
+
        ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
        /* Set PF Reset Done bit so PF/VF Mail Ops can work */
        ctrl_ext |= E1000_CTRL_EXT_PFRSTD;
        E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext);
        E1000_WRITE_FLUSH(hw);
+
        return status;
 }
+
 static void
 igb_identify_hardware(struct rte_eth_dev *dev)
 {
@@ -319,6 +322,61 @@ igb_identify_hardware(struct rte_eth_dev *dev)
        /* need to check if it is a vf device below */
 }
 
+static int
+igb_reset_swfw_lock(struct e1000_hw *hw)
+{
+       int ret_val;
+
+       /*
+        * Do mac ops initialization manually here, since we will need
+        * some function pointers set by this call.
+        */
+       ret_val = e1000_init_mac_params(hw);
+       if (ret_val)
+               return ret_val;
+
+       /*
+        * SMBI 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.
+        */
+       if (e1000_get_hw_semaphore_generic(hw) < 0) {
+               DEBUGOUT("SMBI lock released");
+       }
+       e1000_put_hw_semaphore_generic(hw);
+
+       if (hw->mac.ops.acquire_swfw_sync != NULL) {
+               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.
+                */
+               mask = E1000_SWFW_PHY0_SM << hw->bus.func;
+               if (hw->bus.func > E1000_FUNC_1)
+                       mask <<= 2;
+               if (hw->mac.ops.acquire_swfw_sync(hw, mask) < 0) {
+                       DEBUGOUT1("SWFW phy%d lock released", hw->bus.func);
+               }
+               hw->mac.ops.release_swfw_sync(hw, mask);
+
+               /*
+                * This one is more tricky since it is 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 = E1000_SWFW_EEP_SM;
+               if (hw->mac.ops.acquire_swfw_sync(hw, mask) < 0) {
+                       DEBUGOUT("SWFW common locks released");
+               }
+               hw->mac.ops.release_swfw_sync(hw, mask);
+       }
+
+       return E1000_SUCCESS;
+}
+
 static int
 eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                   struct rte_eth_dev *eth_dev)
@@ -348,13 +406,25 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
        hw->hw_addr= (void *)pci_dev->mem_resource[0].addr;
 
        igb_identify_hardware(eth_dev);
-       if (e1000_setup_init_funcs(hw, TRUE) != E1000_SUCCESS) {
+       if (e1000_setup_init_funcs(hw, FALSE) != E1000_SUCCESS) {
                error = -EIO;
                goto err_late;
        }
 
        e1000_get_bus_info(hw);
 
+       /* Reset any pending lock */
+       if (igb_reset_swfw_lock(hw) != E1000_SUCCESS) {
+               error = -EIO;
+               goto err_late;
+       }
+
+       /* Finish initialization */
+       if (e1000_setup_init_funcs(hw, TRUE) != E1000_SUCCESS) {
+               error = -EIO;
+               goto err_late;
+       }
+
        hw->mac.autoneg = 1;
        hw->phy.autoneg_wait_to_complete = 0;
        hw->phy.autoneg_advertised = E1000_ALL_SPEED_DUPLEX;
@@ -428,7 +498,7 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 
        /* initialize PF if max_vfs not zero */
        igb_pf_host_init(eth_dev);
+
        ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
        /* Set PF Reset Done bit so PF/VF Mail Ops can work */
        ctrl_ext |= E1000_CTRL_EXT_PFRSTD;
@@ -444,10 +514,10 @@ eth_igb_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 
        /* enable uio intr after callback register */
        rte_intr_enable(&(pci_dev->intr_handle));
-        
+
        /* enable support intr */
        igb_intr_enable(eth_dev);
-       
+
        return 0;
 
 err_late:
@@ -502,7 +572,7 @@ eth_igbvf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
 
        /* Disable the interrupts for VF */
        igbvf_intr_disable(hw);
-       
+
        diag = hw->mac.ops.reset_hw(hw);
 
        /* Allocate memory for storing MAC addresses */
@@ -515,7 +585,7 @@ eth_igbvf_dev_init(__attribute__((unused)) struct eth_driver *eth_drv,
                        ETHER_ADDR_LEN * hw->mac.rar_entry_count);
                return -ENOMEM;
        }
-       
+
        /* Copy the permanent MAC address */
        ether_addr_copy((struct ether_addr *) hw->mac.perm_addr,
                        &eth_dev->data->mac_addrs[0]);
@@ -533,9 +603,7 @@ static struct eth_driver rte_igb_pmd = {
        {
                .name = "rte_igb_pmd",
                .id_table = pci_id_igb_map,
-#ifdef RTE_EAL_UNBIND_PORTS
                .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
-#endif
        },
        .eth_dev_init = eth_igb_dev_init,
        .dev_private_size = sizeof(struct e1000_adapter),
@@ -548,16 +616,14 @@ static struct eth_driver rte_igbvf_pmd = {
        {
                .name = "rte_igbvf_pmd",
                .id_table = pci_id_igbvf_map,
-#ifdef RTE_EAL_UNBIND_PORTS
                .drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
-#endif
        },
        .eth_dev_init = eth_igbvf_dev_init,
        .dev_private_size = sizeof(struct e1000_adapter),
 };
 
-int
-rte_igb_pmd_init(void)
+static int
+rte_igb_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
 {
        rte_eth_driver_register(&rte_igb_pmd);
        return 0;
@@ -579,8 +645,8 @@ igb_vmdq_vlan_hw_filter_enable(struct rte_eth_dev *dev)
  * Invoked one at EAL init time.
  * Register itself as the [Virtual Poll Mode] Driver of PCI IGB devices.
  */
-int
-rte_igbvf_pmd_init(void)
+static int
+rte_igbvf_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
 {
        DEBUGFUNC("rte_igbvf_pmd_init");
 
@@ -637,7 +703,7 @@ eth_igb_start(struct rte_eth_dev *dev)
                return (-EIO);
        }
 
-       E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN);
+       E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN << 16 | ETHER_TYPE_VLAN);
 
        ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT);
        /* Set PF Reset Done bit so PF/VF Mail Ops can work */
@@ -674,7 +740,7 @@ eth_igb_start(struct rte_eth_dev *dev)
                /* Enable VLAN filter since VMDq always use VLAN filter */
                igb_vmdq_vlan_hw_filter_enable(dev);
        }
-               
+
        /*
         * Configure the Interrupt Moderation register (EITR) with the maximum
         * possible value (0xFFFF) to minimize "System Partial Write" issued by
@@ -871,7 +937,7 @@ igb_hardware_init(struct e1000_hw *hw)
         *   frames to be received after sending an XOFF.
         * - Low water mark works best when it is very near the high water mark.
         *   This allows the receiver to restart by sending XON when it has
-        *   drained a bit. Here we use an arbitary value of 1500 which will
+        *   drained a bit. Here we use an arbitrary value of 1500 which will
         *   restart after one full frame is pulled from the buffer. There
         *   could be several smaller frames in the buffer and if so they will
         *   not trigger the XON until their total number reduces the buffer
@@ -899,7 +965,7 @@ igb_hardware_init(struct e1000_hw *hw)
        if (diag < 0)
                return (diag);
 
-       E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN);
+       E1000_WRITE_REG(hw, E1000_VET, ETHER_TYPE_VLAN << 16 | ETHER_TYPE_VLAN);
        e1000_get_phy_info(hw);
        e1000_check_for_link(hw);
 
@@ -1027,6 +1093,12 @@ eth_igb_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *rte_stats)
        /* Tx Errors */
        rte_stats->oerrors = stats->ecol + stats->latecol;
 
+       /* XON/XOFF pause frames */
+       rte_stats->tx_pause_xon  = stats->xontxc;
+       rte_stats->rx_pause_xon  = stats->xonrxc;
+       rte_stats->tx_pause_xoff = stats->xofftxc;
+       rte_stats->rx_pause_xoff = stats->xoffrxc;
+
        rte_stats->ipackets = stats->gprc;
        rte_stats->opackets = stats->gptc;
        rte_stats->ibytes   = stats->gorc;
@@ -1129,6 +1201,17 @@ eth_igb_infos_get(struct rte_eth_dev *dev,
        dev_info->min_rx_bufsize = 256; /* See BSIZE field of RCTL register. */
        dev_info->max_rx_pktlen  = 0x3FFF; /* See RLPML register. */
        dev_info->max_mac_addrs = hw->mac.rar_entry_count;
+       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;
 
        switch (hw->mac.type) {
        case e1000_82575:
@@ -1524,14 +1607,14 @@ eth_igb_vlan_offload_set(struct rte_eth_dev *dev, int mask)
                else
                        igb_vlan_hw_strip_disable(dev);
        }
-       
+
        if(mask & ETH_VLAN_FILTER_MASK){
                if (dev->data->dev_conf.rxmode.hw_vlan_filter)
                        igb_vlan_hw_filter_enable(dev);
                else
                        igb_vlan_hw_filter_disable(dev);
        }
-       
+
        if(mask & ETH_VLAN_EXTEND_MASK){
                if (dev->data->dev_conf.rxmode.hw_vlan_extend)
                        igb_vlan_hw_extend_enable(dev);
@@ -1592,7 +1675,7 @@ eth_igb_interrupt_get_status(struct rte_eth_dev *dev)
                intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
        }
 
-       if (icr & E1000_ICR_VMMB) 
+       if (icr & E1000_ICR_VMMB)
                intr->flags |= E1000_FLAG_MAILBOX;
 
        return 0;
@@ -1910,7 +1993,7 @@ igbvf_dev_configure(struct rte_eth_dev *dev)
 static int
 igbvf_dev_start(struct rte_eth_dev *dev)
 {
-       struct e1000_hw *hw = 
+       struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        int ret;
 
@@ -1920,7 +2003,7 @@ igbvf_dev_start(struct rte_eth_dev *dev)
 
        /* Set all vfta */
        igbvf_set_vfta_all(dev,1);
-       
+
        eth_igbvf_tx_init(dev);
 
        /* This can fail when allocating mbufs for descriptor rings */
@@ -1940,9 +2023,9 @@ igbvf_dev_stop(struct rte_eth_dev *dev)
        PMD_INIT_LOG(DEBUG, "igbvf_dev_stop");
 
        igbvf_stop_adapter(dev);
-       
-       /* 
-         * Clear what we set, but we still keep shadow_vfta to 
+
+       /*
+         * Clear what we set, but we still keep shadow_vfta to
          * restore after device starts
          */
        igbvf_set_vfta_all(dev,0);
@@ -1967,7 +2050,7 @@ static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on)
        struct e1000_mbx_info *mbx = &hw->mbx;
        uint32_t msgbuf[2];
 
-       /* After set vlan, vlan strip will also be enabled in igb driver*/ 
+       /* After set vlan, vlan strip will also be enabled in igb driver*/
        msgbuf[0] = E1000_VF_SET_VLAN;
        msgbuf[1] = vid;
        /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
@@ -1979,7 +2062,7 @@ static int igbvf_set_vfta(struct e1000_hw *hw, uint16_t vid, bool on)
 
 static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on)
 {
-       struct e1000_hw *hw = 
+       struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct e1000_vfta * shadow_vfta =
                E1000_DEV_PRIVATE_TO_VFTA(dev->data->dev_private);
@@ -2003,14 +2086,14 @@ static void igbvf_set_vfta_all(struct rte_eth_dev *dev, bool on)
 static int
 igbvf_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
-       struct e1000_hw *hw = 
+       struct e1000_hw *hw =
                E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
        struct e1000_vfta * shadow_vfta =
                E1000_DEV_PRIVATE_TO_VFTA(dev->data->dev_private);
        uint32_t vid_idx = 0;
        uint32_t vid_bit = 0;
        int ret = 0;
-       
+
        PMD_INIT_LOG(DEBUG, "igbvf_vlan_filter_set");
 
        /*vind is not used in VF driver, set to 0, check ixgbe_set_vfta_vf*/
@@ -2036,16 +2119,16 @@ eth_igb_rss_reta_update(struct rte_eth_dev *dev,
                                 struct rte_eth_rss_reta *reta_conf)
 {
        uint8_t i,j,mask;
-       uint32_t reta;  
+       uint32_t reta;
        struct e1000_hw *hw =
-                       E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private); 
-       
-       /*    
-        * Update Redirection Table RETA[n],n=0...31,The redirection table has 
-        * 128-entries in 32 registers 
-        */ 
-       for(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {  
-               if (i < ETH_RSS_RETA_NUM_ENTRIES/2) 
+                       E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+       /*
+        * Update Redirection Table RETA[n],n=0...31,The redirection table has
+        * 128-entries in 32 registers
+        */
+       for(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {
+               if (i < ETH_RSS_RETA_NUM_ENTRIES/2)
                        mask = (uint8_t)((reta_conf->mask_lo >> i) & 0xF);
                else
                        mask = (uint8_t)((reta_conf->mask_hi >>
@@ -2053,7 +2136,7 @@ eth_igb_rss_reta_update(struct rte_eth_dev *dev,
                if (mask != 0) {
                        reta = 0;
                        /* If all 4 entries were set,don't need read RETA register */
-                       if (mask != 0xF)  
+                       if (mask != 0xF)
                                reta = E1000_READ_REG(hw,E1000_RETA(i >> 2));
 
                        for (j = 0; j < 4; j++) {
@@ -2076,11 +2159,11 @@ eth_igb_rss_reta_query(struct rte_eth_dev *dev,
 {
        uint8_t i,j,mask;
        uint32_t reta;
-       struct e1000_hw *hw = 
+       struct e1000_hw *hw =
                        E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
 
-       /* 
-        * Read Redirection Table RETA[n],n=0...31,The redirection table has 
+       /*
+        * Read Redirection Table RETA[n],n=0...31,The redirection table has
         * 128-entries in 32 registers
         */
        for(i = 0; i < ETH_RSS_RETA_NUM_ENTRIES; i += 4) {
@@ -2099,6 +2182,19 @@ eth_igb_rss_reta_query(struct rte_eth_dev *dev,
                        }
                }
        }
+
        return 0;
 }
+
+static struct rte_driver pmd_igb_drv = {
+       .type = PMD_PDEV,
+       .init = rte_igb_pmd_init,
+};
+
+static struct rte_driver pmd_igbvf_drv = {
+       .type = PMD_PDEV,
+       .init = rte_igbvf_pmd_init,
+};
+
+PMD_REGISTER_DRIVER(pmd_igb_drv);
+PMD_REGISTER_DRIVER(pmd_igbvf_drv);