* [PATCH 01/12] sky2: fe+ chip support
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-31 13:43 ` Jeff Garzik
2007-08-29 19:58 ` [PATCH 02/12] sky2: use debugfs rename Stephen Hemminger
` (11 subsequent siblings)
12 siblings, 1 reply; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-fe-p.patch --]
[-- Type: text/plain, Size: 6737 bytes --]
Add support for new Marvell 100mbit chips.
This code is ported from the SysKonnect 10.20.3.3 driver.
It is *untested* because I don't have access to this hardware.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-08-29 11:31:59.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:36:04.000000000 -0700
@@ -118,12 +118,15 @@ static const struct pci_device_id sky2_i
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) }, /* 88E8036 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) }, /* 88E8038 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) }, /* 88E8039 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88E8033 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4356) }, /* 88EC033 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x435A) }, /* 88E8048 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) }, /* 88E8052 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) }, /* 88E8070 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
@@ -147,6 +150,7 @@ static const char *yukon2_name[] = {
"Extreme", /* 0xb5 */
"EC", /* 0xb6 */
"FE", /* 0xb7 */
+ "FE+", /* 0xb8 */
};
/* Access to external PHY */
@@ -332,7 +336,8 @@ static void sky2_phy_init(struct sky2_hw
ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
if (sky2_is_copper(hw)) {
- if (hw->chip_id == CHIP_ID_YUKON_FE) {
+ if (hw->chip_id == CHIP_ID_YUKON_FE ||
+ hw->chip_id == CHIP_ID_YUKON_FE_P) {
/* enable automatic crossover */
ctrl |= PHY_M_PC_MDI_XMODE(PHY_M_PC_ENA_AUTO) >> 1;
} else {
@@ -453,7 +458,7 @@ static void sky2_phy_init(struct sky2_hw
gma_write16(hw, port, GM_GP_CTRL, reg);
- if (hw->chip_id != CHIP_ID_YUKON_FE)
+ if (sky2_is_gigabit(hw))
gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000);
gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv);
@@ -477,6 +482,22 @@ static void sky2_phy_init(struct sky2_hw
gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
break;
+ case CHIP_ID_YUKON_FE_P:
+ /* Enable Link Partner Next Page */
+ ctrl |= PHY_M_PC_ENA_LIP_NP;
+
+ /* disable Energy Detect and enable scrambler */
+ ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
+ gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+ /* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
+ ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
+ PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_LINK) |
+ PHY_M_FELP_LED0_CTRL(LED_PAR_CTRL_SPEED);
+
+ gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, ctrl);
+ break;
+
case CHIP_ID_YUKON_XL:
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
@@ -546,7 +567,13 @@ static void sky2_phy_init(struct sky2_hw
/* set page register to 0 */
gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
+ } else if (hw->chip_id == CHIP_ID_YUKON_FE_P &&
+ hw->chip_rev == CHIP_REV_YU_FE2_A0) {
+ /* apply workaround for integrated resistors calibration */
+ gm_phy_write(hw, port, PHY_MARV_PAGE_ADDR, 17);
+ gm_phy_write(hw, port, PHY_MARV_PAGE_DATA, 0x3f60);
} else if (hw->chip_id != CHIP_ID_YUKON_EX) {
+ /* no effect on Yukon-XL */
gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl);
if (sky2->autoneg == AUTONEG_DISABLE || sky2->speed == SPEED_100) {
@@ -1709,8 +1736,12 @@ static u16 sky2_phy_speed(const struct s
if (!sky2_is_copper(hw))
return SPEED_1000;
- if (hw->chip_id == CHIP_ID_YUKON_FE)
- return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10;
+ if (!sky2_is_gigabit(hw)) {
+ if (aux & PHY_M_PS_SPEED_100)
+ return SPEED_100;
+ else
+ return SPEED_10;
+ }
switch (aux & PHY_M_PS_SPEED_MSK) {
case PHY_M_PS_SPEED_1000:
@@ -1956,7 +1987,9 @@ static int sky2_change_mtu(struct net_de
if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU)
return -EINVAL;
- if (new_mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_FE)
+ if (new_mtu > ETH_DATA_LEN &&
+ (hw->chip_id == CHIP_ID_YUKON_FE ||
+ hw->chip_id == CHIP_ID_YUKON_FE_P))
return -EINVAL;
if (!netif_running(dev)) {
@@ -2544,17 +2577,25 @@ static void sky2_netpoll(struct net_devi
#endif
/* Chip internal frequency for clock calculations */
-static inline u32 sky2_mhz(const struct sky2_hw *hw)
+static u32 sky2_mhz(const struct sky2_hw *hw)
{
switch (hw->chip_id) {
case CHIP_ID_YUKON_EC:
case CHIP_ID_YUKON_EC_U:
case CHIP_ID_YUKON_EX:
- return 125; /* 125 Mhz */
+ return 125;
+
case CHIP_ID_YUKON_FE:
- return 100; /* 100 Mhz */
- default: /* YUKON_XL */
- return 156; /* 156 Mhz */
+ return 100;
+
+ case CHIP_ID_YUKON_FE_P:
+ return 50;
+
+ case CHIP_ID_YUKON_XL:
+ return 156;
+
+ default:
+ BUG();
}
}
@@ -2579,7 +2620,8 @@ static int __devinit sky2_init(struct sk
sky2_write8(hw, B0_CTST, CS_RST_CLR);
hw->chip_id = sky2_read8(hw, B2_CHIP_ID);
- if (hw->chip_id < CHIP_ID_YUKON_XL || hw->chip_id > CHIP_ID_YUKON_FE) {
+ if (hw->chip_id < CHIP_ID_YUKON_XL ||
+ hw->chip_id > CHIP_ID_YUKON_FE_P) {
dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
hw->chip_id);
return -EOPNOTSUPP;
--- a/drivers/net/sky2.h 2007-08-29 11:31:59.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:38:37.000000000 -0700
@@ -470,18 +470,24 @@ enum {
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 */
-
+ CHIP_ID_YUKON_FE_P = 0xb8, /* 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,
-
+};
+enum yukon_fe_p_rev {
+ CHIP_REV_YU_FE2_A0 = 0,
};
enum yukon_ex_rev {
CHIP_REV_YU_EX_A0 = 1,
@@ -2062,6 +2068,12 @@ static inline int sky2_is_copper(const s
return !(hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P');
}
+static inline int sky2_is_gigabit(const struct sky2_hw *hw)
+{
+ return !(hw->chip_id == CHIP_ID_YUKON_FE
+ || hw->chip_id == CHIP_ID_YUKON_FE_P);
+}
+
/* Register accessor for memory mapped device */
static inline u32 sky2_read32(const struct sky2_hw *hw, unsigned reg)
{
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH 01/12] sky2: fe+ chip support
2007-08-29 19:58 ` [PATCH 01/12] sky2: fe+ chip support Stephen Hemminger
@ 2007-08-31 13:43 ` Jeff Garzik
2007-09-14 13:38 ` [PATCH] sky2: fix PHY setup on FE-P Stephen Hemminger
0 siblings, 1 reply; 18+ messages in thread
From: Jeff Garzik @ 2007-08-31 13:43 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, akpm
applied 1-6
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH] sky2: fix PHY setup on FE-P
2007-08-31 13:43 ` Jeff Garzik
@ 2007-09-14 13:38 ` Stephen Hemminger
0 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-09-14 13:38 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
Marvell reported the following fix is necessary to get fe-plus
chips to work.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-09-14 14:40:35.000000000 +0200
+++ b/drivers/net/sky2.c 2007-09-14 14:41:00.000000000 +0200
@@ -488,11 +488,12 @@ static void sky2_phy_init(struct sky2_hw
case CHIP_ID_YUKON_FE_P:
/* Enable Link Partner Next Page */
+ ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
ctrl |= PHY_M_PC_ENA_LIP_NP;
/* disable Energy Detect and enable scrambler */
ctrl &= ~(PHY_M_PC_ENA_ENE_DT | PHY_M_PC_DIS_SCRAMB);
- gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+ gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
/* set LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED */
ctrl = PHY_M_FELP_LED2_CTRL(LED_PAR_CTRL_ACT_BL) |
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 02/12] sky2: use debugfs rename
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
2007-08-29 19:58 ` [PATCH 01/12] sky2: fe+ chip support Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 03/12] sky2: document GPHY_CTRL bits Stephen Hemminger
` (10 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-debugfs-rename.patch --]
[-- Type: text/plain, Size: 1994 bytes --]
Use debugfs rename to handle device neame changes.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-08-29 11:36:04.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:40:09.000000000 -0700
@@ -3712,42 +3712,34 @@ static int sky2_device_event(struct noti
unsigned long event, void *ptr)
{
struct net_device *dev = ptr;
+ struct sky2_port *sky2 = netdev_priv(dev);
- if (dev->open == sky2_up) {
- struct sky2_port *sky2 = netdev_priv(dev);
+ if (dev->open != sky2_up || !sky2_debug)
+ return NOTIFY_DONE;
- switch(event) {
- case NETDEV_CHANGENAME:
- if (!netif_running(dev))
- break;
- /* fallthrough */
- case NETDEV_DOWN:
- case NETDEV_GOING_DOWN:
- if (sky2->debugfs) {
- printk(KERN_DEBUG PFX "%s: remove debugfs\n",
- dev->name);
- debugfs_remove(sky2->debugfs);
- sky2->debugfs = NULL;
- }
+ switch(event) {
+ case NETDEV_CHANGENAME:
+ if (sky2->debugfs) {
+ sky2->debugfs = debugfs_rename(sky2_debug, sky2->debugfs,
+ sky2_debug, dev->name);
+ }
+ break;
- if (event != NETDEV_CHANGENAME)
- break;
- /* fallthrough for changename */
- case NETDEV_UP:
- if (sky2_debug) {
- struct dentry *d;
- d = debugfs_create_file(dev->name, S_IRUGO,
- sky2_debug, dev,
- &sky2_debug_fops);
- if (d == NULL || IS_ERR(d))
- printk(KERN_INFO PFX
- "%s: debugfs create failed\n",
- dev->name);
- else
- sky2->debugfs = d;
- }
- break;
+ case NETDEV_GOING_DOWN:
+ if (sky2->debugfs) {
+ printk(KERN_DEBUG PFX "%s: remove debugfs\n",
+ dev->name);
+ debugfs_remove(sky2->debugfs);
+ sky2->debugfs = NULL;
}
+ break;
+
+ case NETDEV_UP:
+ sky2->debugfs = debugfs_create_file(dev->name, S_IRUGO,
+ sky2_debug, dev,
+ &sky2_debug_fops);
+ if (IS_ERR(sky2->debugfs))
+ sky2->debugfs = NULL;
}
return NOTIFY_DONE;
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 03/12] sky2: document GPHY_CTRL bits
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
2007-08-29 19:58 ` [PATCH 01/12] sky2: fe+ chip support Stephen Hemminger
2007-08-29 19:58 ` [PATCH 02/12] sky2: use debugfs rename Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 04/12] sky2: dont restrict config space access Stephen Hemminger
` (9 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-gphy-doc.patch --]
[-- Type: text/plain, Size: 1380 bytes --]
Add documentation of GPHY_CTRL register bits even if driver
is not using them (yet).
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.h 2007-08-29 11:38:37.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:40:12.000000000 -0700
@@ -1846,6 +1846,28 @@ enum {
/* GPHY_CTRL 32 bit GPHY Control Reg (YUKON only) */
enum {
+ GPC_TX_PAUSE = 1<<30, /* Tx pause enabled (ro) */
+ GPC_RX_PAUSE = 1<<29, /* Rx pause enabled (ro) */
+ GPC_SPEED = 3<<27, /* PHY speed (ro) */
+ GPC_LINK = 1<<26, /* Link up (ro) */
+ GPC_DUPLEX = 1<<25, /* Duplex (ro) */
+ GPC_CLOCK = 1<<24, /* 125Mhz clock stable (ro) */
+
+ GPC_PDOWN = 1<<23, /* Internal regulator 2.5 power down */
+ GPC_TSTMODE = 1<<22, /* Test mode */
+ GPC_REG18 = 1<<21, /* Reg18 Power down */
+ GPC_REG12SEL = 3<<19, /* Reg12 power setting */
+ GPC_REG18SEL = 3<<17, /* Reg18 power setting */
+ GPC_SPILOCK = 1<<16, /* SPI lock (ASF) */
+
+ GPC_LEDMUX = 3<<14, /* LED Mux */
+ GPC_INTPOL = 1<<13, /* Interrupt polarity */
+ GPC_DETECT = 1<<12, /* Energy detect */
+ GPC_1000HD = 1<<11, /* Enable 1000Mbit HD */
+ GPC_SLAVE = 1<<10, /* Slave mode */
+ GPC_PAUSE = 1<<9, /* Pause enable */
+ GPC_LEDCTL = 3<<6, /* GPHY Leds */
+
GPC_RST_CLR = 1<<1, /* Clear GPHY Reset */
GPC_RST_SET = 1<<0, /* Set GPHY Reset */
};
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 04/12] sky2: dont restrict config space access
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (2 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 03/12] sky2: document GPHY_CTRL bits Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 05/12] sky2: advanced error reporting Stephen Hemminger
` (8 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-no-cfg-disable --]
[-- Type: text/plain, Size: 2664 bytes --]
Take out the code that protects driver from accessing the
PCI config space.
We are old enough to run with scissors now.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
drivers/net/sky2.c | 9 ---------
1 file changed, 9 deletions(-)
--- a/drivers/net/sky2.c 2007-08-29 11:40:09.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:40:53.000000000 -0700
@@ -603,7 +603,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 */
@@ -613,7 +612,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);
}
@@ -681,11 +679,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);
@@ -2386,10 +2382,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) {
@@ -2403,11 +2397,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);
hwmsk &= ~Y2_IS_PCI_EXP;
@@ -2670,7 +2661,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);
@@ -2693,8 +2683,6 @@ static void sky2_reset(struct sky2_hw *h
| GMC_BYP_RETR_ON);
}
- sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-
/* Clear I2C IRQ noise */
sky2_write32(hw, B2_I2C_IRQ, 1);
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 05/12] sky2: advanced error reporting
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (3 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 04/12] sky2: dont restrict config space access Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 06/12] sky2: use pci_config access functions Stephen Hemminger
` (7 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-recoverable.patch --]
[-- Type: text/plain, Size: 5963 bytes --]
Use the kernel interfaces for advanced error reporting.
This should be cleaner and clear up errors on boot.
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.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
drivers/net/sky2.c | 51 +++++++++++++++++++++++++++------------------------
drivers/net/sky2.h | 41 -----------------------------------------
2 files changed, 27 insertions(+), 65 deletions(-)
--- a/drivers/net/sky2.c 2007-08-29 11:40:53.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:41:07.000000000 -0700
@@ -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>
@@ -2369,7 +2370,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);
@@ -2379,7 +2384,7 @@ 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,
@@ -2388,22 +2393,13 @@ static void sky2_hw_intr(struct sky2_hw
if (status & Y2_IS_PCI_EXP) {
/* PCI-Express uncorrectable Error occurred */
- u32 pex_err;
-
- pex_err = sky2_pci_read32(hw, PEX_UNC_ERR_STAT);
-
- if (net_ratelimit())
- dev_err(&hw->pdev->dev, "PCI Express error (0x%x)\n",
- pex_err);
+ int pos = pci_find_aer_capability(hw->pdev);
+ u32 err;
- /* 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);
- }
+ pci_read_config_dword(pdev, pos + PCI_ERR_UNCOR_STATUS, &err);
+ if (net_ratelimit())
+ dev_err(&pdev->dev, "PCI Express error (0x%x)\n", err);
+ pci_cleanup_aer_uncorrect_error_status(pdev);
}
if (status & Y2_HWE_L1_MASK)
@@ -2641,8 +2637,10 @@ static int __devinit sky2_init(struct sk
static void sky2_reset(struct sky2_hw *hw)
{
+ struct pci_dev *pdev = hw->pdev;
u16 status;
- int i;
+ int i, cap;
+ u32 hwe_mask = Y2_HWE_ALL_MASK;
/* disable ASF */
if (hw->chip_id == CHIP_ID_YUKON_EX) {
@@ -2666,10 +2664,19 @@ static void sky2_reset(struct sky2_hw *h
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);
+ cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (cap) {
+ /* Check for advanced error reporting */
+ pci_cleanup_aer_uncorrect_error_status(pdev);
+ pci_cleanup_aer_correct_error_status(pdev);
+
+ /* If error bit is stuck on ignore it */
+ if (sky2_read32(hw, B0_HWE_ISRC) & Y2_IS_PCI_EXP)
+ dev_info(&pdev->dev, "ignoring stuck error report bit\n");
+ else if (pci_enable_pcie_error_reporting(pdev))
+ hwe_mask |= Y2_IS_PCI_EXP;
+ }
sky2_power_on(hw);
@@ -2721,7 +2728,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);
--- a/drivers/net/sky2.h 2007-08-29 11:40:51.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:41:07.000000000 -0700
@@ -18,14 +18,6 @@ enum {
PCI_CFG_REG_1 = 0x94,
};
-enum {
- PEX_DEV_CAP = 0xe4,
- PEX_DEV_CTRL = 0xe8,
- PEX_DEV_STA = 0xea,
- PEX_LNK_STAT = 0xf2,
- PEX_UNC_ERR_STAT= 0x104,
-};
-
/* Yukon-2 */
enum pci_dev_reg_1 {
PCI_Y2_PIG_ENA = 1<<31, /* Enable Plug-in-Go (YUKON-2) */
@@ -151,38 +143,6 @@ enum pci_cfg_reg1 {
PCI_STATUS_REC_TARGET_ABORT | \
PCI_STATUS_PARITY)
-enum pex_dev_ctrl {
- PEX_DC_MAX_RRS_MSK = 7<<12, /* Bit 14..12: Max. Read Request Size */
- PEX_DC_EN_NO_SNOOP = 1<<11,/* Enable No Snoop */
- PEX_DC_EN_AUX_POW = 1<<10,/* Enable AUX Power */
- PEX_DC_EN_PHANTOM = 1<<9, /* Enable Phantom Functions */
- PEX_DC_EN_EXT_TAG = 1<<8, /* Enable Extended Tag Field */
- PEX_DC_MAX_PLS_MSK = 7<<5, /* Bit 7.. 5: Max. Payload Size Mask */
- PEX_DC_EN_REL_ORD = 1<<4, /* Enable Relaxed Ordering */
- PEX_DC_EN_UNS_RQ_RP = 1<<3, /* Enable Unsupported Request Reporting */
- PEX_DC_EN_FAT_ER_RP = 1<<2, /* Enable Fatal Error Reporting */
- PEX_DC_EN_NFA_ER_RP = 1<<1, /* Enable Non-Fatal Error Reporting */
- PEX_DC_EN_COR_ER_RP = 1<<0, /* Enable Correctable Error Reporting */
-};
-#define PEX_DC_MAX_RD_RQ_SIZE(x) (((x)<<12) & PEX_DC_MAX_RRS_MSK)
-
-/* PEX_UNC_ERR_STAT PEX Uncorrectable Errors Status Register (Yukon-2) */
-enum pex_err {
- PEX_UNSUP_REQ = 1<<20, /* Unsupported Request Error */
-
- PEX_MALFOR_TLP = 1<<18, /* Malformed TLP */
-
- PEX_UNEXP_COMP = 1<<16, /* Unexpected Completion */
-
- PEX_COMP_TO = 1<<14, /* Completion Timeout */
- PEX_FLOW_CTRL_P = 1<<13, /* Flow Control Protocol Error */
- PEX_POIS_TLP = 1<<12, /* Poisoned TLP */
-
- PEX_DATA_LINK_P = 1<<4, /* Data Link Protocol Error */
- PEX_FATAL_ERRORS= (PEX_MALFOR_TLP | PEX_FLOW_CTRL_P | PEX_DATA_LINK_P),
-};
-
-
enum csr_regs {
B0_RAP = 0x0000,
B0_CTST = 0x0004,
@@ -419,7 +379,6 @@ enum {
Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
- Y2_IS_PCI_EXP |
Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
};
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 06/12] sky2: use pci_config access functions
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (4 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 05/12] sky2: advanced error reporting Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 07/12] sky2: use net_device internal stats Stephen Hemminger
` (6 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-pci-func.patch --]
[-- Type: text/plain, Size: 9045 bytes --]
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.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
drivers/net/sky2.c | 91 +++++++++++++++++++++++++++++------------------------
drivers/net/sky2.h | 21 ------------
2 files changed, 50 insertions(+), 62 deletions(-)
--- a/drivers/net/sky2.c 2007-08-29 11:41:07.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:41:10.000000000 -0700
@@ -222,21 +222,22 @@ static void sky2_power_on(struct sky2_hw
if (hw->chip_id == CHIP_ID_YUKON_EC_U ||
hw->chip_id == CHIP_ID_YUKON_EX) {
+ struct pci_dev *pdev = hw->pdev;
u32 reg;
- sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+ pci_write_config_dword(pdev, PCI_DEV_REG3, 0);
- reg = sky2_pci_read32(hw, PCI_DEV_REG4);
+ pci_read_config_dword(pdev, PCI_DEV_REG4, ®);
/* set all bits to 0 except bits 15..12 and 8 */
reg &= P_ASPM_CONTROL_MSK;
- sky2_pci_write32(hw, PCI_DEV_REG4, reg);
+ pci_write_config_dword(pdev, PCI_DEV_REG4, reg);
- reg = sky2_pci_read32(hw, PCI_DEV_REG5);
+ pci_read_config_dword(pdev, PCI_DEV_REG5, ®);
/* set all bits to 0 except bits 28 & 27 */
reg &= P_CTL_TIM_VMAIN_AV_MSK;
- sky2_pci_write32(hw, PCI_DEV_REG5, reg);
+ pci_write_config_dword(pdev, PCI_DEV_REG5, reg);
- sky2_pci_write32(hw, PCI_CFG_REG_1, 0);
+ pci_write_config_dword(pdev, PCI_CFG_REG_1, 0);
/* Enable workaround for dev 4.107 on Yukon-Ultra & Extreme */
reg = sky2_read32(hw, B2_GP_IO);
@@ -596,6 +597,7 @@ static void sky2_phy_init(struct sky2_hw
static void sky2_phy_power(struct sky2_hw *hw, unsigned port, int onoff)
{
+ struct pci_dev *pdev = hw->pdev;
u32 reg1;
static const u32 phy_power[]
= { PCI_Y2_PHY1_POWD, PCI_Y2_PHY2_POWD };
@@ -604,15 +606,16 @@ static void sky2_phy_power(struct sky2_h
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(pdev, PCI_DEV_REG1, ®1);
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(pdev, PCI_DEV_REG1, reg1);
+ pci_read_config_dword(pdev, PCI_DEV_REG1, ®1);
+
udelay(100);
}
@@ -680,9 +683,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, ®1);
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);
@@ -1281,9 +1284,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;
@@ -2382,13 +2385,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);
}
if (status & Y2_IS_PCI_EXP) {
@@ -2599,10 +2602,13 @@ static inline u32 sky2_clk2us(const stru
static int __devinit sky2_init(struct sky2_hw *hw)
{
+ int rc;
u8 t8;
- /* Enable all clocks */
- sky2_pci_write32(hw, PCI_DEV_REG3, 0);
+ /* Enable all clocks and check for bad PCI access */
+ rc = pci_write_config_dword(hw->pdev, PCI_DEV_REG3, 0);
+ if (rc)
+ return rc;
sky2_write8(hw, B0_CTST, CS_RST_CLR);
@@ -2657,10 +2663,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(pdev, PCI_STATUS, &status);
+ status |= PCI_STATUS_ERROR_BITS;
+ pci_write_config_word(pdev, PCI_STATUS, status);
sky2_write8(hw, B0_CTST, CS_MRST_CLR);
@@ -3477,26 +3482,31 @@ static int sky2_get_eeprom_len(struct ne
struct sky2_port *sky2 = netdev_priv(dev);
u16 reg2;
- reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2);
+ pci_read_config_word(sky2->hw->pdev, PCI_DEV_REG2, ®2);
return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
}
-static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
+static u32 sky2_vpd_read(struct pci_dev *pdev, int cap, u16 offset)
{
- sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+ u32 val;
- while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F))
- cpu_relax();
- return sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+ pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset);
+
+ do {
+ pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
+ } while (!(offset & PCI_VPD_ADDR_F));
+
+ pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val);
+ return val;
}
-static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
+static void sky2_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val)
{
- sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
- sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+ pci_write_config_word(pdev, cap + PCI_VPD_DATA, val);
+ pci_write_config_dword(pdev, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
do {
- cpu_relax();
- } while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F);
+ pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset);
+ } while (offset & PCI_VPD_ADDR_F);
}
static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
@@ -3513,7 +3523,7 @@ static int sky2_get_eeprom(struct net_de
eeprom->magic = SKY2_EEPROM_MAGIC;
while (length > 0) {
- u32 val = sky2_vpd_read(sky2->hw, cap, offset);
+ u32 val = sky2_vpd_read(sky2->hw->pdev, cap, offset);
int n = min_t(int, length, sizeof(val));
memcpy(data, &val, n);
@@ -3543,10 +3553,10 @@ static int sky2_set_eeprom(struct net_de
int n = min_t(int, length, sizeof(val));
if (n < sizeof(val))
- val = sky2_vpd_read(sky2->hw, cap, offset);
+ val = sky2_vpd_read(sky2->hw->pdev, cap, offset);
memcpy(&val, data, n);
- sky2_vpd_write(sky2->hw, cap, offset, val);
+ sky2_vpd_write(sky2->hw->pdev, cap, offset, val);
length -= n;
data += n;
@@ -3990,15 +4000,14 @@ 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 &= ~PCI_REV_DESC;
- sky2_pci_write32(hw, PCI_DEV_REG2, reg);
+ pci_write_config_dword(pdev, PCI_DEV_REG2, reg);
}
#endif
/* ring for status responses */
- hw->st_le = pci_alloc_consistent(hw->pdev, STATUS_LE_BYTES,
- &hw->st_dma);
+ hw->st_le = pci_alloc_consistent(pdev, STATUS_LE_BYTES, &hw->st_dma);
if (!hw->st_le)
goto err_out_iounmap;
@@ -4073,7 +4082,7 @@ err_out_free_netdev:
free_netdev(dev);
err_out_free_pci:
sky2_write8(hw, B0_CTST, CS_RST_SET);
- pci_free_consistent(hw->pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
+ pci_free_consistent(pdev, STATUS_LE_BYTES, hw->st_le, hw->st_dma);
err_out_iounmap:
iounmap(hw->regs);
err_out_free_hw:
@@ -4184,7 +4193,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(pdev, PCI_DEV_REG3, 0);
sky2_reset(hw);
--- a/drivers/net/sky2.h 2007-08-29 11:41:07.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:41:10.000000000 -0700
@@ -2115,25 +2115,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
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 07/12] sky2: use net_device internal stats
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (5 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 06/12] sky2: use pci_config access functions Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-31 13:43 ` Jeff Garzik
2007-08-29 19:58 ` [PATCH 08/12] ktime_sub_ns: analog of ktime_add_ns Stephen Hemminger
` (5 subsequent siblings)
12 siblings, 1 reply; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-int-stats.patch --]
[-- Type: text/plain, Size: 3462 bytes --]
This driver can just use the internal network stats block.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-08-29 11:41:10.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:41:16.000000000 -0700
@@ -1606,8 +1606,8 @@ static void sky2_tx_complete(struct sky2
printk(KERN_DEBUG "%s: tx done %u\n",
dev->name, idx);
- sky2->net_stats.tx_packets++;
- sky2->net_stats.tx_bytes += re->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += re->skb->len;
dev_kfree_skb_any(re->skb);
sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
@@ -2163,12 +2163,12 @@ resubmit:
len_mismatch:
/* Truncation of overlength packets
causes PHY length to not match MAC length */
- ++sky2->net_stats.rx_length_errors;
+ ++dev->stats.rx_length_errors;
error:
- ++sky2->net_stats.rx_errors;
+ ++dev->stats.rx_errors;
if (status & GMR_FS_RX_FF_OV) {
- sky2->net_stats.rx_over_errors++;
+ dev->stats.rx_over_errors++;
goto resubmit;
}
@@ -2177,11 +2177,11 @@ error:
dev->name, status, length);
if (status & (GMR_FS_LONG_ERR | GMR_FS_UN_SIZE))
- sky2->net_stats.rx_length_errors++;
+ dev->stats.rx_length_errors++;
if (status & GMR_FS_FRAGMENT)
- sky2->net_stats.rx_frame_errors++;
+ dev->stats.rx_frame_errors++;
if (status & GMR_FS_CRC_ERR)
- sky2->net_stats.rx_crc_errors++;
+ dev->stats.rx_crc_errors++;
goto resubmit;
}
@@ -2228,7 +2228,7 @@ static int sky2_status_intr(struct sky2_
++rx[port];
skb = sky2_receive(dev, length, status);
if (unlikely(!skb)) {
- sky2->net_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
break;
}
@@ -2243,8 +2243,8 @@ static int sky2_status_intr(struct sky2_
}
skb->protocol = eth_type_trans(skb, dev);
- sky2->net_stats.rx_packets++;
- sky2->net_stats.rx_bytes += skb->len;
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += skb->len;
dev->last_rx = jiffies;
#ifdef SKY2_VLAN_TAG_USED
@@ -2429,12 +2429,12 @@ static void sky2_mac_intr(struct sky2_hw
gma_read16(hw, port, GM_TX_IRQ_SRC);
if (status & GM_IS_RX_FF_OR) {
- ++sky2->net_stats.rx_fifo_errors;
+ ++dev->stats.rx_fifo_errors;
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_CLI_RX_FO);
}
if (status & GM_IS_TX_FF_UR) {
- ++sky2->net_stats.tx_fifo_errors;
+ ++dev->stats.tx_fifo_errors;
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_CLI_TX_FU);
}
}
@@ -3087,12 +3087,6 @@ static void sky2_get_strings(struct net_
}
}
-static struct net_device_stats *sky2_get_stats(struct net_device *dev)
-{
- struct sky2_port *sky2 = netdev_priv(dev);
- return &sky2->net_stats;
-}
-
static int sky2_set_mac_address(struct net_device *dev, void *p)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -3802,7 +3796,7 @@ static __devinit struct net_device *sky2
dev->stop = sky2_down;
dev->do_ioctl = sky2_ioctl;
dev->hard_start_xmit = sky2_xmit_frame;
- dev->get_stats = sky2_get_stats;
+
dev->set_multicast_list = sky2_set_multicast;
dev->set_mac_address = sky2_set_mac_address;
dev->change_mtu = sky2_change_mtu;
--- a/drivers/net/sky2.h 2007-08-29 11:41:10.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:41:16.000000000 -0700
@@ -2019,8 +2019,6 @@ struct sky2_port {
#ifdef CONFIG_SKY2_DEBUG
struct dentry *debugfs;
#endif
- struct net_device_stats net_stats;
-
};
struct sky2_hw {
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 08/12] ktime_sub_ns: analog of ktime_add_ns
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (6 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 07/12] sky2: use net_device internal stats Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 09/12] export reciprocal_value for modules Stephen Hemminger
` (4 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: ktime_sub_ns.patch --]
[-- Type: text/plain, Size: 2030 bytes --]
Add macro/function to subtract constant nanoseconds.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/include/linux/ktime.h 2007-08-29 11:31:59.000000000 -0700
+++ b/include/linux/ktime.h 2007-08-29 11:41:19.000000000 -0700
@@ -102,6 +102,13 @@ static inline ktime_t ktime_set(const lo
#define ktime_add_ns(kt, nsval) \
({ (ktime_t){ .tv64 = (kt).tv64 + (nsval) }; })
+/*
+ * Subtract a ktime_t variable and a scalar nanosecond value.
+ * res = kt - nsval:
+ */
+#define ktime_sub_ns(kt, nsval) \
+ ({ (ktime_t){ .tv64 = (kt).tv64 - (nsval) }; })
+
/* convert a timespec to ktime_t format: */
static inline ktime_t timespec_to_ktime(struct timespec ts)
{
@@ -200,6 +207,15 @@ static inline ktime_t ktime_add(const kt
extern ktime_t ktime_add_ns(const ktime_t kt, u64 nsec);
/**
+ * ktime_sub_ns - Subtract a scalar nanoseconds value to a ktime_t variable
+ * @kt: minuend
+ * @nsec: subtrahend in nanoseconds
+ *
+ * Returns the difference of @kt and @nsec in ktime_t format
+ */
+extern ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec);
+
+/**
* timespec_to_ktime - convert a timespec to ktime_t format
* @ts: the timespec variable to convert
*
--- a/kernel/hrtimer.c 2007-08-29 11:31:59.000000000 -0700
+++ b/kernel/hrtimer.c 2007-08-29 11:41:19.000000000 -0700
@@ -277,6 +277,30 @@ ktime_t ktime_add_ns(const ktime_t kt, u
}
EXPORT_SYMBOL_GPL(ktime_add_ns);
+
+/**
+ * ktime_sub_ns - Subract a scalar nanoseconds value to a ktime_t variable
+ * @kt: minuend
+ * @nsec: subtrahend in nanoseconds
+ *
+ * Returns the difference of kt and nsec in ktime_t format
+ */
+ktime_t ktime_sub_ns(const ktime_t kt, u64 nsec)
+{
+ ktime_t tmp;
+
+ if (likely(nsec < NSEC_PER_SEC)) {
+ tmp.tv64 = nsec;
+ } else {
+ unsigned long rem = do_div(nsec, NSEC_PER_SEC);
+
+ tmp = ktime_set((long)nsec, rem);
+ }
+
+ return ktime_sub(kt, tmp);
+}
+
+EXPORT_SYMBOL_GPL(ktime_add_ns);
# endif /* !CONFIG_KTIME_SCALAR */
/*
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 09/12] export reciprocal_value for modules
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (7 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 08/12] ktime_sub_ns: analog of ktime_add_ns Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 10/12] sky2: hardware receive timestamp counter Stephen Hemminger
` (3 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: reciprocal_export.patch --]
[-- Type: text/plain, Size: 538 bytes --]
Need this in later sky2 code.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/lib/reciprocal_div.c 2007-06-25 09:03:23.000000000 -0700
+++ b/lib/reciprocal_div.c 2007-08-29 11:30:38.000000000 -0700
@@ -1,5 +1,6 @@
#include <asm/div64.h>
#include <linux/reciprocal_div.h>
+#include <linux/module.h>
u32 reciprocal_value(u32 k)
{
@@ -7,3 +8,4 @@ u32 reciprocal_value(u32 k)
do_div(val, k);
return (u32)val;
}
+EXPORT_SYMBOL(reciprocal_value);
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 10/12] sky2: hardware receive timestamp counter
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (8 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 09/12] export reciprocal_value for modules Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 11/12] sky2: avoid divide in receive path Stephen Hemminger
` (2 subsequent siblings)
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-rx-time.patch --]
[-- Type: text/plain, Size: 5021 bytes --]
Use hardware timestamp counter to stamp receive packets.
It allows for higher resolution values without the hardware overhead
of doing gettimeofday.
Even though the network stack is smart enough to not stamp
packets unless needed, any installation with dhcpd ends up
using af_packet and that turns on timestamping by default.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
drivers/net/sky2.c | 159 +++++++++++++++++++++++++++++++++++++++--------------
drivers/net/sky2.h | 5 +
2 files changed, 124 insertions(+), 40 deletions(-)
--- a/drivers/net/sky2.c 2007-08-29 11:41:16.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:41:23.000000000 -0700
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/module.h>
+#include <linux/reciprocal_div.h>
#include <linux/netdevice.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
@@ -2186,6 +2187,36 @@ error:
goto resubmit;
}
+static inline u32 sky2_tist2ns(const struct sky2_hw *hw, u32 clk)
+{
+ return reciprocal_divide(clk * 1000, hw->tist_rate);
+}
+
+/*
+ * Convert hardware timestamp clock into a real time value
+ */
+static void sky2_set_timestamp(struct sk_buff *skb,
+ const struct sky2_hw *hw, u32 stamp)
+{
+ unsigned long seq;
+
+ do {
+ s32 delta;
+
+ seq = read_seqbegin(&hw->tist_lock);
+
+ /* ticks since last synchronization */
+ delta = stamp - hw->tist_base;
+
+ if (delta > 0)
+ skb->tstamp = ktime_add_ns(hw->tist_real,
+ sky2_tist2ns(hw, delta));
+ else
+ skb->tstamp = ktime_sub_ns(hw->tist_real,
+ sky2_tist2ns(hw, -delta));
+ } while (read_seqretry(&hw->tist_lock, seq));
+}
+
/* Transmit complete */
static inline void sky2_tx_done(struct net_device *dev, u16 last)
{
@@ -2262,6 +2293,16 @@ static int sky2_status_intr(struct sky2_
break;
#ifdef SKY2_VLAN_TAG_USED
+ case OP_RXTIMEVLAN:
+ sky2->rx_tag = length;
+ /* fall through */
+#endif
+ case OP_RXTIMESTAMP:
+ skb = sky2->rx_ring[sky2->rx_next].skb;
+ sky2_set_timestamp(skb, hw, status);
+ break;
+
+#ifdef SKY2_VLAN_TAG_USED
case OP_RXVLAN:
sky2->rx_tag = length;
break;
@@ -2457,11 +2498,15 @@ static void sky2_le_error(struct sky2_hw
sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
}
-/* Check for lost IRQ once a second */
+/* Once a second timer for safety checking and polling for timestamp
+ *
+ * Note: receive and timer processing both happen under softirq
+ */
static void sky2_watchdog(unsigned long arg)
{
struct sky2_hw *hw = (struct sky2_hw *) arg;
+ /* Look for lost IRQ */
if (sky2_read32(hw, B0_ISRC)) {
struct net_device *dev = hw->dev[0];
@@ -2469,6 +2514,14 @@ static void sky2_watchdog(unsigned long
__netif_rx_schedule(dev);
}
+ /* Snapshot current system realtime at current timestamp value
+ * @ 150Mhz counter wraps in 28.6 secs
+ */
+ write_seqlock(&hw->tist_lock);
+ hw->tist_real = ktime_get_real();
+ hw->tist_base = sky2_read32(hw, GMAC_TI_ST_VAL);
+ write_sequnlock(&hw->tist_lock);
+
if (hw->active > 0)
mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
}
@@ -2707,9 +2760,8 @@ static void sky2_reset(struct sky2_hw *h
/* Turn off descriptor polling */
sky2_write32(hw, B28_DPT_CTRL, DPT_STOP);
- /* Turn off receive timestamp */
- sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_STOP);
- sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ);
+ /* Turn on receive timestamp */
+ sky2_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ|GMT_ST_START);
/* enable the Tx Arbiters */
for (i = 0; i < hw->ports; i++)
@@ -4061,6 +4113,9 @@ static int __devinit sky2_probe(struct p
sky2_show_addr(dev1);
}
+ seqlock_init(&hw->tist_lock);
+ hw->tist_rate = reciprocal_value(sky2_mhz(hw));
+
setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
INIT_WORK(&hw->restart_work, sky2_restart);
--- a/drivers/net/sky2.h 2007-08-29 11:41:16.000000000 -0700
+++ b/drivers/net/sky2.h 2007-08-29 11:41:23.000000000 -0700
@@ -352,7 +352,7 @@ enum {
/* Hardware error interrupt mask for Yukon 2 */
enum {
- Y2_IS_TIST_OV = 1<<29,/* Time Stamp Timer overflow interrupt */
+ Y2_IS_TIST_OV = 1<<29, /* Time Stamp Timer overflow interrupt */
Y2_IS_SENSOR = 1<<28, /* Sensor interrupt */
Y2_IS_MST_ERR = 1<<27, /* Master error interrupt */
Y2_IS_IRQ_STAT = 1<<26, /* Status exception interrupt */
@@ -378,7 +378,7 @@ enum {
Y2_HWE_L2_MASK = Y2_IS_PAR_RD2 | Y2_IS_PAR_WR2 | Y2_IS_PAR_MAC2 |
Y2_IS_PAR_RX2 | Y2_IS_TCP_TXS2| Y2_IS_TCP_TXA2,
- Y2_HWE_ALL_MASK = Y2_IS_TIST_OV | Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
+ Y2_HWE_ALL_MASK = Y2_IS_MST_ERR | Y2_IS_IRQ_STAT |
Y2_HWE_L1_MASK | Y2_HWE_L2_MASK,
};
@@ -2032,6 +2032,11 @@ struct sky2_hw {
u8 ports;
u8 active;
+ seqlock_t tist_lock;
+ ktime_t tist_real;
+ u32 tist_base;
+ u32 tist_rate;
+
struct sky2_status_le *st_le;
u32 st_idx;
dma_addr_t st_dma;
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 11/12] sky2: avoid divide in receive path
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (9 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 10/12] sky2: hardware receive timestamp counter Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-29 19:58 ` [PATCH 12/12] sky2: 1.18 Stephen Hemminger
2007-08-30 20:36 ` [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-rx-ring-mod.patch --]
[-- Type: text/plain, Size: 687 bytes --]
Avoid divide (modulus) in receive buffer handling path.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-08-29 11:41:23.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:45:00.000000000 -0700
@@ -2140,7 +2140,8 @@ static struct sk_buff *sky2_receive(stru
printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
dev->name, sky2->rx_next, status, length);
- sky2->rx_next = (sky2->rx_next + 1) % sky2->rx_pending;
+ if (++sky2->rx_next >= sky2->rx_pending)
+ sky2->rx_next = 0;
prefetch(sky2->rx_ring + sky2->rx_next);
if (status & GMR_FS_ANY_ERR)
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* [PATCH 12/12] sky2: 1.18
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (10 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 11/12] sky2: avoid divide in receive path Stephen Hemminger
@ 2007-08-29 19:58 ` Stephen Hemminger
2007-08-30 20:36 ` [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-29 19:58 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev, akpm
[-- Attachment #1: sky2-1.18 --]
[-- Type: text/plain, Size: 476 bytes --]
Since ther is new functionality (timestamping), increase
the version.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
--- a/drivers/net/sky2.c 2007-08-29 11:45:00.000000000 -0700
+++ b/drivers/net/sky2.c 2007-08-29 11:46:25.000000000 -0700
@@ -53,7 +53,7 @@
#include "sky2.h"
#define DRV_NAME "sky2"
-#define DRV_VERSION "1.17"
+#define DRV_VERSION "1.18"
#define PFX DRV_NAME " "
/*
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread* Re: [PATCH 0/0] sky2: update for 2.6.24
2007-08-29 19:39 [PATCH 0/0] sky2: update for 2.6.24 Stephen Hemminger
` (11 preceding siblings ...)
2007-08-29 19:58 ` [PATCH 12/12] sky2: 1.18 Stephen Hemminger
@ 2007-08-30 20:36 ` Stephen Hemminger
12 siblings, 0 replies; 18+ messages in thread
From: Stephen Hemminger @ 2007-08-30 20:36 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
Patch number 10 doesn't work right, it causes excess interrupts
and console messages.
8 & 9 are only needed for #10, so skip them as well.
So please only apply 1-7 to netdev for 2.6.24
--
Stephen Hemminger <shemminger@linux-foundation.org>
^ permalink raw reply [flat|nested] 18+ messages in thread