* Re: linux-next: build failure after final merge (net tree)
From: Stephen Rothwell @ 2010-02-17 7:57 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-next, linux-kernel, jengelh
In-Reply-To: <20100216.231109.183048308.davem@davemloft.net>
[-- Attachment #1: Type: text/plain, Size: 435 bytes --]
On Tue, 16 Feb 2010 23:11:09 -0800 (PST) David Miller <davem@davemloft.net> wrote:
>
> From: Stephen Rothwell <sfr@canb.auug.org.au>
> Date: Wed, 17 Feb 2010 17:40:15 +1100
>
> > After merging, today's linux-next build (sparc64 defconfig) failed like
> > this:
>
> Fixed for at least 6 hours:
Excellent, thanks.
--
Cheers,
Stephen Rothwell sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply
* Re: [PATCH V2 net-next 1/2] usbnet: Convert dev(dbg|err|warn|info) macros to netdev_<level>
From: David Miller @ 2010-02-17 8:04 UTC (permalink / raw)
To: joe; +Cc: david-b, gregkh, tilman, netdev, linux-usb, linux-kernel
In-Reply-To: <20100216.233714.39181977.davem@davemloft.net>
I had to revert this series, the build fails:
drivers/net/wireless/rndis_wlan.c: In function 'rndis_query_oid':
drivers/net/wireless/rndis_wlan.c:731: error: implicit declaration of function 'devdbg'
drivers/net/wireless/rndis_wlan.c: In function 'set_essid':
drivers/net/wireless/rndis_wlan.c:948: error: implicit declaration of function 'devwarn'
drivers/net/wireless/rndis_wlan.c: In function 'rndis_connect':
drivers/net/wireless/rndis_wlan.c:1796: error: implicit declaration of function 'deverr'
drivers/net/wireless/rndis_wlan.c: In function 'rndis_wlan_auth_indication':
drivers/net/wireless/rndis_wlan.c:2273: error: implicit declaration of function 'devinfo'
make[3]: *** [drivers/net/wireless/rndis_wlan.o] Error 1
make[3]: *** Waiting for unfinished jobs....
^ permalink raw reply
* Re: [PACH] smsc911x: replace manual phy lookup.
From: Jiri Pirko @ 2010-02-17 8:15 UTC (permalink / raw)
To: davem, steve.glendinning, netdev
In-Reply-To: <20100217075458.GA4388@coldcone>
Wed, Feb 17, 2010 at 08:54:58AM CET, kirjanov@gmail.com wrote:
>Use phy_find_first() function instead of manual lookup.
>
>Signed-off-by: Denis Kirjanov <kirjanov@gmail.com>
>
>---
>
> drivers/net/smsc911x.c | 24 ++++++++++--------------
> 1 files changed, 10 insertions(+), 14 deletions(-)
>
>diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
>index 3c1f9aa..13c0b76 100644
>--- a/drivers/net/smsc911x.c
>+++ b/drivers/net/smsc911x.c
>@@ -770,29 +770,25 @@ static int smsc911x_mii_probe(struct net_device *dev)
> {
> struct smsc911x_data *pdata = netdev_priv(dev);
> struct phy_device *phydev = NULL;
>- int phy_addr;
>+ int ret;
>
> /* find the first phy */
>- for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
>- if (pdata->mii_bus->phy_map[phy_addr]) {
>- phydev = pdata->mii_bus->phy_map[phy_addr];
>- SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X",
>- phy_addr, phydev->addr, phydev->phy_id);
>- break;
>- }
>- }
>-
>+ phydev = phy_find_first(pdata->mii_bus);
> if (!phydev) {
> pr_err("%s: no PHY found\n", dev->name);
> return -ENODEV;
> }
>
>- phydev = phy_connect(dev, dev_name(&phydev->dev),
>- &smsc911x_phy_adjust_link, 0, pdata->config.phy_interface);
>+ SMSC_TRACE(PROBE, "PHY %d: addr %d, phy_id 0x%08X",
>+ phy_addr, phydev->addr, phydev->phy_id);
>+
>+ ret = phy_connect_direct(dev, phydev,
>+ &smsc911x_phy_adjust_link, 0,
>+ pdata->config.phy_interface);
>
>- if (IS_ERR(phydev)) {
>+ if (ret) {
> pr_err("%s: Could not attach to PHY\n", dev->name);
>- return PTR_ERR(phydev);
>+ return ret;
> }
>
> pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
Looks good to me.
Reviewed-by: Jiri Pirko <jpirko@redhat.com>
^ permalink raw reply
* [net-next-2.6 PATCH 01/18] igb: remove unecessary q_vector declarations and remove itr_shift
From: Jeff Kirsher @ 2010-02-17 11:00 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change removes the use of itr_shift since a mac type call can be used
just as easily to identify the only HW that needs to have the itr shifted.
In addition it removes two unecessary declrations of a q_vector pointer from
the initialization path.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb.h | 1 -
drivers/net/igb/igb_main.c | 25 +++++++++++++------------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 83ea117..0efd285 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -176,7 +176,6 @@ struct igb_q_vector {
u16 itr_val;
u8 set_itr;
- u8 itr_shift;
void __iomem *itr_register;
char name[IFNAMSIZ + 9];
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 4fe7b0b..677b5f5 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -504,6 +504,12 @@ static void igb_assign_vector(struct igb_q_vector *q_vector, int msix_vector)
BUG();
break;
}
+
+ /* add q_vector eims value to global eims_enable_mask */
+ adapter->eims_enable_mask |= q_vector->eims_value;
+
+ /* configure q_vector to set itr on first interrupt */
+ q_vector->set_itr = 1;
}
/**
@@ -561,11 +567,8 @@ static void igb_configure_msix(struct igb_adapter *adapter)
adapter->eims_enable_mask |= adapter->eims_other;
- for (i = 0; i < adapter->num_q_vectors; i++) {
- struct igb_q_vector *q_vector = adapter->q_vector[i];
- igb_assign_vector(q_vector, vector++);
- adapter->eims_enable_mask |= q_vector->eims_value;
- }
+ for (i = 0; i < adapter->num_q_vectors; i++)
+ igb_assign_vector(adapter->q_vector[i], vector++);
wrfl();
}
@@ -756,10 +759,8 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter)
if (!q_vector)
goto err_out;
q_vector->adapter = adapter;
- q_vector->itr_shift = (hw->mac.type == e1000_82575) ? 16 : 0;
q_vector->itr_register = hw->hw_addr + E1000_EITR(0);
q_vector->itr_val = IGB_START_ITR;
- q_vector->set_itr = 1;
netif_napi_add(adapter->netdev, &q_vector->napi, igb_poll, 64);
adapter->q_vector[v_idx] = q_vector;
}
@@ -4142,6 +4143,7 @@ static irqreturn_t igb_msix_other(int irq, void *data)
static void igb_write_itr(struct igb_q_vector *q_vector)
{
+ struct igb_adapter *adapter = q_vector->adapter;
u32 itr_val = q_vector->itr_val & 0x7FFC;
if (!q_vector->set_itr)
@@ -4150,8 +4152,8 @@ static void igb_write_itr(struct igb_q_vector *q_vector)
if (!itr_val)
itr_val = 0x4;
- if (q_vector->itr_shift)
- itr_val |= itr_val << q_vector->itr_shift;
+ if (adapter->hw.mac.type == e1000_82575)
+ itr_val |= itr_val << 16;
else
itr_val |= 0x8000000;
@@ -4228,9 +4230,8 @@ static void igb_setup_dca(struct igb_adapter *adapter)
wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
for (i = 0; i < adapter->num_q_vectors; i++) {
- struct igb_q_vector *q_vector = adapter->q_vector[i];
- q_vector->cpu = -1;
- igb_update_dca(q_vector);
+ adapter->q_vector[i]->cpu = -1;
+ igb_update_dca(adapter->q_vector[i]);
}
}
^ permalink raw reply related
* [net-next-2.6 PATCH 02/18] igb: add support for wake-on-link
From: Jeff Kirsher @ 2010-02-17 11:01 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This adds support for wake-on-link/phy activity to the ethtool
interface.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_ethtool.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index f771a6c..145a8eb 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -1812,7 +1812,8 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
struct igb_adapter *adapter = netdev_priv(netdev);
wol->supported = WAKE_UCAST | WAKE_MCAST |
- WAKE_BCAST | WAKE_MAGIC;
+ WAKE_BCAST | WAKE_MAGIC |
+ WAKE_PHY;
wol->wolopts = 0;
/* this function will set ->supported = 0 and return 1 if wol is not
@@ -1835,15 +1836,15 @@ static void igb_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
wol->wolopts |= WAKE_BCAST;
if (adapter->wol & E1000_WUFC_MAG)
wol->wolopts |= WAKE_MAGIC;
-
- return;
+ if (adapter->wol & E1000_WUFC_LNKC)
+ wol->wolopts |= WAKE_PHY;
}
static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE))
+ if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE))
return -EOPNOTSUPP;
if (igb_wol_exclusion(adapter, wol) ||
@@ -1861,6 +1862,8 @@ static int igb_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
adapter->wol |= E1000_WUFC_BC;
if (wol->wolopts & WAKE_MAGIC)
adapter->wol |= E1000_WUFC_MAG;
+ if (wol->wolopts & WAKE_PHY)
+ adapter->wol |= E1000_WUFC_LNKC;
device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
return 0;
^ permalink raw reply related
* [net-next-2.6 PATCH 03/18] igb: Report link status in ethtool when interface is down
From: Jeff Kirsher @ 2010-02-17 11:01 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
With this change ethtool will correctly report link status when
the interface is down. Currently ethtool reports the link as not
detected when the interface is down.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb.h | 1 +
drivers/net/igb/igb_ethtool.c | 20 +++++++++++++++++++-
drivers/net/igb/igb_main.c | 2 +-
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 0efd285..452a4de 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -356,6 +356,7 @@ extern void igb_unmap_and_free_tx_resource(struct igb_ring *,
struct igb_buffer *);
extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
extern void igb_update_stats(struct igb_adapter *);
+extern bool igb_has_link(struct igb_adapter *adapter);
extern void igb_set_ethtool_ops(struct net_device *);
static inline s32 igb_reset_phy(struct e1000_hw *hw)
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 145a8eb..4eea03b 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -234,6 +234,24 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
return 0;
}
+static u32 igb_get_link(struct net_device *netdev)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_mac_info *mac = &adapter->hw.mac;
+
+ /*
+ * If the link is not reported up to netdev, interrupts are disabled,
+ * and so the physical link state may have changed since we last
+ * looked. Set get_link_status to make sure that the true link
+ * state is interrogated, rather than pulling a cached and possibly
+ * stale link state from the driver.
+ */
+ if (!netif_carrier_ok(netdev))
+ mac->get_link_status = 1;
+
+ return igb_has_link(adapter);
+}
+
static void igb_get_pauseparam(struct net_device *netdev,
struct ethtool_pauseparam *pause)
{
@@ -2077,7 +2095,7 @@ static const struct ethtool_ops igb_ethtool_ops = {
.get_msglevel = igb_get_msglevel,
.set_msglevel = igb_set_msglevel,
.nway_reset = igb_nway_reset,
- .get_link = ethtool_op_get_link,
+ .get_link = igb_get_link,
.get_eeprom_len = igb_get_eeprom_len,
.get_eeprom = igb_get_eeprom,
.set_eeprom = igb_set_eeprom,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 677b5f5..e40319e 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3020,7 +3020,7 @@ static void igb_update_phy_info(unsigned long data)
* igb_has_link - check shared code for link and determine up/down
* @adapter: pointer to driver private info
**/
-static bool igb_has_link(struct igb_adapter *adapter)
+bool igb_has_link(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
bool link_active = false;
^ permalink raw reply related
* [net-next-2.6 PATCH 04/18] igb: ignore EEPROM APME check when shutting down serdes link
From: Jeff Kirsher @ 2010-02-17 11:01 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
Checking the EEPROM APME state unnecessarily prevents the link from
shutting down. The standard power down routines should be
sufficient to determine whether the serdes link can power down
when going into D3.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 21 ++-------------------
1 files changed, 2 insertions(+), 19 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index c505b50..59817bc 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -791,27 +791,12 @@ static s32 igb_get_pcs_speed_and_duplex_82575(struct e1000_hw *hw, u16 *speed,
void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
{
u32 reg;
- u16 eeprom_data = 0;
- if (hw->phy.media_type != e1000_media_type_internal_serdes ||
+ if (hw->phy.media_type != e1000_media_type_internal_serdes &&
igb_sgmii_active_82575(hw))
return;
- if (hw->bus.func == E1000_FUNC_0)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data);
- else if (hw->mac.type == e1000_82580)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A +
- NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1,
- &eeprom_data);
- else if (hw->bus.func == E1000_FUNC_1)
- hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_B, 1, &eeprom_data);
-
- /*
- * If APM is not enabled in the EEPROM and management interface is
- * not enabled, then power down.
- */
- if (!(eeprom_data & E1000_NVM_APME_82575) &&
- !igb_enable_mng_pass_thru(hw)) {
+ if (!igb_enable_mng_pass_thru(hw)) {
/* Disable PCS to turn off link */
reg = rd32(E1000_PCS_CFG0);
reg &= ~E1000_PCS_CFG_PCS_EN;
@@ -826,8 +811,6 @@ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
wrfl();
msleep(1);
}
-
- return;
}
/**
^ permalink raw reply related
* [net-next-2.6 PATCH 05/18] igb: Power down link when interface is down
From: Jeff Kirsher @ 2010-02-17 11:01 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This changes the behavior of the driver to power down the link
when the associated interface is down, unless management is enabled.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_82575.c | 44 +++++++++++++++++++++++++++++++++++++++
drivers/net/igb/e1000_82575.h | 2 ++
drivers/net/igb/e1000_defines.h | 1 +
drivers/net/igb/e1000_phy.c | 35 +++++++++++++++++++++++++++++++
drivers/net/igb/e1000_phy.h | 2 ++
drivers/net/igb/igb.h | 1 +
drivers/net/igb/igb_ethtool.c | 16 ++++++++++++--
drivers/net/igb/igb_main.c | 39 +++++++++++++++++++++++++++--------
8 files changed, 129 insertions(+), 11 deletions(-)
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 59817bc..9d7fa2f 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -727,6 +727,34 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
}
/**
+ * igb_power_up_serdes_link_82575 - Power up the serdes link after shutdown
+ * @hw: pointer to the HW structure
+ **/
+void igb_power_up_serdes_link_82575(struct e1000_hw *hw)
+{
+ u32 reg;
+
+
+ if ((hw->phy.media_type != e1000_media_type_internal_serdes) &&
+ !igb_sgmii_active_82575(hw))
+ return;
+
+ /* Enable PCS to turn on link */
+ reg = rd32(E1000_PCS_CFG0);
+ reg |= E1000_PCS_CFG_PCS_EN;
+ wr32(E1000_PCS_CFG0, reg);
+
+ /* Power up the laser */
+ reg = rd32(E1000_CTRL_EXT);
+ reg &= ~E1000_CTRL_EXT_SDP3_DATA;
+ wr32(E1000_CTRL_EXT, reg);
+
+ /* flush the write to verify completion */
+ wrfl();
+ msleep(1);
+}
+
+/**
* igb_get_pcs_speed_and_duplex_82575 - Retrieve current speed/duplex
* @hw: pointer to the HW structure
* @speed: stores the current speed
@@ -1166,6 +1194,22 @@ out:
}
/**
+ * igb_power_down_phy_copper_82575 - Remove link during PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, or wake on lan is not enabled, remove the link.
+ **/
+void igb_power_down_phy_copper_82575(struct e1000_hw *hw)
+{
+ /* If the management interface is not enabled, then power down */
+ if (!(igb_enable_mng_pass_thru(hw) || igb_check_reset_block(hw)))
+ igb_power_down_phy_copper(hw);
+
+ return;
+}
+
+/**
* igb_clear_hw_cntrs_82575 - Clear device specific hardware counters
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index bb53083..fbe1c99 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -29,6 +29,8 @@
#define _E1000_82575_H_
extern void igb_shutdown_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_power_up_serdes_link_82575(struct e1000_hw *hw);
+extern void igb_power_down_phy_copper_82575(struct e1000_hw *hw);
extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 6e036ae..c017150 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -481,6 +481,7 @@
/* PHY Control Register */
#define MII_CR_FULL_DUPLEX 0x0100 /* FDX =1, half duplex =0 */
#define MII_CR_RESTART_AUTO_NEG 0x0200 /* Restart auto negotiation */
+#define MII_CR_POWER_DOWN 0x0800 /* Power down */
#define MII_CR_AUTO_NEG_EN 0x1000 /* Auto Neg Enable */
#define MII_CR_LOOPBACK 0x4000 /* 0 = normal, 1 = loopback */
#define MII_CR_RESET 0x8000 /* 0 = normal, 1 = PHY reset */
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index 3670a66..cf1f323 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -1931,6 +1931,41 @@ s32 igb_phy_init_script_igp3(struct e1000_hw *hw)
}
/**
+ * igb_power_up_phy_copper - Restore copper link in case of PHY power down
+ * @hw: pointer to the HW structure
+ *
+ * In the case of a PHY power down to save power, or to turn off link during a
+ * driver unload, restore the link to previous settings.
+ **/
+void igb_power_up_phy_copper(struct e1000_hw *hw)
+{
+ u16 mii_reg = 0;
+
+ /* The PHY will retain its settings across a power down/up cycle */
+ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
+ mii_reg &= ~MII_CR_POWER_DOWN;
+ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
+}
+
+/**
+ * igb_power_down_phy_copper - Power down copper PHY
+ * @hw: pointer to the HW structure
+ *
+ * Power down PHY to save power when interface is down and wake on lan
+ * is not enabled.
+ **/
+void igb_power_down_phy_copper(struct e1000_hw *hw)
+{
+ u16 mii_reg = 0;
+
+ /* The PHY will retain its settings across a power down/up cycle */
+ hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg);
+ mii_reg |= MII_CR_POWER_DOWN;
+ hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
+ msleep(1);
+}
+
+/**
* igb_check_polarity_82580 - Checks the polarity.
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 555eb54..565a6db 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -60,6 +60,8 @@ s32 igb_setup_copper_link(struct e1000_hw *hw);
s32 igb_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_phy_has_link(struct e1000_hw *hw, u32 iterations,
u32 usec_interval, bool *success);
+void igb_power_up_phy_copper(struct e1000_hw *hw);
+void igb_power_down_phy_copper(struct e1000_hw *hw);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 452a4de..0e0800d 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -358,6 +358,7 @@ extern void igb_alloc_rx_buffers_adv(struct igb_ring *, int);
extern void igb_update_stats(struct igb_adapter *);
extern bool igb_has_link(struct igb_adapter *adapter);
extern void igb_set_ethtool_ops(struct net_device *);
+extern void igb_power_up_link(struct igb_adapter *);
static inline s32 igb_reset_phy(struct e1000_hw *hw)
{
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 4eea03b..4852883 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -1722,6 +1722,9 @@ static void igb_diag_test(struct net_device *netdev,
dev_info(&adapter->pdev->dev, "offline testing starting\n");
+ /* power up link for link test */
+ igb_power_up_link(adapter);
+
/* Link test performed before hardware reset so autoneg doesn't
* interfere with test result */
if (igb_link_test(adapter, &data[4]))
@@ -1745,6 +1748,8 @@ static void igb_diag_test(struct net_device *netdev,
eth_test->flags |= ETH_TEST_FL_FAILED;
igb_reset(adapter);
+ /* power up link for loopback test */
+ igb_power_up_link(adapter);
if (igb_loopback_test(adapter, &data[3]))
eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1763,9 +1768,14 @@ static void igb_diag_test(struct net_device *netdev,
dev_open(netdev);
} else {
dev_info(&adapter->pdev->dev, "online testing starting\n");
- /* Online tests */
- if (igb_link_test(adapter, &data[4]))
- eth_test->flags |= ETH_TEST_FL_FAILED;
+
+ /* PHY is powered down when interface is down */
+ if (!netif_carrier_ok(netdev)) {
+ data[4] = 0;
+ } else {
+ if (igb_link_test(adapter, &data[4]))
+ eth_test->flags |= ETH_TEST_FL_FAILED;
+ }
/* Online tests aren't run; pass by default */
data[0] = 0;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index e40319e..0427e7c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1114,6 +1114,29 @@ static void igb_configure(struct igb_adapter *adapter)
adapter->tx_queue_len = netdev->tx_queue_len;
}
+/**
+ * igb_power_up_link - Power up the phy/serdes link
+ * @adapter: address of board private structure
+ **/
+void igb_power_up_link(struct igb_adapter *adapter)
+{
+ if (adapter->hw.phy.media_type == e1000_media_type_copper)
+ igb_power_up_phy_copper(&adapter->hw);
+ else
+ igb_power_up_serdes_link_82575(&adapter->hw);
+}
+
+/**
+ * igb_power_down_link - Power down the phy/serdes link
+ * @adapter: address of board private structure
+ */
+static void igb_power_down_link(struct igb_adapter *adapter)
+{
+ if (adapter->hw.phy.media_type == e1000_media_type_copper)
+ igb_power_down_phy_copper_82575(&adapter->hw);
+ else
+ igb_shutdown_serdes_link_82575(&adapter->hw);
+}
/**
* igb_up - Open the interface and prepare it to handle traffic
@@ -1335,6 +1358,9 @@ void igb_reset(struct igb_adapter *adapter)
wr32(E1000_PCIEMISC,
reg & ~E1000_PCIEMISC_LX_DECISION);
}
+ if (!netif_running(adapter->netdev))
+ igb_power_down_link(adapter);
+
igb_update_mng_vlan(adapter);
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
@@ -1717,9 +1743,6 @@ static void __devexit igb_remove(struct pci_dev *pdev)
unregister_netdev(netdev);
- if (!igb_check_reset_block(hw))
- igb_reset_phy(hw);
-
igb_clear_interrupt_scheme(adapter);
#ifdef CONFIG_PCI_IOV
@@ -1995,7 +2018,7 @@ static int igb_open(struct net_device *netdev)
if (err)
goto err_setup_rx;
- /* e1000_power_up_phy(adapter); */
+ igb_power_up_link(adapter);
/* before we allocate an interrupt, we must be ready to handle it.
* Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
@@ -2037,7 +2060,7 @@ static int igb_open(struct net_device *netdev)
err_req_irq:
igb_release_hw_control(adapter);
- /* e1000_power_down_phy(adapter); */
+ igb_power_down_link(adapter);
igb_free_all_rx_resources(adapter);
err_setup_rx:
igb_free_all_tx_resources(adapter);
@@ -5820,7 +5843,9 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
*enable_wake = wufc || adapter->en_mng_pt;
if (!*enable_wake)
- igb_shutdown_serdes_link_82575(hw);
+ igb_power_down_link(adapter);
+ else
+ igb_power_up_link(adapter);
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
@@ -5877,8 +5902,6 @@ static int igb_resume(struct pci_dev *pdev)
return -ENOMEM;
}
- /* e1000_power_up_phy(adapter); */
-
igb_reset(adapter);
/* let the f/w know that the h/w is now under the control of the
^ permalink raw reply related
* [net-next-2.6 PATCH 06/18] igb: call pci_save_state after pci_restore_state
From: Jeff Kirsher @ 2010-02-17 11:02 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This patch adds calls to pci_save_state() immediately after
calls to pci_restore_state(). Due to a change in the behavior
of pci_restore_state() it is necessary to call pci_save_state()
to keep the state_saved flag. This patch is based on a similar
patch for ixgbe.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 0427e7c..089a7c3 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -5885,6 +5885,7 @@ static int igb_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+ pci_save_state(pdev);
err = pci_enable_device_mem(pdev);
if (err) {
@@ -6010,6 +6011,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
} else {
pci_set_master(pdev);
pci_restore_state(pdev);
+ pci_save_state(pdev);
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
^ permalink raw reply related
* [net-next-2.6 PATCH 07/18] igb: Allocate rings seperately instead of as a block
From: Jeff Kirsher @ 2010-02-17 11:02 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Alexander Duyck, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change makes it so that the rings are allocated seperately. As a
result we can allocate them on seperate nodes at some point in the future
if we so desire.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb.h | 5 +-
drivers/net/igb/igb_ethtool.c | 46 +++++++++--------
drivers/net/igb/igb_main.c | 113 +++++++++++++++++++++--------------------
3 files changed, 83 insertions(+), 81 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 0e0800d..8f07bc0 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -240,7 +240,6 @@ static inline int igb_desc_unused(struct igb_ring *ring)
}
/* board specific private data structure */
-
struct igb_adapter {
struct timer_list watchdog_timer;
struct timer_list phy_info_timer;
@@ -266,12 +265,12 @@ struct igb_adapter {
unsigned long led_status;
/* TX */
- struct igb_ring *tx_ring; /* One per active queue */
+ struct igb_ring *tx_ring[16];
unsigned long tx_queue_len;
u32 tx_timeout_count;
/* RX */
- struct igb_ring *rx_ring; /* One per active queue */
+ struct igb_ring *rx_ring[16];
int num_tx_queues;
int num_rx_queues;
diff --git a/drivers/net/igb/igb_ethtool.c b/drivers/net/igb/igb_ethtool.c
index 4852883..a4cead1 100644
--- a/drivers/net/igb/igb_ethtool.c
+++ b/drivers/net/igb/igb_ethtool.c
@@ -314,7 +314,7 @@ static int igb_set_pauseparam(struct net_device *netdev,
static u32 igb_get_rx_csum(struct net_device *netdev)
{
struct igb_adapter *adapter = netdev_priv(netdev);
- return !!(adapter->rx_ring[0].flags & IGB_RING_FLAG_RX_CSUM);
+ return !!(adapter->rx_ring[0]->flags & IGB_RING_FLAG_RX_CSUM);
}
static int igb_set_rx_csum(struct net_device *netdev, u32 data)
@@ -324,9 +324,9 @@ static int igb_set_rx_csum(struct net_device *netdev, u32 data)
for (i = 0; i < adapter->num_rx_queues; i++) {
if (data)
- adapter->rx_ring[i].flags |= IGB_RING_FLAG_RX_CSUM;
+ adapter->rx_ring[i]->flags |= IGB_RING_FLAG_RX_CSUM;
else
- adapter->rx_ring[i].flags &= ~IGB_RING_FLAG_RX_CSUM;
+ adapter->rx_ring[i]->flags &= ~IGB_RING_FLAG_RX_CSUM;
}
return 0;
@@ -789,9 +789,9 @@ static int igb_set_ringparam(struct net_device *netdev,
if (!netif_running(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++)
- adapter->tx_ring[i].count = new_tx_count;
+ adapter->tx_ring[i]->count = new_tx_count;
for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].count = new_rx_count;
+ adapter->rx_ring[i]->count = new_rx_count;
adapter->tx_ring_count = new_tx_count;
adapter->rx_ring_count = new_rx_count;
goto clear_reset;
@@ -815,10 +815,10 @@ static int igb_set_ringparam(struct net_device *netdev,
* to the tx and rx ring structs.
*/
if (new_tx_count != adapter->tx_ring_count) {
- memcpy(temp_ring, adapter->tx_ring,
- adapter->num_tx_queues * sizeof(struct igb_ring));
-
for (i = 0; i < adapter->num_tx_queues; i++) {
+ memcpy(&temp_ring[i], adapter->tx_ring[i],
+ sizeof(struct igb_ring));
+
temp_ring[i].count = new_tx_count;
err = igb_setup_tx_resources(&temp_ring[i]);
if (err) {
@@ -830,20 +830,21 @@ static int igb_set_ringparam(struct net_device *netdev,
}
}
- for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(&adapter->tx_ring[i]);
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ igb_free_tx_resources(adapter->tx_ring[i]);
- memcpy(adapter->tx_ring, temp_ring,
- adapter->num_tx_queues * sizeof(struct igb_ring));
+ memcpy(adapter->tx_ring[i], &temp_ring[i],
+ sizeof(struct igb_ring));
+ }
adapter->tx_ring_count = new_tx_count;
}
- if (new_rx_count != adapter->rx_ring->count) {
- memcpy(temp_ring, adapter->rx_ring,
- adapter->num_rx_queues * sizeof(struct igb_ring));
-
+ if (new_rx_count != adapter->rx_ring_count) {
for (i = 0; i < adapter->num_rx_queues; i++) {
+ memcpy(&temp_ring[i], adapter->rx_ring[i],
+ sizeof(struct igb_ring));
+
temp_ring[i].count = new_rx_count;
err = igb_setup_rx_resources(&temp_ring[i]);
if (err) {
@@ -856,11 +857,12 @@ static int igb_set_ringparam(struct net_device *netdev,
}
- for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(&adapter->rx_ring[i]);
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ igb_free_rx_resources(adapter->rx_ring[i]);
- memcpy(adapter->rx_ring, temp_ring,
- adapter->num_rx_queues * sizeof(struct igb_ring));
+ memcpy(adapter->rx_ring[i], &temp_ring[i],
+ sizeof(struct igb_ring));
+ }
adapter->rx_ring_count = new_rx_count;
}
@@ -2036,12 +2038,12 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
for (j = 0; j < adapter->num_tx_queues; j++) {
- queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
+ queue_stat = (u64 *)&adapter->tx_ring[j]->tx_stats;
for (k = 0; k < IGB_TX_QUEUE_STATS_LEN; k++, i++)
data[i] = queue_stat[k];
}
for (j = 0; j < adapter->num_rx_queues; j++) {
- queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
+ queue_stat = (u64 *)&adapter->rx_ring[j]->rx_stats;
for (k = 0; k < IGB_RX_QUEUE_STATS_LEN; k++, i++)
data[i] = queue_stat[k];
}
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 089a7c3..30fb5a8 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -318,31 +318,35 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
*/
if (adapter->vfs_allocated_count) {
for (; i < adapter->rss_queues; i++)
- adapter->rx_ring[i].reg_idx = rbase_offset +
- Q_IDX_82576(i);
+ adapter->rx_ring[i]->reg_idx = rbase_offset +
+ Q_IDX_82576(i);
for (; j < adapter->rss_queues; j++)
- adapter->tx_ring[j].reg_idx = rbase_offset +
- Q_IDX_82576(j);
+ adapter->tx_ring[j]->reg_idx = rbase_offset +
+ Q_IDX_82576(j);
}
case e1000_82575:
case e1000_82580:
default:
for (; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].reg_idx = rbase_offset + i;
+ adapter->rx_ring[i]->reg_idx = rbase_offset + i;
for (; j < adapter->num_tx_queues; j++)
- adapter->tx_ring[j].reg_idx = rbase_offset + j;
+ adapter->tx_ring[j]->reg_idx = rbase_offset + j;
break;
}
}
static void igb_free_queues(struct igb_adapter *adapter)
{
- kfree(adapter->tx_ring);
- kfree(adapter->rx_ring);
-
- adapter->tx_ring = NULL;
- adapter->rx_ring = NULL;
+ int i;
+ for (i = 0; i < adapter->num_tx_queues; i++) {
+ kfree(adapter->tx_ring[i]);
+ adapter->tx_ring[i] = NULL;
+ }
+ for (i = 0; i < adapter->num_rx_queues; i++) {
+ kfree(adapter->rx_ring[i]);
+ adapter->rx_ring[i] = NULL;
+ }
adapter->num_rx_queues = 0;
adapter->num_tx_queues = 0;
}
@@ -356,20 +360,13 @@ static void igb_free_queues(struct igb_adapter *adapter)
**/
static int igb_alloc_queues(struct igb_adapter *adapter)
{
+ struct igb_ring *ring;
int i;
- adapter->tx_ring = kcalloc(adapter->num_tx_queues,
- sizeof(struct igb_ring), GFP_KERNEL);
- if (!adapter->tx_ring)
- goto err;
-
- adapter->rx_ring = kcalloc(adapter->num_rx_queues,
- sizeof(struct igb_ring), GFP_KERNEL);
- if (!adapter->rx_ring)
- goto err;
-
for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *ring = &(adapter->tx_ring[i]);
+ ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
+ if (!ring)
+ goto err;
ring->count = adapter->tx_ring_count;
ring->queue_index = i;
ring->pdev = adapter->pdev;
@@ -377,10 +374,13 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
/* For 82575, context index must be unique per ring. */
if (adapter->hw.mac.type == e1000_82575)
ring->flags = IGB_RING_FLAG_TX_CTX_IDX;
+ adapter->tx_ring[i] = ring;
}
for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igb_ring *ring = &(adapter->rx_ring[i]);
+ ring = kzalloc(sizeof(struct igb_ring), GFP_KERNEL);
+ if (!ring)
+ goto err;
ring->count = adapter->rx_ring_count;
ring->queue_index = i;
ring->pdev = adapter->pdev;
@@ -390,6 +390,7 @@ static int igb_alloc_queues(struct igb_adapter *adapter)
/* set flag indicating ring supports SCTP checksum offload */
if (adapter->hw.mac.type >= e1000_82576)
ring->flags |= IGB_RING_FLAG_RX_SCTP_CSUM;
+ adapter->rx_ring[i] = ring;
}
igb_cache_ring_register(adapter);
@@ -780,10 +781,9 @@ err_out:
static void igb_map_rx_ring_to_vector(struct igb_adapter *adapter,
int ring_idx, int v_idx)
{
- struct igb_q_vector *q_vector;
+ struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
- q_vector = adapter->q_vector[v_idx];
- q_vector->rx_ring = &adapter->rx_ring[ring_idx];
+ q_vector->rx_ring = adapter->rx_ring[ring_idx];
q_vector->rx_ring->q_vector = q_vector;
q_vector->itr_val = adapter->rx_itr_setting;
if (q_vector->itr_val && q_vector->itr_val <= 3)
@@ -793,10 +793,9 @@ static void igb_map_rx_ring_to_vector(struct igb_adapter *adapter,
static void igb_map_tx_ring_to_vector(struct igb_adapter *adapter,
int ring_idx, int v_idx)
{
- struct igb_q_vector *q_vector;
+ struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
- q_vector = adapter->q_vector[v_idx];
- q_vector->tx_ring = &adapter->tx_ring[ring_idx];
+ q_vector->tx_ring = adapter->tx_ring[ring_idx];
q_vector->tx_ring->q_vector = q_vector;
q_vector->itr_val = adapter->tx_itr_setting;
if (q_vector->itr_val && q_vector->itr_val <= 3)
@@ -1106,7 +1105,7 @@ static void igb_configure(struct igb_adapter *adapter)
* at least 1 descriptor unused to make sure
* next_to_use != next_to_clean */
for (i = 0; i < adapter->num_rx_queues; i++) {
- struct igb_ring *ring = &adapter->rx_ring[i];
+ struct igb_ring *ring = adapter->rx_ring[i];
igb_alloc_rx_buffers_adv(ring, igb_desc_unused(ring));
}
@@ -2148,19 +2147,19 @@ static int igb_setup_all_tx_resources(struct igb_adapter *adapter)
int i, err = 0;
for (i = 0; i < adapter->num_tx_queues; i++) {
- err = igb_setup_tx_resources(&adapter->tx_ring[i]);
+ err = igb_setup_tx_resources(adapter->tx_ring[i]);
if (err) {
dev_err(&pdev->dev,
"Allocation for Tx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_tx_resources(&adapter->tx_ring[i]);
+ igb_free_tx_resources(adapter->tx_ring[i]);
break;
}
}
for (i = 0; i < IGB_ABS_MAX_TX_QUEUES; i++) {
int r_idx = i % adapter->num_tx_queues;
- adapter->multi_tx_table[i] = &adapter->tx_ring[r_idx];
+ adapter->multi_tx_table[i] = adapter->tx_ring[r_idx];
}
return err;
}
@@ -2243,7 +2242,7 @@ static void igb_configure_tx(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_configure_tx_ring(adapter, &adapter->tx_ring[i]);
+ igb_configure_tx_ring(adapter, adapter->tx_ring[i]);
}
/**
@@ -2301,12 +2300,12 @@ static int igb_setup_all_rx_resources(struct igb_adapter *adapter)
int i, err = 0;
for (i = 0; i < adapter->num_rx_queues; i++) {
- err = igb_setup_rx_resources(&adapter->rx_ring[i]);
+ err = igb_setup_rx_resources(adapter->rx_ring[i]);
if (err) {
dev_err(&pdev->dev,
"Allocation for Rx Queue %u failed\n", i);
for (i--; i >= 0; i--)
- igb_free_rx_resources(&adapter->rx_ring[i]);
+ igb_free_rx_resources(adapter->rx_ring[i]);
break;
}
}
@@ -2634,7 +2633,7 @@ static void igb_configure_rx(struct igb_adapter *adapter)
/* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring */
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_configure_rx_ring(adapter, &adapter->rx_ring[i]);
+ igb_configure_rx_ring(adapter, adapter->rx_ring[i]);
}
/**
@@ -2671,7 +2670,7 @@ static void igb_free_all_tx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_free_tx_resources(&adapter->tx_ring[i]);
+ igb_free_tx_resources(adapter->tx_ring[i]);
}
void igb_unmap_and_free_tx_resource(struct igb_ring *tx_ring,
@@ -2738,7 +2737,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_tx_queues; i++)
- igb_clean_tx_ring(&adapter->tx_ring[i]);
+ igb_clean_tx_ring(adapter->tx_ring[i]);
}
/**
@@ -2775,7 +2774,7 @@ static void igb_free_all_rx_resources(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_free_rx_resources(&adapter->rx_ring[i]);
+ igb_free_rx_resources(adapter->rx_ring[i]);
}
/**
@@ -2839,7 +2838,7 @@ static void igb_clean_all_rx_rings(struct igb_adapter *adapter)
int i;
for (i = 0; i < adapter->num_rx_queues; i++)
- igb_clean_rx_ring(&adapter->rx_ring[i]);
+ igb_clean_rx_ring(adapter->rx_ring[i]);
}
/**
@@ -3163,7 +3162,7 @@ static void igb_watchdog_task(struct work_struct *work)
igb_update_adaptive(hw);
for (i = 0; i < adapter->num_tx_queues; i++) {
- struct igb_ring *tx_ring = &adapter->tx_ring[i];
+ struct igb_ring *tx_ring = adapter->tx_ring[i];
if (!netif_carrier_ok(netdev)) {
/* We've lost link, so the controller stops DMA,
* but we've got queued Tx work that's never going
@@ -3359,13 +3358,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
adapter->rx_itr = igb_update_itr(adapter,
adapter->rx_itr,
- adapter->rx_ring->total_packets,
- adapter->rx_ring->total_bytes);
+ q_vector->rx_ring->total_packets,
+ q_vector->rx_ring->total_bytes);
adapter->tx_itr = igb_update_itr(adapter,
adapter->tx_itr,
- adapter->tx_ring->total_packets,
- adapter->tx_ring->total_bytes);
+ q_vector->tx_ring->total_packets,
+ q_vector->tx_ring->total_bytes);
current_itr = max(adapter->rx_itr, adapter->tx_itr);
/* conservative mode (itr 3) eliminates the lowest_latency setting */
@@ -3388,10 +3387,10 @@ static void igb_set_itr(struct igb_adapter *adapter)
}
set_itr_now:
- adapter->rx_ring->total_bytes = 0;
- adapter->rx_ring->total_packets = 0;
- adapter->tx_ring->total_bytes = 0;
- adapter->tx_ring->total_packets = 0;
+ q_vector->rx_ring->total_bytes = 0;
+ q_vector->rx_ring->total_packets = 0;
+ q_vector->tx_ring->total_bytes = 0;
+ q_vector->tx_ring->total_packets = 0;
if (new_itr != q_vector->itr_val) {
/* this attempts to bias the interrupt rate towards Bulk
@@ -3950,7 +3949,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
netdev->mtu = new_mtu;
for (i = 0; i < adapter->num_rx_queues; i++)
- adapter->rx_ring[i].rx_buffer_len = rx_buffer_len;
+ adapter->rx_ring[i]->rx_buffer_len = rx_buffer_len;
if (netif_running(netdev))
igb_up(adapter);
@@ -3992,10 +3991,11 @@ void igb_update_stats(struct igb_adapter *adapter)
packets = 0;
for (i = 0; i < adapter->num_rx_queues; i++) {
u32 rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0x0FFF;
- adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
+ struct igb_ring *ring = adapter->rx_ring[i];
+ ring->rx_stats.drops += rqdpc_tmp;
net_stats->rx_fifo_errors += rqdpc_tmp;
- bytes += adapter->rx_ring[i].rx_stats.bytes;
- packets += adapter->rx_ring[i].rx_stats.packets;
+ bytes += ring->rx_stats.bytes;
+ packets += ring->rx_stats.packets;
}
net_stats->rx_bytes = bytes;
@@ -4004,8 +4004,9 @@ void igb_update_stats(struct igb_adapter *adapter)
bytes = 0;
packets = 0;
for (i = 0; i < adapter->num_tx_queues; i++) {
- bytes += adapter->tx_ring[i].tx_stats.bytes;
- packets += adapter->tx_ring[i].tx_stats.packets;
+ struct igb_ring *ring = adapter->tx_ring[i];
+ bytes += ring->tx_stats.bytes;
+ packets += ring->tx_stats.packets;
}
net_stats->tx_bytes = bytes;
net_stats->tx_packets = packets;
^ permalink raw reply related
* [net-next-2.6 PATCH 08/18] igb: remove adaptive IFS from driver
From: Jeff Kirsher @ 2010-02-17 11:02 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
Adaptive IFS support has been included in the igb driver since its
initial release, but it is not a feature on any igb NICs. This patch
removes it from the driver.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/e1000_defines.h | 6 ---
drivers/net/igb/e1000_hw.h | 7 ----
drivers/net/igb/e1000_mac.c | 70 ---------------------------------------
drivers/net/igb/e1000_mac.h | 2 -
drivers/net/igb/igb_main.c | 10 +-----
5 files changed, 2 insertions(+), 93 deletions(-)
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index c017150..fe6cf1b 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -313,12 +313,6 @@
#define E1000_PBA_34K 0x0022
#define E1000_PBA_64K 0x0040 /* 64KB */
-#define IFS_MAX 80
-#define IFS_MIN 40
-#define IFS_RATIO 4
-#define IFS_STEP 10
-#define MIN_NUM_XMITS 1000
-
/* SW Semaphore Register */
#define E1000_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index dbaeb5f..4480052 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -339,19 +339,12 @@ struct e1000_mac_info {
enum e1000_mac_type type;
- u32 collision_delta;
u32 ledctl_default;
u32 ledctl_mode1;
u32 ledctl_mode2;
u32 mc_filter_type;
- u32 tx_packet_delta;
u32 txcw;
- u16 current_ifs_val;
- u16 ifs_max_val;
- u16 ifs_min_val;
- u16 ifs_ratio;
- u16 ifs_step_size;
u16 mta_reg_count;
u16 uta_reg_count;
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 2ad358a..2a8a886 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -1304,76 +1304,6 @@ out:
}
/**
- * igb_reset_adaptive - Reset Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Reset the Adaptive Interframe Spacing throttle to default values.
- **/
-void igb_reset_adaptive(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- if (!mac->adaptive_ifs) {
- hw_dbg("Not in Adaptive IFS mode!\n");
- goto out;
- }
-
- if (!mac->ifs_params_forced) {
- mac->current_ifs_val = 0;
- mac->ifs_min_val = IFS_MIN;
- mac->ifs_max_val = IFS_MAX;
- mac->ifs_step_size = IFS_STEP;
- mac->ifs_ratio = IFS_RATIO;
- }
-
- mac->in_ifs_mode = false;
- wr32(E1000_AIT, 0);
-out:
- return;
-}
-
-/**
- * igb_update_adaptive - Update Adaptive Interframe Spacing
- * @hw: pointer to the HW structure
- *
- * Update the Adaptive Interframe Spacing Throttle value based on the
- * time between transmitted packets and time between collisions.
- **/
-void igb_update_adaptive(struct e1000_hw *hw)
-{
- struct e1000_mac_info *mac = &hw->mac;
-
- if (!mac->adaptive_ifs) {
- hw_dbg("Not in Adaptive IFS mode!\n");
- goto out;
- }
-
- if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) {
- if (mac->tx_packet_delta > MIN_NUM_XMITS) {
- mac->in_ifs_mode = true;
- if (mac->current_ifs_val < mac->ifs_max_val) {
- if (!mac->current_ifs_val)
- mac->current_ifs_val = mac->ifs_min_val;
- else
- mac->current_ifs_val +=
- mac->ifs_step_size;
- wr32(E1000_AIT,
- mac->current_ifs_val);
- }
- }
- } else {
- if (mac->in_ifs_mode &&
- (mac->tx_packet_delta <= MIN_NUM_XMITS)) {
- mac->current_ifs_val = 0;
- mac->in_ifs_mode = false;
- wr32(E1000_AIT, 0);
- }
- }
-out:
- return;
-}
-
-/**
* igb_validate_mdi_setting - Verify MDI/MDIx settings
* @hw: pointer to the HW structure
*
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index bca17d8..601be99 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -67,8 +67,6 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
void igb_put_hw_semaphore(struct e1000_hw *hw);
void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
s32 igb_check_alt_mac_addr(struct e1000_hw *hw);
-void igb_reset_adaptive(struct e1000_hw *hw);
-void igb_update_adaptive(struct e1000_hw *hw);
bool igb_enable_mng_pass_thru(struct e1000_hw *hw);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 30fb5a8..eb48e1a 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1365,7 +1365,6 @@ void igb_reset(struct igb_adapter *adapter)
/* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */
wr32(E1000_VET, ETHERNET_IEEE_VLAN_TYPE);
- igb_reset_adaptive(hw);
igb_get_phy_info(hw);
}
@@ -1508,7 +1507,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
igb_get_bus_info_pcie(hw);
hw->phy.autoneg_wait_to_complete = false;
- hw->mac.adaptive_ifs = true;
/* Copper options */
if (hw->phy.media_type == e1000_media_type_copper) {
@@ -3159,7 +3157,6 @@ static void igb_watchdog_task(struct work_struct *work)
}
igb_update_stats(adapter);
- igb_update_adaptive(hw);
for (i = 0; i < adapter->num_tx_queues; i++) {
struct igb_ring *tx_ring = adapter->tx_ring[i];
@@ -4064,11 +4061,8 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.mptc += rd32(E1000_MPTC);
adapter->stats.bptc += rd32(E1000_BPTC);
- /* used for adaptive IFS */
- hw->mac.tx_packet_delta = rd32(E1000_TPT);
- adapter->stats.tpt += hw->mac.tx_packet_delta;
- hw->mac.collision_delta = rd32(E1000_COLC);
- adapter->stats.colc += hw->mac.collision_delta;
+ adapter->stats.tpt += rd32(E1000_TPT);
+ adapter->stats.colc += rd32(E1000_COLC);
adapter->stats.algnerrc += rd32(E1000_ALGNERRC);
adapter->stats.rxerrc += rd32(E1000_RXERRC);
^ permalink raw reply related
* [net-next-2.6 PATCH 09/18] igb: cap interrupts at 20K per queue when in itr mode 3
From: Jeff Kirsher @ 2010-02-17 11:03 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
In order to maintain similar performance between MSI-X and
legacy/MSI interrupts, this patch reduces the number of interrupts
when receiving small packets to 20K when in interrupt throttle
rate mode 3.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index eb48e1a..4ccc7fc 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3260,6 +3260,10 @@ static void igb_update_ring_itr(struct igb_q_vector *q_vector)
else
new_val = avg_wire_size / 2;
+ /* when in itr mode 3 do not exceed 20K ints/sec */
+ if (adapter->rx_itr_setting == 3 && new_val < 196)
+ new_val = 196;
+
set_itr_val:
if (new_val != q_vector->itr_val) {
q_vector->itr_val = new_val;
^ permalink raw reply related
* [net-next-2.6 PATCH 10/18] igb: only support SRRCTL_DROP_EN when using multiple queues
From: Jeff Kirsher @ 2010-02-17 11:03 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
The SRRCTL.DROP_EN bit should only be set when we are supporting
multiple queues. This bit is meant to prevent head of line blocking
and is unnecessary in the single queue case.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 4ccc7fc..b989b34 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2595,6 +2595,9 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
E1000_SRRCTL_BSIZEPKT_SHIFT;
srrctl |= E1000_SRRCTL_DESCTYPE_ADV_ONEBUF;
}
+ /* Only set Drop Enable if we are supporting multiple queues */
+ if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
+ srrctl |= E1000_SRRCTL_DROP_EN;
wr32(E1000_SRRCTL(reg_idx), srrctl);
^ permalink raw reply related
* [net-next-2.6 PATCH 11/18] igb: only read phy specific stats if in internal phy mode
From: Jeff Kirsher @ 2010-02-17 11:03 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
There are a couple statistics registers that are not meant to
be read when in SGMII/serdes mode. This patch adds a check to
verify mode before reading and updating these statistics.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b989b34..cba0115 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3975,7 +3975,7 @@ void igb_update_stats(struct igb_adapter *adapter)
struct net_device_stats *net_stats = igb_get_stats(adapter->netdev);
struct e1000_hw *hw = &adapter->hw;
struct pci_dev *pdev = adapter->pdev;
- u32 rnbc;
+ u32 rnbc, reg;
u16 phy_tmp;
int i;
u64 bytes, packets;
@@ -4072,8 +4072,13 @@ void igb_update_stats(struct igb_adapter *adapter)
adapter->stats.colc += rd32(E1000_COLC);
adapter->stats.algnerrc += rd32(E1000_ALGNERRC);
- adapter->stats.rxerrc += rd32(E1000_RXERRC);
- adapter->stats.tncrs += rd32(E1000_TNCRS);
+ /* read internal phy specific stats */
+ reg = rd32(E1000_CTRL_EXT);
+ if (!(reg & E1000_CTRL_EXT_LINK_MODE_MASK)) {
+ adapter->stats.rxerrc += rd32(E1000_RXERRC);
+ adapter->stats.tncrs += rd32(E1000_TNCRS);
+ }
+
adapter->stats.tsctc += rd32(E1000_TSCTC);
adapter->stats.tsctfc += rd32(E1000_TSCTFC);
^ permalink raw reply related
* [net-next-2.6 PATCH 12/18] igb: inline igb_maybe_stop_tx
From: Jeff Kirsher @ 2010-02-17 11:04 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
igb_maybe_stop_tx() is extremely small and appears in several spots in
the tx hotpath. This change inlines the function for a possible
performance boost.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index cba0115..a1fe581 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3758,7 +3758,7 @@ static int __igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
return 0;
}
-static int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
+static inline int igb_maybe_stop_tx(struct igb_ring *tx_ring, int size)
{
if (igb_desc_unused(tx_ring) >= size)
return 0;
^ permalink raw reply related
* [net-next-2.6 PATCH 13/18] igb: move gso_segs into buffer_info structure
From: Jeff Kirsher @ 2010-02-17 11:04 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This change moves gso_segs into the buffer_info structure to avoid
a possible cache line miss in clean_tx_irq.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb.h | 1 +
drivers/net/igb/igb_main.c | 3 ++-
2 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 8f07bc0..7854b66 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -141,6 +141,7 @@ struct igb_buffer {
u16 length;
u16 next_to_watch;
u16 mapped_as_page;
+ u16 gso_segs;
};
/* RX */
struct {
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index a1fe581..91c123f 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3641,6 +3641,7 @@ static inline int igb_tx_map_adv(struct igb_ring *tx_ring, struct sk_buff *skb,
}
tx_ring->buffer_info[i].skb = skb;
+ tx_ring->buffer_info[i].gso_segs = skb_shinfo(skb)->gso_segs ?: 1;
tx_ring->buffer_info[first].next_to_watch = i;
return ++count;
@@ -5032,7 +5033,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
if (skb) {
unsigned int segs, bytecount;
/* gso_segs is currently only valid for tcp */
- segs = skb_shinfo(skb)->gso_segs ?: 1;
+ segs = buffer_info->gso_segs;
/* multiply data chunks by size of headers */
bytecount = ((segs - 1) * skb_headlen(skb)) +
skb->len;
^ permalink raw reply related
* [net-next-2.6 PATCH 14/18] igb: minor type cleanups
From: Jeff Kirsher @ 2010-02-17 11:04 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This change cleans up some instances where unsigned int and u32
were being used interchangeably, and cleans up hdr_len which
was being set to 0 twice.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 91c123f..ff392e9 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3434,8 +3434,8 @@ static inline int igb_tso_adv(struct igb_ring *tx_ring,
int err;
struct igb_buffer *buffer_info;
u32 info = 0, tu_cmd = 0;
- u32 mss_l4len_idx, l4len;
- *hdr_len = 0;
+ u32 mss_l4len_idx;
+ u8 l4len;
if (skb_header_cloned(skb)) {
err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
@@ -3671,7 +3671,7 @@ dma_error:
}
static inline void igb_tx_queue_adv(struct igb_ring *tx_ring,
- int tx_flags, int count, u32 paylen,
+ u32 tx_flags, int count, u32 paylen,
u8 hdr_len)
{
union e1000_adv_tx_desc *tx_desc;
@@ -3770,10 +3770,10 @@ netdev_tx_t igb_xmit_frame_ring_adv(struct sk_buff *skb,
struct igb_ring *tx_ring)
{
struct igb_adapter *adapter = netdev_priv(tx_ring->netdev);
- unsigned int first;
- unsigned int tx_flags = 0;
- u8 hdr_len = 0;
int tso = 0, count;
+ u32 tx_flags = 0;
+ u16 first;
+ u8 hdr_len = 0;
union skb_shared_tx *shtx = skb_tx(skb);
/* need: 1 descriptor per page,
^ permalink raw reply related
* [net-next-2.6 PATCH 15/18] igb: remove unused vmolr value
From: Jeff Kirsher @ 2010-02-17 11:05 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
In an earlier version of igb_write_mc_addr_list() the vmolr register
was modified. This register is no longer accessed, although the variable
still exists. This patch removes it from the function.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index ff392e9..a9f4e02 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -2883,7 +2883,6 @@ static int igb_write_mc_addr_list(struct net_device *netdev)
struct e1000_hw *hw = &adapter->hw;
struct dev_mc_list *mc_ptr = netdev->mc_list;
u8 *mta_list;
- u32 vmolr = 0;
int i;
if (netdev_mc_empty(netdev)) {
@@ -2897,9 +2896,6 @@ static int igb_write_mc_addr_list(struct net_device *netdev)
if (!mta_list)
return -ENOMEM;
- /* set vmolr receive overflow multicast bit */
- vmolr |= E1000_VMOLR_ROMPE;
-
/* The shared function expects a packed array of only addresses. */
mc_ptr = netdev->mc_list;
^ permalink raw reply related
* [net-next-2.6 PATCH 16/18] igb: use igb_free_q_vectors to cleanup failure in igb_alloc_q_vectors
From: Jeff Kirsher @ 2010-02-17 11:05 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This change makes it so that igb_free_q_vectors is reused in
igb_alloc_q_vectors to handle the cleanup instead of unwinding
through the allocations.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index a9f4e02..ab7c5e9 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -649,6 +649,8 @@ static void igb_free_q_vectors(struct igb_adapter *adapter)
for (v_idx = 0; v_idx < adapter->num_q_vectors; v_idx++) {
struct igb_q_vector *q_vector = adapter->q_vector[v_idx];
adapter->q_vector[v_idx] = NULL;
+ if (!q_vector)
+ continue;
netif_napi_del(&q_vector->napi);
kfree(q_vector);
}
@@ -768,13 +770,7 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter)
return 0;
err_out:
- while (v_idx) {
- v_idx--;
- q_vector = adapter->q_vector[v_idx];
- netif_napi_del(&q_vector->napi);
- kfree(q_vector);
- adapter->q_vector[v_idx] = NULL;
- }
+ igb_free_q_vectors(adapter);
return -ENOMEM;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 17/18] igb: change descriptor control thresholds
From: Jeff Kirsher @ 2010-02-17 11:05 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This change simplifies the code by setting RX_PTHRESH to 8 for
all devices, as it was unlikely that there was any advantage to
set it at 16 for earlier cards. Additionally TX_WTHRESH is
set to 1 for the 82576 NIC to improve performance by enabling
a minimal amount of write combining when writing back descriptors.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 7854b66..a177570 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -95,13 +95,13 @@ struct vf_data_storage {
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
-#define IGB_RX_PTHRESH (hw->mac.type <= e1000_82576 ? 16 : 8)
+#define IGB_RX_PTHRESH 8
#define IGB_RX_HTHRESH 8
#define IGB_RX_WTHRESH 1
#define IGB_TX_PTHRESH 8
#define IGB_TX_HTHRESH 1
#define IGB_TX_WTHRESH ((hw->mac.type == e1000_82576 && \
- adapter->msix_entries) ? 0 : 16)
+ adapter->msix_entries) ? 1 : 16)
/* this is the size past which hardware will drop packets when setting LPE=0 */
#define MAXIMUM_ETHERNET_VLAN_SIZE 1522
^ permalink raw reply related
* [net-next-2.6 PATCH 18/18] igb: update tx DMA mapping error handling
From: Jeff Kirsher @ 2010-02-17 11:06 UTC (permalink / raw)
To: davem; +Cc: netdev, gospo, Nicholas Nunley, Jeff Kirsher
In-Reply-To: <20100217105953.17723.36633.stgit@localhost.localdomain>
From: Nick Nunley <nicholasx.d.nunley@intel.com>
This updates the tx DMA mapping error handling code to
resemble e1000e/ixgbe.
Signed-off-by: Nicholas Nunley <nicholasx.d.nunley@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/igb/igb_main.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index ab7c5e9..f588e49 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -3647,14 +3647,12 @@ dma_error:
buffer_info->length = 0;
buffer_info->next_to_watch = 0;
buffer_info->mapped_as_page = false;
- count--;
/* clear timestamp and dma mappings for remaining portion of packet */
- while (count >= 0) {
- count--;
+ while (count--) {
+ if (i == 0)
+ i = tx_ring->count;
i--;
- if (i < 0)
- i += tx_ring->count;
buffer_info = &tx_ring->buffer_info[i];
igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
}
^ permalink raw reply related
* [PATCH net-next-2.6 1/4] be2net: a mini optimization in rx_compl_process() code
From: Sathya Perla @ 2010-02-17 11:34 UTC (permalink / raw)
To: netdev
Introduce unlikely() for skb alloc failure and vlanf checks...
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be_main.c | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index cbfaa3f..7bf1900 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -768,16 +768,8 @@ static void be_rx_compl_process(struct be_adapter *adapter,
u32 vlanf, vid;
u8 vtm;
- vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
- vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
-
- /* vlanf could be wrongly set in some cards.
- * ignore if vtm is not set */
- if ((adapter->cap & 0x400) && !vtm)
- vlanf = 0;
-
skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
- if (!skb) {
+ if (unlikely(!skb)) {
if (net_ratelimit())
dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
be_rx_compl_discard(adapter, rxcp);
@@ -795,7 +787,15 @@ static void be_rx_compl_process(struct be_adapter *adapter,
skb->protocol = eth_type_trans(skb, adapter->netdev);
skb->dev = adapter->netdev;
- if (vlanf) {
+ vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
+ vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp);
+
+ /* vlanf could be wrongly set in some cards.
+ * ignore if vtm is not set */
+ if ((adapter->cap & 0x400) && !vtm)
+ vlanf = 0;
+
+ if (unlikely(vlanf)) {
if (!adapter->vlan_grp || adapter->vlans_added == 0) {
kfree_skb(skb);
return;
--
1.6.3.3
^ permalink raw reply related
* [PATCH net-next-2.6 2/4] be2net: don't rearm mcc cq when device is not open
From: Sathya Perla @ 2010-02-17 11:35 UTC (permalink / raw)
To: netdev
When an MCC cmd is issued (via a netdev/ethtool op)
while the device is not open, the MCC CQ gets processed but the EQ
is not processed (as isr is not registered.) This can cause the EQ
to become full. So, while the device is not open, CQ must not be re-armed
to prevent EQ entries.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be.h | 1 +
drivers/net/benet/be_cmds.c | 20 ++++++++++++++++++--
drivers/net/benet/be_cmds.h | 2 ++
drivers/net/benet/be_main.c | 5 +++++
4 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 5038c16..2734a41 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -151,6 +151,7 @@ struct be_eq_obj {
struct be_mcc_obj {
struct be_queue_info q;
struct be_queue_info cq;
+ bool rearm_cq;
};
struct be_drvr_stats {
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 477f82b..d7546b4 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -104,10 +104,26 @@ static struct be_mcc_compl *be_mcc_compl_get(struct be_adapter *adapter)
return NULL;
}
+void be_async_mcc_enable(struct be_adapter *adapter)
+{
+ spin_lock_bh(&adapter->mcc_cq_lock);
+
+ be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, 0);
+ adapter->mcc_obj.rearm_cq = true;
+
+ spin_unlock_bh(&adapter->mcc_cq_lock);
+}
+
+void be_async_mcc_disable(struct be_adapter *adapter)
+{
+ adapter->mcc_obj.rearm_cq = false;
+}
+
int be_process_mcc(struct be_adapter *adapter)
{
struct be_mcc_compl *compl;
int num = 0, status = 0;
+ struct be_mcc_obj *mcc_obj = &adapter->mcc_obj;
spin_lock_bh(&adapter->mcc_cq_lock);
while ((compl = be_mcc_compl_get(adapter))) {
@@ -120,14 +136,14 @@ int be_process_mcc(struct be_adapter *adapter)
(struct be_async_event_link_state *) compl);
} else if (compl->flags & CQE_FLAGS_COMPLETED_MASK) {
status = be_mcc_compl_process(adapter, compl);
- atomic_dec(&adapter->mcc_obj.q.used);
+ atomic_dec(&mcc_obj->q.used);
}
be_mcc_compl_use(compl);
num++;
}
if (num)
- be_cq_notify(adapter, adapter->mcc_obj.cq.id, true, num);
+ be_cq_notify(adapter, mcc_obj->cq.id, mcc_obj->rearm_cq, num);
spin_unlock_bh(&adapter->mcc_cq_lock);
return status;
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 7297b5a..01501db 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -937,6 +937,8 @@ extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
struct be_dma_mem *nonemb_cmd);
extern int be_cmd_fw_init(struct be_adapter *adapter);
extern int be_cmd_fw_clean(struct be_adapter *adapter);
+extern void be_async_mcc_enable(struct be_adapter *adapter);
+extern void be_async_mcc_disable(struct be_adapter *adapter);
extern int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
u32 loopback_type, u32 pkt_size,
u32 num_pkts, u64 pattern);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 7bf1900..43dbe28 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1655,6 +1655,9 @@ static int be_open(struct net_device *netdev)
/* Rx compl queue may be in unarmed state; rearm it */
be_cq_notify(adapter, adapter->rx_obj.cq.id, true, 0);
+ /* Now that interrupts are on we can process async mcc */
+ be_async_mcc_enable(adapter);
+
status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
&link_speed);
if (status)
@@ -1780,6 +1783,8 @@ static int be_close(struct net_device *netdev)
cancel_delayed_work_sync(&adapter->work);
+ be_async_mcc_disable(adapter);
+
netif_stop_queue(netdev);
netif_carrier_off(netdev);
adapter->link_up = false;
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] atm : fix /sys/devices/virtual/atm/X/carrier(ATM_PHY_SIG_UNKNOWN)
From: Philippe De Muyter @ 2010-02-17 11:35 UTC (permalink / raw)
To: David Miller; +Cc: chas3, chas, netdev
In-Reply-To: <20100216.221651.189702430.davem@davemloft.net>
Hi Chas, David,
On Tue, Feb 16, 2010 at 10:16:51PM -0800, David Miller wrote:
> From: "Chas Williams (CONTRACTOR)" <chas@cmf.nrl.navy.mil>
> Date: Sun, 14 Feb 2010 16:34:40 -0500
>
> > as i said before there is carrier or there is not. if the driver
> > doesnt support checking/knowing the carrier status it should simply
> > say 'yes i have carrier'.
>
> I agree %100 and this is how we handle similar situations
> for other networking device types.
I also agree 100% with that : the low-level driver must do that, not the
generic class driver. Here cxacru is punished because other atm drivers
forget to set signal = ATM_PHY_SIG_FOUND.
Philippe
^ permalink raw reply
* [PATCH net-next-2.6 3/4] be2net: fix rx-path to ignore a flush completion
From: Sathya Perla @ 2010-02-17 11:35 UTC (permalink / raw)
To: netdev
The flush compl (compl with numfrags == 0; no data) is rcvd
from hw to indicate completion of RXQ destory operation. Fix
the RX path to not process it as RX data.
Signed-off-by: Sathya Perla <sathyap@serverengines.com>
---
drivers/net/benet/be_main.c | 23 +++++++++++++++++++----
1 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 43dbe28..0ce2c26 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -680,17 +680,17 @@ static void be_rx_compl_discard(struct be_adapter *adapter,
* indicated by rxcp.
*/
static void skb_fill_rx_data(struct be_adapter *adapter,
- struct sk_buff *skb, struct be_eth_rx_compl *rxcp)
+ struct sk_buff *skb, struct be_eth_rx_compl *rxcp,
+ u16 num_rcvd)
{
struct be_queue_info *rxq = &adapter->rx_obj.q;
struct be_rx_page_info *page_info;
- u16 rxq_idx, i, num_rcvd, j;
+ u16 rxq_idx, i, j;
u32 pktsize, hdr_len, curr_frag_len, size;
u8 *start;
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
- num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
page_info = get_rx_page_info(adapter, rxq_idx);
@@ -766,8 +766,14 @@ static void be_rx_compl_process(struct be_adapter *adapter,
{
struct sk_buff *skb;
u32 vlanf, vid;
+ u16 num_rcvd;
u8 vtm;
+ num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+ /* Is it a flush compl that has no data */
+ if (unlikely(num_rcvd == 0))
+ return;
+
skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
if (unlikely(!skb)) {
if (net_ratelimit())
@@ -776,7 +782,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
return;
}
- skb_fill_rx_data(adapter, skb, rxcp);
+ skb_fill_rx_data(adapter, skb, rxcp, num_rcvd);
if (do_pkt_csum(rxcp, adapter->rx_csum))
skb->ip_summed = CHECKSUM_NONE;
@@ -823,6 +829,10 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter,
u8 vtm;
num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp);
+ /* Is it a flush compl that has no data */
+ if (unlikely(num_rcvd == 0))
+ return;
+
pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp);
vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp);
@@ -1273,6 +1283,11 @@ static void be_rx_queues_destroy(struct be_adapter *adapter)
q = &adapter->rx_obj.q;
if (q->created) {
be_cmd_q_destroy(adapter, q, QTYPE_RXQ);
+
+ /* After the rxq is invalidated, wait for a grace time
+ * of 1ms for all dma to end and the flush compl to arrive
+ */
+ mdelay(1);
be_rx_q_clean(adapter);
}
be_queue_free(adapter, q);
--
1.6.3.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox