/*-
* BSD LICENSE
- *
+ *
* 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
* * 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
#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"
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);
.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,
};
/*
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);
}
{
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)
{
/* 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)
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;
/* 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;
/* 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:
/* Disable the interrupts for VF */
igbvf_intr_disable(hw);
-
+
diag = hw->mac.ops.reset_hw(hw);
/* Allocate memory for storing MAC addresses */
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,
ð_dev->data->mac_addrs[0]);
.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;
* 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");
/* 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
* 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
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);
intr->flags |= E1000_FLAG_NEED_LINK_UPDATE;
}
- if (icr & E1000_ICR_VMMB)
+ if (icr & E1000_ICR_VMMB)
intr->flags |= E1000_FLAG_MAILBOX;
return 0;
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;
/* Set all vfta */
igbvf_set_vfta_all(dev,1);
-
+
eth_igbvf_tx_init(dev);
/* This can fail when allocating mbufs for descriptor rings */
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);
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" */
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);
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*/
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 >>
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++) {
{
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) {
}
}
}
-
+
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);