Skip to contentSkip to conversation

sky2 update for 2.6.22

PATCH In review Stephen Hemminger 5 participants 29 messages May 9, 2007 – May 15, 2007

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover sky2 update for 2.6.22

Patches are against netdev-2.6 upstream code branch.

This includes a several bug fixes, and code cleanup to use standard functions. There are a couple of PCI changes. One bug fix, and moving common code in PCI base.

--

#1 lore raw

PATCH 1/17 sky2: fix oops on shutdown

If device is not fails during module startup (like unsupported chip version) then driver would crash dereferencing a null pointer.

---
 drivers/net/sky2.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/net/sky2.c +4 -0
@@ -3732,6 +3732,7 @@ err_out_free_regions:
 err_out_disable:
 	pci_disable_device(pdev);
 err_out:
+	pci_set_drvdata(pdev, NULL);
 	return err;
 }
 
@@ -3861,6 +3862,9 @@ static void sky2_shutdown(struct pci_dev
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
 	int i, wol = 0;
 
+	if (!hw)
+		return;
+
 	del_timer_sync(&hw->idle_timer);
 	netif_poll_disable(hw->dev[0]);
 

--

#2 lore raw

PATCH 2/17 sky2: dont restrict config space access

In reply to Stephen Hemminger

Take out the code that protects driver from accessing the PCI config space. We are old enough to run with scissors now.

---
 drivers/net/sky2.c |   11 -----------
 1 file changed, 11 deletions(-)
drivers/net/sky2.c +0 -11
@@ -556,7 +556,6 @@ static void sky2_phy_power(struct sky2_h
 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
 		onoff = !onoff;
 
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
 	if (onoff)
 		/* Turn off phy power saving */
@@ -566,7 +565,6 @@ static void sky2_phy_power(struct sky2_h
 
 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
 	sky2_pci_read32(hw, PCI_DEV_REG1);
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 	udelay(100);
 }
 
@@ -634,11 +632,9 @@ static void sky2_wol_init(struct sky2_po
 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
 
 	/* Turn on legacy PCI-Express PME mode */
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
 	reg1 |= PCI_Y2_PME_LEGACY;
 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
 	/* block receiver */
 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
@@ -2292,10 +2288,8 @@ static void sky2_hw_intr(struct sky2_hw 
 			dev_err(&hw->pdev->dev, "PCI hardware error (0x%x)\n",
 			        pci_err);
 
-		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		sky2_pci_write16(hw, PCI_STATUS,
 				 pci_err | PCI_STATUS_ERROR_BITS);
-		sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 	}
 
 	if (status & Y2_IS_PCI_EXP) {
@@ -2309,10 +2303,8 @@ static void sky2_hw_intr(struct sky2_hw 
 				pex_err);
 
 		/* clear the interrupt */
-		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 		sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
 				       0xffffffffUL);
-		sky2_write32(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 
 		if (pex_err & PEX_FATAL_ERRORS) {
 			u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
@@ -2564,7 +2556,6 @@ static void sky2_reset(struct sky2_hw *h
 	/* clear PCI errors, if any */
 	status = sky2_pci_read16(hw, PCI_STATUS);
 
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
 	sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS);
 
 
@@ -2582,8 +2573,6 @@ static void sky2_reset(struct sky2_hw *h
 		sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
 	}
 
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
 	/* Clear I2C IRQ noise */
 	sky2_write32(hw, B2_I2C_IRQ, 1);
 

--

#3 lore raw

PATCH 3/17 sky2: keep track of receive alloc failures

In reply to Stephen Hemminger

When driver can't allocate receive buffer it drops incoming packet, so update counter.

---
 drivers/net/sky2.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/sky2.c +3 -1
@@ -2132,8 +2132,10 @@ static int sky2_status_intr(struct sky2_
 		switch (le->opcode & ~HW_OWNER) {
 		case OP_RXSTAT:
 			skb = sky2_receive(dev, length, status);
-			if (!skb)
+			if (unlikely(!skb)) {
+				sky2->net_stats.rx_dropped++;
 				goto force_update;
+			}
 
 			skb->protocol = eth_type_trans(skb, dev);
 			sky2->net_stats.rx_packets++;

--

#4 lore raw

PATCH 4/17 sky2: remove dual port workaround

In reply to Stephen Hemminger

This workaround was added to deal with NAPI core and how it affected dual port shared polling. It turned out not to be necessary, the core code in dev_stop() waits for NAPI but doesn't kill it.

---
 drivers/net/sky2.c |    7 -------
 1 file changed, 7 deletions(-)
drivers/net/sky2.c +0 -7
@@ -1570,13 +1570,6 @@ static int sky2_down(struct net_device *
 	imask &= ~portirq_msk[port];
 	sky2_write32(hw, B0_IMSK, imask);
 
-	/*
-	 * Both ports share the NAPI poll on port 0, so if necessary undo the
-	 * the disable that is done in dev_close.
-	 */
-	if (sky2->port == 0 && hw->ports > 1)
-		netif_poll_enable(dev);
-
 	sky2_gmac_reset(hw, port);
 
 	/* Stop transmitter */

--

#5 lore raw

PATCH 5/17 pci: advanced error reporting stub return values

In reply to Stephen Hemminger

The stubs for advanced PCI error reporting are wrong. They don't match the function return values. This breaks compilation for any driver that tries to use these functions (that's the next sky2 patch).

include/linux/aer.h +4 -4
@@ -14,10 +14,10 @@
 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
 #else
-#define pci_enable_pcie_error_reporting(dev)		do { } while (0)
-#define pci_find_aer_capability(dev)			do { } while (0)
-#define pci_disable_pcie_error_reporting(dev)		do { } while (0)
-#define pci_cleanup_aer_uncorrect_error_status(dev)	do { } while (0)
+#define pci_enable_pcie_error_reporting(dev)		(-EINVAL)
+#define pci_find_aer_capability(dev)			(0)
+#define pci_disable_pcie_error_reporting(dev)		(-EINVAL)
+#define pci_cleanup_aer_uncorrect_error_status(dev)	(-EINVAL)
 #endif
 
 #endif //_AER_H_

--

#6 lore raw

Re: [PATCH 05/17] pci: advanced error reporting stub return values

Quoted 15 lines · On Tue, 08 May 2007 20:49:54 -0700 Stephen Hemminger…

The stubs for advanced PCI error reporting are wrong. They don't match the function return values. This breaks compilation for any driver that tries to use these functions (that's the next sky2 patch).

include/linux/aer.h +0 -3
@@ -14,10 +14,10 @@
 extern int pci_disable_pcie_error_reporting(struct pci_dev *dev);
 extern int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev);
 #else
-#define pci_enable_pcie_error_reporting(dev)		do { } while (0)
-#define pci_find_aer_capability(dev)			do { } while (0)
-#define pci_disable_pcie_error_reporting(dev)		do { } while (0)

include/linux/aer.h

Quoted 10 lines
include/linux/aer.h +4 -2
-#define pci_cleanup_aer_uncorrect_error_status(dev)	do { } while (0)
+#define pci_enable_pcie_error_reporting(dev)		(-EINVAL)
+#define pci_find_aer_capability(dev)			(0)
+#define pci_disable_pcie_error_reporting(dev)		(-EINVAL)
+#define pci_cleanup_aer_uncorrect_error_status(dev)	(-EINVAL)
 #endif
 
 #endif //_AER_H_
 
--

Greg could you put this in as a bug fix now.
I don't think I'll put in the usage of aer funcs until 2.6.22 -mm, but hopefully this will be fixed by then.

Signature · 1 line
Stephen Hemminger <[email protected]>
#7 lore raw

PATCH 6/17 sky2: advanced error reporting

In reply to Stephen Hemminger

Use the kernel interfaces for advanced error reporting. This should be cleaner and clear up errors on boot.

Note: for those systems with busted BIOS's that don't correctly support mmconfig, advanced error reporting will be disabled. The PCI registers for advanced error reporting start at 0x100 which is too large to be accessed by legacy functions.

---
 drivers/net/sky2.c |   50 ++++++++++++++++++++++++++++++--------------------
 drivers/net/sky2.h |   41 -----------------------------------------
 2 files changed, 30 insertions(+), 61 deletions(-)
drivers/net/sky2.c +30 -20
@@ -31,6 +31,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/pci.h>
+#include <linux/aer.h>
 #include <linux/ip.h>
 #include <net/ip.h>
 #include <linux/tcp.h>
@@ -2270,7 +2271,11 @@ static void sky2_hw_error(struct sky2_hw
 
 static void sky2_hw_intr(struct sky2_hw *hw)
 {
+	struct pci_dev *pdev = hw->pdev;
 	u32 status = sky2_read32(hw, B0_HWE_ISRC);
+	u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
+
+	status &= hwmsk;
 
 	if (status & Y2_IS_TIST_OV)
 		sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
@@ -2280,32 +2285,34 @@ static void sky2_hw_intr(struct sky2_hw 
 
 		pci_err = sky2_pci_read16(hw, PCI_STATUS);
 		if (net_ratelimit())
-			dev_err(&hw->pdev->dev, "PCI hardware error (0x%x)\n",
+			dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
 			        pci_err);
 
 		sky2_pci_write16(hw, PCI_STATUS,
 				 pci_err | PCI_STATUS_ERROR_BITS);
 	}
 
+	/* PCI-Express error occurred */
 	if (status & Y2_IS_PCI_EXP) {
-		/* PCI-Express uncorrectable Error occurred */
-		u32 pex_err;
+		int pos = pci_find_aer_capability(hw->pdev);
+		u32 status, mask;
+
+		/* should never happen since found capability during reset */
+		BUG_ON(!pos);
 
-		pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &status);
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &mask);
 
 		if (net_ratelimit())
-			dev_err(&hw->pdev->dev, "PCI Express error (0x%x)\n",
-				pex_err);
+			dev_err(&pdev->dev, "PCI Express error (0x%x)\n",
+				status);
 
-		/* clear the interrupt */
-		sky2_pci_write32(hw, PEX_UNC_ERR_STAT,
-				       0xffffffffUL);
-
-		if (pex_err & PEX_FATAL_ERRORS) {
-			u32 hwmsk = sky2_read32(hw, B0_HWE_IMSK);
-			hwmsk &= ~Y2_IS_PCI_EXP;
-			sky2_write32(hw, B0_HWE_IMSK, hwmsk);
-		}
+		if (pdev->error_state == pci_channel_io_normal)
+			status &= ~mask; /* Clear corresponding nonfatal bits */
+		else
+			status &= mask; /* Clear corresponding fatal bits */
+
+		pci_write_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, status);
 	}
 
 	if (status & Y2_HWE_L1_MASK)
@@ -2533,6 +2540,7 @@ static void sky2_reset(struct sky2_hw *h
 {
 	u16 status;
 	int i;
+	u32 hwe_mask = Y2_HWE_ALL_MASK;
 
 	/* disable ASF */
 	if (hw->chip_id == CHIP_ID_YUKON_EX) {
@@ -2550,16 +2558,18 @@ static void sky2_reset(struct sky2_hw *h
 
 	/* clear PCI errors, if any */
 	status = sky2_pci_read16(hw, PCI_STATUS);
-
 	sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS);
 
 
 	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
-	/* clear any PEX errors */
-	if (pci_find_capability(hw->pdev, PCI_CAP_ID_EXP))
-		sky2_pci_write32(hw, PEX_UNC_ERR_STAT, 0xffffffffUL);
+	/* Check for advanced error reporting */
+	if (pci_find_aer_capability(hw->pdev)) {
+		hwe_mask |= Y2_IS_PCI_EXP;
 
+		pci_cleanup_aer_uncorrect_error_status(hw->pdev);
+		pci_enable_pcie_error_reporting(hw->pdev);
+	}
 
 	sky2_power_on(hw);
 
@@ -2606,7 +2616,7 @@ static void sky2_reset(struct sky2_hw *h
 		sky2_write8(hw, RAM_BUFFER(i, B3_RI_RTO_XS2), SK_RI_TO_53);
 	}
 
-	sky2_write32(hw, B0_HWE_IMSK, Y2_HWE_ALL_MASK);
+	sky2_write32(hw, B0_HWE_IMSK, hwe_mask);
 
 	for (i = 0; i < hw->ports; i++)
 		sky2_gmac_reset(hw, i);
drivers/net/sky2.h +0 -41

59 lines not on this page · raw message

--

#8 lore raw

Re: [PATCH 06/17] sky2: advanced error reporting

Quoted 2 lines · Stephen Hemminger

Use the kernel interfaces for advanced error reporting. This should be cleaner and clear up errors on boot.

Hmm. I thought that the AER functions would eventually be handled by the struct pci_error_handlers callbacks, so that dev drivers wouldn't actually have code such as

drivers/net/sky2.c static void sky2_hw_intr(struct sky2_hw · line 2304

Quoted 2 lines
drivers/net/sky2.c +2 -0
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &status);
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &mask);

in them. But perhaps I haven't studed what this drivr is trying to do; nor have I really kept track of the aer code.

--linas

#9 lore raw

Re: [PATCH 06/17] sky2: advanced error reporting

Quoted 7 lines · On Wed, 9 May 2007 12:05:51 -0500 [email protected] (Linas Vepstas) wrote:
Quoted 2 lines · Stephen Hemminger

Use the kernel interfaces for advanced error reporting. This should be cleaner and clear up errors on boot.

Hmm. I thought that the AER functions would eventually be handled by the struct pci_error_handlers callbacks, so that dev drivers wouldn't actually have code such as

No, it doesn't seem to work that way. Those callback seems to be for bus reported errors, not device reported errors.

Quoted 6 lines

drivers/net/sky2.c static void sky2_hw_intr(struct sky2_hw · line 2304

Quoted 2 lines
drivers/net/sky2.c +2 -0
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &status);
+		pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_SEVER, &mask);

in them. But perhaps I haven't studed what this drivr is trying to do; nor have I really kept track of the aer code.

On boot up it clears errors because power on seems to leave a bogus error report.

When error is detected, it gets an IRQ and than has to decode it as PCI error.

Earlier versions of the driver (pre AER) were doing the same thing but with only minimal handling of errors. Now at least it uses common code.

#10 lore raw

PATCH 7/17 sky2: use pci_config access functions

In reply to Stephen Hemminger

Use the PCI layer config access functions. The driver was using the memory mapped window in device, to workaround issues accessing the advanced error reporting registers.

---
 drivers/net/sky2.c |   44 ++++++++++++++++++++++----------------------
 drivers/net/sky2.h |   21 ---------------------
 2 files changed, 22 insertions(+), 43 deletions(-)
drivers/net/sky2.c +22 -22
@@ -220,11 +220,11 @@ static void sky2_power_on(struct sky2_hw
 	if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
 		u32 reg1;
 
-		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
-		reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0);
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG4, &reg1);
 		reg1 &= P_ASPM_CONTROL_MSK;
-		sky2_pci_write32(hw, PCI_DEV_REG4, reg1);
-		sky2_pci_write32(hw, PCI_DEV_REG5, 0);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG4, reg1);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG5, 0);
 	}
 }
 
@@ -556,16 +556,16 @@ static void sky2_phy_power(struct sky2_h
 	/* looks like this XL is back asswards .. */
 	if (hw->chip_id == CHIP_ID_YUKON_XL && hw->chip_rev > 1)
 		onoff = !onoff;
-
-	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+	pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
 	if (onoff)
 		/* Turn off phy power saving */
 		reg1 &= ~phy_power[port];
 	else
 		reg1 |= phy_power[port];
 
-	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
-	sky2_pci_read32(hw, PCI_DEV_REG1);
+	pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
+	pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
+
 	udelay(100);
 }
 
@@ -633,9 +633,9 @@ static void sky2_wol_init(struct sky2_po
 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
 
 	/* Turn on legacy PCI-Express PME mode */
-	reg1 = sky2_pci_read32(hw, PCI_DEV_REG1);
+	pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg1);
 	reg1 |= PCI_Y2_PME_LEGACY;
-	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
+	pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg1);
 
 	/* block receiver */
 	sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
@@ -1216,9 +1216,9 @@ static int sky2_up(struct net_device *de
  		struct sky2_port *osky2 = netdev_priv(otherdev);
  		u16 cmd;
 
- 		cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
+		pci_read_config_word(hw->pdev, cap + PCI_X_CMD, &cmd);
  		cmd &= ~PCI_X_CMD_MAX_SPLIT;
- 		sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
+ 		pci_write_config_word(hw->pdev, cap + PCI_X_CMD, cmd);
 
  		sky2->rx_csum = 0;
  		osky2->rx_csum = 0;
@@ -2283,13 +2283,13 @@ static void sky2_hw_intr(struct sky2_hw 
 	if (status & (Y2_IS_MST_ERR | Y2_IS_IRQ_STAT)) {
 		u16 pci_err;
 
-		pci_err = sky2_pci_read16(hw, PCI_STATUS);
+		pci_read_config_word(pdev, PCI_STATUS, &pci_err);
 		if (net_ratelimit())
 			dev_err(&pdev->dev, "PCI hardware error (0x%x)\n",
 			        pci_err);
 
-		sky2_pci_write16(hw, PCI_STATUS,
-				 pci_err | PCI_STATUS_ERROR_BITS);
+		pci_write_config_word(pdev, PCI_STATUS,
+				      pci_err | PCI_STATUS_ERROR_BITS);
 	}
 
 	/* PCI-Express error occurred */
@@ -2513,7 +2513,7 @@ static int __devinit sky2_init(struct sk
 
 	/* Make sure and enable all clocks */
 	if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
-		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0);
 
 	hw->chip_rev = (sky2_read8(hw, B2_MAC_CFG) & CFG_CHIP_R_MSK) >> 4;
 
@@ -2557,9 +2557,9 @@ static void sky2_reset(struct sky2_hw *h
 	sky2_write8(hw, B0_CTST, CS_RST_CLR);
 
 	/* clear PCI errors, if any */
-	status = sky2_pci_read16(hw, PCI_STATUS);
-	sky2_pci_write16(hw, PCI_STATUS, status | PCI_STATUS_ERROR_BITS);
-
+	pci_read_config_word(hw->pdev, PCI_STATUS, &status);
+	pci_write_config_word(hw->pdev, PCI_STATUS,
+			      status | PCI_STATUS_ERROR_BITS);
 
 	sky2_write8(hw, B0_CTST, CS_MRST_CLR);
 
@@ -3631,9 +3631,9 @@ static int __devinit sky2_probe(struct p
 	 */
 	{
 		u32 reg;
-		reg = sky2_pci_read32(hw, PCI_DEV_REG2);
+		pci_read_config_dword(pdev,PCI_DEV_REG2, &reg);
 		reg &= ~PCI_REV_DESC;
-		sky2_pci_write32(hw, PCI_DEV_REG2, reg);
+		pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
 	}
 #endif
 
@@ -3822,7 +3822,7 @@ static int sky2_resume(struct pci_dev *p
 
 	/* Re-enable all clocks */
 	if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
-		sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0);
 
 	sky2_reset(hw);
 
drivers/net/sky2.h +0 -21
@@ -1973,25 +1973,4 @@ static inline void gma_set_addr(struct s
 	gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8));
 	gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8));
 }
-
-/* PCI config space access */
-static inline u32 sky2_pci_read32(const struct sky2_hw *hw, unsigned reg)
-{
-	return sky2_read32(hw, Y2_CFG_SPC + reg);
-}
-
-static inline u16 sky2_pci_read16(const struct sky2_hw *hw, unsigned reg)
-{
-	return sky2_read16(hw, Y2_CFG_SPC + reg);
-}
-
-static inline void sky2_pci_write32(struct sky2_hw *hw, unsigned reg, u32 val)
-{
-	sky2_write32(hw, Y2_CFG_SPC + reg, val);
-}
-
-static inline void sky2_pci_write16(struct sky2_hw *hw, unsigned reg, u16 val)
-{
-	sky2_write16(hw, Y2_CFG_SPC + reg, val);
-}
 #endif

--

#11 lore raw

PATCH 8/17 sky2: MIB counter overflow handling

In reply to Stephen Hemminger

Make sure that if we ever get a MIB counter overflow interrupt (normally masked off), that it is cleared.

---
 drivers/net/sky2.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/net/sky2.c +6 -0
@@ -2332,6 +2332,12 @@ static void sky2_mac_intr(struct sky2_hw
 		printk(KERN_INFO PFX "%s: mac interrupt status 0x%x\n",
 		       dev->name, status);
 
+	if (status & GM_IS_RX_CO_OV)
+		gma_read16(hw, port, GM_RX_IRQ_SRC);
+
+	if (status & GM_IS_TX_CO_OV)
+		gma_read16(hw, port, GM_TX_IRQ_SRC);
+
 	if (status & GM_IS_RX_FF_OR) {
 		++sky2->net_stats.rx_fifo_errors;
 		sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);

--

#12 lore raw

PATCH 9/17 sky2: memory barriers change

In reply to Stephen Hemminger

Do some memory barrier changes for safety/perfomance:
Don't need read after update to index, mmiowb() followed by read at end of irq is sufficient.

---
 drivers/net/sky2.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/net/sky2.c +11 -4
@@ -836,10 +836,12 @@ static inline struct tx_ring_info *tx_le
 /* Update chip's next pointer */
 static inline void sky2_put_idx(struct sky2_hw *hw, unsigned q, u16 idx)
 {
-	q = Y2_QADDR(q, PREF_UNIT_PUT_IDX);
+	/* Make sure write' to descriptors are complete before we tell hardware */
 	wmb();
-	sky2_write16(hw, q, idx);
-	sky2_read16(hw, q);
+	sky2_write16(hw, Y2_QADDR(q, PREF_UNIT_PUT_IDX), idx);
+
+	/* Synchronize I/O on since next processor may write to tail */
+	mmiowb();
 }
 
 
@@ -971,6 +973,7 @@ stopped:
 
 	/* reset the Rx prefetch unit */
 	sky2_write32(hw, Y2_QADDR(rxq, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
+	mmiowb();
 }
 
 /* Clean out receive buffer area, assumes receiver hardware stopped */
@@ -1190,7 +1193,7 @@ static int sky2_rx_start(struct sky2_por
 	}
 
 	/* Tell chip about available buffers */
-	sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put);
+	sky2_put_idx(hw, rxq, sky2->rx_put);
 	return 0;
 nomem:
 	sky2_rx_clean(sky2);
@@ -1532,6 +1535,8 @@ static void sky2_tx_complete(struct sky2
 	}
 
 	sky2->tx_cons = idx;
+	smp_mb();
+
 	if (tx_avail(sky2) > MAX_SKB_TX_LE + 4)
 		netif_wake_queue(dev);
 }
@@ -2210,6 +2215,7 @@ force_update:
 
 	/* Fully processed status ring so clear irq */
 	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+	mmiowb();
 
 exit_loop:
 	if (buf_write[0]) {
@@ -2436,6 +2442,7 @@ static int sky2_poll(struct net_device *
 	if (work_done < work_limit) {
 		netif_rx_complete(dev0);
 
+		/* end of interrupt, re-enables also acts as I/O synchronization */
 		sky2_read32(hw, B0_Y2_SP_LISR);
 		return 0;
 	} else {

--

#13 lore raw

PATCH 10/17 sky2: add prefetch for next skb on receive

In reply to Stephen Hemminger

Prefetch the next skb information in receive.

---
 drivers/net/sky2.c |    1 +
 1 file changed, 1 insertion(+)
drivers/net/sky2.c +1 -0
@@ -2160,6 +2160,7 @@ force_update:
 			/* Stop after net poll weight */
 			if (++work_done >= to_do)
 				goto exit_loop;
+			prefetch(sky2->rx_ring[sky2->rx_next].skb);
 			break;
 
 #ifdef SKY2_VLAN_TAG_USED

--

#14 lore raw

PATCH 11/17 sky2: use MII defines

In reply to Stephen Hemminger

To make driver easier to understand, use the PHY register definitions from standard mii.h include file rather than those inherited from sk98lin.

---
 drivers/net/sky2.c |   62 +++++++++----------
 drivers/net/sky2.h |  166 ++++-------------------------------------------------
 2 files changed, 43 insertions(+), 185 deletions(-)
drivers/net/sky2.c +30 -32
@@ -268,17 +268,17 @@ static void sky2_gmac_reset(struct sky2_
 /* flow control to advertise bits */
 static const u16 copper_fc_adv[] = {
 	[FC_NONE]	= 0,
-	[FC_TX]		= PHY_M_AN_ASP,
-	[FC_RX]		= PHY_M_AN_PC,
-	[FC_BOTH]	= PHY_M_AN_PC | PHY_M_AN_ASP,
+	[FC_TX]		= ADVERTISE_PAUSE_ASYM,
+	[FC_RX]		= ADVERTISE_PAUSE_CAP,
+	[FC_BOTH]	= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
 };
 
 /* flow control to advertise bits when using 1000BaseX */
 static const u16 fiber_fc_adv[] = {
-	[FC_BOTH] = PHY_M_P_BOTH_MD_X,
-	[FC_TX]   = PHY_M_P_ASYM_MD_X,
-	[FC_RX]	  = PHY_M_P_SYM_MD_X,
-	[FC_NONE] = PHY_M_P_NO_PAUSE_X,
+	[FC_NONE] = 0,
+	[FC_TX]   = ADVERTISE_1000XPAUSE,
+	[FC_RX]	  = ADVERTISE_1000XPSE_ASYM,
+	[FC_BOTH] = ADVERTISE_1000XPAUSE | ADVERTISE_1000XPSE_ASYM,
 };
 
 /* flow control to GMA disable bits */
@@ -360,69 +360,67 @@ static void sky2_phy_init(struct sky2_hw
 			/* for SFP-module set SIGDET polarity to low */
 			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
 			ctrl |= PHY_M_FIB_SIGD_POL;
-			gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+			gm_phy_write(hw, port, MII_BMCR, ctrl);
 		}
 
 		gm_phy_write(hw, port, PHY_MARV_EXT_ADR, pg);
 	}
 
-	ctrl = PHY_CT_RESET;
+	ctrl = BMCR_RESET;
 	ct1000 = 0;
-	adv = PHY_AN_CSMA;
+	adv = ADVERTISE_CSMA;
 	reg = 0;
 
 	if (sky2->autoneg == AUTONEG_ENABLE) {
 		if (sky2_is_copper(hw)) {
 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
-				ct1000 |= PHY_M_1000C_AFD;
+				ct1000 |= ADVERTISE_1000FULL;
 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
-				ct1000 |= PHY_M_1000C_AHD;
+				ct1000 |= ADVERTISE_1000HALF;
 			if (sky2->advertising & ADVERTISED_100baseT_Full)
-				adv |= PHY_M_AN_100_FD;
+				adv |= ADVERTISE_100FULL;
 			if (sky2->advertising & ADVERTISED_100baseT_Half)
-				adv |= PHY_M_AN_100_HD;
+				adv |= ADVERTISE_100HALF;
 			if (sky2->advertising & ADVERTISED_10baseT_Full)
-				adv |= PHY_M_AN_10_FD;
+				adv |= ADVERTISE_10FULL;
 			if (sky2->advertising & ADVERTISED_10baseT_Half)
-				adv |= PHY_M_AN_10_HD;
+				adv |= ADVERTISE_10HALF;
 
 			adv |= copper_fc_adv[sky2->flow_mode];
 		} else {	/* special defines for FIBER (88E1040S only) */
 			if (sky2->advertising & ADVERTISED_1000baseT_Full)
-				adv |= PHY_M_AN_1000X_AFD;
+				adv |= ADVERTISE_1000XFULL;
 			if (sky2->advertising & ADVERTISED_1000baseT_Half)
-				adv |= PHY_M_AN_1000X_AHD;
+				adv |= ADVERTISE_1000XHALF;
 
 			adv |= fiber_fc_adv[sky2->flow_mode];
 		}
 
 		/* Restart Auto-negotiation */
-		ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG;
+		ctrl |= BMCR_ANRESTART | BMCR_ANENABLE;
 	} else {
 		/* forced speed/duplex settings */
-		ct1000 = PHY_M_1000C_MSE;
 
 		/* Disable auto update for duplex flow control and speed */
 		reg |= GM_GPCR_AU_ALL_DIS;
 
 		switch (sky2->speed) {
 		case SPEED_1000:
-			ctrl |= PHY_CT_SP1000;
+			ctrl |= BMCR_SPEED1000;
 			reg |= GM_GPCR_SPEED_1000;
 			break;
 		case SPEED_100:
-			ctrl |= PHY_CT_SP100;
+			ctrl |= BMCR_SPEED100;
 			reg |= GM_GPCR_SPEED_100;
 			break;
 		}
 
 		if (sky2->duplex == DUPLEX_FULL) {
 			reg |= GM_GPCR_DUP_FULL;
-			ctrl |= PHY_CT_DUP_MD;
+			ctrl |= BMCR_FULLDPLX;
 		} else if (sky2->speed < SPEED_1000)
 			sky2->flow_mode = FC_NONE;
 
-
  		reg |= gm_fc_disable[sky2->flow_mode];
 
 		/* Forward pause packets to GMAC? */
@@ -435,10 +433,10 @@ static void sky2_phy_init(struct sky2_hw
 	gma_write16(hw, port, GM_GP_CTRL, reg);
 
 	if (hw->chip_id != CHIP_ID_YUKON_FE)
-		gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
+		gm_phy_write(hw, port, MII_CTRL1000, ct1000);
 
-	gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
-	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+	gm_phy_write(hw, port, MII_ADVERTISE, adv);
+	gm_phy_write(hw, port, MII_BMCR, ctrl);
 
 	/* Setup Phy LED's */
 	ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS);
@@ -661,8 +659,8 @@ static void sky2_mac_init(struct sky2_hw
 		do {
 			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_SET);
 			sky2_write8(hw, SK_REG(1, GMAC_CTRL), GMC_RST_CLR);
-		} while (gm_phy_read(hw, 1, PHY_MARV_ID0) != PHY_MARV_ID0_VAL ||
-			 gm_phy_read(hw, 1, PHY_MARV_ID1) != PHY_MARV_ID1_Y2 ||
+		} while (gm_phy_read(hw, 1, MII_PHYSID1) != ID1_MARVELL ||
+			 gm_phy_read(hw, 1, MII_PHYSID2) != ID2_Y2 ||
 			 gm_phy_read(hw, 1, PHY_MARV_INT_MASK) != 0);
 	}
 
@@ -1762,9 +1760,9 @@ static int sky2_autoneg_done(struct sky2
 	unsigned port = sky2->port;
 	u16 advert, lpa;
 
-	advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
-	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
-	if (lpa & PHY_M_AN_RF) {
+	advert = gm_phy_read(hw, port, MII_ADVERTISE);
+	lpa = gm_phy_read(hw, port, MII_LPA);
+	if (lpa & LPA_RFAULT) {
 		printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
 		return -1;
 	}
drivers/net/sky2.h +13 -153

216 lines not on this page · raw message

--

#15 lore raw

PATCH 12/17 sky2: chip id enum

In reply to Stephen Hemminger

Make the chip id value's an enum. This makes it possible for GCC to do better type checking for us.

---
 drivers/net/sky2.h |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/net/sky2.h +8 -5
@@ -332,24 +332,27 @@ enum {
 };
 
 /*	B2_CHIP_ID		 8 bit 	Chip Identification Number */
-enum {
+enum sky2_chip_id {
 	CHIP_ID_YUKON_XL   = 0xb3, /* Chip ID for YUKON-2 XL */
 	CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
 	CHIP_ID_YUKON_EX   = 0xb5, /* Chip ID for YUKON-2 Extreme */
 	CHIP_ID_YUKON_EC   = 0xb6, /* Chip ID for YUKON-2 EC */
  	CHIP_ID_YUKON_FE   = 0xb7, /* Chip ID for YUKON-2 FE */
+};
 
+enum yukon_ec_rev {
 	CHIP_REV_YU_EC_A1    = 0,  /* Chip Rev. for Yukon-EC A1/A0 */
 	CHIP_REV_YU_EC_A2    = 1,  /* Chip Rev. for Yukon-EC A2 */
 	CHIP_REV_YU_EC_A3    = 2,  /* Chip Rev. for Yukon-EC A3 */
-
+};
+enum yukon_ec_u_rev {
 	CHIP_REV_YU_EC_U_A0  = 1,
 	CHIP_REV_YU_EC_U_A1  = 2,
 	CHIP_REV_YU_EC_U_B0  = 3,
-
+};
+enum yukon_fe_rev {
 	CHIP_REV_YU_FE_A1    = 1,
 	CHIP_REV_YU_FE_A2    = 2,
-
 };
 
 /*	B2_Y2_CLK_GATE	 8 bit	Clock Gating (Yukon-2 only) */
@@ -1753,7 +1756,7 @@ struct sky2_hw {
 	struct pci_dev	     *pdev;
 	struct net_device    *dev[2];
 
-	u8	     	     chip_id;
+	enum sky2_chip_id    chip_id;
 	u8		     chip_rev;
 	u8		     pmd_type;
 	u8		     ports;

--

#16 lore raw

PATCH 13/17 sky2: whitespace cleanups

In reply to Stephen Hemminger

Get rid of extra whitespace and break long lines. Add white space around operators.

---
 drivers/net/sky2.c |  135 ++++++++++++++++++++++++++---------------------------
 1 file changed, 67 insertions(+), 68 deletions(-)
drivers/net/sky2.c +67 -68
@@ -60,7 +60,7 @@
  * similar to Tigon3.
  */
 
-#define RX_LE_SIZE	    	1024
+#define RX_LE_SIZE		1024
 #define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
 #define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING		RX_MAX_PENDING
@@ -105,7 +105,7 @@ static const struct pci_device_id sky2_i
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },	/* DGE-560T */
-	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, 	/* DGE-550SX */
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) },	/* DGE-550SX */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B02) },	/* DGE-560SX */
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4B03) },	/* DGE-550T */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) }, /* 88E8021 */
@@ -145,7 +145,7 @@ static const u32 portirq_msk[] = { Y2_IS
 /* This driver supports yukon2 chipset only */
 static const char *yukon2_name[] = {
 	"XL",		/* 0xb3 */
-	"EC Ultra", 	/* 0xb4 */
+	"EC Ultra",	/* 0xb4 */
 	"Extreme",	/* 0xb5 */
 	"EC",		/* 0xb6 */
 	"FE",		/* 0xb7 */
@@ -170,7 +170,7 @@ static int gm_phy_write(struct sky2_hw *
 	return -ETIMEDOUT;
 }
 
-static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 *val)
+static int __gm_phy_read(struct sky2_hw *hw, unsigned port, u16 reg, u16 * val)
 {
 	int i;
 
@@ -194,11 +194,11 @@ static u16 gm_phy_read(struct sky2_hw *h
 	u16 v;
 
 	if (__gm_phy_read(hw, port, reg, &v) != 0)
-		printk(KERN_WARNING PFX "%s: phy read timeout\n", hw->dev[port]->name);
+		printk(KERN_WARNING PFX "%s: phy read timeout\n",
+		       hw->dev[port]->name);
 	return v;
 }
 
-
 static void sky2_power_on(struct sky2_hw *hw)
 {
 	/* switch power to VCC (WA for VAUX problem) */
@@ -289,7 +289,6 @@ static const u16 gm_fc_disable[] = {
 	[FC_BOTH] = 0,
 };
 
-
 static void sky2_phy_init(struct sky2_hw *hw, unsigned port)
 {
 	struct sky2_port *sky2 = netdev_priv(hw->dev[port]);
@@ -353,7 +352,7 @@ static void sky2_phy_init(struct sky2_hw
 		ctrl |= PHY_M_MAC_MODE_SEL(PHY_M_MAC_MD_1000BX);
 		gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
 
-		if (hw->pmd_type  == 'P') {
+		if (hw->pmd_type == 'P') {
 			/* select page 1 to access Fiber registers */
 			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 1);
 
@@ -421,7 +420,7 @@ static void sky2_phy_init(struct sky2_hw
 		} else if (sky2->speed < SPEED_1000)
 			sky2->flow_mode = FC_NONE;
 
- 		reg |= gm_fc_disable[sky2->flow_mode];
+		reg |= gm_fc_disable[sky2->flow_mode];
 
 		/* Forward pause packets to GMAC? */
 		if (sky2->flow_mode & FC_RX)
@@ -607,8 +606,8 @@ static void sky2_wol_init(struct sky2_po
 
 	/* Set GMAC to no flow control and auto update for speed/duplex */
 	gma_write16(hw, port, GM_GP_CTRL,
-		    GM_GPCR_FC_TX_DIS|GM_GPCR_TX_ENA|GM_GPCR_RX_ENA|
-		    GM_GPCR_DUP_FULL|GM_GPCR_FC_RX_DIS|GM_GPCR_AU_FCT_DIS);
+		    GM_GPCR_FC_TX_DIS | GM_GPCR_TX_ENA | GM_GPCR_RX_ENA |
+		    GM_GPCR_DUP_FULL | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS);
 
 	/* Set WOL address */
 	memcpy_toio(hw->regs + WOL_REGS(port, WOL_MAC_ADDR),
@@ -618,16 +617,18 @@ static void sky2_wol_init(struct sky2_po
 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), WOL_CTL_CLEAR_RESULT);
 	ctrl = 0;
 	if (sky2->wol & WAKE_PHY)
-		ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG|WOL_CTL_ENA_LINK_CHG_UNIT;
+		ctrl |= WOL_CTL_ENA_PME_ON_LINK_CHG | WOL_CTL_ENA_LINK_CHG_UNIT;
 	else
-		ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG|WOL_CTL_DIS_LINK_CHG_UNIT;
+		ctrl |= WOL_CTL_DIS_PME_ON_LINK_CHG | WOL_CTL_DIS_LINK_CHG_UNIT;
 
 	if (sky2->wol & WAKE_MAGIC)
-		ctrl |= WOL_CTL_ENA_PME_ON_MAGIC_PKT|WOL_CTL_ENA_MAGIC_PKT_UNIT;
+		ctrl |=
+		    WOL_CTL_ENA_PME_ON_MAGIC_PKT | WOL_CTL_ENA_MAGIC_PKT_UNIT;
 	else
-		ctrl |= WOL_CTL_DIS_PME_ON_MAGIC_PKT|WOL_CTL_DIS_MAGIC_PKT_UNIT;;
+		ctrl |=
+		    WOL_CTL_DIS_PME_ON_MAGIC_PKT | WOL_CTL_DIS_MAGIC_PKT_UNIT;;
 
-	ctrl |= WOL_CTL_DIS_PME_ON_PATTERN|WOL_CTL_DIS_PATTERN_UNIT;
+	ctrl |= WOL_CTL_DIS_PME_ON_PATTERN | WOL_CTL_DIS_PATTERN_UNIT;
 	sky2_write16(hw, WOL_REGS(port, WOL_CTRL_STAT), ctrl);
 
 	/* Turn on legacy PCI-Express PME mode */
@@ -648,7 +649,7 @@ static void sky2_mac_init(struct sky2_hw
 	const u8 *addr = hw->dev[port]->dev_addr;
 
 	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR|GPC_ENA_PAUSE);
+	sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR | GPC_ENA_PAUSE);
 
 	sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR);
 
@@ -727,15 +728,16 @@ static void sky2_mac_init(struct sky2_hw
 	sky2_write16(hw, SK_REG(port, RX_GMF_FL_MSK), GMR_FS_ANY_ERR);
 
 	/* Set threshold to 0xa (64 bytes) + 1 to workaround pause bug  */
-	sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1);
+	sky2_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF + 1);
 
 	/* Configure Tx MAC FIFO */
 	sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR);
 	sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 
-	if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) {
-		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
-		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U
+	    || hw->chip_id == CHIP_ID_YUKON_EX) {
+		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768 / 8);
+		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024 / 8);
 
 		/* set Tx GMAC FIFO Almost Empty Threshold */
 		sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
@@ -757,8 +759,8 @@ static void sky2_ramset(struct sky2_hw *
 	u32 end;
 
 	/* convert from K bytes to qwords used for hw register */
-	start *= 1024/8;
-	space *= 1024/8;
+	start *= 1024 / 8;
+	space *= 1024 / 8;
 	end = start + space - 1;
 
 	sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
@@ -768,18 +770,18 @@ static void sky2_ramset(struct sky2_hw *
 	sky2_write32(hw, RB_ADDR(q, RB_RP), start);
 
 	if (q == Q_R1 || q == Q_R2) {
-		u32 tp = space - space/4;
+		u32 tp = space - space / 4;
 
 		/* On receive queue's set the thresholds
 		 * give receiver priority when > 3/4 full
 		 * send pause when down to 2K
 		 */
 		sky2_write32(hw, RB_ADDR(q, RB_RX_UTHP), tp);
-		sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space/2);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTHP), space / 2);
 
-		tp = space - 2048/8;
+		tp = space - 2048 / 8;
 		sky2_write32(hw, RB_ADDR(q, RB_RX_UTPP), tp);
-		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space/4);
+		sky2_write32(hw, RB_ADDR(q, RB_RX_LTPP), space / 4);
 	} else {
 		/* Enable store & forward on Tx queue's because
 		 * Tx FIFO is only 1K on Yukon
@@ -797,19 +799,19 @@ static void sky2_qset(struct sky2_hw *hw
 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_RESET);
 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_OPER_INIT);
 	sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_FIFO_OP_ON);
-	sky2_write32(hw, Q_ADDR(q, Q_WM),  BMU_WM_DEFAULT);
+	sky2_write32(hw, Q_ADDR(q, Q_WM), BMU_WM_DEFAULT);
 }
 
 /* Setup prefetch unit registers. This is the interface between
  * hardware and driver list elements
  */
 static void sky2_prefetch_init(struct sky2_hw *hw, u32 qaddr,
-				      u64 addr, u32 last)
+			       u64 addr, u32 last)
 {
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_SET);
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_RST_CLR);
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_HI), addr >> 32);
-	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32) addr);
+	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_ADDR_LO), (u32)addr);
 	sky2_write16(hw, Y2_QADDR(qaddr, PREF_UNIT_LAST_IDX), last);
 	sky2_write32(hw, Y2_QADDR(qaddr, PREF_UNIT_CTRL), PREF_UNIT_OP_ON);
 
@@ -842,7 +844,6 @@ static inline void sky2_put_idx(struct s
 	mmiowb();
 }
 
-
 static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
 {
 	struct sky2_rx_le *le = sky2->rx_le + sky2->rx_put;
@@ -858,7 +859,7 @@ static inline u32 high32(dma_addr_t a)
 }
 
 /* Build description to hardware for one receive segment */
-static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
+static void sky2_rx_add(struct sky2_port *sky2, u8 op,
 			dma_addr_t map, unsigned len)
 {
 	struct sky2_rx_le *le;
@@ -889,7 +890,6 @@ static void sky2_rx_submit(struct sky2_p
 		sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE);
 }
 
-
 static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re,
 			    unsigned size)
 {
@@ -1082,7 +1082,7 @@ static struct sk_buff *sky2_rx_alloc(str
 	if (!skb)
 		goto nomem;
 
-	p = (unsigned long) skb->data;
+	p = (unsigned long)skb->data;
 	skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p);
 
 	for (i = 0; i < sky2->rx_nfrags; i++) {
@@ -1209,21 +1209,21 @@ static int sky2_up(struct net_device *de
 	struct net_device *otherdev = hw->dev[sky2->port^1];
 
 	/*
- 	 * On dual port PCI-X card, there is an problem where status
+	 * On dual port PCI-X card, there is an problem where status
 	 * can be received out of order due to split transactions
 	 */
 	if (otherdev && netif_running(otherdev) &&
- 	    (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
- 		struct sky2_port *osky2 = netdev_priv(otherdev);
- 		u16 cmd;
+	    (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
+		struct sky2_port *osky2 = netdev_priv(otherdev);
+		u16 cmd;
 
 		pci_read_config_word(hw->pdev, cap + PCI_X_CMD, &cmd);
- 		cmd &= ~PCI_X_CMD_MAX_SPLIT;
- 		pci_write_config_word(hw->pdev, cap + PCI_X_CMD, cmd);
+		cmd &= ~PCI_X_CMD_MAX_SPLIT;
+		pci_write_config_word(hw->pdev, cap + PCI_X_CMD, cmd);
 
- 		sky2->rx_csum = 0;
- 		osky2->rx_csum = 0;
- 	}
+		sky2->rx_csum = 0;
+		osky2->rx_csum = 0;
+	}
 
 	if (netif_msg_ifup(sky2))
 		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
@@ -1267,7 +1267,7 @@ static int sky2_up(struct net_device *de
 		if (ramsize < 16)
 			rxspace = ramsize / 2;
 		else
-			rxspace = 8 + (2*(ramsize - 16))/3;
+			rxspace = 8 + (2 * (ramsize - 16)) / 3;
 
 		sky2_ramset(hw, rxqaddr[port], 0, rxspace);
 		sky2_ramset(hw, txqaddr[port], rxspace, ramsize - rxspace);
@@ -1365,8 +1365,8 @@ static int sky2_xmit_frame(struct sk_buf
 	u16 mss;
 	u8 ctrl;
 
- 	if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
-  		return NETDEV_TX_BUSY;
+	if (unlikely(tx_avail(sky2) < tx_le_req(skb)))
+		return NETDEV_TX_BUSY;
 
 	if (unlikely(netif_msg_tx_queued(sky2)))
 		printk(KERN_DEBUG "%s: tx queued, slot %u, len %d\n",
@@ -1387,7 +1387,7 @@ static int sky2_xmit_frame(struct sk_buf
 	/* Check for TCP Segmentation Offload */
 	mss = skb_shinfo(skb)->gso_size;
 	if (mss != 0) {
-		mss += tcp_optlen(skb); /* TCP options */
+		mss += tcp_optlen(skb);	/* TCP options */
 		mss += ip_hdrlen(skb) + sizeof(struct tcphdr);
 		mss += ETH_HLEN;
 
@@ -1406,7 +1406,7 @@ static int sky2_xmit_frame(struct sk_buf
 		if (!le) {
 			le = get_tx_le(sky2);
 			le->addr = 0;
-			le->opcode = OP_VLAN|HW_OWNER;
+			le->opcode = OP_VLAN | HW_OWNER;
 		} else
 			le->opcode |= OP_VLAN;
 		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1419,7 +1419,7 @@ static int sky2_xmit_frame(struct sk_buf
 		const unsigned offset = skb_transport_offset(skb);
 		u32 tcpsum;
 
-		tcpsum = offset << 16;		/* sum start */
+		tcpsum = offset << 16;	/* sum start */
 		tcpsum |= offset + skb->csum_offset;	/* sum write */
 
 		ctrl = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM;
@@ -1504,7 +1504,7 @@ static void sky2_tx_complete(struct sky2
 		struct sky2_tx_le *le = sky2->tx_le + idx;
 		struct tx_ring_info *re = sky2->tx_ring + idx;
 
-		switch(le->opcode & ~HW_OWNER) {
+		switch (le->opcode & ~HW_OWNER) {
 		case OP_LARGESEND:
 		case OP_PACKET:
 			pci_unmap_single(pdev,
@@ -1695,7 +1695,7 @@ static void sky2_link_up(struct sky2_por
 		u16 pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
 		u16 led = PHY_M_LEDC_LOS_CTRL(1);	/* link active */
 
-		switch(sky2->speed) {
+		switch (sky2->speed) {
 		case SPEED_10:
 			led |= PHY_M_LEDC_INIT_CTRL(7);
 			break;
@@ -1994,7 +1994,7 @@ static void skb_put_frags(struct sk_buff
 			__free_page(frag->page);
 			--skb_shinfo(skb)->nr_frags;
 		} else {
-			size = min(length, (unsigned) PAGE_SIZE);
+			size = min(length, (unsigned)PAGE_SIZE);
 
 			frag->size = size;
 			skb->data_len += size;
@@ -2041,7 +2041,7 @@ static struct sk_buff *receive_new(struc
 static struct sk_buff *sky2_receive(struct net_device *dev,
 				    u16 length, u32 status)
 {
- 	struct sky2_port *sky2 = netdev_priv(dev);
+	struct sky2_port *sky2 = netdev_priv(dev);
 	struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
 	struct sk_buff *skb = NULL;
 
@@ -2111,7 +2111,7 @@ static int sky2_status_intr(struct sky2_
 	rmb();
 
 	while (hw->st_idx != hwidx) {
-		struct sky2_status_le *le  = hw->st_le + hw->st_idx;
+		struct sky2_status_le *le = hw->st_le + hw->st_idx;
 		struct net_device *dev;
 		struct sk_buff *skb;
 		u32 status;
@@ -2384,7 +2384,7 @@ static inline void sky2_idle_start(struc
 
 static void sky2_idle(unsigned long arg)
 {
-	struct sky2_hw *hw = (struct sky2_hw *) arg;
+	struct sky2_hw *hw = (struct sky2_hw *)arg;
 	struct net_device *dev = hw->dev[0];
 
 	if (__netif_rx_schedule_prep(dev))
@@ -2876,12 +2876,12 @@ static const struct sky2_stat {
 	{ "rx_mac_pause",  GM_RXF_MPAUSE },
 	{ "collisions",    GM_TXF_COL },
 	{ "late_collision",GM_TXF_LAT_COL },
-	{ "aborted", 	   GM_TXF_ABO_COL },
+	{ "aborted",	   GM_TXF_ABO_COL },
 	{ "single_collisions", GM_TXF_SNG_COL },
 	{ "multi_collisions", GM_TXF_MUL_COL },
 
 	{ "rx_short",      GM_RXF_SHT },
-	{ "rx_runt", 	   GM_RXE_FRAG },
+	{ "rx_runt",	   GM_RXE_FRAG },
 	{ "rx_64_byte_packets", GM_RXF_64B },
 	{ "rx_65_to_127_byte_packets", GM_RXF_127B },
 	{ "rx_128_to_255_byte_packets", GM_RXF_255B },
@@ -3019,7 +3019,7 @@ static int sky2_set_mac_address(struct n
 	return 0;
 }
 
-static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
+static void inline sky2_add_filter(u8 filter[8], const u8 * addr)
 {
 	u32 bit;
 
@@ -3096,7 +3096,7 @@ static void sky2_led(struct sky2_hw *hw,
 
 	default:
 		gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0);
-		gm_phy_write(hw, port, PHY_MARV_LED_OVER, 
+		gm_phy_write(hw, port, PHY_MARV_LED_OVER,
 			     on ? PHY_M_LED_ALL : 0);
 	}
 }
@@ -3239,11 +3239,11 @@ static int sky2_set_coalesce(struct net_
 	    ecmd->rx_coalesce_usecs_irq > tmax)
 		return -EINVAL;
 
-	if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE-1)
+	if (ecmd->tx_max_coalesced_frames >= TX_RING_SIZE - 1)
 		return -EINVAL;
 	if (ecmd->rx_max_coalesced_frames > RX_MAX_PENDING)
 		return -EINVAL;
-	if (ecmd->rx_max_coalesced_frames_irq >RX_MAX_PENDING)
+	if (ecmd->rx_max_coalesced_frames_irq > RX_MAX_PENDING)
 		return -EINVAL;
 
 	if (ecmd->tx_coalesce_usecs == 0)
@@ -3367,7 +3367,6 @@ static int sky2_set_tx_csum(struct net_d
 	return ethtool_op_set_tx_csum(dev, data);
 }
 
-
 static int sky2_set_tso(struct net_device *dev, u32 data)
 {
 	if (data && no_tx_offload(dev))
@@ -3527,7 +3526,7 @@ static int __devinit sky2_test_msi(struc
 	struct pci_dev *pdev = hw->pdev;
 	int err;
 
-	init_waitqueue_head (&hw->msi_wait);
+	init_waitqueue_head(&hw->msi_wait);
 
 	sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
 
@@ -3540,7 +3539,7 @@ static int __devinit sky2_test_msi(struc
 	sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
 	sky2_read8(hw, B0_CTST);
 
-	wait_event_timeout(hw->msi_wait, hw->msi, HZ/10);
+	wait_event_timeout(hw->msi_wait, hw->msi, HZ / 10);
 
 	if (!hw->msi) {
 		/* MSI test failed, go back to INTx mode */
@@ -3675,10 +3674,10 @@ static int __devinit sky2_probe(struct p
 	if (!disable_msi && pci_enable_msi(pdev) == 0) {
 		err = sky2_test_msi(hw);
 		if (err == -EOPNOTSUPP)
- 			pci_disable_msi(pdev);
+			pci_disable_msi(pdev);
 		else if (err)
 			goto err_out_free_netdev;
- 	}
+	}
 
 	err = register_netdev(dev);
 	if (err) {
@@ -3686,7 +3685,7 @@ static int __devinit sky2_probe(struct p
 		goto err_out_free_netdev;
 	}
 
-	err = request_irq(pdev->irq,  sky2_intr, hw->msi ? 0 : IRQF_SHARED,
+	err = request_irq(pdev->irq, sky2_intr, hw->msi ? 0 : IRQF_SHARED,
 			  dev->name, hw);
 	if (err) {
 		dev_err(&pdev->dev, "cannot assign irq %d\n", pdev->irq);
@@ -3711,7 +3710,7 @@ static int __devinit sky2_probe(struct p
 			sky2_show_addr(dev1);
 	}
 
-	setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
+	setup_timer(&hw->idle_timer, sky2_idle, (unsigned long)hw);
 	INIT_WORK(&hw->restart_work, sky2_restart);
 
 	sky2_idle_start(hw);

--

#17 lore raw

PATCH 14/17 pci_wake_enabled function

In reply to Stephen Hemminger

Both skge and sky2 drivers have test to see if PCI wakeup is enabled in the BIOS. It makes sense to move this to common code.

---
 drivers/net/skge.c  |   18 ------------------
 drivers/net/sky2.c  |   11 -----------
 drivers/pci/pci.c   |   22 ++++++++++++++++++++++
 include/linux/pci.h |    1 +
 4 files changed, 23 insertions(+), 29 deletions(-)
drivers/net/skge.c +0 -18
@@ -144,24 +144,6 @@ static u32 wol_supported(const struct sk
 	return WAKE_MAGIC | WAKE_PHY;
 }
 
-static u32 pci_wake_enabled(struct pci_dev *dev)
-{
-	int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
-	u16 value;
-
-	/* If device doesn't support PM Capabilities, but request is to disable
-	 * wake events, it's a nop; otherwise fail */
-	if (!pm)
-		return 0;
-
-	pci_read_config_word(dev, pm + PCI_PM_PMC, &value);
-
-	value &= PCI_PM_CAP_PME_MASK;
-	value >>= ffs(PCI_PM_CAP_PME_MASK) - 1;   /* First bit of mask */
-
-	return value != 0;
-}
-
 static void skge_wol_init(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
drivers/net/sky2.c +0 -11
@@ -3558,17 +3558,6 @@ static int __devinit sky2_test_msi(struc
 	return err;
 }
 
-static int __devinit pci_wake_enabled(struct pci_dev *dev)
-{
-	int pm  = pci_find_capability(dev, PCI_CAP_ID_PM);
-	u16 value;
-
-	if (!pm)
-		return 0;
-	if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
-		return 0;
-	return value & PCI_PM_CTRL_PME_ENABLE;
-}
 
 static int __devinit sky2_probe(struct pci_dev *pdev,
 				const struct pci_device_id *ent)
drivers/pci/pci.c +22 -0
@@ -991,6 +991,27 @@ int pci_enable_wake(struct pci_dev *dev,
 	return 0;
 }
 
+/**
+ * pci_wake_enabled - is wakeup event from this PCI device entabled
+ * @dev: PCI device affected
+ *
+ * This checks if device has a wakeup event source.
+ *
+ * 0 is returned if the device is not a wakeup event source.
+ * 1 is returned if the device cat generate wakeup events.
+ */
+int pci_wake_enabled(struct pci_dev *dev)
+{
+	int pm  = pci_find_capability(dev, PCI_CAP_ID_PM);
+	u16 value;
+
+	if (!pm)
+		return 0;
+	if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
+		return 0;
+	return (value & PCI_PM_CTRL_PME_ENABLE) != 0;
+}
+
 int
 pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
 {
@@ -1454,5 +1475,6 @@ EXPORT_SYMBOL(pci_set_power_state);
 EXPORT_SYMBOL(pci_save_state);
 EXPORT_SYMBOL(pci_restore_state);
 EXPORT_SYMBOL(pci_enable_wake);
+EXPORT_SYMBOL(pci_wake_enabled);
 EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state);
 
include/linux/pci.h +1 -0
@@ -567,6 +567,7 @@ int pci_restore_state(struct pci_dev *de
 int pci_set_power_state(struct pci_dev *dev, pci_power_t state);
 pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state);
 int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable);
+int pci_wake_enabled(struct pci_dev *dev);
 
 /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */
 void pci_bus_assign_resources(struct pci_bus *bus);

--

#18 lore raw

PATCH 15/17 sky2: only disable 88e8056 on some boards

In reply to Stephen Hemminger

Use DMI to add a blacklist of broken board. For now only one is known bad. Gentoo users report driver works on other motherboards (strange).

Hopefully, the problems will be solved later, and the the whole blacklist can disappear.

---
 drivers/net/sky2.c |   41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)
drivers/net/sky2.c +30 -11
@@ -41,6 +41,7 @@
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <linux/mii.h>
+#include <linux/dmi.h>
 
 #include <asm/irq.h>
 
@@ -151,6 +152,8 @@ static const char *yukon2_name[] = {
 	"FE",		/* 0xb7 */
 };
 
+static int broken_ec_u;			/* blacklist */
+
 /* Access to external PHY */
 static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
 {
@@ -2519,10 +2522,21 @@ static int __devinit sky2_init(struct sk
 		return -EOPNOTSUPP;
 	}
 
+
 	if (hw->chip_id == CHIP_ID_YUKON_EX)
 		dev_warn(&hw->pdev->dev, "this driver not yet tested on this chip type\n"
 			 "Please report success or failure to <[email protected]>\n");
 
+
+	/* Some Gigabyte motherboards have 88e8056 but cause problems
+	 * There is some unresolved hardware related problem that causes
+	 * descriptor errors and receive data corruption.
+	 */
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U && broken_ec_u) {
+		dev_err(&hw->pdev->dev, "broken 88e8056 detected.\n");
+		return -EOPNOTSUPP;
+	}
+
 	/* Make sure and enable all clocks */
 	if (hw->chip_id == CHIP_ID_YUKON_EX || hw->chip_id == CHIP_ID_YUKON_EC_U)
 		pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0);
@@ -3572,17 +3586,6 @@ static int __devinit sky2_probe(struct p
 		goto err_out;
 	}
 
-	/* Some Gigabyte motherboards have 88e8056 but cause problems
-	 * There is some unresolved hardware related problem that causes
-	 * descriptor errors and receive data corruption.
-	 */
-	if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
-	    pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
-		dev_err(&pdev->dev,
-			"88E8056 on Gigabyte motherboards not supported\n");
-		goto err_out_disable;
-	}
-
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
@@ -3895,8 +3898,24 @@ static struct pci_driver sky2_driver = {
 	.shutdown = sky2_shutdown,
 };
 
+
+static struct dmi_system_id __initdata gigabyte_dmi_table[] = {
+	{
+		.ident = "Gigabyte 965P-S3",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),
+
+		},
+	},
+	{ }
+};
+
 static int __init sky2_init_module(void)
 {
+	if (dmi_check_system(gigabyte_dmi_table))
+		broken_ec_u = 1;
+
 	return pci_register_driver(&sky2_driver);
 }
 

--

#19 lore raw

PATCH 15/17 sky2: only disable 88e8056 on some boards

Hi Stephen,

Quoted 2 lines · Stephen Hemminger

Use DMI to add a blacklist of broken board. For now only one is known bad. Gentoo users report driver works on other motherboards (strange).

[snip]

Quoted 5 lines
drivers/net/sky2.c +3 -0
+               .ident = "Gigabyte 965P-S3",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., 

Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),

Actually, I've been using sky2 with a 965P-S3 for a couple of months (x86_64 kernel) and as far as I can tell it works like a charm. Recently I had to hack around the blacklisting but other than that I haven't noticed anything strange.

What failures are you trying to prevent? Would a warning (instead of blacklisting) be acceptable?

Thanks,
Florin

04:00.0 Ethernet controller: Marvell Technology Group Ltd. 88E8056 PCI-E Gigabit Ethernet Controller (rev 12)
Subsystem: Giga-byte Technology Unknown device e000
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR-
Latency: 0, Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 315
Region 0: Memory at f5000000 (64-bit, non-prefetchable) [size=16K]
Region 2: I/O ports at 9000 [size=256]
[virtual] Expansion ROM at 80000000 [disabled] [size=128K]
Capabilities: [48] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [50] Vital Product Data
Capabilities: [5c] Message Signalled Interrupts: Mask- 64bit+ Queue=0/0 Enable+
Address: 00000000fee00000 Data: 40d9
Capabilities: [e0] Express Legacy Endpoint IRQ 0
Device: Supported: MaxPayload 128 bytes, PhantFunc 0, ExtTag-
Device: Latency L0s unlimited, L1 unlimited
Device: AtnBtn- AtnInd- PwrInd-
Device: Errors: Correctable- Non-Fatal- Fatal- Unsupported-
Device: RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
Device: MaxPayload 128 bytes, MaxReadReq 512 bytes
Link: Supported Speed 2.5Gb/s, Width x1, ASPM L0s L1, Port 0
Link: Latency L0s <256ns, L1 unlimited
Link: ASPM Disabled RCB 128 bytes CommClk- ExtSynch-
Link: Speed 2.5Gb/s, Width x1
Capabilities: [100] Advanced Error Reporting
00: ab 11 64 43 07 04 10 00 12 00 00 02 08 00 00 00
10: 04 00 00 f5 00 00 00 00 01 90 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 58 14 00 e0
30: 00 00 00 00 48 00 00 00 00 00 00 00 0b 01 00 00

# dmidecode 2.7
SMBIOS 2.4 present.
39 structures occupying 1192 bytes.
Table at 0x000F0100.

Handle 0x0000, DMI type 0, 24 bytes.
BIOS Information
Vendor: Award Software International, Inc.
Version: F8
Release Date: 01/11/2007
Address: 0xE0000
Runtime Size: 128 kB
ROM Size: 1024 kB
Characteristics:
PCI is supported
PNP is supported
APM is supported
BIOS is upgradeable
BIOS shadowing is allowed
Boot from CD is supported
Selectable boot is supported
EDD is supported
5.25"/360 KB floppy services are supported (int 13h) 5.25"/1.2 MB floppy services are supported (int 13h) 3.5"/720 KB floppy services are supported (int 13h) 3.5"/2.88 MB floppy services are supported (int 13h) Print screen service is supported (int 5h) 8042 keyboard services are supported (int 9h) Serial services are supported (int 14h) Printer services are supported (int 17h) CGA/mono video services are supported (int 10h) ACPI is supported
USB legacy is supported
LS-120 boot is supported
ATAPI Zip drive boot is supported
BIOS boot specification is supported Targeted content distribution is supported

Handle 0x0001, DMI type 1, 27 bytes.
System Information

	Manufacturer: Gigabyte Technology Co., Ltd.
	Product Name: 965P-S3
	Version:  
	Serial Number:  
	UUID: 00000000-0000-0000-0000-0016E6D4022E
	Wake-up Type: Power Switch
	SKU Number:  
	Family:  

Handle 0x0002, DMI type 2, 8 bytes.
Base Board Information

	Manufacturer: Gigabyte Technology Co., Ltd.
	Product Name: 965P-S3
	Version:  
	Serial Number:  

Handle 0x0003, DMI type 3, 17 bytes. Chassis Information
Manufacturer: Gigabyte Technology Co., Ltd.
Type: Desktop
Lock: Not Present
Version:
Serial Number:
Asset Tag:
Boot-up State: Unknown
Power Supply State: Unknown
Thermal State: Unknown
Security Status: Unknown
OEM Information: 0x00000000

Handle 0x0004, DMI type 4, 35 bytes. Processor Information
Socket Designation: Socket 775
Type: Central Processor
Family: Other
Manufacturer: Intel
ID: F2 06 00 00 FF FB EB BF
Version: Intel(R) Core(TM)2 CPU 640
Voltage: 1.3 V
External Clock: 384 MHz
Max Speed: 4000 MHz
Current Speed: 3072 MHz
Status: Populated, Enabled
Upgrade: Socket 478
L1 Cache Handle: 0x000A
L2 Cache Handle: 0x000B
L3 Cache Handle: Not Provided Serial Number:
Asset Tag:
Part Number:

#20 lore raw

Re: [PATCH 15/17] sky2: only disable 88e8056 on some boards

Quoted 17 lines · On Mon, 14 May 2007 00:53:42 -0400 Florin Malita <[email protected]> wrote:

Hi Stephen,

Quoted 2 lines · Stephen Hemminger

Use DMI to add a blacklist of broken board. For now only one is known bad. Gentoo users report driver works on other motherboards (strange).

[snip]

Quoted 5 lines
drivers/net/sky2.c +3 -0
+               .ident = "Gigabyte 965P-S3",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., 

Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),

Actually, I've been using sky2 with a 965P-S3 for a couple of months (x86_64 kernel) and as far as I can tell it works like a charm. Recently I had to hack around the blacklisting but other than that I haven't noticed anything strange.

Quoted 5 lines

What failures are you trying to prevent? Would a warning (instead of blacklisting) be acceptable?

Thanks,
Florin

What happens on my system is that the chip is accessing some unknown memory location when it reads the descriptors. This leads to:
* Transmit descriptor errors because the transmit descriptor doesn't have the "Owner" bit set. The list is fine, and all the barriers are there it seems like the chip read of memory is getting crap.
* TSO errors (probably same problem as before)
* Receive packets with no data. The stack ends up ignoring the garbage; but since we reuse the memory the DMA can/will happen later and cause random memory corruption.

Overall it looks like a PCI synchronization problem. Possible differences between working/non-working are:
* BIOS, tried up to the latest beta version with no change
* Memory, switched to name brand DDR2 800 (2G)
* MSI
* AHCI/SATA, I am using Raptor with AHCI when booted with i386 on old IDE drive saw no problems

#21 lore raw

Re: [PATCH 15/17] sky2: only disable 88e8056 on some boards

Hello, Stephen,

Quoted 1 line

RE: sky2 88e8056 Gigabyte GA-965GM-S2 uATX motherboard

A couple days ago I posted my observations that this was a hardware problem. My boards are now working!

I used the GIGABYTE MOTHERBOARD webpage for SUPPORT. They replied with a EEPROM program for the Marvell Yukon ethernet chip.
Once the EEPROM was reprogrammed the diskless system on my bench started working and has for the past 24 hours taken a beating on the NFS mount as well as receiving a ping flood from another node.

I am not using the sky2 driver, rather the sk98lin from Marvell's website. It was a last grasp before buying PCI ethernet cards. Marvell's sk98lin was no better than sky2 before the EEPROM reprogramming. My observation is that sky2/v1.10 still does not work after the reprogramming. I will grab your latest sky2 patches and report results.

Here are the details:
---------------------
Suse 10.0
2.6.21 i386
sk98lin: Network Device Driver v10.0.5.3
(download from Marvell's webpage)

Marvell Yukon chip 88E8056 reprogrammed with files provided by GIGABYTE MOTHERBOARD manufacturer:

    1024 Feb  9 08:51 GBT5614n.raw
      24 May 16 00:23 VPD.BAT
      93 Mar  2 13:08 eep.bat

155729 Oct 19 2006 mac.exe
224533 Oct 31 2006 yukonvpd.exe

Contents of the eep.bat file:
-----------------------------
@echo off
@del vpd.bat
mac
yukonvpd -P GBT5614n.raw
yukonvpd -u 1458E000
call vpd.bat

Contents of the VPD.BAT file:
-----------------------------
YUKONVPD -M 0016E6FFFFFF
(I replace the full MAC with FF FF FF)

More as it happens,
-Rob

Quoted 14 lines

RE: sky2 88e8056 Gigabyte GA-965GM-S2 uATX motherboard

I have now too many of these Gigabyte mobos, GA-965GM-S2 with the Marvell 88e8056 www.gigabyte.com.tw / Products / Motherboard / Products_Overview.aspx?ProductID=2388

Observations.
-------------
The problem may not be sky2 specific. I have diskless nodes where too many can NOT
1) reliably DHCP an IP number from the server
2) and if the pxelinux.cfg/default loads, it is not certain if the kernel or the initrd would tftp transfer.

There are two of 12 diskless nodes that work, ... always work. All mobos are the same, all CMOS is set identically

Quoted 49 lines · Stephen Hemminger
Quoted 17 lines · On Mon, 14 May 2007 00:53:42 -0400 Florin Malita <[email protected]> wrote:

Hi Stephen,

Quoted 2 lines · Stephen Hemminger

Use DMI to add a blacklist of broken board. For now only one is known bad. Gentoo users report driver works on other motherboards (strange).

[snip]

Quoted 5 lines
drivers/net/sky2.c +3 -0
+               .ident = "Gigabyte 965P-S3",
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., 

Ltd."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),

Actually, I've been using sky2 with a 965P-S3 for a couple of months (x86_64 kernel) and as far as I can tell it works like a charm. Recently I had to hack around the blacklisting but other than that I haven't noticed anything strange.

Quoted 5 lines

What failures are you trying to prevent? Would a warning (instead of blacklisting) be acceptable?

Thanks,
Florin

What happens on my system is that the chip is accessing some unknown memory location when it reads the descriptors. This leads to:
* Transmit descriptor errors because the transmit descriptor doesn't have the "Owner" bit set. The list is fine, and all the barriers are there it seems like the chip read of memory is getting crap.
* TSO errors (probably same problem as before)
* Receive packets with no data. The stack ends up ignoring the garbage; but since we reuse the memory the DMA can/will happen later and cause random memory corruption.

Overall it looks like a PCI synchronization problem. Possible differences between working/non-working are:
* BIOS, tried up to the latest beta version with no change
* Memory, switched to name brand DDR2 800 (2G)
* MSI
* AHCI/SATA, I am using Raptor with AHCI when booted with i386 on old IDE drive saw no problems

-
To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#22 lore raw

Re: [PATCH 15/17] sky2: only disable 88e8056 on some boards

Quoted 9 lines · On Tue, 15 May 2007 15:43:39 -0400 [email protected] wrote:

Hello, Stephen,

Quoted 1 line

RE: sky2 88e8056 Gigabyte GA-965GM-S2 uATX motherboard

A couple days ago I posted my observations that this was a hardware problem. My boards are now working!

I used the GIGABYTE MOTHERBOARD webpage for SUPPORT. They replied with a EEPROM program for the Marvell Yukon ethernet chip.
Once the EEPROM was reprogrammed the diskless system on my bench started working and has for the past 24 hours taken a beating on the NFS mount as well as receiving a ping flood from another node.

Any chance of sending me the stuff to verify if it fixes my system.

#23 lore raw

PATCH 16/17 sky2: make sure high DMA bits set

In reply to Stephen Hemminger

Be more frugal on memory on 32bit platforms (less rx elements are needed), and make sure high DMA bits are set on 64bit platforms.

---
 drivers/net/sky2.c |   62 ++++++++++++++++++++++++++++++++++++-----------------
 drivers/net/sky2.h |    2 -
 2 files changed, 43 insertions(+), 21 deletions(-)
drivers/net/sky2.c +43 -19
@@ -61,9 +61,11 @@
  * similar to Tigon3.
  */
 
-#define RX_LE_SIZE		1024
-#define RX_LE_BYTES		(RX_LE_SIZE*sizeof(struct sky2_rx_le))
-#define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
+#define NDMA_LE			(sizeof(dma_addr_t)/sizeof(u32))
+
+#define RX_LE_SIZE	    	(512 * NDMA_LE)
+#define RX_LE_BYTES		(RX_LE_SIZE * sizeof(struct sky2_rx_le))
+#define RX_MAX_PENDING		500
 #define RX_DEF_PENDING		RX_MAX_PENDING
 #define RX_SKB_ALIGN		8
 #define RX_BUF_WRITE		16
@@ -71,7 +73,7 @@
 #define TX_RING_SIZE		512
 #define TX_DEF_PENDING		(TX_RING_SIZE - 1)
 #define TX_MIN_PENDING		64
-#define MAX_SKB_TX_LE		(4 + (sizeof(dma_addr_t)/sizeof(u32))*MAX_SKB_FRAGS)
+#define MAX_SKB_TX_LE		(2 + (NDMA_LE * (MAX_SKB_FRAGS + 1)))
 
 #define STATUS_RING_SIZE	2048	/* 2 ports * (TX + 2*RX) */
 #define STATUS_LE_BYTES		(STATUS_RING_SIZE*sizeof(struct sky2_status_le))
@@ -826,7 +828,6 @@ static inline struct sky2_tx_le *get_tx_
 	struct sky2_tx_le *le = sky2->tx_le + sky2->tx_prod;
 
 	sky2->tx_prod = RING_NEXT(sky2->tx_prod, TX_RING_SIZE);
-	le->ctrl = 0;
 	return le;
 }
 
@@ -866,13 +867,14 @@ static void sky2_rx_add(struct sky2_port
 			dma_addr_t map, unsigned len)
 {
 	struct sky2_rx_le *le;
-	u32 hi = high32(map);
 
-	if (sky2->rx_addr64 != hi) {
+	if (sizeof(map) > sizeof(u32)) {
+		u32 hi = high32(map);
+
 		le = sky2_next_rx(sky2);
 		le->addr = cpu_to_le32(hi);
+		le->ctrl = 0;
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->rx_addr64 = high32(map + len);
 	}
 
 	le = sky2_next_rx(sky2);
@@ -1168,6 +1170,14 @@ static int sky2_rx_start(struct sky2_por
 	}
 	sky2->rx_data_size = size;
 
+	/* On 32bit platforms high bits always zero */
+	if (sizeof(dma_addr_t) == sizeof(u32)) {
+		struct sky2_rx_le *le = sky2_next_rx(sky2);
+		le->addr = 0;
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+	}
+
 	/* Fill Rx ring */
 	for (i = 0; i < sky2->rx_pending; i++) {
 		re = sky2->rx_ring + i;
@@ -1287,6 +1297,14 @@ static int sky2_up(struct net_device *de
 	    && hw->chip_rev == CHIP_REV_YU_EC_U_A0)
 		sky2_write16(hw, Q_ADDR(txqaddr[port], Q_AL), ECU_TXFF_LEV);
 
+	/* Initial high bits to zero */
+	if (sizeof(dma_addr_t) == sizeof(u32)) {
+		struct sky2_tx_le *le = get_tx_le(sky2);
+		le->addr = 0;
+		le->ctrl = 0;
+		le->opcode = OP_ADDR64 | HW_OWNER;
+	}
+
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
 			   TX_RING_SIZE - 1);
 
@@ -1336,13 +1354,16 @@ static inline int tx_avail(const struct 
 /* Estimate of number of transmit list elements required */
 static unsigned tx_le_req(const struct sk_buff *skb)
 {
-	unsigned count;
+	unsigned count = NDMA_LE;	/* OP_PACKET */
 
-	count = sizeof(dma_addr_t) / sizeof(u32);
-	count += skb_shinfo(skb)->nr_frags * count;
+	count += skb_shinfo(skb)->nr_frags * NDMA_LE;	/* OP_BUFFER */
 
 	if (skb_is_gso(skb))
 		++count;
+#ifdef SKY2_VLAN_TAG_USED
+	else if (vlan_tx_tag_present(skb))
+		++count;
+#endif
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL)
 		++count;
@@ -1379,12 +1400,11 @@ static int sky2_xmit_frame(struct sk_buf
 	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
 	addr64 = high32(mapping);
 
-	/* Send high bits if changed or crosses boundary */
-	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+	if (sizeof(mapping) > sizeof(u32)) {
 		le = get_tx_le(sky2);
 		le->addr = cpu_to_le32(addr64);
+		le->ctrl = 0;
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->tx_addr64 = high32(mapping + len);
 	}
 
 	/* Check for TCP Segmentation Offload */
@@ -1398,6 +1418,7 @@ static int sky2_xmit_frame(struct sk_buf
 			le = get_tx_le(sky2);
 			le->addr = cpu_to_le32(mss);
 			le->opcode = OP_LRGLEN | HW_OWNER;
+			le->ctrl = 0;
 			sky2->tx_last_mss = mss;
 		}
 	}
@@ -1410,6 +1431,7 @@ static int sky2_xmit_frame(struct sk_buf
 			le = get_tx_le(sky2);
 			le->addr = 0;
 			le->opcode = OP_VLAN | HW_OWNER;
+			le->ctrl = 0;
 		} else
 			le->opcode |= OP_VLAN;
 		le->length = cpu_to_be16(vlan_tx_tag_get(skb));
@@ -1453,16 +1475,18 @@ static int sky2_xmit_frame(struct sk_buf
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		u32 hi;
 
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
-		addr64 = high32(mapping);
-		if (addr64 != sky2->tx_addr64) {
+		hi = high32(mapping);
+
+		if (addr64 != hi) {
 			le = get_tx_le(sky2);
-			le->addr = cpu_to_le32(addr64);
-			le->ctrl = 0;
+			le->addr = cpu_to_le32(hi);
 			le->opcode = OP_ADDR64 | HW_OWNER;
-			sky2->tx_addr64 = addr64;
+			le->ctrl = 0;
+			addr64 = hi;
 		}
 
 		le = get_tx_le(sky2);
drivers/net/sky2.h +0 -2
@@ -1717,14 +1717,12 @@ struct sky2_port {
 	struct sky2_tx_le    *tx_le;
 	u16		     tx_cons;		/* next le to check */
 	u16		     tx_prod;		/* next le to use */
-	u32		     tx_addr64;
 	u16		     tx_pending;
 	u16		     tx_last_mss;
 	u32		     tx_tcpsum;
 
 	struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;
 	struct sky2_rx_le    *rx_le;
-	u32		     rx_addr64;
 	u16		     rx_next;		/* next re to check */
 	u16		     rx_put;		/* next le index to use */
 	u16		     rx_pending;

--

#25 lore raw
In reply to Stephen Hemminger
Quoted 5 lines · Stephen Hemminger

Patches are against netdev-2.6 upstream code branch.

This includes a several bug fixes, and code cleanup to use standard functions. There are a couple of PCI changes. One bug fix, and moving common code in PCI base.

The standard development process is:

* new code gets pushed to me during 2.6.X-rc
* that code is auto-propagated to akpm's -mm tree for additional exposure
* merge window opens
* I push upstream

That ensures code gets at least /some/ additional review, testing, "settling" time.

This is a late date to be expecting stuff to be pushed straight into 2.6.22.

Additionally, the rule for creating patches is: diff against latest vanilla linux-2.6.git tree, unless dependencies exist in netdev. After the merge window opens, #upstream is often empty or even a bit behind upstream, since Linus pulls that.

Jeff

#26 lore raw
Quoted 9 lines · On Wed, 09 May 2007 00:16:48 -0400 Jeff Garzik <[email protected]> wrote:
Quoted 5 lines · Stephen Hemminger

Patches are against netdev-2.6 upstream code branch.

This includes a several bug fixes, and code cleanup to use standard functions. There are a couple of PCI changes. One bug fix, and moving common code in PCI base.

The standard development process is:

Quoted 8 lines

* new code gets pushed to me during 2.6.X-rc
* that code is auto-propagated to akpm's -mm tree for additional exposure
* merge window opens
* I push upstream

That ensures code gets at least /some/ additional review, testing, "settling" time.

Sorry for the late merge, but between the closing of OSDL office and the fixing of critical bugs the other stuff got pushed into the "next release" bin and wasn't really ready until now.

Quoted 1 line

This is a late date to be expecting stuff to be pushed straight into 2.6.22.

Then hold it for 2.6.23.

Quoted 4 lines

Additionally, the rule for creating patches is: diff against latest vanilla linux-2.6.git tree, unless dependencies exist in netdev. After the merge window opens, #upstream is often empty or even a bit behind upstream, since Linus pulls that.

One patch wouldn't have applied unless the recent patch that you accepted was included.

Quoted 4 lines

Jeff

Signature · 1 line
Stephen Hemminger <[email protected]>
#27 lore raw
Quoted 19 lines · Stephen Hemminger
Quoted 8 lines · On Wed, 09 May 2007 00:16:48 -0400 Jeff Garzik <[email protected]> wrote:
Quoted 5 lines · Stephen Hemminger

Patches are against netdev-2.6 upstream code branch.

This includes a several bug fixes, and code cleanup to use standard functions. There are a couple of PCI changes. One bug fix, and moving common code in PCI base.

The standard development process is:

Quoted 7 lines

* new code gets pushed to me during 2.6.X-rc
* that code is auto-propagated to akpm's -mm tree for additional exposure
* merge window opens
* I push upstream

That ensures code gets at least /some/ additional review, testing, "settling" time.

Quoted 7 lines

Sorry for the late merge, but between the closing of OSDL office and the fixing of critical bugs the other stuff got pushed into the "next release" bin and wasn't really ready until now.

Quoted 1 line

This is a late date to be expecting stuff to be pushed straight into 2.6.22.

Then hold it for 2.6.23.

You sure you don't want to split off the bug fixes, and submit those for 2.6.22?

An oops fix is certainly 2.6.22 material...

Quoted 4 lines
Quoted 1 line

Additionally, the rule for creating patches is: diff against latest vanilla linux-2.6.git tree, unless dependencies exist in netdev. After the merge window opens, #upstream is often empty or even a bit behind upstream, since Linus pulls that.

One patch wouldn't have applied unless the recent patch that you accepted was included.

OK, I stand corrected on this issue, then. It sounds like you diff'd correctly.

Jeff

#28 lore raw
Quoted 25 lines · On Wed, 09 May 2007 19:27:17 -0400 Jeff Garzik <[email protected]> wrote:
Quoted 24 lines · Stephen Hemminger
Quoted 8 lines · On Wed, 09 May 2007 00:16:48 -0400 Jeff Garzik <[email protected]> wrote:
Quoted 5 lines · Stephen Hemminger

Patches are against netdev-2.6 upstream code branch.

This includes a several bug fixes, and code cleanup to use standard functions. There are a couple of PCI changes. One bug fix, and moving common code in PCI base.

The standard development process is:

Quoted 8 lines

* new code gets pushed to me during 2.6.X-rc
* that code is auto-propagated to akpm's -mm tree for additional exposure
* merge window opens
* I push upstream

That ensures code gets at least /some/ additional review, testing, "settling" time.

Sorry for the late merge, but between the closing of OSDL office and the fixing of critical bugs the other stuff got pushed into the "next release" bin and wasn't really ready until now.

Quoted 9 lines
Quoted 3 lines
Quoted 1 line

This is a late date to be expecting stuff to be pushed straight into 2.6.22.

Then hold it for 2.6.23.

You sure you don't want to split off the bug fixes, and submit those for 2.6.22?

An oops fix is certainly 2.6.22 material...

I'll split into groups and let you decide where the cut off is:

1) crashes for stable and 2.6.22
2) stuff that should be fixed in 2.6.22 but isn't stable material
3) newer stuff for -mm or later release

Also, I just got loaner versions of the just release 88e807X hardware so it maybe possible to get that working before 2.6.22 final.

Signature · 1 line
Stephen Hemminger <[email protected]>