Netdev List
 help / color / mirror / Atom feed
* Re: [net-2.6 PATCH 2/6] e1000e: 82579 SMBus address and LEDs incorrect after device reset
From: David Miller @ 2010-09-23  4:10 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, bphilips, bruce.w.allan
In-Reply-To: <20100923031532.10976.41477.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 22 Sep 2010 20:15:33 -0700

> From: Bruce Allan <bruce.w.allan@intel.com>
> 
> Since the hardware is prevented from performing automatic PHY configuration
> (the driver does it instead), the OEM_WRITE_ENABLE bit in the EXTCNF_CTRL
> register will not get cleared preventing the SMBus address and the LED
> configuration to be written to the PHY registers.  On 82579, do not check
> the OEM_WRITE_ENABLE bit.
> 
> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [net-2.6 PATCH 1/6] e1000e: 82577/8/9 issues with device in Sx
From: David Miller @ 2010-09-23  4:10 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, bphilips, bruce.w.allan
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 22 Sep 2010 20:15:08 -0700

> From: Bruce Allan <bruce.w.allan@intel.com>
> 
> When going to Sx, disable gigabit in PHY (e1000_oem_bits_config_ich8lan)
> in addition to the MAC before configuring PHY wakeup otherwise the PHY
> configuration writes might be missed.  Also write the LED configuration
> and SMBus address to the PHY registers (e1000_oem_bits_config_ich8lan and
> e1000_write_smbus_addr, respectively).  The reset is no longer needed
> since re-auto-negotiation is forced in e1000_oem_bits_config_ich8lan and
> leaving it in causes issues with auto-negotiating the link.
> 
> Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* [net-next-2.6 PATCH] e1000/e1000e/igb/ixgb/ixgbe: set NETIF_F_HIGHDMA for VLAN feature flags
From: Jeff Kirsher @ 2010-09-23  3:57 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Yi Zou, Jeff Kirsher

From: Yi Zou <yi.zou@intel.com>

If the netdev->features is set with NETIF_F_HIGHDMA, we should set the
corresponding netdev->vlan_features as well to allow VLAN netdev created
on top of the real netdev to be able to also benefit from HIGHDMA on 32bit
system, reducing the performance hit that is caused by __skb_linearize(),
particularly for large send. This is fixed in this patch for all Intel e1000,
e1000e, igb, ixgbe, and ixgbe drivers since this should be beneficial
to all devices supported by these drivers.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000/e1000_main.c |    4 +++-
 drivers/net/e1000e/netdev.c    |    4 +++-
 drivers/net/igb/igb_main.c     |    4 +++-
 drivers/net/ixgb/ixgb_main.c   |    4 +++-
 drivers/net/ixgbe/ixgbe_main.c |    4 +++-
 5 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 8d9269d..a1dacea 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -988,8 +988,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	   (hw->mac_type != e1000_82547))
 		netdev->features |= NETIF_F_TSO;
 
-	if (pci_using_dac)
+	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_HW_CSUM;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e2c7e0d..4630bad 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -5683,8 +5683,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	netdev->vlan_features |= NETIF_F_HW_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
-	if (pci_using_dac)
+	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 	if (e1000e_enable_mng_pass_thru(&adapter->hw))
 		adapter->flags |= FLAG_MNG_PT_ENABLED;
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 61892b8..f915e9c 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -1858,8 +1858,10 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 	netdev->vlan_features |= NETIF_F_IPV6_CSUM;
 	netdev->vlan_features |= NETIF_F_SG;
 
-	if (pci_using_dac)
+	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 	if (hw->mac.type >= e1000_82576)
 		netdev->features |= NETIF_F_SCTP_CSUM;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index c2f6e71..80e6257 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -446,8 +446,10 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			   NETIF_F_HW_VLAN_FILTER;
 	netdev->features |= NETIF_F_TSO;
 
-	if (pci_using_dac)
+	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 	/* make sure the EEPROM is good */
 
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index d03eef9..0ec4ef2 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6842,8 +6842,10 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 		netdev->vlan_features |= NETIF_F_FCOE_MTU;
 	}
 #endif /* IXGBE_FCOE */
-	if (pci_using_dac)
+	if (pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
+		netdev->vlan_features |= NETIF_F_HIGHDMA;
+	}
 
 	if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
 		netdev->features |= NETIF_F_LRO;


^ permalink raw reply related

* [net-next-2.6 PATCH 2/2] igb: Add support for DH89xxCC
From: Jeff Kirsher @ 2010-09-23  3:56 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Joseph Gasparakis, Jeff Kirsher
In-Reply-To: <20100923035538.11511.16233.stgit@localhost.localdomain>

From: Joseph Gasparakis <joseph.gasparakis@intel.com>

This patch adds support for the Intel(r) DH89xxCC series. The new
device will be using Intel(r) i347-AT4 and Marvell(r) M88E1322 and
M88E1112 PHYs. Support for these devices has also been added here.

Signed-off-by: Joseph Gasparakis <joseph.gasparakis@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/e1000_82575.c   |   18 +++
 drivers/net/igb/e1000_defines.h |   31 ++++++
 drivers/net/igb/e1000_hw.h      |    2 
 drivers/net/igb/e1000_phy.c     |  206 +++++++++++++++++++++++++++++++++++++--
 drivers/net/igb/e1000_phy.h     |    2 
 drivers/net/igb/igb_main.c      |    2 
 6 files changed, 247 insertions(+), 14 deletions(-)

diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index 187622f..bc183f5 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -132,6 +132,8 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 	case E1000_DEV_ID_82580_SERDES:
 	case E1000_DEV_ID_82580_SGMII:
 	case E1000_DEV_ID_82580_COPPER_DUAL:
+	case E1000_DEV_ID_DH89XXCC_SGMII:
+	case E1000_DEV_ID_DH89XXCC_SERDES:
 		mac->type = e1000_82580;
 		break;
 	case E1000_DEV_ID_I350_COPPER:
@@ -282,10 +284,18 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
 
 	/* Verify phy id and set remaining function pointers */
 	switch (phy->id) {
+	case I347AT4_E_PHY_ID:
+	case M88E1112_E_PHY_ID:
 	case M88E1111_I_PHY_ID:
 		phy->type                   = e1000_phy_m88;
 		phy->ops.get_phy_info       = igb_get_phy_info_m88;
-		phy->ops.get_cable_length   = igb_get_cable_length_m88;
+
+		if (phy->id == I347AT4_E_PHY_ID ||
+		    phy->id == M88E1112_E_PHY_ID)
+			phy->ops.get_cable_length = igb_get_cable_length_m88_gen2;
+		else
+			phy->ops.get_cable_length = igb_get_cable_length_m88;
+
 		phy->ops.force_speed_duplex = igb_phy_force_speed_duplex_m88;
 		break;
 	case IGP03E1000_E_PHY_ID:
@@ -1058,7 +1068,11 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
 	}
 	switch (hw->phy.type) {
 	case e1000_phy_m88:
-		ret_val = igb_copper_link_setup_m88(hw);
+		if (hw->phy.id == I347AT4_E_PHY_ID ||
+		    hw->phy.id == M88E1112_E_PHY_ID)
+			ret_val = igb_copper_link_setup_m88_gen2(hw);
+		else
+			ret_val = igb_copper_link_setup_m88(hw);
 		break;
 	case e1000_phy_igp_3:
 		ret_val = igb_copper_link_setup_igp(hw);
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index bbd2ec3..6222279 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -634,6 +634,8 @@
  * E = External
  */
 #define M88E1111_I_PHY_ID    0x01410CC0
+#define M88E1112_E_PHY_ID    0x01410C90
+#define I347AT4_E_PHY_ID     0x01410DC0
 #define IGP03E1000_E_PHY_ID  0x02A80390
 #define I82580_I_PHY_ID      0x015403A0
 #define I350_I_PHY_ID        0x015403B0
@@ -702,6 +704,35 @@
 #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
 #define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
 
+/* Intel i347-AT4 Registers */
+
+#define I347AT4_PCDL                   0x10 /* PHY Cable Diagnostics Length */
+#define I347AT4_PCDC                   0x15 /* PHY Cable Diagnostics Control */
+#define I347AT4_PAGE_SELECT            0x16
+
+/* i347-AT4 Extended PHY Specific Control Register */
+
+/*
+ *  Number of times we will attempt to autonegotiate before downshifting if we
+ *  are the master
+ */
+#define I347AT4_PSCR_DOWNSHIFT_ENABLE 0x0800
+#define I347AT4_PSCR_DOWNSHIFT_MASK   0x7000
+#define I347AT4_PSCR_DOWNSHIFT_1X     0x0000
+#define I347AT4_PSCR_DOWNSHIFT_2X     0x1000
+#define I347AT4_PSCR_DOWNSHIFT_3X     0x2000
+#define I347AT4_PSCR_DOWNSHIFT_4X     0x3000
+#define I347AT4_PSCR_DOWNSHIFT_5X     0x4000
+#define I347AT4_PSCR_DOWNSHIFT_6X     0x5000
+#define I347AT4_PSCR_DOWNSHIFT_7X     0x6000
+#define I347AT4_PSCR_DOWNSHIFT_8X     0x7000
+
+/* i347-AT4 PHY Cable Diagnostics Control */
+#define I347AT4_PCDC_CABLE_LENGTH_UNIT 0x0400 /* 0=cm 1=meters */
+
+/* Marvell 1112 only registers */
+#define M88E1112_VCT_DSP_DISTANCE       0x001A
+
 /* M88EC018 Rev 2 specific DownShift settings */
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index cb8db78..c0b017f 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -54,6 +54,8 @@ struct e1000_hw;
 #define E1000_DEV_ID_82580_SERDES             0x1510
 #define E1000_DEV_ID_82580_SGMII              0x1511
 #define E1000_DEV_ID_82580_COPPER_DUAL        0x1516
+#define E1000_DEV_ID_DH89XXCC_SGMII           0x0436
+#define E1000_DEV_ID_DH89XXCC_SERDES          0x0438
 #define E1000_DEV_ID_I350_COPPER              0x1521
 #define E1000_DEV_ID_I350_FIBER               0x1522
 #define E1000_DEV_ID_I350_SERDES              0x1523
diff --git a/drivers/net/igb/e1000_phy.c b/drivers/net/igb/e1000_phy.c
index cf1f323..ddd036a 100644
--- a/drivers/net/igb/e1000_phy.c
+++ b/drivers/net/igb/e1000_phy.c
@@ -570,6 +570,89 @@ out:
 }
 
 /**
+ *  igb_copper_link_setup_m88_gen2 - Setup m88 PHY's for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets up MDI/MDI-X and polarity for i347-AT4, m88e1322 and m88e1112 PHY's.
+ *  Also enables and sets the downshift parameters.
+ **/
+s32 igb_copper_link_setup_m88_gen2(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data;
+
+	if (phy->reset_disable) {
+		ret_val = 0;
+		goto out;
+	}
+
+	/* Enable CRS on Tx. This must be set for half-duplex operation. */
+	ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
+	if (ret_val)
+		goto out;
+
+	/*
+	 * Options:
+	 *   MDI/MDI-X = 0 (default)
+	 *   0 - Auto for all speeds
+	 *   1 - MDI mode
+	 *   2 - MDI-X mode
+	 *   3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes)
+	 */
+	phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
+
+	switch (phy->mdix) {
+	case 1:
+		phy_data |= M88E1000_PSCR_MDI_MANUAL_MODE;
+		break;
+	case 2:
+		phy_data |= M88E1000_PSCR_MDIX_MANUAL_MODE;
+		break;
+	case 3:
+		/* M88E1112 does not support this mode) */
+		if (phy->id != M88E1112_E_PHY_ID) {
+			phy_data |= M88E1000_PSCR_AUTO_X_1000T;
+			break;
+		}
+	case 0:
+	default:
+		phy_data |= M88E1000_PSCR_AUTO_X_MODE;
+		break;
+	}
+
+	/*
+	 * Options:
+	 *   disable_polarity_correction = 0 (default)
+	 *       Automatic Correction for Reversed Cable Polarity
+	 *   0 - Disabled
+	 *   1 - Enabled
+	 */
+	phy_data &= ~M88E1000_PSCR_POLARITY_REVERSAL;
+	if (phy->disable_polarity_correction == 1)
+		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
+
+	/* Enable downshift and setting it to X6 */
+	phy_data &= ~I347AT4_PSCR_DOWNSHIFT_MASK;
+	phy_data |= I347AT4_PSCR_DOWNSHIFT_6X;
+	phy_data |= I347AT4_PSCR_DOWNSHIFT_ENABLE;
+
+	ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
+	if (ret_val)
+		goto out;
+
+	/* Commit the changes. */
+	ret_val = igb_phy_sw_reset(hw);
+	if (ret_val) {
+		hw_dbg("Error committing the PHY changes\n");
+		goto out;
+	}
+
+out:
+	return ret_val;
+}
+
+/**
  *  igb_copper_link_setup_igp - Setup igp PHY's for copper link
  *  @hw: pointer to the HW structure
  *
@@ -1124,18 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 			goto out;
 
 		if (!link) {
-			/*
-			 * We didn't get link.
-			 * Reset the DSP and cross our fingers.
-			 */
-			ret_val = phy->ops.write_reg(hw,
-						     M88E1000_PHY_PAGE_SELECT,
-						     0x001d);
-			if (ret_val)
-				goto out;
-			ret_val = igb_phy_reset_dsp(hw);
-			if (ret_val)
-				goto out;
+			if (hw->phy.type != e1000_phy_m88 ||
+			    hw->phy.id == I347AT4_E_PHY_ID ||
+			    hw->phy.id == M88E1112_E_PHY_ID) {
+				hw_dbg("Link taking longer than expected.\n");
+			} else {
+
+				/*
+				 * We didn't get link.
+				 * Reset the DSP and cross our fingers.
+				 */
+				ret_val = phy->ops.write_reg(hw,
+							     M88E1000_PHY_PAGE_SELECT,
+							     0x001d);
+				if (ret_val)
+					goto out;
+				ret_val = igb_phy_reset_dsp(hw);
+				if (ret_val)
+					goto out;
+			}
 		}
 
 		/* Try once more */
@@ -1145,6 +1235,11 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 			goto out;
 	}
 
+	if (hw->phy.type != e1000_phy_m88 ||
+	    hw->phy.id == I347AT4_E_PHY_ID ||
+	    hw->phy.id == M88E1112_E_PHY_ID)
+		goto out;
+
 	ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		goto out;
@@ -1557,6 +1652,93 @@ out:
 	return ret_val;
 }
 
+s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
+{
+	struct e1000_phy_info *phy = &hw->phy;
+	s32 ret_val;
+	u16 phy_data, phy_data2, index, default_page, is_cm;
+
+	switch (hw->phy.id) {
+	case I347AT4_E_PHY_ID:
+		/* Remember the original page select and set it to 7 */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
+					    &default_page);
+		if (ret_val)
+			goto out;
+
+		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x07);
+		if (ret_val)
+			goto out;
+
+		/* Get cable length from PHY Cable Diagnostics Control Reg */
+		ret_val = phy->ops.read_reg(hw, (I347AT4_PCDL + phy->addr),
+					    &phy_data);
+		if (ret_val)
+			goto out;
+
+		/* Check if the unit of cable length is meters or cm */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PCDC, &phy_data2);
+		if (ret_val)
+			goto out;
+
+		is_cm = !(phy_data & I347AT4_PCDC_CABLE_LENGTH_UNIT);
+
+		/* Populate the phy structure with cable length in meters */
+		phy->min_cable_length = phy_data / (is_cm ? 100 : 1);
+		phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
+		phy->cable_length = phy_data / (is_cm ? 100 : 1);
+
+		/* Reset the page selec to its original value */
+		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
+					     default_page);
+		if (ret_val)
+			goto out;
+		break;
+	case M88E1112_E_PHY_ID:
+		/* Remember the original page select and set it to 5 */
+		ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
+					    &default_page);
+		if (ret_val)
+			goto out;
+
+		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT, 0x05);
+		if (ret_val)
+			goto out;
+
+		ret_val = phy->ops.read_reg(hw, M88E1112_VCT_DSP_DISTANCE,
+					    &phy_data);
+		if (ret_val)
+			goto out;
+
+		index = (phy_data & M88E1000_PSSR_CABLE_LENGTH) >>
+			M88E1000_PSSR_CABLE_LENGTH_SHIFT;
+		if (index >= M88E1000_CABLE_LENGTH_TABLE_SIZE - 1) {
+			ret_val = -E1000_ERR_PHY;
+			goto out;
+		}
+
+		phy->min_cable_length = e1000_m88_cable_length_table[index];
+		phy->max_cable_length = e1000_m88_cable_length_table[index + 1];
+
+		phy->cable_length = (phy->min_cable_length +
+				     phy->max_cable_length) / 2;
+
+		/* Reset the page select to its original value */
+		ret_val = phy->ops.write_reg(hw, I347AT4_PAGE_SELECT,
+					     default_page);
+		if (ret_val)
+			goto out;
+
+		break;
+	default:
+		ret_val = -E1000_ERR_PHY;
+		goto out;
+	}
+
+out:
+	return ret_val;
+}
+
 /**
  *  igb_get_cable_length_igp_2 - Determine cable length for igp2 PHY
  *  @hw: pointer to the HW structure
diff --git a/drivers/net/igb/e1000_phy.h b/drivers/net/igb/e1000_phy.h
index 565a6db..2cc1177 100644
--- a/drivers/net/igb/e1000_phy.h
+++ b/drivers/net/igb/e1000_phy.h
@@ -45,9 +45,11 @@ s32  igb_check_downshift(struct e1000_hw *hw);
 s32  igb_check_reset_block(struct e1000_hw *hw);
 s32  igb_copper_link_setup_igp(struct e1000_hw *hw);
 s32  igb_copper_link_setup_m88(struct e1000_hw *hw);
+s32  igb_copper_link_setup_m88_gen2(struct e1000_hw *hw);
 s32  igb_phy_force_speed_duplex_igp(struct e1000_hw *hw);
 s32  igb_phy_force_speed_duplex_m88(struct e1000_hw *hw);
 s32  igb_get_cable_length_m88(struct e1000_hw *hw);
+s32  igb_get_cable_length_m88_gen2(struct e1000_hw *hw);
 s32  igb_get_cable_length_igp_2(struct e1000_hw *hw);
 s32  igb_get_phy_id(struct e1000_hw *hw);
 s32  igb_get_phy_info_igp(struct e1000_hw *hw);
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index fd922e7..61892b8 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -71,6 +71,8 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_SGMII), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82580_COPPER_DUAL), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SGMII), board_82575 },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_DH89XXCC_SERDES), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS), board_82575 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82576_NS_SERDES), board_82575 },


^ permalink raw reply related

* [net-next-2.6 PATCH 1/2] igb: clear VF_PROMISC bits instead of setting all other bits
From: Jeff Kirsher @ 2010-09-23  3:56 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Alexander Duyck, Jeff Kirsher

From: Alexander Duyck <alexander.h.duyck@intel.com>

This change corrects an issue in which we were setting all flag bits except
for promisc instead of clearing the promisc bits due to the incorrect use
of an |= instead of an &=.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/igb/igb_main.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index c4d861b..fd922e7 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -4659,12 +4659,13 @@ static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
 	u32 vmolr = rd32(E1000_VMOLR(vf));
 	struct vf_data_storage *vf_data = &adapter->vf_data[vf];
 
-	vf_data->flags |= ~(IGB_VF_FLAG_UNI_PROMISC |
+	vf_data->flags &= ~(IGB_VF_FLAG_UNI_PROMISC |
 	                    IGB_VF_FLAG_MULTI_PROMISC);
 	vmolr &= ~(E1000_VMOLR_ROPE | E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
 
 	if (*msgbuf & E1000_VF_SET_PROMISC_MULTICAST) {
 		vmolr |= E1000_VMOLR_MPME;
+		vf_data->flags |= IGB_VF_FLAG_MULTI_PROMISC;
 		*msgbuf &= ~E1000_VF_SET_PROMISC_MULTICAST;
 	} else {
 		/*


^ permalink raw reply related

* Re: [PATCH] net: fix a lockdep splat
From: David Miller @ 2010-09-23  3:53 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jarkao2, penguin-kernel, linux-fsdevel, netdev
In-Reply-To: <1285195419.2380.39.camel@edumazet-laptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 23 Sep 2010 00:43:39 +0200

> (A) (this is used in net/sunrpc/xprtsock.c)
> read_lock(&sk->sk_callback_lock) (without blocking BH)
> <BH>
> spin_lock(&sk->sk_slock.slock);
> ...
> read_lock(&sk->sk_callback_lock);
> ...

What's the exact path that leads to this?  I looked quickly and couldn't
find which sunrpc callback override does it.

Thanks.


^ permalink raw reply

* Re: [PATCH 0/6] netfilter: netfilter fixes
From: Patrick McHardy @ 2010-09-23  3:49 UTC (permalink / raw)
  To: David Miller; +Cc: netfilter-devel, netdev
In-Reply-To: <20100922.131232.59680750.davem@davemloft.net>

Am 22.09.2010 22:12, schrieb David Miller:
> From: kaber@trash.net
> Date: Wed, 22 Sep 2010 09:17:28 +0200
> 
>> Please apply or pull from:
>>
>> git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6.git master
> 
> Patrick I can't pull from this, it's not based upon net-2.6

Indeed, that's what I've always based my nf-2.6 tree on for one
or two years now, but this time I made a fresh clone at a quite
late time because of my absence.

> It looks like it's based upon Linus's tree, because when I pull
> I get a bunch of changes that are in Linus's tree but aren't
> in net-2.6

I didn't notice that, sorry.

> Please base all future pull requests on net-2.6, thanks.

Sure, will do.

> I'll apply these patches by hand (and also this will allow me
> to fix Eric's author email in that one patch).
> 
> Thanks again.

Thanks Dave!


^ permalink raw reply

* Re: [net-next-2.6 RFC PATCH] e1000e: NUMA changes, add Node= parameter
From: David Miller @ 2010-09-23  3:36 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, gospo, bphilips, jesse.brandeburg
In-Reply-To: <20100923032534.11274.77976.stgit@localhost.localdomain>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Wed, 22 Sep 2010 20:28:10 -0700

> Although a module parameter is not the preferred way for
> in-tree modules, this problem is not solvable in ethtool without
> mod params because of needing the information at probe time to
> control early allocations of memory.  Ideally there would even be
> a way to control the node where the memory of the netdev struct
> would be allocated also.

Sorry, no.

Various folks are working on infrastructure such that the Numa node of
everything other than the netdev struct can be dynamically choosen.

I'm sure we can find a way to dynamically reallocate and re-attach the
netdev structure as well.

^ permalink raw reply

* Re: [RFC PATCH] dont create cached routes from ARP requests
From: David Miller @ 2010-09-23  3:34 UTC (permalink / raw)
  To: uweber; +Cc: netdev
In-Reply-To: <20100922162209.GA10281@babylon>

From: Ulrich Weber <uweber@astaro.com>
Date: Wed, 22 Sep 2010 18:22:09 +0200

> Do we really have to cache routes based on ARP requests?
> Are there any other reasons than expecting new connections?
> 
> Attached is a patch to skip caching for ARP requests
> not related to local IP addresses or ARP proxy.
> 
> Background: At home I have two Internet connections, DSL and Cable.
> DSL is the primary uplink while Cable is the secondary.
> My Cable ISP is flooding me with ARP request from 10.0.0.0/8,
> which creates routes via the primary uplink.
> There are thousands of cached routes and after some time
> I get "Neighbour table overflow" messages.

If you get neighbour table overflows, something is holding a reference
to the routing cache entry and/or the neighbour entries those routing
cache entries are attached to.

If these really are transient entries, they should be trivially
garbage collected and not cause any problems at all.

^ permalink raw reply

* [net-next-2.6 RFC PATCH] e1000e: NUMA changes, add Node= parameter
From: Jeff Kirsher @ 2010-09-23  3:28 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Jesse Brandeburg, Jeff Kirsher

From: Jesse Brandeburg <jesse.brandeburg@intel.com>

NUMA changes associated with routing performance on 82571 and
x58/S5500 chipsets. Patch allows user to set new Node= parameter
that controls driver memory allocations for any port to a single
cpu/memory complex.  Since e1000e does not support multiple
queues this is a (relatively) simple implementation.

Although a module parameter is not the preferred way for
in-tree modules, this problem is not solvable in ethtool without
mod params because of needing the information at probe time to
control early allocations of memory.  Ideally there would even be
a way to control the node where the memory of the netdev struct
would be allocated also.

Special thanks to Emil Tantilov for testing, review and suggestions.

Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Emil Tantilov <emil.s.tantilov@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/e1000.h   |    1 +
 drivers/net/e1000e/ethtool.c |    6 ++++--
 drivers/net/e1000e/netdev.c  |   41 ++++++++++++++++++++++++++++-------------
 drivers/net/e1000e/param.c   |   36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index f9a31c8..6378da7 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -370,6 +370,7 @@ struct e1000_adapter {
 	struct work_struct print_hang_task;
 
 	bool idle_check;
+	int node; /* store the node to allocate memory on */
 };
 
 struct e1000_info {
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6355a1b..1f7fe31 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -690,7 +690,8 @@ static int e1000_set_ringparam(struct net_device *netdev,
 	rx_old = adapter->rx_ring;
 
 	err = -ENOMEM;
-	tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	tx_ring = kzalloc_node(sizeof(struct e1000_ring), GFP_KERNEL,
+			       adapter->node);
 	if (!tx_ring)
 		goto err_alloc_tx;
 	/*
@@ -700,7 +701,8 @@ static int e1000_set_ringparam(struct net_device *netdev,
 	 */
 	memcpy(tx_ring, tx_old, sizeof(struct e1000_ring));
 
-	rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	rx_ring = kzalloc_node(sizeof(struct e1000_ring), GFP_KERNEL,
+			       adapter->node);
 	if (!rx_ring)
 		goto err_alloc_rx;
 	memcpy(rx_ring, rx_old, sizeof(struct e1000_ring));
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index e2c7e0d..0af7cf2 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -605,7 +605,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 				continue;
 			}
 			if (!ps_page->page) {
-				ps_page->page = alloc_page(GFP_ATOMIC);
+				ps_page->page = alloc_pages_node(adapter->node,
+								 GFP_ATOMIC, 0);
 				if (!ps_page->page) {
 					adapter->alloc_rx_buff_failed++;
 					goto no_buffers;
@@ -714,7 +715,8 @@ static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
 check_page:
 		/* allocate a new page if necessary */
 		if (!buffer_info->page) {
-			buffer_info->page = alloc_page(GFP_ATOMIC);
+			buffer_info->page = alloc_pages_node(adapter->node,
+							     GFP_ATOMIC, 0);
 			if (unlikely(!buffer_info->page)) {
 				adapter->alloc_rx_buff_failed++;
 				break;
@@ -1796,9 +1798,9 @@ void e1000e_set_interrupt_capability(struct e1000_adapter *adapter)
 	case E1000E_INT_MODE_MSIX:
 		if (adapter->flags & FLAG_HAS_MSIX) {
 			adapter->num_vectors = 3; /* RxQ0, TxQ0 and other */
-			adapter->msix_entries = kcalloc(adapter->num_vectors,
-						      sizeof(struct msix_entry),
-						      GFP_KERNEL);
+			adapter->msix_entries = kzalloc_node(adapter->num_vectors *
+						     sizeof(struct msix_entry),
+						     GFP_KERNEL, adapter->node);
 			if (adapter->msix_entries) {
 				for (i = 0; i < adapter->num_vectors; i++)
 					adapter->msix_entries[i].entry = i;
@@ -2038,13 +2040,23 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter,
 				struct e1000_ring *ring)
 {
 	struct pci_dev *pdev = adapter->pdev;
+	int old_node = dev_to_node(&pdev->dev);
+	int retval = 0;
 
+	/*
+	 * must use set_dev_node here to work around the lack of a
+	 * dma_alloc_coherent_node function call
+	 */
+	if (adapter->node != -1)
+		set_dev_node(&pdev->dev, adapter->node);
 	ring->desc = dma_alloc_coherent(&pdev->dev, ring->size, &ring->dma,
 					GFP_KERNEL);
 	if (!ring->desc)
-		return -ENOMEM;
+		retval = -ENOMEM;
 
-	return 0;
+	if (adapter->node != -1)
+		set_dev_node(&pdev->dev, old_node);
+	return retval;
 }
 
 /**
@@ -2059,7 +2071,7 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
 	int err = -ENOMEM, size;
 
 	size = sizeof(struct e1000_buffer) * tx_ring->count;
-	tx_ring->buffer_info = vmalloc(size);
+	tx_ring->buffer_info = vmalloc_node(size, adapter->node);
 	if (!tx_ring->buffer_info)
 		goto err;
 	memset(tx_ring->buffer_info, 0, size);
@@ -2095,16 +2107,16 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
 	int i, size, desc_len, err = -ENOMEM;
 
 	size = sizeof(struct e1000_buffer) * rx_ring->count;
-	rx_ring->buffer_info = vmalloc(size);
+	rx_ring->buffer_info = vmalloc_node(size, adapter->node);
 	if (!rx_ring->buffer_info)
 		goto err;
 	memset(rx_ring->buffer_info, 0, size);
 
 	for (i = 0; i < rx_ring->count; i++) {
 		buffer_info = &rx_ring->buffer_info[i];
-		buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
+		buffer_info->ps_pages = kzalloc_node(PS_PAGE_BUFFERS *
 						sizeof(struct e1000_ps_page),
-						GFP_KERNEL);
+						GFP_KERNEL, adapter->node);
 		if (!buffer_info->ps_pages)
 			goto err_pages;
 	}
@@ -2348,11 +2360,13 @@ set_itr_now:
  **/
 static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter)
 {
-	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	adapter->tx_ring = kzalloc_node(sizeof(struct e1000_ring), GFP_KERNEL,
+					adapter->node);
 	if (!adapter->tx_ring)
 		goto err;
 
-	adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
+	adapter->rx_ring = kzalloc_node(sizeof(struct e1000_ring), GFP_KERNEL,
+					adapter->node);
 	if (!adapter->rx_ring)
 		goto err;
 
@@ -5594,6 +5608,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	pci_set_drvdata(pdev, netdev);
 	adapter = netdev_priv(netdev);
 	hw = &adapter->hw;
+	adapter->node = -1;
 	adapter->netdev = netdev;
 	adapter->pdev = pdev;
 	adapter->ei = ei;
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 34aeec1..9351ab0 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -28,6 +28,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/pci.h>
+#include <linux/nodemask.h>
 
 #include "e1000.h"
 
@@ -161,6 +162,17 @@ E1000_PARAM(WriteProtectNVM, "Write-protect NVM [WARNING: disabling this can lea
 E1000_PARAM(CrcStripping, "Enable CRC Stripping, disable if your BMC needs " \
                           "the CRC");
 
+/* Enable node specific allocation of all data structures, typically
+ *  specific to routing setups, not generally useful.
+ *
+ *  Depends on: NUMA configuration
+ *
+ * Valid Range: -1 or 0 to (MAX_NUMNODES - 1)
+ *
+ * Default Value: -1 (disabled, default to kernel choice of node)
+ */
+E1000_PARAM(Node, "[ROUTING] Node to allocate memory on, default -1");
+
 struct e1000_option {
 	enum { enable_option, range_option, list_option } type;
 	const char *name;
@@ -477,4 +489,28 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 			}
 		}
 	}
+	{ /* configure node specific allocation */
+		static struct e1000_option opt = {
+			.type = range_option,
+			.name = "Node used to allocate memory",
+			.err  = "defaulting to -1 (disabled)",
+			.def  = -1,
+			.arg  = { .r = { .min = 0,
+					 .max = MAX_NUMNODES - 1 } }
+		};
+		int node = opt.def;
+
+		if (num_Node > bd) {
+			node = Node[bd];
+			e1000_validate_option((uint *)&node, &opt, adapter);
+		}
+
+		/* check sanity of the value */
+		if ((node != -1) && !node_online(node)) {
+			e_info("ignoring node set to invalid value %d\n", node);
+			node = opt.def;
+		}
+
+		adapter->node = node;
+	}
 }


^ permalink raw reply related

* Re: [PATCH] xfrm4: strip ECN bits from tos field
From: David Miller @ 2010-09-23  3:26 UTC (permalink / raw)
  To: uweber; +Cc: netdev
In-Reply-To: <20100922164511.GA10963@babylon>

From: Ulrich Weber <uweber@astaro.com>
Date: Wed, 22 Sep 2010 18:45:11 +0200

> otherwise ECT(1) bit will get interpreted as RTO_ONLINK
> and routing will fail with XfrmOutBundleGenError.
> 
> Signed-off-by: Ulrich Weber <uweber@astaro.com>

Applied, thanks a lot.

^ permalink raw reply

* [net-2.6 PATCH 6/6] e1000e: 82579 do not gate auto config of PHY by hardware during nominal use
From: Jeff Kirsher @ 2010-09-23  3:17 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

For non-managed versions of 82579, set the bit that prevents the hardware
from automatically configuring the PHY after resets only when the driver
performs a reset, clear the bit after resets.  This is so the hardware can
configure the PHY automatically when the part is reset in a manner that is
not controlled by the driver (e.g. in a virtual environment via PCI FLR)
otherwise the PHY will be mis-configured causing issues such as failing to
link at 1000Mbps.
For managed versions of 82579, keep the previous behavior since the
manageability firmware will handle the PHY configuration.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |   77 +++++++++++++++++++++++++++++++++++++-----
 1 files changed, 68 insertions(+), 9 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index bb346ae..57b5435 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -243,6 +243,7 @@ static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
 static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -278,7 +279,7 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
 static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 {
 	struct e1000_phy_info *phy = &hw->phy;
-	u32 ctrl;
+	u32 ctrl, fwsm;
 	s32 ret_val = 0;
 
 	phy->addr                     = 1;
@@ -300,7 +301,8 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 	 * disabled, then toggle the LANPHYPC Value bit to force
 	 * the interconnect to PCIe mode.
 	 */
-	if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+	fwsm = er32(FWSM);
+	if (!(fwsm & E1000_ICH_FWSM_FW_VALID)) {
 		ctrl = er32(CTRL);
 		ctrl |=  E1000_CTRL_LANPHYPC_OVERRIDE;
 		ctrl &= ~E1000_CTRL_LANPHYPC_VALUE;
@@ -309,6 +311,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 		ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE;
 		ew32(CTRL, ctrl);
 		msleep(50);
+
+		/*
+		 * Gate automatic PHY configuration by hardware on
+		 * non-managed 82579
+		 */
+		if (hw->mac.type == e1000_pch2lan)
+			e1000_gate_hw_phy_config_ich8lan(hw, true);
 	}
 
 	/*
@@ -321,6 +330,13 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
 	if (ret_val)
 		goto out;
 
+	/* Ungate automatic PHY configuration on non-managed 82579 */
+	if ((hw->mac.type == e1000_pch2lan)  &&
+	    !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
+		msleep(10);
+		e1000_gate_hw_phy_config_ich8lan(hw, false);
+	}
+
 	phy->id = e1000_phy_unknown;
 	ret_val = e1000e_get_phy_id(hw);
 	if (ret_val)
@@ -567,13 +583,10 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
 	if (mac->type == e1000_ich8lan)
 		e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, true);
 
-	/* Disable PHY configuration by hardware, config by software */
-	if (mac->type == e1000_pch2lan) {
-		u32 extcnf_ctrl = er32(EXTCNF_CTRL);
-
-		extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
-		ew32(EXTCNF_CTRL, extcnf_ctrl);
-	}
+	/* Gate automatic PHY configuration by hardware on managed 82579 */
+	if ((mac->type == e1000_pch2lan) &&
+	    (er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+		e1000_gate_hw_phy_config_ich8lan(hw, true);
 
 	return 0;
 }
@@ -1621,6 +1634,32 @@ out:
 }
 
 /**
+ *  e1000_gate_hw_phy_config_ich8lan - disable PHY config via hardware
+ *  @hw:   pointer to the HW structure
+ *  @gate: boolean set to true to gate, false to ungate
+ *
+ *  Gate/ungate the automatic PHY configuration via hardware; perform
+ *  the configuration via software instead.
+ **/
+static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate)
+{
+	u32 extcnf_ctrl;
+
+	if (hw->mac.type != e1000_pch2lan)
+		return;
+
+	extcnf_ctrl = er32(EXTCNF_CTRL);
+
+	if (gate)
+		extcnf_ctrl |= E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+	else
+		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_GATE_PHY_CFG;
+
+	ew32(EXTCNF_CTRL, extcnf_ctrl);
+	return;
+}
+
+/**
  *  e1000_lan_init_done_ich8lan - Check for PHY config completion
  *  @hw: pointer to the HW structure
  *
@@ -1695,6 +1734,13 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 	/* Configure the LCD with the OEM bits in NVM */
 	ret_val = e1000_oem_bits_config_ich8lan(hw, true);
 
+	/* Ungate automatic PHY configuration on non-managed 82579 */
+	if ((hw->mac.type == e1000_pch2lan) &&
+	    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
+		msleep(10);
+		e1000_gate_hw_phy_config_ich8lan(hw, false);
+	}
+
 out:
 	return ret_val;
 }
@@ -1711,6 +1757,11 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 {
 	s32 ret_val = 0;
 
+	/* Gate automatic PHY configuration by hardware on non-managed 82579 */
+	if ((hw->mac.type == e1000_pch2lan) &&
+	    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+		e1000_gate_hw_phy_config_ich8lan(hw, true);
+
 	ret_val = e1000e_phy_hw_reset_generic(hw);
 	if (ret_val)
 		goto out;
@@ -2975,6 +3026,14 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 		 * external PHY is reset.
 		 */
 		ctrl |= E1000_CTRL_PHY_RST;
+
+		/*
+		 * Gate automatic PHY configuration by hardware on
+		 * non-managed 82579
+		 */
+		if ((hw->mac.type == e1000_pch2lan) &&
+		    !(er32(FWSM) & E1000_ICH_FWSM_FW_VALID))
+			e1000_gate_hw_phy_config_ich8lan(hw, true);
 	}
 	ret_val = e1000_acquire_swflag_ich8lan(hw);
 	e_dbg("Issuing a global reset to ich8lan\n");


^ permalink raw reply related

* [net-2.6 PATCH 5/6] e1000e: 82579 jumbo frame workaround causing CRC errors
From: Jeff Kirsher @ 2010-09-23  3:16 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

The subject workaround was causing CRC errors due to writing the wrong
register with updates of the RCTL register.  It was also found that the
workaround function which modifies the RCTL register was being called in
the middle of a read-modify-write operation of the RCTL register, so the
function call has been moved appropriately.  Lastly, jumbo frames must not
be allowed when CRC stripping is disabled by a module parameter because the
workaround requires the CRC be stripped.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |   12 +-----------
 drivers/net/e1000e/netdev.c  |   29 +++++++++++++++++++----------
 2 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 89b1e1a..bb346ae 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -1475,10 +1475,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 			goto out;
 
 		/* Enable jumbo frame workaround in the PHY */
-		e1e_rphy(hw, PHY_REG(769, 20), &data);
-		ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
-		if (ret_val)
-			goto out;
 		e1e_rphy(hw, PHY_REG(769, 23), &data);
 		data &= ~(0x7F << 5);
 		data |= (0x37 << 5);
@@ -1487,7 +1483,6 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 			goto out;
 		e1e_rphy(hw, PHY_REG(769, 16), &data);
 		data &= ~(1 << 13);
-		data |= (1 << 12);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
 		if (ret_val)
 			goto out;
@@ -1512,7 +1507,7 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 
 		mac_reg = er32(RCTL);
 		mac_reg &= ~E1000_RCTL_SECRC;
-		ew32(FFLT_DBG, mac_reg);
+		ew32(RCTL, mac_reg);
 
 		ret_val = e1000e_read_kmrn_reg(hw,
 						E1000_KMRNCTRLSTA_CTRL_OFFSET,
@@ -1538,17 +1533,12 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
 			goto out;
 
 		/* Write PHY register values back to h/w defaults */
-		e1e_rphy(hw, PHY_REG(769, 20), &data);
-		ret_val = e1e_wphy(hw, PHY_REG(769, 20), data & ~(1 << 14));
-		if (ret_val)
-			goto out;
 		e1e_rphy(hw, PHY_REG(769, 23), &data);
 		data &= ~(0x7F << 5);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 23), data);
 		if (ret_val)
 			goto out;
 		e1e_rphy(hw, PHY_REG(769, 16), &data);
-		data &= ~(1 << 12);
 		data |= (1 << 13);
 		ret_val = e1e_wphy(hw, PHY_REG(769, 16), data);
 		if (ret_val)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 2b8ef44..e561d15 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -2704,6 +2704,16 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 	u32 psrctl = 0;
 	u32 pages = 0;
 
+	/* Workaround Si errata on 82579 - configure jumbo frame flow */
+	if (hw->mac.type == e1000_pch2lan) {
+		s32 ret_val;
+
+		if (adapter->netdev->mtu > ETH_DATA_LEN)
+			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
+		else
+			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
+	}
+
 	/* Program MC offset vector base */
 	rctl = er32(RCTL);
 	rctl &= ~(3 << E1000_RCTL_MO_SHIFT);
@@ -2744,16 +2754,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 		e1e_wphy(hw, 22, phy_data);
 	}
 
-	/* Workaround Si errata on 82579 - configure jumbo frame flow */
-	if (hw->mac.type == e1000_pch2lan) {
-		s32 ret_val;
-
-		if (rctl & E1000_RCTL_LPE)
-			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, true);
-		else
-			ret_val = e1000_lv_jumbo_workaround_ich8lan(hw, false);
-	}
-
 	/* Setup buffer sizes */
 	rctl &= ~E1000_RCTL_SZ_4096;
 	rctl |= E1000_RCTL_BSEX;
@@ -4833,6 +4833,15 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 		return -EINVAL;
 	}
 
+	/* Jumbo frame workaround on 82579 requires CRC be stripped */
+	if ((adapter->hw.mac.type == e1000_pch2lan) &&
+	    !(adapter->flags2 & FLAG2_CRC_STRIPPING) &&
+	    (new_mtu > ETH_DATA_LEN)) {
+		e_err("Jumbo Frames not supported on 82579 when CRC "
+		      "stripping is disabled.\n");
+		return -EINVAL;
+	}
+
 	/* 82573 Errata 17 */
 	if (((adapter->hw.mac.type == e1000_82573) ||
 	     (adapter->hw.mac.type == e1000_82574)) &&


^ permalink raw reply related

* [net-2.6 PATCH 4/6] e1000e: 82579 unaccounted missed packets
From: Jeff Kirsher @ 2010-09-23  3:16 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

On 82579, there is a hardware bug that can cause received packets to not
get transferred from the PHY to the MAC due to K1 (a power saving feature
of the PHY-MAC interconnect similar to ASPM L1).  Since the MAC controls
the accounting of missed packets, these will go unnoticed.  Workaround the
issue by setting the K1 beacon duration according to the link speed.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/hw.h      |    1 +
 drivers/net/e1000e/ich8lan.c |   48 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 66ed08f..ba302a5 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -57,6 +57,7 @@ enum e1e_registers {
 	E1000_SCTL     = 0x00024, /* SerDes Control - RW */
 	E1000_FCAL     = 0x00028, /* Flow Control Address Low - RW */
 	E1000_FCAH     = 0x0002C, /* Flow Control Address High -RW */
+	E1000_FEXTNVM4 = 0x00024, /* Future Extended NVM 4 - RW */
 	E1000_FEXTNVM  = 0x00028, /* Future Extended NVM - RW */
 	E1000_FCT      = 0x00030, /* Flow Control Type - RW */
 	E1000_VET      = 0x00038, /* VLAN Ether Type - RW */
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 6f9cb0d..89b1e1a 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -105,6 +105,10 @@
 #define E1000_FEXTNVM_SW_CONFIG		1
 #define E1000_FEXTNVM_SW_CONFIG_ICH8M (1 << 27) /* Bit redefined for ICH8M :/ */
 
+#define E1000_FEXTNVM4_BEACON_DURATION_MASK    0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_8USEC   0x7
+#define E1000_FEXTNVM4_BEACON_DURATION_16USEC  0x3
+
 #define PCIE_ICH8_SNOOP_ALL		PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES		7
@@ -238,6 +242,7 @@ static s32  e1000_k1_gig_workaround_hv(struct e1000_hw *hw, bool link);
 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -653,6 +658,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
 			goto out;
 	}
 
+	if (hw->mac.type == e1000_pch2lan) {
+		ret_val = e1000_k1_workaround_lv(hw);
+		if (ret_val)
+			goto out;
+	}
+
 	/*
 	 * Check if there was DownShift, must be checked
 	 * immediately after link-up
@@ -1583,6 +1594,43 @@ out:
 }
 
 /**
+ *  e1000_k1_gig_workaround_lv - K1 Si workaround
+ *  @hw:   pointer to the HW structure
+ *
+ *  Workaround to set the K1 beacon duration for 82579 parts
+ **/
+static s32 e1000_k1_workaround_lv(struct e1000_hw *hw)
+{
+	s32 ret_val = 0;
+	u16 status_reg = 0;
+	u32 mac_reg;
+
+	if (hw->mac.type != e1000_pch2lan)
+		goto out;
+
+	/* Set K1 beacon duration based on 1Gbps speed or otherwise */
+	ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg);
+	if (ret_val)
+		goto out;
+
+	if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE))
+	    == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) {
+		mac_reg = er32(FEXTNVM4);
+		mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK;
+
+		if (status_reg & HV_M_STATUS_SPEED_1000)
+			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC;
+		else
+			mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC;
+
+		ew32(FEXTNVM4, mac_reg);
+	}
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000_lan_init_done_ich8lan - Check for PHY config completion
  *  @hw: pointer to the HW structure
  *


^ permalink raw reply related

* [net-2.6 PATCH 3/6] e1000e: 82566DC fails to get link
From: Jeff Kirsher @ 2010-09-23  3:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, stable, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Two recent patches to cleanup the reset[1] and initial PHY configuration[2]
code paths for ICH/PCH devices inadvertently left out a 10msec delay and
device ID check respectively which are necessary for the 82566DC (device id
0x104b) to be configured properly, otherwise it will not get link.

[1] commit e98cac447cc1cc418dff1d610a5c79c4f2bdec7f
[2] commit 3f0c16e84438d657d29446f85fe375794a93f159

CC: stable@kernel.org
Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index fc8c3ce..6f9cb0d 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -932,7 +932,6 @@ out:
  **/
 static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 {
-	struct e1000_adapter *adapter = hw->adapter;
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask;
 	s32 ret_val = 0;
@@ -950,7 +949,8 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 		if (phy->type != e1000_phy_igp_3)
 			return ret_val;
 
-		if (adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) {
+		if ((hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_AMT) ||
+		    (hw->adapter->pdev->device == E1000_DEV_ID_ICH8_IGP_C)) {
 			sw_cfg_mask = E1000_FEXTNVM_SW_CONFIG;
 			break;
 		}
@@ -1626,6 +1626,9 @@ static s32 e1000_post_phy_reset_ich8lan(struct e1000_hw *hw)
 	if (e1000_check_reset_block(hw))
 		goto out;
 
+	/* Allow time for h/w to get to quiescent state after reset */
+	msleep(10);
+
 	/* Perform any necessary post-reset workarounds */
 	switch (hw->mac.type) {
 	case e1000_pchlan:


^ permalink raw reply related

* [net-2.6 PATCH 2/6] e1000e: 82579 SMBus address and LEDs incorrect after device reset
From: Jeff Kirsher @ 2010-09-23  3:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher
In-Reply-To: <20100923031432.10976.81909.stgit@localhost.localdomain>

From: Bruce Allan <bruce.w.allan@intel.com>

Since the hardware is prevented from performing automatic PHY configuration
(the driver does it instead), the OEM_WRITE_ENABLE bit in the EXTCNF_CTRL
register will not get cleared preventing the SMBus address and the LED
configuration to be written to the PHY registers.  On 82579, do not check
the OEM_WRITE_ENABLE bit.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 822de48..fc8c3ce 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -990,9 +990,9 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 	cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
 	cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
 
-	if (!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
-	    ((hw->mac.type == e1000_pchlan) ||
-	     (hw->mac.type == e1000_pch2lan))) {
+	if ((!(data & E1000_EXTCNF_CTRL_OEM_WRITE_ENABLE) &&
+	    (hw->mac.type == e1000_pchlan)) ||
+	     (hw->mac.type == e1000_pch2lan)) {
 		/*
 		 * HW configures the SMBus address and LEDs when the
 		 * OEM and LCD Write Enable bits are set in the NVM.


^ permalink raw reply related

* [net-2.6 PATCH 1/6] e1000e: 82577/8/9 issues with device in Sx
From: Jeff Kirsher @ 2010-09-23  3:15 UTC (permalink / raw)
  To: davem; +Cc: netdev, gospo, bphilips, Bruce Allan, Jeff Kirsher

From: Bruce Allan <bruce.w.allan@intel.com>

When going to Sx, disable gigabit in PHY (e1000_oem_bits_config_ich8lan)
in addition to the MAC before configuring PHY wakeup otherwise the PHY
configuration writes might be missed.  Also write the LED configuration
and SMBus address to the PHY registers (e1000_oem_bits_config_ich8lan and
e1000_write_smbus_addr, respectively).  The reset is no longer needed
since re-auto-negotiation is forced in e1000_oem_bits_config_ich8lan and
leaving it in causes issues with auto-negotiating the link.

Signed-off-by: Bruce Allan <bruce.w.allan@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/e1000e/ich8lan.c |   47 +++++++++++++++++++++++++++++++++++-------
 1 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 63930d1..822de48 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -125,6 +125,7 @@
 
 /* SMBus Address Phy Register */
 #define HV_SMB_ADDR            PHY_REG(768, 26)
+#define HV_SMB_ADDR_MASK       0x007F
 #define HV_SMB_ADDR_PEC_EN     0x0200
 #define HV_SMB_ADDR_VALID      0x0080
 
@@ -895,6 +896,34 @@ static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000_write_smbus_addr - Write SMBus address to PHY needed during Sx states
+ *  @hw: pointer to the HW structure
+ *
+ *  Assumes semaphore already acquired.
+ *
+ **/
+static s32 e1000_write_smbus_addr(struct e1000_hw *hw)
+{
+	u16 phy_data;
+	u32 strap = er32(STRAP);
+	s32 ret_val = 0;
+
+	strap &= E1000_STRAP_SMBUS_ADDRESS_MASK;
+
+	ret_val = e1000_read_phy_reg_hv_locked(hw, HV_SMB_ADDR, &phy_data);
+	if (ret_val)
+		goto out;
+
+	phy_data &= ~HV_SMB_ADDR_MASK;
+	phy_data |= (strap >> E1000_STRAP_SMBUS_ADDRESS_SHIFT);
+	phy_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
+	ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR, phy_data);
+
+out:
+	return ret_val;
+}
+
+/**
  *  e1000_sw_lcd_config_ich8lan - SW-based LCD Configuration
  *  @hw:   pointer to the HW structure
  *
@@ -970,12 +999,7 @@ static s32 e1000_sw_lcd_config_ich8lan(struct e1000_hw *hw)
 		 * When both NVM bits are cleared, SW will configure
 		 * them instead.
 		 */
-		data = er32(STRAP);
-		data &= E1000_STRAP_SMBUS_ADDRESS_MASK;
-		reg_data = data >> E1000_STRAP_SMBUS_ADDRESS_SHIFT;
-		reg_data |= HV_SMB_ADDR_PEC_EN | HV_SMB_ADDR_VALID;
-		ret_val = e1000_write_phy_reg_hv_locked(hw, HV_SMB_ADDR,
-							reg_data);
+		ret_val = e1000_write_smbus_addr(hw);
 		if (ret_val)
 			goto out;
 
@@ -3460,13 +3484,20 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
 void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
 {
 	u32 phy_ctrl;
+	s32 ret_val;
 
 	phy_ctrl = er32(PHY_CTRL);
 	phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE;
 	ew32(PHY_CTRL, phy_ctrl);
 
-	if (hw->mac.type >= e1000_pchlan)
-		e1000_phy_hw_reset_ich8lan(hw);
+	if (hw->mac.type >= e1000_pchlan) {
+		e1000_oem_bits_config_ich8lan(hw, true);
+		ret_val = hw->phy.ops.acquire(hw);
+		if (ret_val)
+			return;
+		e1000_write_smbus_addr(hw);
+		hw->phy.ops.release(hw);
+	}
 }
 
 /**


^ permalink raw reply related

* linux-next: manual merge of the net tree with the net-current tree
From: Stephen Rothwell @ 2010-09-23  2:14 UTC (permalink / raw)
  To: David Miller, netdev; +Cc: linux-next, linux-kernel, Eric Dumazet

Hi all,

Today's linux-next merge of the net tree got a conflict in
net/ipv4/ip_output.c between commit
3d13008e7345fa7a79d8f6438150dc15d6ba6e9d ("ip: fix truesize mismatch in
ip fragmentation") from the net-current tree and commit
21dc330157454046dd7c494961277d76e1c957fe ("net: Rename skb_has_frags to
skb_has_frag_list") from the net tree.

Just context changes.  I fixed it up (see below) and can carry the fix
for a while.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc net/ipv4/ip_output.c
index 7649d77,e427620..0000000
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@@ -487,9 -487,10 +487,9 @@@ int ip_fragment(struct sk_buff *skb, in
  	 * LATER: this step can be merged to real generation of fragments,
  	 * we can switch to copy when see the first bad fragment.
  	 */
- 	if (skb_has_frags(skb)) {
+ 	if (skb_has_frag_list(skb)) {
 -		struct sk_buff *frag;
 +		struct sk_buff *frag, *frag2;
  		int first_len = skb_pagelen(skb);
 -		int truesizes = 0;
  
  		if (first_len - hlen > mtu ||
  		    ((first_len - hlen) & 7) ||

^ permalink raw reply

* Re: Fw: rcu warning
From: Paul E. McKenney @ 2010-09-22 23:12 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: akpm, netdev
In-Reply-To: <1285196665.2380.54.camel@edumazet-laptop>

On Thu, Sep 23, 2010 at 01:04:25AM +0200, Eric Dumazet wrote:
> Le mercredi 22 septembre 2010 à 14:44 -0700, Paul E. McKenney a écrit :
> > > Date: Wed, 22 Sep 2010 13:52:28 -0700
> > > From: Andrew Morton <akpm@linux-foundation.org>
> > > To: "Paul E. McKenney" <paulmck@us.ibm.com>
> > > Subject: rcu warning
> > > X-Mailer: Sylpheed 2.4.8 (GTK+ 2.12.9; x86_64-pc-linux-gnu)
> > > 
> > > [   56.803750] 
> > > [   56.803752] ===================================================
> > > [   56.804082] [ INFO: suspicious rcu_dereference_check() usage. ]
> > > [   56.804249] ---------------------------------------------------
> > > [   56.804421] include/linux/inetdevice.h:219 invoked rcu_dereference_check() without protection!
> > > [   56.804708] 
> > > [   56.804709] other info that might help us debug this:
> > > [   56.804710] 
> > > [   56.805183] 
> > > [   56.805184] rcu_scheduler_active = 1, debug_locks = 1
> > > [   56.805501] 3 locks held by kworker/0:1/0:
> > > [   56.805664]  #0:  (&in_dev->mr_ifc_timer){+.-...}, at: [<ffffffff81042466>] run_timer_softirq+0xfd/0x226
> > > [   56.806126]  #1:  (&in_dev->mc_list_lock){++.-..}, at: [<ffffffff8133e81d>] igmp_ifc_timer_expire+0x2a/0x221
> > > [   56.806588]  #2:  (&(&im->lock)->rlock){+.-...}, at: [<ffffffff8133e948>] igmp_ifc_timer_expire+0x155/0x221
> > > [   56.807043] 
> > > [   56.807044] stack backtrace:
> > > [   56.807364] Pid: 0, comm: kworker/0:1 Not tainted 2.6.36-rc5-mm1 #1
> > > [   56.807561] Call Trace:
> > > [   56.807723]  <IRQ>  [<ffffffff8105b88b>] lockdep_rcu_dereference+0x99/0xa2
> > > [   56.807948]  [<ffffffff8130dc66>] __ip_route_output_key+0x34f/0xb19
> > > [   56.808120]  [<ffffffff8130d94a>] ? __ip_route_output_key+0x33/0xb19
> > > [   56.814367]  [<ffffffff8130e453>] ip_route_output_flow+0x23/0x1ee
> > > [   56.814536]  [<ffffffff8130e62c>] ip_route_output_key+0xe/0x10
> > > [   56.814704]  [<ffffffff8133e19d>] igmpv3_newpack+0x7f/0x1c2
> > > [   56.814873]  [<ffffffff8133e30d>] add_grhead+0x2d/0x94
> > > [   56.815039]  [<ffffffff8133e6c2>] add_grec+0x34e/0x38c
> > > [   56.815206]  [<ffffffff8133e9a8>] igmp_ifc_timer_expire+0x1b5/0x221
> > > [   56.815375]  [<ffffffff810424e8>] run_timer_softirq+0x17f/0x226
> > > [   56.815547]  [<ffffffff81042466>] ? run_timer_softirq+0xfd/0x226
> > > [   56.815715]  [<ffffffff8133e7f3>] ? igmp_ifc_timer_expire+0x0/0x221
> > > [   56.815885]  [<ffffffff8103ca8f>] __do_softirq+0xa5/0x13a
> > > [   56.816051]  [<ffffffff8100390c>] call_softirq+0x1c/0x28
> > > [   56.816219]  [<ffffffff81004eba>] do_softirq+0x38/0x82
> > > [   56.816385]  [<ffffffff8103c9e8>] irq_exit+0x47/0x49
> > > [   56.816553]  [<ffffffff81019ce3>] smp_apic_timer_interrupt+0x88/0x96
> > > [   56.816722]  [<ffffffff810033d3>] apic_timer_interrupt+0x13/0x20
> > > [   56.816888]  <EOI>  [<ffffffff8138607a>] ? __atomic_notifier_call_chain+0x0/0x84
> > > [   56.817215]  [<ffffffff81009a9b>] ? mwait_idle+0x65/0x71
> > > [   56.817382]  [<ffffffff81009a91>] ? mwait_idle+0x5b/0x71
> > > [   56.817549]  [<ffffffff810014ca>] cpu_idle+0x48/0x66
> > > [   56.817716]  [<ffffffff8137b4da>] start_secondary+0x1b9/0x1bd
> > > [   56.817883]  [<ffffffff8137b321>] ? start_secondary+0x0/0x1bd
> > 
> > Hello, Eric,
> > 
> > In linux/master, there is an rcu_read_lock_bh() in the call path, but
> > an rcu_dereference() instead of an rcu_dereference_bh().  Thoughts?
> > 
> > (I have asked Andrew what kernel this is against -- I don't see the
> > rcu_read_lock() that I would expect to see in the lockdep output.)
> > 
> > 							Thanx, Paul
> 
> This seems strange
> 
> include/linux/inetdevice.h:219
> 
> static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
> {
> 	return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
> }
> 
> But I dont think RTNL can possibly be held at this point ???
> 
> Oh wait, this is line 2582 in net/ipv4/route.c
> 
> It seems buggy and proud of it :)
> 
> 	/* RACE: Check return value of inet_select_addr instead. */ 
> 	if (__in_dev_get_rtnl(dev_out) == NULL) {
> 
> This should be changed to 
> 
> 	if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) {
> 
> No ?

You beat me to it.  ;-)

							Thanx, Paul

> In commit e5ed639913eea3e, Herbert mentioned a race so I suspect some
> more thinking is needed before applying the following patch
> 
> Sorry its late here, I now need to sleep :)
> 
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index e24d48d..8d08377 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2579,7 +2579,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
>  			goto out;
> 
>  		/* RACE: Check return value of inet_select_addr instead. */
> -		if (__in_dev_get_rtnl(dev_out) == NULL) {
> +		if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) {
>  			dev_put(dev_out);
>  			goto out;	/* Wrong error code */
>  		}
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Fw: rcu warning
From: Paul E. McKenney @ 2010-09-22 23:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: eric.dumazet, netdev
In-Reply-To: <20100922144736.baf75544.akpm@linux-foundation.org>

On Wed, Sep 22, 2010 at 02:47:36PM -0700, Andrew Morton wrote:
> On Wed, 22 Sep 2010 14:44:38 -0700
> "Paul E. McKenney" <paulmck@linux.vnet.ibm.com> wrote:
> 
> > In linux/master, there is an rcu_read_lock_bh() in the call path, but
> > an rcu_dereference() instead of an rcu_dereference_bh().  Thoughts?
> > 
> > (I have asked Andrew what kernel this is against -- I don't see the
> > rcu_read_lock() that I would expect to see in the lockdep output.)
> 
> current linux-next.

Thank you!!!

OK, here we have __in_dev_get_rtnl() called from ip_route_output_slow().
I might be missing something, but I don't see either an rcu_read_lock()
or an RTNL acquisition in ip_route_output_slow().

But the call to __in_dev_get_rtnl() simply compares to NULL, so I don't
understand why this can't instead call __in_dev_get_rcu().  Given that
there are a number of places where the return value from __in_dev_get_rtnl()
is compared to NULL, one approach would be to have something like the
following:

	static inline int __in_dev_check_null(const struct net_device *dev)
	{
		return rcu_dereference_raw(dev->ip_ptr) == NULL;
	}

Thoughts?

							Thanx, Paul

^ permalink raw reply

* Re: Fw: rcu warning
From: Eric Dumazet @ 2010-09-22 23:04 UTC (permalink / raw)
  To: paulmck; +Cc: akpm, netdev
In-Reply-To: <20100922214438.GN2435@linux.vnet.ibm.com>

Le mercredi 22 septembre 2010 à 14:44 -0700, Paul E. McKenney a écrit :
> > Date: Wed, 22 Sep 2010 13:52:28 -0700
> > From: Andrew Morton <akpm@linux-foundation.org>
> > To: "Paul E. McKenney" <paulmck@us.ibm.com>
> > Subject: rcu warning
> > X-Mailer: Sylpheed 2.4.8 (GTK+ 2.12.9; x86_64-pc-linux-gnu)
> > 
> > [   56.803750] 
> > [   56.803752] ===================================================
> > [   56.804082] [ INFO: suspicious rcu_dereference_check() usage. ]
> > [   56.804249] ---------------------------------------------------
> > [   56.804421] include/linux/inetdevice.h:219 invoked rcu_dereference_check() without protection!
> > [   56.804708] 
> > [   56.804709] other info that might help us debug this:
> > [   56.804710] 
> > [   56.805183] 
> > [   56.805184] rcu_scheduler_active = 1, debug_locks = 1
> > [   56.805501] 3 locks held by kworker/0:1/0:
> > [   56.805664]  #0:  (&in_dev->mr_ifc_timer){+.-...}, at: [<ffffffff81042466>] run_timer_softirq+0xfd/0x226
> > [   56.806126]  #1:  (&in_dev->mc_list_lock){++.-..}, at: [<ffffffff8133e81d>] igmp_ifc_timer_expire+0x2a/0x221
> > [   56.806588]  #2:  (&(&im->lock)->rlock){+.-...}, at: [<ffffffff8133e948>] igmp_ifc_timer_expire+0x155/0x221
> > [   56.807043] 
> > [   56.807044] stack backtrace:
> > [   56.807364] Pid: 0, comm: kworker/0:1 Not tainted 2.6.36-rc5-mm1 #1
> > [   56.807561] Call Trace:
> > [   56.807723]  <IRQ>  [<ffffffff8105b88b>] lockdep_rcu_dereference+0x99/0xa2
> > [   56.807948]  [<ffffffff8130dc66>] __ip_route_output_key+0x34f/0xb19
> > [   56.808120]  [<ffffffff8130d94a>] ? __ip_route_output_key+0x33/0xb19
> > [   56.814367]  [<ffffffff8130e453>] ip_route_output_flow+0x23/0x1ee
> > [   56.814536]  [<ffffffff8130e62c>] ip_route_output_key+0xe/0x10
> > [   56.814704]  [<ffffffff8133e19d>] igmpv3_newpack+0x7f/0x1c2
> > [   56.814873]  [<ffffffff8133e30d>] add_grhead+0x2d/0x94
> > [   56.815039]  [<ffffffff8133e6c2>] add_grec+0x34e/0x38c
> > [   56.815206]  [<ffffffff8133e9a8>] igmp_ifc_timer_expire+0x1b5/0x221
> > [   56.815375]  [<ffffffff810424e8>] run_timer_softirq+0x17f/0x226
> > [   56.815547]  [<ffffffff81042466>] ? run_timer_softirq+0xfd/0x226
> > [   56.815715]  [<ffffffff8133e7f3>] ? igmp_ifc_timer_expire+0x0/0x221
> > [   56.815885]  [<ffffffff8103ca8f>] __do_softirq+0xa5/0x13a
> > [   56.816051]  [<ffffffff8100390c>] call_softirq+0x1c/0x28
> > [   56.816219]  [<ffffffff81004eba>] do_softirq+0x38/0x82
> > [   56.816385]  [<ffffffff8103c9e8>] irq_exit+0x47/0x49
> > [   56.816553]  [<ffffffff81019ce3>] smp_apic_timer_interrupt+0x88/0x96
> > [   56.816722]  [<ffffffff810033d3>] apic_timer_interrupt+0x13/0x20
> > [   56.816888]  <EOI>  [<ffffffff8138607a>] ? __atomic_notifier_call_chain+0x0/0x84
> > [   56.817215]  [<ffffffff81009a9b>] ? mwait_idle+0x65/0x71
> > [   56.817382]  [<ffffffff81009a91>] ? mwait_idle+0x5b/0x71
> > [   56.817549]  [<ffffffff810014ca>] cpu_idle+0x48/0x66
> > [   56.817716]  [<ffffffff8137b4da>] start_secondary+0x1b9/0x1bd
> > [   56.817883]  [<ffffffff8137b321>] ? start_secondary+0x0/0x1bd
> 
> Hello, Eric,
> 
> In linux/master, there is an rcu_read_lock_bh() in the call path, but
> an rcu_dereference() instead of an rcu_dereference_bh().  Thoughts?
> 
> (I have asked Andrew what kernel this is against -- I don't see the
> rcu_read_lock() that I would expect to see in the lockdep output.)
> 
> 							Thanx, Paul

This seems strange

include/linux/inetdevice.h:219

static inline struct in_device *__in_dev_get_rtnl(const struct net_device *dev)
{
	return rcu_dereference_check(dev->ip_ptr, lockdep_rtnl_is_held());
}

But I dont think RTNL can possibly be held at this point ???

Oh wait, this is line 2582 in net/ipv4/route.c

It seems buggy and proud of it :)

	/* RACE: Check return value of inet_select_addr instead. */ 
	if (__in_dev_get_rtnl(dev_out) == NULL) {

This should be changed to 

	if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) {

No ?


In commit e5ed639913eea3e, Herbert mentioned a race so I suspect some
more thinking is needed before applying the following patch

Sorry its late here, I now need to sleep :)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e24d48d..8d08377 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2579,7 +2579,7 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
 			goto out;
 
 		/* RACE: Check return value of inet_select_addr instead. */
-		if (__in_dev_get_rtnl(dev_out) == NULL) {
+		if (rcu_dereference_raw(dev_out->ip_ptr) == NULL) {
 			dev_put(dev_out);
 			goto out;	/* Wrong error code */
 		}



^ permalink raw reply related

* Re: kvm networking todo wiki
From: Sridhar Samudrala @ 2010-09-22 22:46 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Krishna Kumar2, lmr, Xin, Xiaohui, Rusty Russell, akong, kvm,
	netdev, Shirley Ma, David Stevens, qemu-devel, herbert, jdike,
	sri
In-Reply-To: <20100921161124.GC22845@redhat.com>

[-- Attachment #1: Type: text/plain, Size: 1447 bytes --]

  On Tue, 2010-09-21 at 18:11 +0200, Michael S. Tsirkin wrote:
> I've put up a wiki page with a kvm networking todo list,
> mainly to avoid effort duplication, but also in the hope
> to draw attention to what I think we should try addressing
> in KVM:
>
> http://www.linux-kvm.org/page/NetworkingTodo
>
> This page could cover all networking related activity in KVM,
> currently most info is related to virtio-net.
>
> Note: if there's no developer listed for an item,
> this just means I don't know of anyone actively working
> on an issue at the moment, not that no one intends to.
>
> I would appreciate it if others working on one of the items on this list
> would add their names so we can communicate better.  If others like this
> wiki page, please go ahead and add stuff you are working on if any.
>
> It would be especially nice to add autotest projects:
> there is just a short test matrix and a catch-all
> 'Cover test matrix with autotest', currently.
>
> Currently there are some links to Red Hat bugzilla entries,
> feel free to add links to other bugzillas.

Thanks for capturing these items. It is really useful.

Another item that is missing is
- support assigning SR-IOV VF to a guest via tap/macvtap

Currently, this requires
  - VF to be put in promiscuous mode when using a bridge/tap
  - add a new mac address to VF when using macvtap.

I don't think any of the VF drivers provide these capabilities
at this time.

-Sridhar


[-- Attachment #2: Type: text/html, Size: 2199 bytes --]

^ permalink raw reply

* Re: [PATCH] net: fix a lockdep splat
From: Eric Dumazet @ 2010-09-22 22:43 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: Tetsuo Handa, David Miller, linux-fsdevel, netdev
In-Reply-To: <4C9A7F7F.5010507@gmail.com>

Le jeudi 23 septembre 2010 à 00:13 +0200, Jarek Poplawski a écrit :
> Eric Dumazet wrote:
> > [PATCH] net: fix a lockdep splat
> > 
> > We have for each socket :
> > 
> > One spinlock (sk_slock.slock)
> > One rwlock (sk_callback_lock)
> > 
> > Possible scenarios are :
> > 
> > (A) (this is used in net/sunrpc/xprtsock.c)
> > read_lock(&sk->sk_callback_lock) (without blocking BH)
> > <BH>
> > spin_lock(&sk->sk_slock.slock);
> > ...
> > read_lock(&sk->sk_callback_lock);
> > ...
> > 
> > 
> > (B)
> > write_lock_bh(&sk->sk_callback_lock)
> > stuff
> > write_unlock_bh(&sk->sk_callback_lock)
> > 
> > 
> > (C)
> > spin_lock_bh(&sk->sk_slock)
> > ...
> > write_lock_bh(&sk->sk_callback_lock)
> > stuff
> > write_unlock_bh(&sk->sk_callback_lock)
> > spin_unlock_bh(&sk->sk_slock)
> > 
> > This (C) case conflicts with (A) :
> > 
> > CPU1 [A]                         CPU2 [C]
> > read_lock(callback_lock)
> > <BH>                             spin_lock_bh(slock)
> > <wait to spin_lock(slock)>
> >                                  <wait to write_lock_bh(callback_lock)>
> > 
> > We have one problematic (C) use case in inet_csk_listen_stop() :
> > 
> > local_bh_disable();
> > bh_lock_sock(child); // spin_lock_bh(&sk->sk_slock)
> > WARN_ON(sock_owned_by_user(child));
> > ...
> > sock_orphan(child); // write_lock_bh(&sk->sk_callback_lock)
> > 
> > lockdep is not happy with this, as reported by Tetsuo Handa
> > 
> > This patch makes sure inet_csk_listen_stop() uses following lock order :
> > 
> > write_lock_bh(&sk->sk_callback_lock)
> > spin_lock(&sk->sk_slock)
> > ...
> > spin_unlock(&sk->sk_slock)
> > write_unlock_bh(&sk->sk_callback_lock)
> 
> IMHO this order conflicts with (A) too (but I'm not sure lockdep
> tracks that):
>  

It should... thats strange I did not hit it in my tests

> CPU1 [A]                         CPU2 [C-reversed]
> ...				write_lock_bh(callback_lock)
> <BH>                             
> spin_lock(slock)
> 				<wait to spin_lock(slock)>
> <wait to read_lock(callback_lock)>
> 


Oh well, you're right. I tried to avoid the _bh everywhere but it seems
buggy too.


> My proposal is to BH protect read_lock(sk_callback_lock) everywhere (it's
> done by netfilter in a few places already).
> 

Yes... its a bit strange we never hit this lockdep splat before...

I tried to track recent changes but really I am mystified ???

Thanks !

[PATCH v2] net: fix a lockdep splat

We have for each socket :

One spinlock (sk_slock.slock)
One rwlock (sk_callback_lock)

Possible scenarios are :

(A) (this is used in net/sunrpc/xprtsock.c)
read_lock(&sk->sk_callback_lock) (without blocking BH)
<BH>
spin_lock(&sk->sk_slock.slock);
...
read_lock(&sk->sk_callback_lock);
...


(B)
write_lock_bh(&sk->sk_callback_lock)
stuff
write_unlock_bh(&sk->sk_callback_lock)


(C)
spin_lock_bh(&sk->sk_slock)
...
write_lock_bh(&sk->sk_callback_lock)
stuff
write_unlock_bh(&sk->sk_callback_lock)
spin_unlock_bh(&sk->sk_slock)

This (C) case conflicts with (A) :

CPU1 [A]                         CPU2 [C]
read_lock(callback_lock)
<BH>                             spin_lock_bh(slock)
<wait to spin_lock(slock)>
                                 <wait to write_lock_bh(callback_lock)>

We have one problematic (C) use case in inet_csk_listen_stop() :

local_bh_disable();
bh_lock_sock(child); // spin_lock_bh(&sk->sk_slock)
WARN_ON(sock_owned_by_user(child));
...
sock_orphan(child); // write_lock_bh(&sk->sk_callback_lock)

lockdep is not happy with this, as reported by Tetsuo Handa

It seems only way to deal with this is to use read_lock_bh(callbacklock)
everywhere.

Thanks to Jarek for pointing a bug in my first attempt and suggesting
this solution.

Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Jarek Poplawski <jarkao2@gmail.com>
---
 net/core/sock.c       |    8 ++++----
 net/rds/tcp_connect.c |    4 ++--
 net/rds/tcp_listen.c  |    4 ++--
 net/rds/tcp_recv.c    |    4 ++--
 net/rds/tcp_send.c    |    4 ++--
 net/sunrpc/xprtsock.c |   28 ++++++++++++++--------------
 6 files changed, 26 insertions(+), 26 deletions(-)

diff --git a/net/core/sock.c b/net/core/sock.c
index b05b9b6..ef30e9d 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1351,9 +1351,9 @@ int sock_i_uid(struct sock *sk)
 {
 	int uid;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	uid = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_uid : 0;
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 	return uid;
 }
 EXPORT_SYMBOL(sock_i_uid);
@@ -1362,9 +1362,9 @@ unsigned long sock_i_ino(struct sock *sk)
 {
 	unsigned long ino;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	ino = sk->sk_socket ? SOCK_INODE(sk->sk_socket)->i_ino : 0;
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 	return ino;
 }
 EXPORT_SYMBOL(sock_i_ino);
diff --git a/net/rds/tcp_connect.c b/net/rds/tcp_connect.c
index c397524..c519939 100644
--- a/net/rds/tcp_connect.c
+++ b/net/rds/tcp_connect.c
@@ -43,7 +43,7 @@ void rds_tcp_state_change(struct sock *sk)
 	struct rds_connection *conn;
 	struct rds_tcp_connection *tc;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	conn = sk->sk_user_data;
 	if (conn == NULL) {
 		state_change = sk->sk_state_change;
@@ -68,7 +68,7 @@ void rds_tcp_state_change(struct sock *sk)
 			break;
 	}
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 	state_change(sk);
 }
 
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index 975183f..27844f2 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -114,7 +114,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
 
 	rdsdebug("listen data ready sk %p\n", sk);
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	ready = sk->sk_user_data;
 	if (ready == NULL) { /* check for teardown race */
 		ready = sk->sk_data_ready;
@@ -131,7 +131,7 @@ void rds_tcp_listen_data_ready(struct sock *sk, int bytes)
 		queue_work(rds_wq, &rds_tcp_listen_work);
 
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 	ready(sk, bytes);
 }
 
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index 1aba687..e437974 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -324,7 +324,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
 
 	rdsdebug("data ready sk %p bytes %d\n", sk, bytes);
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	conn = sk->sk_user_data;
 	if (conn == NULL) { /* check for teardown race */
 		ready = sk->sk_data_ready;
@@ -338,7 +338,7 @@ void rds_tcp_data_ready(struct sock *sk, int bytes)
 	if (rds_tcp_read_sock(conn, GFP_ATOMIC, KM_SOFTIRQ0) == -ENOMEM)
 		queue_delayed_work(rds_wq, &conn->c_recv_w, 0);
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 	ready(sk, bytes);
 }
 
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c
index a28b895..2f012a0 100644
--- a/net/rds/tcp_send.c
+++ b/net/rds/tcp_send.c
@@ -224,7 +224,7 @@ void rds_tcp_write_space(struct sock *sk)
 	struct rds_connection *conn;
 	struct rds_tcp_connection *tc;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	conn = sk->sk_user_data;
 	if (conn == NULL) {
 		write_space = sk->sk_write_space;
@@ -244,7 +244,7 @@ void rds_tcp_write_space(struct sock *sk)
 		queue_delayed_work(rds_wq, &conn->c_send_w, 0);
 
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 
 	/*
 	 * write_space is only called when data leaves tcp's send queue if
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index b6309db..fe9306b 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -800,7 +800,7 @@ static void xs_udp_data_ready(struct sock *sk, int len)
 	u32 _xid;
 	__be32 *xp;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	dprintk("RPC:       xs_udp_data_ready...\n");
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
@@ -852,7 +852,7 @@ static void xs_udp_data_ready(struct sock *sk, int len)
  dropit:
 	skb_free_datagram(sk, skb);
  out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
@@ -1229,7 +1229,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
 
 	dprintk("RPC:       xs_tcp_data_ready...\n");
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
 	if (xprt->shutdown)
@@ -1248,7 +1248,7 @@ static void xs_tcp_data_ready(struct sock *sk, int bytes)
 		read = tcp_read_sock(sk, &rd_desc, xs_tcp_data_recv);
 	} while (read > 0);
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /*
@@ -1301,7 +1301,7 @@ static void xs_tcp_state_change(struct sock *sk)
 {
 	struct rpc_xprt *xprt;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
 	dprintk("RPC:       xs_tcp_state_change client %p...\n", xprt);
@@ -1313,7 +1313,7 @@ static void xs_tcp_state_change(struct sock *sk)
 
 	switch (sk->sk_state) {
 	case TCP_ESTABLISHED:
-		spin_lock_bh(&xprt->transport_lock);
+		spin_lock(&xprt->transport_lock);
 		if (!xprt_test_and_set_connected(xprt)) {
 			struct sock_xprt *transport = container_of(xprt,
 					struct sock_xprt, xprt);
@@ -1327,7 +1327,7 @@ static void xs_tcp_state_change(struct sock *sk)
 
 			xprt_wake_pending_tasks(xprt, -EAGAIN);
 		}
-		spin_unlock_bh(&xprt->transport_lock);
+		spin_unlock(&xprt->transport_lock);
 		break;
 	case TCP_FIN_WAIT1:
 		/* The client initiated a shutdown of the socket */
@@ -1365,7 +1365,7 @@ static void xs_tcp_state_change(struct sock *sk)
 		xs_sock_mark_closed(xprt);
 	}
  out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /**
@@ -1376,7 +1376,7 @@ static void xs_error_report(struct sock *sk)
 {
 	struct rpc_xprt *xprt;
 
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 	if (!(xprt = xprt_from_sock(sk)))
 		goto out;
 	dprintk("RPC:       %s client %p...\n"
@@ -1384,7 +1384,7 @@ static void xs_error_report(struct sock *sk)
 			__func__, xprt, sk->sk_err);
 	xprt_wake_pending_tasks(xprt, -EAGAIN);
 out:
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_write_space(struct sock *sk)
@@ -1416,13 +1416,13 @@ static void xs_write_space(struct sock *sk)
  */
 static void xs_udp_write_space(struct sock *sk)
 {
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 
 	/* from net/core/sock.c:sock_def_write_space */
 	if (sock_writeable(sk))
 		xs_write_space(sk);
 
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 /**
@@ -1437,13 +1437,13 @@ static void xs_udp_write_space(struct sock *sk)
  */
 static void xs_tcp_write_space(struct sock *sk)
 {
-	read_lock(&sk->sk_callback_lock);
+	read_lock_bh(&sk->sk_callback_lock);
 
 	/* from net/core/stream.c:sk_stream_write_space */
 	if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk))
 		xs_write_space(sk);
 
-	read_unlock(&sk->sk_callback_lock);
+	read_unlock_bh(&sk->sk_callback_lock);
 }
 
 static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)



^ permalink raw reply related

* Re: [PATCH 2/2] siw: Add support for CRC32C offload instruction using libcrypto crc32c-intel
From: Nicholas A. Bellinger @ 2010-09-22 22:36 UTC (permalink / raw)
  To: Jason Gunthorpe; +Cc: linux-kernel, netdev, linux-rdma, Bernard Metzler
In-Reply-To: <20100922220611.GL11157@obsidianresearch.com>

On Wed, 2010-09-22 at 16:06 -0600, Jason Gunthorpe wrote:
> On Wed, Sep 22, 2010 at 02:38:31PM -0700, Nicholas A. Bellinger wrote:
> 
> > So I think the main bit here is the ability to request
> > crc32c-intel.ko first, and then fall back to crc32c.ko when the
> > former is not available on CONFIG_X86.
> 
> Well, it is what Andi said, everything is working fine but there is no
> mechanism to autoload the accelerated crypto module. If you did
> modprobe crc32c_intel prior to loading your driver it would
> automatically get crc32c-intel when it asks for crc32c since it is
> loaded and a higher priority.
> 

Ah, OK.  I see what you mean now here wrt to libcrypto priorities and
crc32c + crc32c_intel modules.   My apologies for the in-experience with
libcrypto here..

> So, the drivers are correct to just request crc32c .. The work around
> to limited autoprobing is so trivial (modprob crc32_intel) I'm not
> sure including extra autoprobing code in the drivers is worthwhile?
> 

Indeed, I am happy to drop this patch if Bernard would be nice enough to
add a 'modprobe crc32_intel' into the SIW scripts.

Thanks for your comments Jason!

--nab

^ permalink raw reply

* Re: [PATCH] Use firmware provided index to register a network interface
From: Stephen Hemminger @ 2010-09-22 22:16 UTC (permalink / raw)
  To: Tim Small
  Cc: Narendra K, netdev, linux-hotplug, linux-pci, matt_domsch,
	charles_rose, jordan_hargrave, vijay_nijhawan
In-Reply-To: <4C9A7E39.2020304@buttersideup.com>

On Wed, 22 Sep 2010 23:07:53 +0100
Tim Small <tim@buttersideup.com> wrote:

> Narendra K wrote:
> > Hello,
> >
> > Here is another approach to address the issue of "eth0 does not always
> > map to the Integrated NIC Port 1 as denoted on server chassis label".
> > For more details please refer to the thread -
> > http://marc.info/?l=linux-netdev&m=128163454631618&w=3.
> >   
> 
> 
> Hi,
> 
> Out of interest, that link says that doing it in usespace was rejected,
> but doesn't give any references... I'd be interested to know why this
> wasn't viable - since this seemed like the best fit at first glance -
> most people will never use this, so no need to grow their kernel size
> and complexity?
> 

This proposal was to ad changes into every application that
knows about network names (iproute, iptables, snmp, quagga, openswan, ...)
to do aliasing at the application layer.

I rejected it as an unmanageable since it would require changes to so
many packages (many of which are more BSD focused). Also doing aliasing
would lead to security and other issues. For example, if you write a
iptables rule based on the "Embedded NIC 1" rule would it work and know
when the packet name lookup returned eth0, or what about device names
in the Quagga RIB, ...

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox