[PATCH 4/5] resend forcedeth: tx pause watermarks

2008-02-06 Thread Ayaz Abdulla
New chipsets introduced variant Rx FIFO sizes that need to be taken into 
account when setting up the tx pause watermarks. This patch introduces 
the new device feature flags based on a version and implements the new 
watermarks.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-02-05 12:16:21.0 -0500
+++ new/drivers/net/forcedeth.c 2008-02-05 12:19:39.0 -0500
@@ -166,22 +166,24 @@
  * Hardware access:
  */
 
-#define DEV_NEED_TIMERIRQ  0x0001  /* set the timer irq flag in the irq 
mask */
-#define DEV_NEED_LINKTIMER 0x0002  /* poll link settings. Relies on the 
timer irq */
-#define DEV_HAS_LARGEDESC  0x0004  /* device supports jumbo frames and 
needs packet format 2 */
-#define DEV_HAS_HIGH_DMA0x0008  /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM0x0010  /* device supports tx and rx checksum 
offloads */
-#define DEV_HAS_VLAN0x0020  /* device supports vlan tagging and 
striping */
-#define DEV_HAS_MSI 0x0040  /* device supports MSI */
-#define DEV_HAS_MSI_X   0x0080  /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL 0x0100  /* device supports power savings */
-#define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics 
version 1 */
-#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
-#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
-#define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
-#define DEV_HAS_COLLISION_FIX   0x8000  /* device supports tx collision fix */
+#define DEV_NEED_TIMERIRQ  0x1  /* set the timer irq flag in the 
irq mask */
+#define DEV_NEED_LINKTIMER 0x2  /* poll link settings. Relies on 
the timer irq */
+#define DEV_HAS_LARGEDESC  0x4  /* device supports jumbo frames 
and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA   0x8  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM   0x00010  /* device supports tx and rx 
checksum offloads */
+#define DEV_HAS_VLAN   0x00020  /* device supports vlan tagging 
and striping */
+#define DEV_HAS_MSI0x00040  /* device supports MSI */
+#define DEV_HAS_MSI_X  0x00080  /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL0x00100  /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1  0x00200  /* device supports hw statistics 
version 1 */
+#define DEV_HAS_STATISTICS_V2  0x00400  /* device supports hw statistics 
version 2 */
+#define DEV_HAS_TEST_EXTENDED  0x00800  /* device supports extended 
diagnostic test */
+#define DEV_HAS_MGMT_UNIT  0x01000  /* device supports management unit 
*/
+#define DEV_HAS_CORRECT_MACADDR0x02000  /* device supports correct mac 
address order */
+#define DEV_HAS_COLLISION_FIX  0x04000  /* device supports tx collision 
fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1   0x08000  /* device supports tx pause frames 
version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2   0x1  /* device supports tx pause frames 
version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3   0x2  /* device supports tx pause frames 
version 3 */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -322,8 +324,10 @@
NvRegTxRingPhysAddrHigh = 0x148,
NvRegRxRingPhysAddrHigh = 0x14C,
NvRegTxPauseFrame = 0x170,
-#define NVREG_TX_PAUSEFRAME_DISABLE0x01ff0080
-#define NVREG_TX_PAUSEFRAME_ENABLE 0x01800010
+#define NVREG_TX_PAUSEFRAME_DISABLE0x0fff0080
+#define NVREG_TX_PAUSEFRAME_ENABLE_V1  0x01800010
+#define NVREG_TX_PAUSEFRAME_ENABLE_V2  0x056003f0
+#define NVREG_TX_PAUSEFRAME_ENABLE_V3  0x09f00880
NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR0x0001
 #define NVREG_MIISTAT_LINKCHANGE   0x0008
@@ -2755,7 +2759,12 @@
if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) {
u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX;
if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) {
-   writel(NVREG_TX_PAUSEFRAME_ENABLE,  base + 
NvRegTxPauseFrame);
+   u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
+   if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
+   pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
+   if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)
+   pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
+   writel(pause_enable,  base + NvRegTxPauseFrame);
writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
 

[PATCH 2/5] resend forcedeth: tx collision fix

2008-02-06 Thread Ayaz Abdulla
This patch supports a new fix in hardware regarding tx collisions. In 
the cases where we are in autoneg mode and the link partner is in forced 
mode, we need to setup the tx deferral register differently in order to 
reduce collisions on the wire.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-02-05 12:07:53.0 -0500
+++ new/drivers/net/forcedeth.c 2008-02-05 12:10:54.0 -0500
@@ -181,6 +181,7 @@
 #define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
 #define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
 #define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
+#define DEV_HAS_COLLISION_FIX   0x8000  /* device supports tx collision fix */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -266,9 +267,12 @@
 #define NVREG_RNDSEED_FORCE3   0x7400
 
NvRegTxDeferral = 0xA0,
-#define NVREG_TX_DEFERRAL_DEFAULT  0x15050f
-#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
-#define NVREG_TX_DEFERRAL_RGMII_1000   0x14050f
+#define NVREG_TX_DEFERRAL_DEFAULT  0x15050f
+#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
+#define NVREG_TX_DEFERRAL_RGMII_1000   0x14050f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10 0x16190f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_1000x16300f
+#define NVREG_TX_DEFERRAL_MII_STRETCH  0x152000
NvRegRxDeferral = 0xA4,
 #define NVREG_RX_DEFERRAL_DEFAULT  0x16
NvRegMacAddrA = 0xA8,
@@ -2785,6 +2789,7 @@
int retval = 0;
u32 control_1000, status_1000, phyreg, pause_flags, txreg;
u32 txrxFlags = 0;
+   u32 phy_exp;
 
/* BMSR_LSTATUS is latched, read it twice:
 * we want the current value.
@@ -2912,13 +2917,25 @@
phyreg |= PHY_1000;
writel(phyreg, base + NvRegPhyInterface);
 
+   phy_exp = mii_rw(dev, np->phyaddr, MII_EXPANSION, MII_READ) & 
EXPANSION_NWAY; /* autoneg capable */
if (phyreg & PHY_RGMII) {
-   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000)
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000) {
txreg = NVREG_TX_DEFERRAL_RGMII_1000;
-   else
-   txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+   } else {
+   if (!phy_exp && !np->duplex && (np->driver_data & 
DEV_HAS_COLLISION_FIX)) {
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_10)
+   txreg = 
NVREG_TX_DEFERRAL_RGMII_STRETCH_10;
+   else
+   txreg = 
NVREG_TX_DEFERRAL_RGMII_STRETCH_100;
+   } else {
+   txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+   }
+   }
} else {
-   txreg = NVREG_TX_DEFERRAL_DEFAULT;
+   if (!phy_exp && !np->duplex && (np->driver_data & 
DEV_HAS_COLLISION_FIX))
+   txreg = NVREG_TX_DEFERRAL_MII_STRETCH;
+   else
+   txreg = NVREG_TX_DEFERRAL_DEFAULT;
}
writel(txreg, base + NvRegTxDeferral);
 
@@ -5615,51 +5632,51 @@
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_28),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_29),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_30),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV

[PATCH 5/5] forcedeth: preserve registers

2008-02-05 Thread Ayaz Abdulla

Various registers need to be preserved before resetting the device.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-17 16:51:40.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-20 11:56:45.0 -0500
@@ -1443,16 +1443,30 @@
 {
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+   u32 temp1, temp2, temp3;
 
dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+
writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, 
base + NvRegTxRxControl);
pci_push(base);
+
+   /* save registers since they will be cleared on reset */
+   temp1 = readl(base + NvRegMacAddrA);
+   temp2 = readl(base + NvRegMacAddrB);
+   temp3 = readl(base + NvRegTransmitPoll);
+
writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
pci_push(base);
udelay(NV_MAC_RESET_DELAY);
writel(0, base + NvRegMacReset);
pci_push(base);
udelay(NV_MAC_RESET_DELAY);
+
+   /* restore saved registers */
+   writel(temp1, base + NvRegMacAddrA);
+   writel(temp2, base + NvRegMacAddrB);
+   writel(temp3, base + NvRegTransmitPoll);
+
writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
pci_push(base);
 }


[PATCH 4/5] forcedeth: tx pause watermarks

2008-02-05 Thread Ayaz Abdulla
New chipsets introduced variant Rx FIFO sizes that need to be taken into 
account when setting up the tx pause watermarks. This patch introduces 
the new device feature flags based on a version and implements the new 
watermarks.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-17 16:50:29.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-17 16:51:02.0 -0500
@@ -166,22 +166,24 @@
  * Hardware access:
  */
 
-#define DEV_NEED_TIMERIRQ  0x0001  /* set the timer irq flag in the irq 
mask */
-#define DEV_NEED_LINKTIMER 0x0002  /* poll link settings. Relies on the 
timer irq */
-#define DEV_HAS_LARGEDESC  0x0004  /* device supports jumbo frames and 
needs packet format 2 */
-#define DEV_HAS_HIGH_DMA0x0008  /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM0x0010  /* device supports tx and rx checksum 
offloads */
-#define DEV_HAS_VLAN0x0020  /* device supports vlan tagging and 
striping */
-#define DEV_HAS_MSI 0x0040  /* device supports MSI */
-#define DEV_HAS_MSI_X   0x0080  /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL 0x0100  /* device supports power savings */
-#define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics 
version 1 */
-#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
-#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
-#define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
-#define DEV_HAS_COLLISION_FIX   0x8000  /* device supports tx collision fix */
+#define DEV_NEED_TIMERIRQ  0x1  /* set the timer irq flag in the 
irq mask */
+#define DEV_NEED_LINKTIMER 0x2  /* poll link settings. Relies on 
the timer irq */
+#define DEV_HAS_LARGEDESC  0x4  /* device supports jumbo frames 
and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA   0x8  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM   0x00010  /* device supports tx and rx 
checksum offloads */
+#define DEV_HAS_VLAN   0x00020  /* device supports vlan tagging 
and striping */
+#define DEV_HAS_MSI0x00040  /* device supports MSI */
+#define DEV_HAS_MSI_X  0x00080  /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL0x00100  /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1  0x00200  /* device supports hw statistics 
version 1 */
+#define DEV_HAS_STATISTICS_V2  0x00400  /* device supports hw statistics 
version 2 */
+#define DEV_HAS_TEST_EXTENDED  0x00800  /* device supports extended 
diagnostic test */
+#define DEV_HAS_MGMT_UNIT  0x01000  /* device supports management unit 
*/
+#define DEV_HAS_CORRECT_MACADDR0x02000  /* device supports correct mac 
address order */
+#define DEV_HAS_COLLISION_FIX  0x04000  /* device supports tx collision 
fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1   0x08000  /* device supports tx pause frames 
version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2   0x1  /* device supports tx pause frames 
version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3   0x2  /* device supports tx pause frames 
version 3 */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -322,8 +324,10 @@
NvRegTxRingPhysAddrHigh = 0x148,
NvRegRxRingPhysAddrHigh = 0x14C,
NvRegTxPauseFrame = 0x170,
-#define NVREG_TX_PAUSEFRAME_DISABLE0x01ff0080
-#define NVREG_TX_PAUSEFRAME_ENABLE 0x01800010
+#define NVREG_TX_PAUSEFRAME_DISABLE0x0fff0080
+#define NVREG_TX_PAUSEFRAME_ENABLE_V1  0x01800010
+#define NVREG_TX_PAUSEFRAME_ENABLE_V2  0x056003f0
+#define NVREG_TX_PAUSEFRAME_ENABLE_V3  0x09f00880
NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR0x0001
 #define NVREG_MIISTAT_LINKCHANGE   0x0008
@@ -2741,7 +2745,12 @@
if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) {
u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX;
if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) {
-   writel(NVREG_TX_PAUSEFRAME_ENABLE,  base + 
NvRegTxPauseFrame);
+   u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
+   if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
+   pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
+   if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)
+   pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
+   writel(pause_enable,  base + NvRegTxPauseFrame);
writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
 

[PATCH 2/5] forcedeth: tx collision fix

2008-02-05 Thread Ayaz Abdulla
This patch supports a new fix in hardware regarding tx collisions. In 
the cases where we are in autoneg mode and the link partner is in forced 
mode, we need to setup the tx deferral register differently in order to 
reduce collisions on the wire.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-15 17:44:38.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-15 18:28:08.0 -0500
@@ -181,6 +181,7 @@
 #define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
 #define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
 #define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
+#define DEV_HAS_COLLISION_FIX   0x8000  /* device supports tx collision fix */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -266,9 +267,12 @@
 #define NVREG_RNDSEED_FORCE3   0x7400
 
NvRegTxDeferral = 0xA0,
-#define NVREG_TX_DEFERRAL_DEFAULT  0x15050f
-#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
-#define NVREG_TX_DEFERRAL_RGMII_1000   0x14050f
+#define NVREG_TX_DEFERRAL_DEFAULT  0x15050f
+#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
+#define NVREG_TX_DEFERRAL_RGMII_1000   0x14050f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10 0x16190f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_1000x16300f
+#define NVREG_TX_DEFERRAL_MII_STRETCH  0x152000
NvRegRxDeferral = 0xA4,
 #define NVREG_RX_DEFERRAL_DEFAULT  0x16
NvRegMacAddrA = 0xA8,
@@ -2771,6 +2775,7 @@
int retval = 0;
u32 control_1000, status_1000, phyreg, pause_flags, txreg;
u32 txrxFlags = 0;
+   u32 phy_exp;
 
/* BMSR_LSTATUS is latched, read it twice:
 * we want the current value.
@@ -2898,13 +2903,25 @@
phyreg |= PHY_1000;
writel(phyreg, base + NvRegPhyInterface);
 
+   phy_exp = mii_rw(dev, np->phyaddr, MII_EXPANSION, MII_READ) & 
EXPANSION_NWAY; /* autoneg capable */
if (phyreg & PHY_RGMII) {
-   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000)
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000) {
txreg = NVREG_TX_DEFERRAL_RGMII_1000;
-   else
-   txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+   } else {
+   if (!phy_exp && !np->duplex && (np->driver_data & 
DEV_HAS_COLLISION_FIX)) {
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_10)
+   txreg = 
NVREG_TX_DEFERRAL_RGMII_STRETCH_10;
+   else
+   txreg = 
NVREG_TX_DEFERRAL_RGMII_STRETCH_100;
+   } else {
+   txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+   }
+   }
} else {
-   txreg = NVREG_TX_DEFERRAL_DEFAULT;
+   if (!phy_exp && !np->duplex && (np->driver_data & 
DEV_HAS_COLLISION_FIX))
+   txreg = NVREG_TX_DEFERRAL_MII_STRETCH;
+   else
+   txreg = NVREG_TX_DEFERRAL_DEFAULT;
}
writel(txreg, base + NvRegTxDeferral);
 
@@ -5603,51 +5620,51 @@
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_28),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_29),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
},
{   /* MCP73 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_30),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV

[PATCH 3/5] forcedeth: phy status fix

2008-02-05 Thread Ayaz Abdulla
The driver needs to ack only the phy status bits that it is currently 
handling and preserve the other bits for the other handlers. For 
example, when reading/writing from the phy, it should not clear the link 
change interrupt bit. This will cause a missing link change interrupt.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-15 18:38:52.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-15 19:27:55.0 -0500
@@ -327,8 +327,8 @@
NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR0x0001
 #define NVREG_MIISTAT_LINKCHANGE   0x0008
-#define NVREG_MIISTAT_MASK 0x000f
-#define NVREG_MIISTAT_MASK20x000f
+#define NVREG_MIISTAT_MASK_RW  0x0007
+#define NVREG_MIISTAT_MASK_ALL 0x000f
NvRegMIIMask = 0x184,
 #define NVREG_MII_LINKCHANGE   0x0008
 
@@ -1068,7 +1068,7 @@
u32 reg;
int retval;
 
-   writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_MASK_RW, base + NvRegMIIStatus);
 
reg = readl(base + NvRegMIIControl);
if (reg & NVREG_MIICTL_INUSE) {
@@ -3012,7 +3012,7 @@
u32 miistat;
 
miistat = readl(base + NvRegMIIStatus);
-   writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus);
dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, 
miistat);
 
if (miistat & (NVREG_MIISTAT_LINKCHANGE))
@@ -4887,7 +4887,7 @@
 
writel(0, base + NvRegMIIMask);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
-   writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 
writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
writel(readl(base + NvRegTransmitterStatus), base + 
NvRegTransmitterStatus);
@@ -4925,7 +4925,7 @@
 
nv_disable_hw_interrupts(dev, np->irqmask);
pci_push(base);
-   writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
pci_push(base);
 
@@ -4948,7 +4948,7 @@
{
u32 miistat;
miistat = readl(base + NvRegMIIStatus);
-   writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat);
}
/* set linkspeed to invalid value, thus force nv_update_linkspeed
@@ -5320,7 +5320,7 @@
phystate &= ~NVREG_ADAPTCTL_RUNNING;
writel(phystate, base + NvRegAdapterControl);
}
-   writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+   writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 
if (id->driver_data & DEV_HAS_MGMT_UNIT) {
/* management unit running on the mac? */


[PATCH 1/5] forcedeth: restart tx/rx

2008-02-05 Thread Ayaz Abdulla
This patch fixes the issue where the transmitter and receiver must be 
restarted when applying new changes to certain registers.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-15 17:41:00.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-15 17:41:02.0 -0500
@@ -624,6 +624,9 @@
 #define NV_MSI_X_VECTOR_TX0x1
 #define NV_MSI_X_VECTOR_OTHER 0x2
 
+#define NV_RESTART_TX 0x1
+#define NV_RESTART_RX 0x2
+
 /* statistics */
 struct nv_ethtool_str {
char name[ETH_GSTRING_LEN];
@@ -2767,6 +2770,7 @@
int mii_status;
int retval = 0;
u32 control_1000, status_1000, phyreg, pause_flags, txreg;
+   u32 txrxFlags = 0;
 
/* BMSR_LSTATUS is latched, read it twice:
 * we want the current value.
@@ -2862,6 +2866,16 @@
np->duplex = newdup;
np->linkspeed = newls;
 
+   /* The transmitter and receiver must be restarted for safe update */
+   if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) {
+   txrxFlags |= NV_RESTART_TX;
+   nv_stop_tx(dev);
+   }
+   if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
+   txrxFlags |= NV_RESTART_RX;
+   nv_stop_rx(dev);
+   }
+
if (np->gigabit == PHY_GIGABIT) {
phyreg = readl(base + NvRegRandomSeed);
phyreg &= ~(0x3FF00);
@@ -2950,6 +2964,11 @@
}
nv_update_pause(dev, pause_flags);
 
+   if (txrxFlags & NV_RESTART_TX)
+   nv_start_tx(dev);
+   if (txrxFlags & NV_RESTART_RX)
+   nv_start_rx(dev);
+
return retval;
 }
 


Re: [patch 2/4] forcedeth: fix MAC address detection on network card (regression in 2.6.23)

2008-02-05 Thread Ayaz Abdulla



Jeff Garzik wrote:

Ayaz Abdulla wrote:


Andrew Morton wrote:


On Tue, 05 Feb 2008 13:20:59 -0500 Jeff Garzik <[EMAIL PROTECTED]> wrote:



Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>



NAK - this fixes one set of users, and breaks a working set of users.

Need to add DMI check for the specific motherboard 
(dmi_check_system), and flip flag according to success/failure of 
that check.




OK :)  I added the above to the changelog for next time.

You guys can hide, but this patch isn't going away!



I believe Michael determined that a newer BIOS fixes this issue.




That's a solution that makes vendors happy... but we still have to deal 
with it in Linux.  There are plenty of the old broken BIOS still out in 
the field...


Jeff




Michael, can you provide which BIOS version had this issue and which 
version fixed the issue?




---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
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


Re: [patch 2/4] forcedeth: fix MAC address detection on network card (regression in 2.6.23)

2008-02-05 Thread Ayaz Abdulla



Andrew Morton wrote:

On Tue, 05 Feb 2008 13:20:59 -0500 Jeff Garzik <[EMAIL PROTECTED]> wrote:



Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>


NAK - this fixes one set of users, and breaks a working set of users.

Need to add DMI check for the specific motherboard (dmi_check_system), 
and flip flag according to success/failure of that check.



OK :)  I added the above to the changelog for next time.

You guys can hide, but this patch isn't going away!


I believe Michael determined that a newer BIOS fixes this issue.

---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
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


Re: forcedeth oops

2008-01-29 Thread Ayaz Abdulla



Jeff Garzik wrote:

Andrew Brooks wrote:
 > Hello
 >
 > I'm getting an oops in forcedeth whenever I shutdown, details below.
 >
 > I've tried kernel 2.6.16.59 and the latest forcedeth.c from nvidia.com
 > which is package-1.23 version-0.62 date-2007/04/27.
 >
 > How can I download the latest forcedeth.c (including 2008-01-13 
patches) ?

 > It's not in the latest snapshot linux-2.6.24-rc8.
 >
 > Also, why is the version on nvidia.com not just older than the one in
 > the kernel, but it appears to have forked back in May 2006.  Has there
 > been independent development on each version?  They should be the same!

We don't run nvidia.com here :)


 > Here's the diff:
 > <  *0.56: 22 Mar 2006: Additional ethtool and moduleparam support.
 > <  *0.57: 14 May 2006: Moved mac address writes to nv_probe and 
nv_remove.

 > <  *0.58: 20 May 2006: Optimized rx and tx data paths.
 > <  *0.59: 31 May 2006: Added support for sideband management unit.
 > <  *0.60: 31 May 2006: Added support for recoverable error.
 > <  *0.61: 18 Jul 2006: Added support for suspend/resume.
 > <  *0.62: 16 Jan 2007: Fixed statistics, mgmt communication, and 
low phy speed on S5.

 > ---
 >>  *0.56: 22 Mar 2006: Additional ethtool config and moduleparam 
support.
 >>  *0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.

 >>  *0.58: 30 Oct 2006: Added support for sideband management unit.
 >>  *0.59: 30 Oct 2006: Added support for recoverable error.
 >>  *0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data 
paths, and stats.

 >
 >
 > Here's the details of the oops:
 > md: md0 switched to read-only mode.
 > Unable to handle kernel NULL pointer dereference at virtual address 


 > printing eip:
 > f8ccdd55
 > *pde = 36c6a001
 > Oops:  [#1]
 > SMP
 > Modules linked in: nvidia ... forcedeth ... sata_nv
 > CPU: 1
 > EIP:
 > EFLAGS: 00010286 (2.6.16.59 #1)
 > EIP is at nv_suspend+0x85/0x350 [forcedeth]
 > eax:
 > esi:
 > ds:
 > Process reboot
 > Stack:
 > Call Trace:
 > show_stack_log
 > show_registers
 > die
 > do_page_fault
 > error_code
 > nv_reboot_handler
 > notifier_call_chain
 > kernel_restart_prepare
 > kernel_restart
 > sys_reboot
 > sysenter_past_esp
 > Code: 8b 8c 3a 98 01 00 00 01 c8 8b ...
 > INIT: no more processes left in this runlevel

Please reproduce this problem on a modern kernel (2.6.24-rc) without any
closed source modules or drivers loaded.  Thanks.


Andrew,

The driver from the nvidia.com site was forked because we needed to 
create a backport driver package for older kernels. At some point, we 
need to converge the two branches again.


Let us know if you still have an issue with the latest kernel as Jeff 
mentioned.


Regards,
Ayaz




Jeff



--
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



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
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


[PATCH] forcedeth: mac address mcp77/79

2008-01-29 Thread Ayaz Abdulla
This patch is a critical fix for MCP77 and MCP79 devices. The feature 
flags were missing the define for correct mac address 
(DEV_HAS_CORRECT_MACADDR).


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-28 10:15:28.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-28 10:17:38.0 -0500
@@ -5603,35 +5603,35 @@
},
{   /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_32),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_33),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_34),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP77 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_35),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_36),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_37),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_38),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_39),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .drive

[PATCH 5/5] forcedeth: multicast fix

2008-01-14 Thread Ayaz Abdulla
This patch fixes the case where no multicast addresses are requested to 
be added to the multicast filter. The multicast mask must be set to all 
1's instead of all 0's.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-13 15:15:22.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-13 15:24:22.0 -0500
@@ -277,7 +277,9 @@
 #define NVREG_MCASTADDRA_FORCE 0x01
NvRegMulticastAddrB = 0xB4,
NvRegMulticastMaskA = 0xB8,
+#define NVREG_MCASTMASKA_NONE  0x
NvRegMulticastMaskB = 0xBC,
+#define NVREG_MCASTMASKB_NONE  0x
 
NvRegPhyInterface = 0xC0,
 #define PHY_RGMII  0x1000
@@ -2693,6 +2695,9 @@
addr[1] = alwaysOn[1];
mask[0] = alwaysOn[0] | alwaysOff[0];
mask[1] = alwaysOn[1] | alwaysOff[1];
+   } else {
+   mask[0] = NVREG_MCASTMASKA_NONE;
+   mask[1] = NVREG_MCASTMASKB_NONE;
}
}
addr[0] |= NVREG_MCASTADDRA_FORCE;
@@ -4803,8 +4808,8 @@
nv_mac_reset(dev);
writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
writel(0, base + NvRegMulticastAddrB);
-   writel(0, base + NvRegMulticastMaskA);
-   writel(0, base + NvRegMulticastMaskB);
+   writel(NVREG_MCASTMASKA_NONE, base + NvRegMulticastMaskA);
+   writel(NVREG_MCASTMASKB_NONE, base + NvRegMulticastMaskB);
writel(0, base + NvRegPacketFilterFlags);
 
writel(0, base + NvRegTransmitterControl);
@@ -4898,8 +4903,8 @@
spin_lock_irq(&np->lock);
writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
writel(0, base + NvRegMulticastAddrB);
-   writel(0, base + NvRegMulticastMaskA);
-   writel(0, base + NvRegMulticastMaskB);
+   writel(NVREG_MCASTMASKA_NONE, base + NvRegMulticastMaskA);
+   writel(NVREG_MCASTMASKB_NONE, base + NvRegMulticastMaskB);
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + 
NvRegPacketFilterFlags);
/* One manual link speed update: Interrupts are enabled, future link
 * speed changes cause interrupts and are handled by nv_link_irq().


[PATCH 3/5] forcedeth: updated copyright section

2008-01-14 Thread Ayaz Abdulla

This patch updates the copyright section to include 2007 and 2008.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-13 15:10:18.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-13 15:11:47.0 -0500
@@ -13,7 +13,7 @@
  * Copyright (C) 2004 Andrew de Quincey (wol support)
  * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
  * IRQ rate fixes, bigendian fixes, cleanups, verification)
- * Copyright (c) 2004,5,6 NVIDIA Corporation
+ * Copyright (c) 2004,2005,2006,2007,2008 NVIDIA Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by


[PATCH 4/5] forcedeth: tx pause fix

2008-01-14 Thread Ayaz Abdulla
This patch fixes the tx pause enable watermark flags. The new values 
where determined to be optimal during testing.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-13 15:12:16.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-13 15:14:55.0 -0500
@@ -316,8 +316,8 @@
NvRegTxRingPhysAddrHigh = 0x148,
NvRegRxRingPhysAddrHigh = 0x14C,
NvRegTxPauseFrame = 0x170,
-#define NVREG_TX_PAUSEFRAME_DISABLE0x1ff0080
-#define NVREG_TX_PAUSEFRAME_ENABLE 0x0c00030
+#define NVREG_TX_PAUSEFRAME_DISABLE0x01ff0080
+#define NVREG_TX_PAUSEFRAME_ENABLE 0x01800010
NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR0x0001
 #define NVREG_MIISTAT_LINKCHANGE   0x0008


[PATCH 1/5] forcedeth: reset register fix

2008-01-14 Thread Ayaz Abdulla

This patch fixes the reset register definition from 0x3C to 0x34.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2008-01-13 15:00:43.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-13 15:00:48.0 -0500
@@ -226,7 +226,7 @@
 #define NVREG_MISC1_HD 0x02
 #define NVREG_MISC1_FORCE  0x3b0f3c
 
-   NvRegMacReset = 0x3c,
+   NvRegMacReset = 0x34,
 #define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01


[PATCH 2/5] forcedeth: checksum fix

2008-01-14 Thread Ayaz Abdulla
The driver should inform the stack when checksum has been performed by 
the HW when both IP and TCP (or UDP) checksum flags are indicated by HW.


Previously, it would also inform the stack when only IP checksum flag 
was indicated by HW. This can cause data corruption when IP fragments 
are used. The IP Identification field can wrap around and cause data 
from new fragments to fill into older fragment slots with same IP Id. 
The stack would then not perform TCP/UDP checksum (after re-assembly of 
all fragments) since driver falsely stated it was already calculated.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>


--- old/drivers/net/forcedeth.c 2008-01-13 15:01:36.0 -0500
+++ new/drivers/net/forcedeth.c 2008-01-13 15:08:31.0 -0500
@@ -471,9 +471,9 @@
 #define NV_RX_AVAIL(1<<31)
 
 #define NV_RX2_CHECKSUMMASK(0x1C00)
-#define NV_RX2_CHECKSUMOK1 (0x1000)
-#define NV_RX2_CHECKSUMOK2 (0x1400)
-#define NV_RX2_CHECKSUMOK3 (0x1800)
+#define NV_RX2_CHECKSUM_IP (0x1000)
+#define NV_RX2_CHECKSUM_IP_TCP (0x1400)
+#define NV_RX2_CHECKSUM_IP_UDP (0x1800)
 #define NV_RX2_DESCRIPTORVALID (1<<29)
 #define NV_RX2_SUBSTRACT1  (1<<25)
 #define NV_RX2_ERROR1  (1<<18)
@@ -2375,14 +2375,9 @@
goto next_pkt;
}
}
-   if ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK2)/*ip and tcp */ {
+   if (((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUM_IP_TCP) || /*ip and tcp */
+   ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUM_IP_UDP))   /*ip and udp */
skb->ip_summed = CHECKSUM_UNNECESSARY;
-   } else {
-   if ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK1 ||
-   (flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK3) {
-   skb->ip_summed = 
CHECKSUM_UNNECESSARY;
-   }
-   }
} else {
dev_kfree_skb(skb);
goto next_pkt;
@@ -2474,14 +2469,9 @@
}
}
 
-   if ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK2)/*ip and tcp */ {
+   if (((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUM_IP_TCP) || /*ip and tcp */
+   ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUM_IP_UDP))   /*ip and udp */
skb->ip_summed = CHECKSUM_UNNECESSARY;
-   } else {
-   if ((flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK1 ||
-   (flags & NV_RX2_CHECKSUMMASK) == 
NV_RX2_CHECKSUMOK3) {
-   skb->ip_summed = CHECKSUM_UNNECESSARY;
-   }
-   }
 
/* got a valid packet - forward it to the network core 
*/
skb_put(skb, len);


RE: [patch 02/10] forcedeth: power down phy when interface is down

2007-12-14 Thread Ayaz Abdulla
Ed,

You mention that the phy will become 100Mbit half duplex, but during
nv_close, the phy setting is not modified. This might be a separate
issue.

Ayaz

-Original Message-
From: Andrew Morton [mailto:[EMAIL PROTECTED] 
Sent: Thursday, December 13, 2007 5:07 PM
To: Ed Swierk
Cc: Ayaz Abdulla; [EMAIL PROTECTED]; netdev@vger.kernel.org
Subject: Re: [patch 02/10] forcedeth: power down phy when interface is
down


On Thu, 13 Dec 2007 16:53:58 -0800
"Ed Swierk" <[EMAIL PROTECTED]> wrote:

> On 12/13/07, Andrew Morton <[EMAIL PROTECTED]> wrote:
> > Does this patch actually fix any observeable problem?
> 
> Without the patch, ifconfig down leaves the physical link up, which
> confuses datacenter users who expect the link lights both on the NIC
> and the switch to go out when they bring an interface down.
> 
> Furthermore, even though the phy is powered on, autonegotiation stops
> working, so a normally gigabit link might suddenly become 100 Mbit
> half-duplex when the interface goes down, and become gigabit when it
> comes up again.
> 

OK, thanks, I added that text to the changelog along with Ayaz's
objection
and shall continue to bug people with it until we have a fix merged.  
---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
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


RE: [patch 02/10] forcedeth: power down phy when interface is down

2007-12-13 Thread Ayaz Abdulla
I would not include this patch until further testing is performed.
NVIDIA MCP chips use 3rd party PHY vendors. By powering down the phy, it
could have adverse affects on certain phys.

Ayaz


-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
Sent: Thursday, December 13, 2007 4:03 PM
To: [EMAIL PROTECTED]
Cc: netdev@vger.kernel.org; [EMAIL PROTECTED];
[EMAIL PROTECTED]; Ayaz Abdulla
Subject: [patch 02/10] forcedeth: power down phy when interface is down


From: "Ed Swierk" <[EMAIL PROTECTED]>

Bring the physical link down when the interface is down by placing the
PHY
in power-down state, unless WOL is enabled.  This mirrors the behavior
of
other drivers including e1000 and tg3.

Signed-off-by: Ed Swierk <[EMAIL PROTECTED]>
Cc: Jeff Garzik <[EMAIL PROTECTED]>
Cc: Ayaz Abdulla <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/net/forcedeth.c |   12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff -puN
drivers/net/forcedeth.c~forcedeth-power-down-phy-when-interface-is-down
drivers/net/forcedeth.c
---
a/drivers/net/forcedeth.c~forcedeth-power-down-phy-when-interface-is-dow
n
+++ a/drivers/net/forcedeth.c
@@ -1312,9 +1312,9 @@ static int phy_init(struct net_device *d
/* some phys clear out pause advertisment on reset, set it back
*/
mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
 
-   /* restart auto negotiation */
+   /* restart auto negotiation, power down phy */
mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
-   mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+   mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN);
if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
return PHY_ERROR;
}
@@ -4798,6 +4798,10 @@ static int nv_open(struct net_device *de
 
dprintk(KERN_DEBUG "nv_open: begin\n");
 
+   /* power up phy */
+   mii_rw(dev, np->phyaddr, MII_BMCR,
+  mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) &
~BMCR_PDOWN);
+
/* erase previous misconfiguration */
if (np->driver_data & DEV_HAS_POWER_CNTRL)
nv_mac_reset(dev);
@@ -4980,6 +4984,10 @@ static int nv_close(struct net_device *d
if (np->wolenabled) {
writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base +
NvRegPacketFilterFlags);
nv_start_rx(dev);
+   } else {
+   /* power down phy */
+   mii_rw(dev, np->phyaddr, MII_BMCR,
+  mii_rw(dev, np->phyaddr, MII_BMCR,
MII_READ)|BMCR_PDOWN);
}
 
/* FIXME: power down nic */
_
---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--
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


RE: [patch 2/8] forcedeth: fix MAC address detection on network card (regression in 2.6.23)

2007-11-21 Thread Ayaz Abdulla
The solution is to get the OEM to update their BIOS (instead of
integrating this patch) since the MCP61 specs indicate that the MAC
Address should be in correct order from BIOS.

By changing the feature DEV_HAS_CORRECT_MACADDR to all MCP61 boards, it
could cause it to break on other OEM systems who have implemented it
correctly.

Thanks,
Ayaz



-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 
Sent: Wednesday, November 21, 2007 3:03 PM
To: [EMAIL PROTECTED]
Cc: netdev@vger.kernel.org; [EMAIL PROTECTED];
[EMAIL PROTECTED]; Ayaz Abdulla; [EMAIL PROTECTED]
Subject: [patch 2/8] forcedeth: fix MAC address detection on network
card (regression in 2.6.23)


From: Michael Pyne <[EMAIL PROTECTED]>

Partially revert a change to mac address detection introduced to the
forcedeth
driver.  The change was intended to correct mac address detection for
newer
nVidia chipsets where the mac address was stored in reverse order.  One
of
those chipsets appears to still have the mac address in reverse order
(or at
least, it does on my system).

The change that broke mac address detection for my card was commit
ef756b3e56c68a4d76d9d7b9a73fa8f4f739180f "forcedeth: mac address
correct"

My network card is an nVidia built-in Ethernet card, output from lspci
as
follows (with text and numeric ids):
$ lspci | grep Ethernet
00:07.0 Bridge: nVidia Corporation MCP61 Ethernet (rev a2)
$ lspci -n | grep 07.0
00:07.0 0680: 10de:03ef (rev a2)

The vendor id is, of course, nVidia.  The device id corresponds to the
NVIDIA_NVENET_19 entry.

The included patch fixes the MAC address detection on my system.
Interestingly, the MAC address appears to be in the range reserved for
my
motherboard manufacturer (Gigabyte) and not nVidia.

Signed-off-by: Michael J. Pyne <[EMAIL PROTECTED]>
Cc: Jeff Garzik <[EMAIL PROTECTED]>
Cc: Ayaz Abdulla <[EMAIL PROTECTED]>
Cc: <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/net/forcedeth.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff -puN
drivers/net/forcedeth.c~forcedeth-fix-mac-address-detection-on-network-c
ard-regression-in-2623 drivers/net/forcedeth.c
---
a/drivers/net/forcedeth.c~forcedeth-fix-mac-address-detection-on-network
-card-regression-in-2623
+++ a/drivers/net/forcedeth.c
@@ -,7 +,7 @@ static struct pci_device_id pci_tbl[] = 
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_19),
-   .driver_data =
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTR
L|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_E
XTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+   .driver_data =
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTR
L|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_E
XTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_20),
_
---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


Re: [PATCH] forcedeth boot delay fix

2007-11-20 Thread Ayaz Abdulla

Missed that "break". Here is the corrected patch.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>



Andrew Morton wrote:

On Sun, 18 Nov 2007 14:13:41 -0500 Ayaz Abdulla <[EMAIL PROTECTED]> wrote:


This patch fixes a long boot delay in the forcedeth driver. During 
initialization, the timeout for the handshake between mgmt unit and 
driver can be very long. The patch reduces the timeout by eliminating a 
extra loop around the timeout logic.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>



[patch-forcedeth-sema-fix  text/plain (1.3KB)]
--- old/drivers/net/forcedeth.c 2007-11-08 17:33:00.0 -0500
+++ new/drivers/net/forcedeth.c 2007-11-08 17:34:25.0 -0500
@@ -5286,20 +5286,17 @@
if (readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_PHY_INIT) {
np->mac_in_use = readl(base + NvRegTransmitterControl) 
& NVREG_XMITCTL_MGMT_ST;
dprintk(KERN_INFO "%s: mgmt unit is running. mac in use 
%x.\n", pci_name(pci_dev), np->mac_in_use);
-   for (i = 0; i < 5000; i++) {
-   msleep(1);
-   if (nv_mgmt_acquire_sema(dev)) {
-   /* management unit setup the phy 
already? */
-   if ((readl(base + NvRegTransmitterControl) 
& NVREG_XMITCTL_SYNC_MASK) ==
-   NVREG_XMITCTL_SYNC_PHY_INIT) {
-   /* phy is inited by mgmt unit */
-   phyinitialized = 1;
-   dprintk(KERN_INFO "%s: Phy already 
initialized by mgmt unit.\n", pci_name(pci_dev));
-   } else {
-   /* we need to init the phy */
-   }
-   break;
+   if (nv_mgmt_acquire_sema(dev)) {
+   /* management unit setup the phy already? */
+   if ((readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_MASK) ==
+   NVREG_XMITCTL_SYNC_PHY_INIT) {
+   /* phy is inited by mgmt unit */
+   phyinitialized = 1;
+   dprintk(KERN_INFO "%s: Phy already 
initialized by mgmt unit.\n", pci_name(pci_dev));
+   } else {
+   /* we need to init the phy */
}
+   break;
}
}
}



drivers/net/forcedeth.c: In function 'nv_probe':
drivers/net/forcedeth.c:5307: error: break statement not within loop or switch  
--- old/drivers/net/forcedeth.c 2007-11-08 17:33:00.0 -0500
+++ new/drivers/net/forcedeth.c 2007-11-19 13:09:03.0 -0500
@@ -5286,19 +5286,15 @@
if (readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_PHY_INIT) {
np->mac_in_use = readl(base + NvRegTransmitterControl) 
& NVREG_XMITCTL_MGMT_ST;
dprintk(KERN_INFO "%s: mgmt unit is running. mac in use 
%x.\n", pci_name(pci_dev), np->mac_in_use);
-   for (i = 0; i < 5000; i++) {
-   msleep(1);
-   if (nv_mgmt_acquire_sema(dev)) {
-   /* management unit setup the phy 
already? */
-   if ((readl(base + 
NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
-   NVREG_XMITCTL_SYNC_PHY_INIT) {
-   /* phy is inited by mgmt unit */
-   phyinitialized = 1;
-   dprintk(KERN_INFO "%s: Phy 
already initialized by mgmt unit.\n", pci_name(pci_dev));
-   } else {
-   /* we need to init the phy */
-   }
-   break;
+   if (nv_mgmt_acquire_sema(dev)) {
+   /* management unit setup the phy already? */
+   if ((readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_MASK) ==
+   NVREG_XMITCTL_SYNC_PHY_INIT) {
+   /* phy is inited by mgmt unit */
+   phyinitialized = 1;
+   dprintk(KERN_INFO "%s: Phy already 
initialized by mgmt unit.\n", pci_name(pci_dev));
+   } else {
+   /* we need to init the phy */
}
}
}


[PATCH] forcedeth boot delay fix

2007-11-19 Thread Ayaz Abdulla
This patch fixes a long boot delay in the forcedeth driver. During 
initialization, the timeout for the handshake between mgmt unit and 
driver can be very long. The patch reduces the timeout by eliminating a 
extra loop around the timeout logic.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-11-08 17:33:00.0 -0500
+++ new/drivers/net/forcedeth.c 2007-11-08 17:34:25.0 -0500
@@ -5286,20 +5286,17 @@
if (readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_PHY_INIT) {
np->mac_in_use = readl(base + NvRegTransmitterControl) 
& NVREG_XMITCTL_MGMT_ST;
dprintk(KERN_INFO "%s: mgmt unit is running. mac in use 
%x.\n", pci_name(pci_dev), np->mac_in_use);
-   for (i = 0; i < 5000; i++) {
-   msleep(1);
-   if (nv_mgmt_acquire_sema(dev)) {
-   /* management unit setup the phy 
already? */
-   if ((readl(base + 
NvRegTransmitterControl) & NVREG_XMITCTL_SYNC_MASK) ==
-   NVREG_XMITCTL_SYNC_PHY_INIT) {
-   /* phy is inited by mgmt unit */
-   phyinitialized = 1;
-   dprintk(KERN_INFO "%s: Phy 
already initialized by mgmt unit.\n", pci_name(pci_dev));
-   } else {
-   /* we need to init the phy */
-   }
-   break;
+   if (nv_mgmt_acquire_sema(dev)) {
+   /* management unit setup the phy already? */
+   if ((readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_SYNC_MASK) ==
+   NVREG_XMITCTL_SYNC_PHY_INIT) {
+   /* phy is inited by mgmt unit */
+   phyinitialized = 1;
+   dprintk(KERN_INFO "%s: Phy already 
initialized by mgmt unit.\n", pci_name(pci_dev));
+   } else {
+   /* we need to init the phy */
}
+   break;
}
}
}


[PATCH 1/2] forcedeth new mcp79 device ids

2007-11-08 Thread Ayaz Abdulla

This patch adds new device ids for mcp79 devices.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/include/linux/pci_ids.h 2007-11-07 14:14:01.0 -0500
+++ new/include/linux/pci_ids.h 2007-11-07 14:13:53.0 -0500
@@ -1237,6 +1237,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_33  0x0761
 #define PCI_DEVICE_ID_NVIDIA_NVENET_34  0x0762
 #define PCI_DEVICE_ID_NVIDIA_NVENET_35  0x0763
+#define PCI_DEVICE_ID_NVIDIA_NVENET_36  0x0AB0
+#define PCI_DEVICE_ID_NVIDIA_NVENET_37  0x0AB1
+#define PCI_DEVICE_ID_NVIDIA_NVENET_38  0x0AB2
+#define PCI_DEVICE_ID_NVIDIA_NVENET_39  0x0AB3
 
 #define PCI_VENDOR_ID_IMS  0x10e0
 #define PCI_DEVICE_ID_IMS_TT1280x9128


[PATCH 2/2] forcedeth new mcp79 device ids

2007-11-08 Thread Ayaz Abdulla
This patch adds new device ids and features for mcp79 devices into the 
forcedeth driver.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-11-07 14:13:47.0 -0500
+++ new/drivers/net/forcedeth.c 2007-11-07 14:13:39.0 -0500
@@ -5613,6 +5613,22 @@
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_35),
.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
+   {   /* MCP79 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_36),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP79 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_37),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP79 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_38),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP79 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_39),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
{0,},
 };
 


[PATCH 2/2] forcedeth new device ids

2007-10-24 Thread Ayaz Abdulla
This patch adds new device ids and features for mcp77 devices into the 
forcedeth driver.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>
--- old/drivers/net/forcedeth.c 2007-10-23 16:47:08.0 -0400
+++ new/drivers/net/forcedeth.c 2007-10-23 16:47:11.0 -0400
@@ -5597,6 +5597,22 @@
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_31),
.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
+   {   /* MCP77 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_32),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP77 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_33),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP77 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_34),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP77 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_35),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
{0,},
 };
 


[PATCH 1/2] forcedeth new device ids

2007-10-24 Thread Ayaz Abdulla

This patch adds new device ids for mcp77 devices.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>
--- old/include/linux/pci_ids.h 2007-10-23 16:49:46.0 -0400
+++ new/include/linux/pci_ids.h 2007-10-23 16:50:50.0 -0400
@@ -1236,6 +1236,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE   0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE   0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE   0x0759
+#define PCI_DEVICE_ID_NVIDIA_NVENET_32  0x0760
+#define PCI_DEVICE_ID_NVIDIA_NVENET_33  0x0761
+#define PCI_DEVICE_ID_NVIDIA_NVENET_34  0x0762
+#define PCI_DEVICE_ID_NVIDIA_NVENET_35  0x0763
 
 #define PCI_VENDOR_ID_IMS  0x10e0
 #define PCI_DEVICE_ID_IMS_TT1280x9128


Re: [PATCH] forcedeth: Fix MAC address detection on network card (regression in 2.6.23)

2007-10-15 Thread Ayaz Abdulla



Jeff Garzik wrote:

Michael Pyne wrote:

Partially revert a change to mac address detection introduced to the 
forcedeth driver.  The change was intended to correct mac address 
detection for newer nVidia chipsets where the mac address was stored 
in reverse order.  One of those chipsets appears to still have the mac 
address in reverse order (or at least, it does on my system).


Signed-off-by: Michael J. Pyne <[EMAIL PROTECTED]>
---
The change that broke mac address detection for my card was commit 
ef756b3e56c68a4d76d9d7b9a73fa8f4f739180f "forcedeth: mac address correct"


My network card is an nVidia built-in Ethernet card, output from lspci 
as follows (with text and numeric ids):

$ lspci | grep Ethernet
00:07.0 Bridge: nVidia Corporation MCP61 Ethernet (rev a2)
$ lspci -n | grep 07.0
00:07.0 0680: 10de:03ef (rev a2)

The vendor id is, of course, nVidia.  The device id corresponds to the 
NVIDIA_NVENET_19 entry.


The included patch fixes the MAC address detection on my system.  
Interestingly, the MAC address appears to be in the range reserved for 
my motherboard manufacturer (Gigabyte) and not nVidia.


If you need any further information about my hardware configuration 
just let me know.


Regards,
 - Michael Pyne

--- a/drivers/net/forcedeth.c   2007-10-11 22:01:26 -0400
+++ b/drivers/net/forcedeth-new.c   2007-10-11 22:06:52 -0400
@@ -5513,7 +5513,7 @@ static struct pci_device_id pci_tbl[] =  },
 {/* MCP61 Ethernet Controller */
 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_19),
-.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|
DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2| 


DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|
DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2| 


DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
 },
 {/* MCP65 Ethernet Controller */
 PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),



your patch is word-wrapped.  Anyway...

Ayaz -- ACK this patch?


ASUS should be contacted to fix their SBIOS instead of patching the driver.

MCP61 reference has the correct address programmed by SBIOS. There are 
other vendor boards that will have correct address (as defined by MCP61 
reference).










---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


MSI interrupts and disable_irq

2007-09-28 Thread Ayaz Abdulla
I am trying to track down a forcedeth driver issue described by bug 9047 
in bugzilla (2.6.23-rc7-git1 forcedeth w/ MCP55 oops under heavy load). 
I added a patch to synchronize the timer handlers so that one handler 
doesn't accidently enable the IRQ while another timer handler is running 
(see attachment 'Add timer lock' in bug report) and for other processing 
protection.


However, the system still had an Oops. So I added a lock around the 
nv_rx_process_optimized() and the Oops has not happened (see attachment 
'New patch for locking' in bug report). This would imply a 
synchronization issue. However, the only callers of that function are 
the IRQ handler and the timer handlers (in non-NAPI case). The timer 
handlers  use disable_irq so that the IRQ handler does not contend with 
them. It looks as if disable_irq is not working properly.


This issue repros only with MSI interrupt and not legacy INTx 
interrupts. Any ideas?


Thanks,
Ayaz
-
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


Re: [PATCH] forcedeth: power down phy when interface is down

2007-09-20 Thread Ayaz Abdulla

It seems that you are powering down the phy even if WOL is enabled.

Secondly, can you powerdown the phy at the same time you start 
performing autoneg restart?



Ed Swierk wrote:

Bring the physical link down when the interface is down, by placing
the PHY in power-down state. This mirrors the behavior of other
drivers including e1000 and tg3.

Signed-off-by: Ed Swierk <[EMAIL PROTECTED]>



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


[PATCH] forcedeth: mac address correct

2007-07-27 Thread Ayaz Abdulla

Resending:

In older chipsets, the mac address was stored in reversed order.
However, in newer chipsets, the mac address is in correct order. This
patch takes those newer chipsets into account and does not rely on a
special bit setup by BIOS'.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-07-26 23:09:31.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-26 23:43:09.0 -0400
@@ -178,6 +178,7 @@
 #define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
 #define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
 #define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -5172,7 +5173,8 @@
 
/* check the workaround bit for correct mac address order */
txreg = readl(base + NvRegTransmitPoll);
-   if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+   if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
+   (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
/* mac address is already in correct order */
dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
@@ -5500,67 +5502,67 @@
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_16),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_17),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_18),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_19),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_21),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Con

[PATCH] forcedeth: mac address correct

2007-07-27 Thread Ayaz Abdulla

In older chipsets, the mac address was stored in reversed order.
However, in newer chipsets, the mac address is in correct order. This
patch takes those newer chipsets into account and does not rely on a
special bit setup by BIOS'.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>


--- old/drivers/net/forcedeth.c 2007-07-26 23:09:31.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-26 23:11:04.0 -0400
@@ -178,6 +178,7 @@
 #define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
 #define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
 #define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address 
order */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -5172,7 +5173,8 @@
 
/* check the workaround bit for correct mac address order */
txreg = readl(base + NvRegTransmitPoll);
-   if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+   if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
+   (id->driver_data & DEV_HAS_CORRECT_MACADDR) {
/* mac address is already in correct order */
dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
@@ -5500,67 +5502,67 @@
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_16),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_17),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_18),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP61 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_19),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_21),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
},
{   /* MCP65 Ethernet Con

[PATCH 2/2] forcedeth: mcp73 device addition

2007-07-23 Thread Ayaz Abdulla

This patch contains new device settings for MCP73 chipset.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-07-22 19:02:41.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-22 19:31:56.0 -0400
@@ -5550,6 +5550,22 @@
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_27),
.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
+   {   /* MCP73 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_28),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP73 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_29),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP73 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_30),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP73 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_31),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
{0,},
 };
 


[PATCH 1/2] forcedeth: new device ids in pci_ids.h

2007-07-23 Thread Ayaz Abdulla

This patch contains new device ids for MCP73 chipset.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/include/linux/pci_ids.h 2007-07-22 18:57:26.0 -0400
+++ new/include/linux/pci_ids.h 2007-07-22 18:57:11.0 -0400
@@ -1223,6 +1223,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_25  0x054D
 #define PCI_DEVICE_ID_NVIDIA_NVENET_26  0x054E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_27  0x054F
+#define PCI_DEVICE_ID_NVIDIA_NVENET_28  0x07DC
+#define PCI_DEVICE_ID_NVIDIA_NVENET_29  0x07DD
+#define PCI_DEVICE_ID_NVIDIA_NVENET_30  0x07DE
+#define PCI_DEVICE_ID_NVIDIA_NVENET_31  0x07DF
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE   0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE   0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE   0x0759


[PATCH 3/3] forcedeth bug fix: realtek phy

2007-07-15 Thread Ayaz Abdulla

This patch contains errata fixes for the realtek phy.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>


--- old/drivers/net/forcedeth.c 2007-07-15 06:31:00.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-15 06:40:29.0 -0400
@@ -551,6 +551,7 @@
 #define PHY_OUI_MARVELL0x5043
 #define PHY_OUI_CICADA 0x03f1
 #define PHY_OUI_VITESSE0x01c1
+#define PHY_OUI_REALTEK0x01c1
 #define PHYID1_OUI_MASK0x03ff
 #define PHYID1_OUI_SHFT6
 #define PHYID2_OUI_MASK0xfc00
@@ -580,6 +581,13 @@
 #define PHY_VITESSE_INIT8  0x0100
 #define PHY_VITESSE_INIT9  0x8f82
 #define PHY_VITESSE_INIT10 0x0
+#define PHY_REALTEK_INIT_REG1  0x1f
+#define PHY_REALTEK_INIT_REG2  0x19
+#define PHY_REALTEK_INIT_REG3  0x13
+#define PHY_REALTEK_INIT1  0x
+#define PHY_REALTEK_INIT2  0x8e00
+#define PHY_REALTEK_INIT3  0x0001
+#define PHY_REALTEK_INIT4  0xad17
 
 #define PHY_GIGABIT0x0100
 
@@ -1114,6 +1122,28 @@
return PHY_ERROR;
}
}
+   if (np->phy_oui == PHY_OUI_REALTEK) {
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, 
PHY_REALTEK_INIT2)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT3)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, 
PHY_REALTEK_INIT4)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   }
 
/* set advertise register */
reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
@@ -1250,6 +1280,30 @@
return PHY_ERROR;
}
}
+   if (np->phy_oui == PHY_OUI_REALTEK) {
+   /* reset could have cleared these out, set them back */
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, 
PHY_REALTEK_INIT2)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT3)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, 
PHY_REALTEK_INIT4)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, 
PHY_REALTEK_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   }
+
/* some phys clear out pause advertisment on reset, set it back */
mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
 


[PATCH 2/3] forcedeth bug fix: vitesse phy

2007-07-15 Thread Ayaz Abdulla

This patch contains errata fixes for the vitesse phy.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-07-15 06:25:01.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-15 06:29:38.0 -0400
@@ -550,6 +550,7 @@
 /* PHY defines */
 #define PHY_OUI_MARVELL0x5043
 #define PHY_OUI_CICADA 0x03f1
+#define PHY_OUI_VITESSE0x01c1
 #define PHYID1_OUI_MASK0x03ff
 #define PHYID1_OUI_SHFT6
 #define PHYID2_OUI_MASK0xfc00
@@ -563,6 +564,23 @@
 #define PHY_CICADA_INIT4   0x0200
 #define PHY_CICADA_INIT5   0x0004
 #define PHY_CICADA_INIT6   0x02000
+#define PHY_VITESSE_INIT_REG1  0x1f
+#define PHY_VITESSE_INIT_REG2  0x10
+#define PHY_VITESSE_INIT_REG3  0x11
+#define PHY_VITESSE_INIT_REG4  0x12
+#define PHY_VITESSE_INIT_MSK1  0xc
+#define PHY_VITESSE_INIT_MSK2  0x0180
+#define PHY_VITESSE_INIT1  0x52b5
+#define PHY_VITESSE_INIT2  0xaf8a
+#define PHY_VITESSE_INIT3  0x8
+#define PHY_VITESSE_INIT4  0x8f8a
+#define PHY_VITESSE_INIT5  0xaf86
+#define PHY_VITESSE_INIT6  0x8f86
+#define PHY_VITESSE_INIT7  0xaf82
+#define PHY_VITESSE_INIT8  0x0100
+#define PHY_VITESSE_INIT9  0x8f82
+#define PHY_VITESSE_INIT10 0x0
+
 #define PHY_GIGABIT0x0100
 
 #define PHY_TIMEOUT0x1
@@ -1162,6 +1180,76 @@
return PHY_ERROR;
}
}
+   if (np->phy_oui == PHY_OUI_VITESSE) {
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, 
PHY_VITESSE_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT2)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
MII_READ);
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
MII_READ);
+   phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+   phy_reserved |= PHY_VITESSE_INIT3;
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT4)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT5)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
MII_READ);
+   phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+   phy_reserved |= PHY_VITESSE_INIT3;
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
MII_READ);
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT6)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT7)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
MII_READ);
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_rese

[PATCH 1/3] forcedeth bug fix: cicada phy

2007-07-15 Thread Ayaz Abdulla
This patch contains errata fixes for the cicada phy. It only renamed the 
defines to be phy specific.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-07-15 06:20:14.0 -0400
+++ new/drivers/net/forcedeth.c 2007-07-15 06:24:20.0 -0400
@@ -557,12 +557,12 @@
 #define PHYID2_MODEL_MASK  0x03f0
 #define PHY_MODEL_MARVELL_E30160x220
 #define PHY_MARVELL_E3016_INITMASK 0x0300
-#define PHY_INIT1  0x0f000
-#define PHY_INIT2  0x0e00
-#define PHY_INIT3  0x01000
-#define PHY_INIT4  0x0200
-#define PHY_INIT5  0x0004
-#define PHY_INIT6  0x02000
+#define PHY_CICADA_INIT1   0x0f000
+#define PHY_CICADA_INIT2   0x0e00
+#define PHY_CICADA_INIT3   0x01000
+#define PHY_CICADA_INIT4   0x0200
+#define PHY_CICADA_INIT5   0x0004
+#define PHY_CICADA_INIT6   0x02000
 #define PHY_GIGABIT0x0100
 
 #define PHY_TIMEOUT0x1
@@ -1141,14 +1141,14 @@
/* phy vendor specific configuration */
if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
-   phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
-   phy_reserved |= (PHY_INIT3 | PHY_INIT4);
+   phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
+   phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;
}
phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
-   phy_reserved |= PHY_INIT5;
+   phy_reserved |= PHY_CICADA_INIT5;
if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;
@@ -1156,7 +1156,7 @@
}
if (np->phy_oui == PHY_OUI_CICADA) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, 
MII_READ);
-   phy_reserved |= PHY_INIT6;
+   phy_reserved |= PHY_CICADA_INIT6;
if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;


[PATCH 1/4] forcedeth: add vitesse phy

2007-05-21 Thread Ayaz Abdulla

This patch adds errata support for the vitesse phy.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-05-01 15:30:53.0 -0400
+++ new/drivers/net/forcedeth.c 2007-05-01 15:30:57.0 -0400
@@ -550,6 +550,7 @@
 /* PHY defines */
 #define PHY_OUI_MARVELL0x5043
 #define PHY_OUI_CICADA 0x03f1
+#define PHY_OUI_VITESSE0x01c1
 #define PHYID1_OUI_MASK0x03ff
 #define PHYID1_OUI_SHFT6
 #define PHYID2_OUI_MASK0xfc00
@@ -557,12 +558,29 @@
 #define PHYID2_MODEL_MASK  0x03f0
 #define PHY_MODEL_MARVELL_E30160x220
 #define PHY_MARVELL_E3016_INITMASK 0x0300
-#define PHY_INIT1  0x0f000
-#define PHY_INIT2  0x0e00
-#define PHY_INIT3  0x01000
-#define PHY_INIT4  0x0200
-#define PHY_INIT5  0x0004
-#define PHY_INIT6  0x02000
+#define PHY_CICADA_INIT1   0x0f000
+#define PHY_CICADA_INIT2   0x0e00
+#define PHY_CICADA_INIT3   0x01000
+#define PHY_CICADA_INIT4   0x0200
+#define PHY_CICADA_INIT5   0x0004
+#define PHY_CICADA_INIT6   0x02000
+#define PHY_VITESSE_INIT_REG1  0x1f
+#define PHY_VITESSE_INIT_REG2  0x10
+#define PHY_VITESSE_INIT_REG3  0x11
+#define PHY_VITESSE_INIT_REG4  0x12
+#define PHY_VITESSE_INIT_MSK1  0xc
+#define PHY_VITESSE_INIT_MSK2  0x0180
+#define PHY_VITESSE_INIT1  0x52b5
+#define PHY_VITESSE_INIT2  0xaf8a
+#define PHY_VITESSE_INIT3  0x8
+#define PHY_VITESSE_INIT4  0x8f8a
+#define PHY_VITESSE_INIT5  0xaf86
+#define PHY_VITESSE_INIT6  0x8f86
+#define PHY_VITESSE_INIT7  0xaf82
+#define PHY_VITESSE_INIT8  0x0100
+#define PHY_VITESSE_INIT9  0x8f82
+#define PHY_VITESSE_INIT10 0x0
+
 #define PHY_GIGABIT0x0100
 
 #define PHY_TIMEOUT0x1
@@ -1141,14 +1159,14 @@
/* phy vendor specific configuration */
if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
-   phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
-   phy_reserved |= (PHY_INIT3 | PHY_INIT4);
+   phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
+   phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;
}
phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
-   phy_reserved |= PHY_INIT5;
+   phy_reserved |= PHY_CICADA_INIT5;
if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;
@@ -1156,12 +1174,82 @@
}
if (np->phy_oui == PHY_OUI_CICADA) {
phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, 
MII_READ);
-   phy_reserved |= PHY_INIT6;
+   phy_reserved |= PHY_CICADA_INIT6;
if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
return PHY_ERROR;
}
}
+   if (np->phy_oui == PHY_OUI_VITESSE) {
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, 
PHY_VITESSE_INIT1)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT2)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
MII_READ);
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
MII_READ);
+   phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+   phy_reserved |= PHY_VITESSE_INIT3;
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, 
phy_reserved)) {
+   printk(KERN_INFO "%s: phy init failed.\n", 
pci_name(np->pci_dev));
+   return PHY_ERROR;
+   }
+   if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, 
PHY_VITESSE_INIT4)) {
+   printk(KERN_INFO "%s: phy init failed.\n

[PATCH 3/4] forcedeth: fix cpu irq mask

2007-05-21 Thread Ayaz Abdulla
This patch fixes the cpu irq mask define to include the timer irq. 
Another flag check was setting up the timer bit in all cases so we 
didn't notice the issue.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-05-21 20:07:44.0 -0400
+++ new/drivers/net/forcedeth.c 2007-05-21 20:08:34.0 -0400
@@ -195,7 +195,7 @@
 #define NVREG_IRQ_TX_FORCED0x0100
 #define NVREG_IRQ_RECOVER_ERROR0x8000
 #define NVREG_IRQMASK_THROUGHPUT   0x00df
-#define NVREG_IRQMASK_CPU  0x0040
+#define NVREG_IRQMASK_CPU  0x0060
 #define NVREG_IRQ_TX_ALL   
(NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
 #define NVREG_IRQ_RX_ALL   
(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
 #define NVREG_IRQ_OTHER
(NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)


[PATCH 2/4] forcedeth: fix power management support

2007-05-21 Thread Ayaz Abdulla
This patch fixes the power management functions. It includes lowering 
the phy speed to conserve power.


Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-05-01 15:32:03.0 -0400
+++ new/drivers/net/forcedeth.c 2007-05-21 19:54:39.0 -0400
@@ -812,6 +812,10 @@
 
/* flow control */
u32 pause_flags;
+
+   /* power saved state */
+   u32 saved_config_space[64];
+   u32 saved_phyinterface;
 };
 
 /*
@@ -5344,42 +5348,137 @@
 }
 
 #ifdef CONFIG_PM
+static void nv_set_low_speed(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   int adv = 0;
+   int lpa = 0;
+   int adv_lpa, bmcr, tries = 0;
+   int mii_status;
+   u32 control_1000;
+
+   /* lower the speed if we are in 1000Mbps autoneg */
+   if (np->autoneg == 0 || ((np->linkspeed & 0xFFF) != 
NVREG_LINKSPEED_1000))
+   return;
+
+   adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
+   lpa = mii_rw(dev, np->phyaddr, MII_LPA, MII_READ);
+   control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ);
+
+   adv_lpa = lpa & adv;
+
+   /* lower the speed if partner has advertised other speeds */
+   if ((adv_lpa & LPA_10FULL) || (adv_lpa & LPA_10HALF)) {
+   adv &= ~(ADVERTISE_100BASE4 | ADVERTISE_100FULL | 
ADVERTISE_100HALF);
+   control_1000 &= ~ADVERTISE_1000FULL;
+   } else if ((adv_lpa & LPA_100FULL) || (adv_lpa & LPA_100HALF)) {
+   control_1000 &= ~ADVERTISE_1000FULL;
+   } else
+   return;
+
+   /* set new advertisements */
+   mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv);
+   mii_rw(dev, np->phyaddr, MII_CTRL1000, control_1000);
+
+   bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+   if (np->phy_model == PHY_MODEL_MARVELL_E3016) {
+   bmcr |= BMCR_ANENABLE;
+   /* reset the phy in order for settings to stick,
+* and cause autoneg to start */
+   if (phy_reset(dev, bmcr)) {
+   printk(KERN_INFO "%s: phy reset failed\n", dev->name);
+   return;
+   }
+   } else {
+   bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART);
+   mii_rw(dev, np->phyaddr, MII_BMCR, bmcr);
+   }
+   mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+   mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+   while (!(mii_status & BMSR_ANEGCOMPLETE)) {
+   msleep(100);
+   mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ);
+   if (tries++ > 50)
+   break;
+   }
+
+   nv_update_linkspeed(dev);
+
+   return;
+}
+
 static int nv_suspend(struct pci_dev *pdev, pm_message_t state)
 {
struct net_device *dev = pci_get_drvdata(pdev);
struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+   int i;
 
-   if (!netif_running(dev))
-   goto out;
+   dprintk(KERN_DEBUG "forcedeth: nv_suspend\n");
+
+   if (netif_running(dev)) {
+   netif_device_detach(dev);
 
-   netif_device_detach(dev);
+   /* bring down the adapter */
+   nv_close(dev);
+   }
 
-   // Gross.
-   nv_close(dev);
+   /* set phy to a lower speed to conserve power */
+   if (!np->mac_in_use)
+   nv_set_low_speed(dev);
 
pci_save_state(pdev);
+
+   /* save any device state */
+   np->saved_phyinterface = readl(base + NvRegPhyInterface);
+   for (i = 0; i < 64; i++) {
+   pci_read_config_dword(pdev, i*4, &np->saved_config_space[i]);
+   }
+
pci_enable_wake(pdev, pci_choose_state(pdev, state), np->wolenabled);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
-out:
+
return 0;
 }
 
 static int nv_resume(struct pci_dev *pdev)
 {
struct net_device *dev = pci_get_drvdata(pdev);
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
int rc = 0;
+   int i;
+   u32 txreg;
 
-   if (!netif_running(dev))
-   goto out;
-
-   netif_device_attach(dev);
+   dprintk(KERN_DEBUG "forcedeth: nv_resume\n");
 
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
+
+   /* restore saved config space */
+   for (i = 0; i < 64; i++) {
+   pci_write_config_dword(pdev, i*4, np->saved_config_space[i]);
+   }
+
pci_enable_wake(pdev, PCI_D0, 0);
 
-   rc = nv_open(dev);
-out:
+   /* restore saved driver state */
+   txreg = readl(base + NvRegTransmitPoll);
+   txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV;
+   writel(txreg, base + NvRegTransmitPoll);
+   writel(np->saved

[PATCH 4/4] forcedeth: version bump

2007-05-21 Thread Ayaz Abdulla

This patch bumps up the version.

Signed-off-by: Ayaz Abdulla <[EMAIL PROTECTED]>

--- old/drivers/net/forcedeth.c 2007-05-21 20:09:03.0 -0400
+++ new/drivers/net/forcedeth.c 2007-05-21 20:10:32.0 -0400
@@ -112,6 +112,7 @@
  * 0.58: 30 Oct 2006: Added support for sideband management unit.
  * 0.59: 30 Oct 2006: Added support for recoverable error.
  * 0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, 
and stats.
+ * 0.61: 21 May 2007: Fix power management code, cpu mask, and added 
vitesse phy.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -128,7 +129,7 @@
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION  "0.60"
+#define FORCEDETH_VERSION  "0.61"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -5634,6 +5635,7 @@
 MODULE_AUTHOR("Manfred Spraul <[EMAIL PROTECTED]>");
 MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(FORCEDETH_VERSION);
 
 MODULE_DEVICE_TABLE(pci, pci_tbl);
 


Re: [patch 09/11] forcedeth: improve NAPI logic

2007-04-26 Thread Ayaz Abdulla



Jeff Garzik wrote:

Ayaz Abdulla wrote:

I don't see why the NAPI handler needs to process tx packets. The ISR 
will handle all tx processing.



It is a design choice, not a requirement.

Moving non-RX interrupt processing to the NAPI handler can help as loads 
increase.  The basic idea is to do as much work as possible in the NAPI 
handler with NIC interrupts masked.  That mitigates global system 
per-interrupt overhead even more than an only-RX NAPI scheme.


Several net drivers do TX completion handling in the NAPI handler.


Ok. In that case, the patch needs to be improved.

The following needs to be done when NAPI is enabled:
- remove the tx handling within the ISRs
- mask off the tx interrupts within the ISRs that handle tx processing
- re-enable tx interrupts within the NAPI handler
- add tx handling within the NAPI handler (this patch covers it)



Jeff




---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


Re: [patch 09/11] forcedeth: improve NAPI logic

2007-04-26 Thread Ayaz Abdulla
I don't see why the NAPI handler needs to process tx packets. The ISR 
will handle all tx processing.



[EMAIL PROTECTED] wrote:

From: Ingo Molnar <[EMAIL PROTECTED]>

Another forcedeth.c thing: i noticed that its NAPI handler does not do
tx-ring processing.  The patch below implements this - tested on DESC_VER_2
hardware, with CONFIG_FORCEDETH_NAPI=y.

Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
Cc: Ayaz Abdulla <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
---

 drivers/net/forcedeth.c |8 
 1 file changed, 8 insertions(+)

diff -puN drivers/net/forcedeth.c~forcedeth-improve-napi-logic 
drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c~forcedeth-improve-napi-logic
+++ a/drivers/net/forcedeth.c
@@ -3108,9 +3108,17 @@ static int nv_napi_poll(struct net_devic
int retcode;
 
 	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {

+   spin_lock_irqsave(&np->lock, flags);
+   nv_tx_done(dev);
+   spin_unlock_irqrestore(&np->lock, flags);
+
pkts = nv_rx_process(dev, limit);
retcode = nv_alloc_rx(dev);
} else {
+   spin_lock_irqsave(&np->lock, flags);
+   nv_tx_done_optimized(dev, np->tx_ring_size);
+   spin_unlock_irqrestore(&np->lock, flags);
+
pkts = nv_rx_process_optimized(dev, limit);
retcode = nv_alloc_rx_optimized(dev);
}
_

-
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


RE: [patch 10/10] forcedeth: work around NULL skb dereference crash

2007-04-02 Thread Ayaz Abdulla
I had responded eariler to the thread asking you to try out the patch
found in bug 8058:
http://bugzilla.kernel.org/show_bug.cgi?id=8058

I believe that is the caush of the NULL skb dereference issue.

Thanks,
Ayaz


-Original Message-
From: Ingo Molnar [mailto:[EMAIL PROTECTED] 
Sent: Monday, April 02, 2007 4:53 AM
To: [EMAIL PROTECTED]
Cc: [EMAIL PROTECTED]; netdev@vger.kernel.org; Ayaz Abdulla
Subject: Re: [patch 10/10] forcedeth: work around NULL skb dereference
crash


* [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:

> From: Ingo Molnar <[EMAIL PROTECTED]>
> 
> work around a NULL skb dereference crash that occurs during high load.
> 
> Signed-off-by: Ingo Molnar <[EMAIL PROTECTED]>
> Cc: Ayaz Abdulla <[EMAIL PROTECTED]>
> Cc: Jeff Garzik <[EMAIL PROTECTED]>
> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>

ping? No reaction from the forcedeth.c maintainer, yet.

Ingo
---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


[PATCH 2/2] forcedeth: fix tx timeout

2007-03-23 Thread Ayaz Abdulla
The tx timeout routine was waking the tx queue conditionally. However, 
it must call it unconditionally since the dev_watchdog has halted the tx 
queue before calling the timeout function.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-03-11 20:59:06.0 -0500
+++ new/drivers/net/forcedeth.c 2007-03-11 20:58:59.0 -0500
@@ -2050,9 +2050,10 @@
nv_drain_tx(dev);
nv_init_tx(dev);
setup_hw_rings(dev, NV_SETUP_TX_RING);
-   netif_wake_queue(dev);
}
 
+   netif_wake_queue(dev);
+
/* 4) restart tx engine */
nv_start_tx(dev);
spin_unlock_irq(&np->lock);


[PATCH 1/2] forcedeth: fix nic poll

2007-03-23 Thread Ayaz Abdulla
The nic poll routine was missing the call to the optimized irq routine. 
This patch adds the missing call for the optimized path.


See http://bugzilla.kernel.org/show_bug.cgi?id=7950 for more information.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-03-11 20:38:20.0 -0500
+++ new/drivers/net/forcedeth.c 2007-03-11 20:38:24.0 -0500
@@ -3536,7 +3536,10 @@
pci_push(base);
 
if (!using_multi_irqs(dev)) {
-   nv_nic_irq(0, dev);
+   if (np->desc_ver == DESC_VER_3)
+   nv_nic_irq_optimized(0, dev);
+   else
+   nv_nic_irq(0, dev);
if (np->msi_flags & NV_MSI_X_ENABLED)

enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else


[PATCH 2/3] forcedeth: disable msix

2007-02-20 Thread Ayaz Abdulla
There seems to be an issue when both MSI-X is enabled and NAPI is 
configured. This patch disables MSI-X until the issue is root caused.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-20 03:29:04.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-20 03:29:33.0 -0500
@@ -839,7 +839,7 @@
NV_MSIX_INT_DISABLED,
NV_MSIX_INT_ENABLED
 };
-static int msix = NV_MSIX_INT_ENABLED;
+static int msix = NV_MSIX_INT_DISABLED;
 
 /*
  * DMA 64bit


[PATCH 3/3] forcedeth: fix checksum feature in mcp65

2007-02-20 Thread Ayaz Abdulla

This patch removes checksum offload feature in mcp65 chipsets as they
are not supported in hw.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-20 03:30:16.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-20 03:30:29.0 -0500
@@ -5374,19 +5374,19 @@
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_21),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_22),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_23),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_24),


[PATCH 1/3] forcedeth: fixed missing call in napi poll

2007-02-20 Thread Ayaz Abdulla
The napi poll routine was missing the call to the optimized rx process 
routine. This patch adds the missing call for the optimized path.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-20 03:17:21.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-20 03:28:31.0 -0500
@@ -3104,13 +3104,17 @@
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
+   int retcode;
 
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
pkts = nv_rx_process(dev, limit);
-   else
+   retcode = nv_alloc_rx(dev);
+   } else {
pkts = nv_rx_process_optimized(dev, limit);
+   retcode = nv_alloc_rx_optimized(dev);
+   }
 
-   if (nv_alloc_rx(dev)) {
+   if (retcode) {
spin_lock_irqsave(&np->lock, flags);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);


[PATCH 3/3] forcedeth: fix checksum feature in mcp65

2007-02-19 Thread Ayaz Abdulla
This patch removes checksum offload feature in mcp65 chipsets as they 
are not supported in hw.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-19 09:17:41.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-19 09:19:43.0 -0500
@@ -5374,19 +5374,19 @@
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_21),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_22),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP65 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_23),
-   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
{   /* MCP67 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_24),


Re: forcedeth problems on 2.6.20-rc6-mm3

2007-02-19 Thread Ayaz Abdulla



Robert Hancock wrote:

Ayaz Abdulla wrote:



For all those who are having issues, please try out the attached patch.

Ayaz


--- 

This email message is for the sole use of the intended recipient(s) 
and may contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact 
the sender by

reply email and destroy all copies of the original message.
--- 






--- orig/drivers/net/forcedeth.c2007-02-08 21:41:59.0 -0500
+++ new/drivers/net/forcedeth.c2007-02-08 21:44:53.0 -0500
@@ -3104,13 +3104,17 @@
 struct fe_priv *np = netdev_priv(dev);
 u8 __iomem *base = get_hwbase(dev);
 unsigned long flags;
+u32 retcode;
 
-if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)

+if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
 pkts = nv_rx_process(dev, limit);
-else
+retcode = nv_alloc_rx(dev);
+} else {
 pkts = nv_rx_process_optimized(dev, limit);
+retcode = nv_alloc_rx_optimized(dev);
+}
 
-if (nv_alloc_rx(dev)) {

+if (retcode) {
 spin_lock_irqsave(&np->lock, flags);
 if (!np->in_shutdown)
 mod_timer(&np->oom_kick, jiffies + OOM_REFILL);



Did anyone push this patch into mainline? forcedeth on 2.6.20-git14 is 
still completely broken without this patch.




I have submitted the patch to netdev mailing list.

-
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


[PATCH 2/3] forcedeth: disable msix

2007-02-19 Thread Ayaz Abdulla
There seems to be an issue when both MSI-X is enabled and NAPI is 
configured. This patch disables MSI-X until the issue is root caused.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-19 09:17:02.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-19 09:17:07.0 -0500
@@ -839,7 +839,7 @@
NV_MSIX_INT_DISABLED,
NV_MSIX_INT_ENABLED
 };
-static int msix = NV_MSIX_INT_ENABLED;
+static int msix = NV_MSIX_INT_DISABLED;
 
 /*
  * DMA 64bit


[PATCH 1/3] forcedeth: fixed missing call in napi poll

2007-02-19 Thread Ayaz Abdulla
The napi poll routine was missing the call to the optimized rx process 
routine. This patch adds the missing call for the optimized path.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-02-19 09:13:10.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-19 09:13:46.0 -0500
@@ -3104,13 +3104,17 @@
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
+   u32 retcode;
 
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
pkts = nv_rx_process(dev, limit);
-   else
+   retcode = nv_alloc_rx(dev);
+   } else {
pkts = nv_rx_process_optimized(dev, limit);
+   retcode = nv_alloc_rx_optimized(dev);
+   }
 
-   if (nv_alloc_rx(dev)) {
+   if (retcode) {
spin_lock_irqsave(&np->lock, flags);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);


Re: forcedeth problems on 2.6.20-rc6-mm3

2007-02-08 Thread Ayaz Abdulla

David Ford wrote:
On 2/5/07, *Andrew Morton* <[EMAIL PROTECTED] 
> wrote:


On Sun, 04 Feb 2007 23:48:33 -0600 Robert Hancock <[EMAIL PROTECTED]
> wrote:

 > Andrew Morton wrote:
 > > On Sun, 04 Feb 2007 23:13:09 -0600 Robert Hancock <
[EMAIL PROTECTED] > wrote:
 > >
 > >> Something's busted with forcedeth in 2.6.20-rc6-mm3 for me
relative to
 > >> 2.6.20-rc6. There's no errors in dmesg, but it seems no
packets ever get
 > >> received and so the machine can't get an IP address. I tried
reverting
 > >> all the -mm changes to drivers/net/forcedeth.c, which didn't
help. The
 > >> network controller shares an IRQ with the USB OHCI controller
which is
 > >> receiving interrupts, so it doesn't seem like an interrupt routing
 > >> problem, though I suppose something wierd could be happening
there.
 > >>
 > >> This is on an Asus A8N-SLI Deluxe (CK804 chipset) on x86_64.
 > >>
 > >> Any suggestions on how to debug/what to try reverting to see
what's
 > >> causing this?
 > >
 > > There are many forcedeth changes in git-netdev-all.patch.  Can you
 > > try reverting drivers/net/forcedeth.c back to the unpatched version
 > > from 2.6.20-rc6?
 > >
 > > Thanks.
 > >
 >
 > That's essentially what I did, it didn't appear to help. I assume
the
 > problem must lie elsewhere..
 >

doh, I missed that.

It's presumably not the driver and nobody else seems to be hitting
this, so
it must be something peculiar to your setup.  But I don't know what it
might be, sorry.



Actually it has been reported by several other people here including 
myself but it seems to have been overlooked here ;)


See the messages with forcedeth in the subject line over the past few 
weeks.


I put 2.6.20-gentoo on my machine this weekend with debug printks 
enabled and right now I have yet to lose connectivity -- going on ~20 
hours worth.


Previously I would lose connectivity within minutes of booting up.  I 
had a script set up that detected the ping loss of a gateway and would 
restart both interfaces (dual onboard nics).


Tonight I will disable the debug printks and see if the system remains 
online.  There was a big patch applied to forcedeth for 2.6.20, 
previously I was having these issues for several of the -19 series.


David


For all those who are having issues, please try out the attached patch.

Ayaz


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig/drivers/net/forcedeth.c2007-02-08 21:41:59.0 -0500
+++ new/drivers/net/forcedeth.c 2007-02-08 21:44:53.0 -0500
@@ -3104,13 +3104,17 @@
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
unsigned long flags;
+   u32 retcode;
 
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
pkts = nv_rx_process(dev, limit);
-   else
+   retcode = nv_alloc_rx(dev);
+   } else {
pkts = nv_rx_process_optimized(dev, limit);
+   retcode = nv_alloc_rx_optimized(dev);
+   }
 
-   if (nv_alloc_rx(dev)) {
+   if (retcode) {
spin_lock_irqsave(&np->lock, flags);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);


[PATCH 12/12] forcedeth: statistics optimization

2007-01-23 Thread Ayaz Abdulla

This patch optimizes the data paths that can support hw counters. It
removes the sw counted statistics.

This is the last patch for the optimization set. Bumping up version of 
driver.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-21 17:38:50.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-21 17:41:49.0 -0500
@@ -111,6 +111,7 @@
  * 0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.
  * 0.58: 30 Oct 2006: Added support for sideband management unit.
  * 0.59: 30 Oct 2006: Added support for recoverable error.
+ * 0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, 
and stats.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -127,7 +128,7 @@
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION  "0.59"
+#define FORCEDETH_VERSION  "0.60"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -1351,10 +1352,19 @@
 {
struct fe_priv *np = netdev_priv(dev);
 
-   /* It seems that the nic always generates interrupts and doesn't
-* accumulate errors internally. Thus the current values in np->stats
-* are already up to date.
-*/
+   /* If the nic supports hw counters then retrieve latest values */
+   if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
+   nv_get_hw_stats(dev);
+
+   /* copy to net_device stats */
+   np->stats.tx_bytes = np->estats.tx_bytes;
+   np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+   np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+   np->stats.rx_crc_errors = np->estats.rx_crc_errors;
+   np->stats.rx_over_errors = np->estats.rx_over_errors;
+   np->stats.rx_errors = np->estats.rx_errors_total;
+   np->stats.tx_errors = np->estats.tx_errors_total;
+   }
return &np->stats;
 }
 
@@ -1944,16 +1954,8 @@
np->get_tx_ctx->dma = 0;
 
if (flags & NV_TX2_LASTPACKET) {
-   if (flags & NV_TX2_ERROR) {
-   if (flags & NV_TX2_UNDERFLOW)
-   np->stats.tx_fifo_errors++;
-   if (flags & NV_TX2_CARRIERLOST)
-   np->stats.tx_carrier_errors++;
-   np->stats.tx_errors++;
-   } else {
+   if (!(flags & NV_TX2_ERROR))
np->stats.tx_packets++;
-   np->stats.tx_bytes += np->get_tx_ctx->skb->len;
-   }
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
}
@@ -2290,7 +2292,6 @@
if (flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2303,11 +2304,6 @@
}
/* the rest are hard errors */
else {
-   if (flags & NV_RX2_CRCERR)
-   np->stats.rx_crc_errors++;
-   if (flags & NV_RX2_OVERFLOW)
-   np->stats.rx_over_errors++;
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -4941,7 +4937,7 @@
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
dev->features |= NETIF_F_TSO;
-   }
+   }
 
np->vlanctl_bits = 0;
if (id->driver_data & DEV_HAS_VLAN) {


[PATCH 11/12] forcedeth: statistics supported

2007-01-23 Thread Ayaz Abdulla

This patch introduces hw statistics for older devices that supported it.
It breaks up the counters supported into separate versions.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-21 17:33:59.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-21 17:38:23.0 -0500
@@ -173,9 +173,10 @@
 #define DEV_HAS_MSI_X   0x0080  /* device supports MSI-X */
 #define DEV_HAS_POWER_CNTRL 0x0100  /* device supports power savings */
 #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS  0x0400  /* device supports hw statistics */
-#define DEV_HAS_TEST_EXTENDED   0x0800  /* device supports extended diagnostic 
test */
-#define DEV_HAS_MGMT_UNIT   0x1000  /* device supports management unit */
+#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics 
version 1 */
+#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
+#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
+#define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -487,7 +488,8 @@
 
 /* Miscelaneous hardware related defines: */
 #define NV_PCI_REGSZ_VER1  0x270
-#define NV_PCI_REGSZ_VER2  0x604
+#define NV_PCI_REGSZ_VER2  0x2d4
+#define NV_PCI_REGSZ_VER3  0x604
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -605,9 +607,6 @@
{ "tx_carrier_errors" },
{ "tx_excess_deferral" },
{ "tx_retry_error" },
-   { "tx_deferral" },
-   { "tx_packets" },
-   { "tx_pause" },
{ "rx_frame_error" },
{ "rx_extra_byte" },
{ "rx_late_collision" },
@@ -620,11 +619,17 @@
{ "rx_unicast" },
{ "rx_multicast" },
{ "rx_broadcast" },
+   { "rx_packets" },
+   { "rx_errors_total" },
+   { "tx_errors_total" },
+
+   /* version 2 stats */
+   { "tx_deferral" },
+   { "tx_packets" },
{ "rx_bytes" },
+   { "tx_pause" },
{ "rx_pause" },
-   { "rx_drop_frame" },
-   { "rx_packets" },
-   { "rx_errors_total" }
+   { "rx_drop_frame" }
 };
 
 struct nv_ethtool_stats {
@@ -637,9 +642,6 @@
u64 tx_carrier_errors;
u64 tx_excess_deferral;
u64 tx_retry_error;
-   u64 tx_deferral;
-   u64 tx_packets;
-   u64 tx_pause;
u64 rx_frame_error;
u64 rx_extra_byte;
u64 rx_late_collision;
@@ -652,13 +654,22 @@
u64 rx_unicast;
u64 rx_multicast;
u64 rx_broadcast;
+   u64 rx_packets;
+   u64 rx_errors_total;
+   u64 tx_errors_total;
+
+   /* version 2 stats */
+   u64 tx_deferral;
+   u64 tx_packets;
u64 rx_bytes;
+   u64 tx_pause;
u64 rx_pause;
u64 rx_drop_frame;
-   u64 rx_packets;
-   u64 rx_errors_total;
 };
 
+#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct 
nv_ethtool_stats)/sizeof(u64))
+#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
+
 /* diagnostics */
 #define NV_TEST_COUNT_BASE 3
 #define NV_TEST_COUNT_EXTENDED 4
@@ -1275,6 +1286,61 @@
pci_push(base);
 }
 
+static void nv_get_hw_stats(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   np->estats.tx_bytes += readl(base + NvRegTxCnt);
+   np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt);
+   np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt);
+   np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt);
+   np->estats.tx_late_collision += readl(base + NvRegTxLateCol);
+   np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow);
+   np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier);
+   np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef);
+   np->estats.tx_retry_error += readl(base + NvRegTxRetryErr);
+   np->estats.rx_frame_error += readl(base + NvRegRxFrameErr);
+   np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte);
+   np->estats.rx_late_collision += readl(base + NvRegRxLateCol);
+   np->estats.rx_runt += readl(base + NvRegRxRunt);
+   np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong);
+   np->estats.rx_over_errors += readl(base + NvRegRxOverflow);
+   np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr);
+   np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr);
+   np->estats.rx_length_error += readl(base + NvRegRxLenErr);
+   np->estats.rx_unic

[PATCH 10/12] forcedeth: tx max work

2007-01-23 Thread Ayaz Abdulla

This patch adds a limit to how much tx work can be done in each
iteration of tx processing. If the max limit is reached, remaining tx 
completions will be handled by timer interrupt.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-19 11:13:59.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-21 17:33:02.0 -0500
@@ -210,7 +210,7 @@
  * NVREG_POLL_DEFAULT=97 would result in an interval length of 1 ms
  */
NvRegPollingInterval = 0x00c,
-#define NVREG_POLL_DEFAULT_THROUGHPUT  970
+#define NVREG_POLL_DEFAULT_THROUGHPUT  970 /* backup tx cleanup if loop max 
reached */
 #define NVREG_POLL_DEFAULT_CPU 13
NvRegMSIMap0 = 0x020,
NvRegMSIMap1 = 0x024,
@@ -1859,14 +1859,15 @@
}
 }
 
-static void nv_tx_done_optimized(struct net_device *dev)
+static void nv_tx_done_optimized(struct net_device *dev, int limit)
 {
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
 
while ((np->get_tx.ex != np->put_tx.ex) &&
-  !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID)) {
+  !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) &&
+  (limit-- > 0)) {
 
dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
dev->name, flags);
@@ -1973,7 +1974,7 @@
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
nv_tx_done(dev);
else
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, np->tx_ring_size);
 
/* 3) if there are dead entries: clear everything */
if (np->get_tx_ctx != np->put_tx_ctx) {
@@ -2899,7 +2900,7 @@
break;
 
spin_lock(&np->lock);
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock(&np->lock);
 
 #ifdef CONFIG_FORCEDETH_NAPI
@@ -3006,7 +3007,7 @@
break;
 
spin_lock_irqsave(&np->lock, flags);
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock_irqrestore(&np->lock, flags);
 
if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
@@ -3163,6 +3164,11 @@
if (!(events & np->irqmask))
break;
 
+   /* check tx in case we reached max loop limit in tx isr */
+   spin_lock_irqsave(&np->lock, flags);
+   nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
+   spin_unlock_irqrestore(&np->lock, flags);
+
if (events & NVREG_IRQ_LINK) {
spin_lock_irqsave(&np->lock, flags);
nv_link_irq(dev);


[PATCH 5/12] forcedeth: optimized routines

2007-01-21 Thread Ayaz Abdulla

This patch breaks up the routines into two versions, one for legacy
descriptor versions (ver 1 and ver 2) and one for desc ver 3. This will
make the new desc functions more leaner and further reductions will be
made in next few patches.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-19 10:54:32.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-19 10:54:14.0 -0500
@@ -1307,50 +1307,57 @@
 static int nv_alloc_rx(struct net_device *dev)
 {
struct fe_priv *np = netdev_priv(dev);
-   union ring_type less_rx;
+   struct ring_desc* less_rx;
 
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   less_rx.orig = np->get_rx.orig;
-   if (less_rx.orig-- == np->first_rx.orig)
-   less_rx.orig = np->last_rx.orig;
-   } else {
-   less_rx.ex = np->get_rx.ex;
-   if (less_rx.ex-- == np->first_rx.ex)
-   less_rx.ex = np->last_rx.ex;
-   }
+   less_rx = np->get_rx.orig;
+   if (less_rx-- == np->first_rx.orig)
+   less_rx = np->last_rx.orig;
 
-   while (1) {
-   struct sk_buff *skb;
-
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   if (np->put_rx.orig == less_rx.orig)
-   break;
+   while (np->put_rx.orig != less_rx) {
+   struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 
NV_RX_ALLOC_PAD);
+   if (skb) {
+   skb->dev = dev;
+   np->put_rx_ctx->skb = skb;
+   np->put_rx_ctx->dma = pci_map_single(np->pci_dev, 
skb->data,
+
skb->end-skb->data, PCI_DMA_FROMDEVICE);
+   np->put_rx_ctx->dma_len = skb->end-skb->data;
+   np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
+   wmb();
+   np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX_AVAIL);
+   if (np->put_rx.orig++ == np->last_rx.orig)
+   np->put_rx.orig = np->first_rx.orig;
+   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   np->put_rx_ctx = np->first_rx_ctx;
} else {
-   if (np->put_rx.ex == less_rx.ex)
-   break;
+   return 1;
}
+   }
+   return 0;
+}
+
+static int nv_alloc_rx_optimized(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   struct ring_desc_ex* less_rx;
+
+   less_rx = np->get_rx.ex;
+   if (less_rx-- == np->first_rx.ex)
+   less_rx = np->last_rx.ex;
 
-   skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
+   while (np->put_rx.ex != less_rx) {
+   struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 
NV_RX_ALLOC_PAD);
if (skb) {
skb->dev = dev;
np->put_rx_ctx->skb = skb;
np->put_rx_ctx->dma = pci_map_single(np->pci_dev, 
skb->data,
 
skb->end-skb->data, PCI_DMA_FROMDEVICE);
np->put_rx_ctx->dma_len = skb->end-skb->data;
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == 
DESC_VER_2) {
-   np->put_rx.orig->buf = 
cpu_to_le32(np->put_rx_ctx->dma);
-   wmb();
-   np->put_rx.orig->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL);
-   if (np->put_rx.orig++ == np->last_rx.orig)
-   np->put_rx.orig = np->first_rx.orig;
-   } else {
-   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
-   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
-   wmb();
-   np->put_rx.ex->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL);
-   if (np->put_rx.ex++ == np->last_rx.ex)
-   np->put_rx.ex = np->first_rx.ex;
-   }
+   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
+   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
+   w

[PATCH 12/12] forcedeth: statistics optimization

2007-01-21 Thread Ayaz Abdulla

This patch optimizes the data paths that can support hw counters. It
removes the sw counted statistics.

This is the last patch for the optimization set. Bumping up version of 
driver.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-21 17:38:50.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-21 17:41:49.0 -0500
@@ -111,6 +111,7 @@
  * 0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.
  * 0.58: 30 Oct 2006: Added support for sideband management unit.
  * 0.59: 30 Oct 2006: Added support for recoverable error.
+ * 0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, 
and stats.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -127,7 +128,7 @@
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION  "0.59"
+#define FORCEDETH_VERSION  "0.60"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -1351,10 +1352,19 @@
 {
struct fe_priv *np = netdev_priv(dev);
 
-   /* It seems that the nic always generates interrupts and doesn't
-* accumulate errors internally. Thus the current values in np->stats
-* are already up to date.
-*/
+   /* If the nic supports hw counters then retrieve latest values */
+   if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
+   nv_get_hw_stats(dev);
+
+   /* copy to net_device stats */
+   np->stats.tx_bytes = np->estats.tx_bytes;
+   np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+   np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+   np->stats.rx_crc_errors = np->estats.rx_crc_errors;
+   np->stats.rx_over_errors = np->estats.rx_over_errors;
+   np->stats.rx_errors = np->estats.rx_errors_total;
+   np->stats.tx_errors = np->estats.tx_errors_total;
+   }
return &np->stats;
 }
 
@@ -1944,16 +1954,8 @@
np->get_tx_ctx->dma = 0;
 
if (flags & NV_TX2_LASTPACKET) {
-   if (flags & NV_TX2_ERROR) {
-   if (flags & NV_TX2_UNDERFLOW)
-   np->stats.tx_fifo_errors++;
-   if (flags & NV_TX2_CARRIERLOST)
-   np->stats.tx_carrier_errors++;
-   np->stats.tx_errors++;
-   } else {
+   if (!(flags & NV_TX2_ERROR))
np->stats.tx_packets++;
-   np->stats.tx_bytes += np->get_tx_ctx->skb->len;
-   }
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
}
@@ -2290,7 +2292,6 @@
if (flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2303,11 +2304,6 @@
}
/* the rest are hard errors */
else {
-   if (flags & NV_RX2_CRCERR)
-   np->stats.rx_crc_errors++;
-   if (flags & NV_RX2_OVERFLOW)
-   np->stats.rx_over_errors++;
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -4941,7 +4937,7 @@
np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
dev->features |= NETIF_F_TSO;
-   }
+   }
 
np->vlanctl_bits = 0;
if (id->driver_data & DEV_HAS_VLAN) {


[PATCH 11/12] forcedeth: statistics supported

2007-01-21 Thread Ayaz Abdulla

This patch introduces hw statistics for older devices that supported it.
It breaks up the counters supported into separate versions.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>
--- orig/drivers/net/forcedeth.c2007-01-21 17:33:59.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-21 17:38:23.0 -0500
@@ -173,9 +173,10 @@
 #define DEV_HAS_MSI_X   0x0080  /* device supports MSI-X */
 #define DEV_HAS_POWER_CNTRL 0x0100  /* device supports power savings */
 #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS  0x0400  /* device supports hw statistics */
-#define DEV_HAS_TEST_EXTENDED   0x0800  /* device supports extended diagnostic 
test */
-#define DEV_HAS_MGMT_UNIT   0x1000  /* device supports management unit */
+#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics 
version 1 */
+#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
+#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
+#define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -487,7 +488,8 @@
 
 /* Miscelaneous hardware related defines: */
 #define NV_PCI_REGSZ_VER1  0x270
-#define NV_PCI_REGSZ_VER2  0x604
+#define NV_PCI_REGSZ_VER2  0x2d4
+#define NV_PCI_REGSZ_VER3  0x604
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -605,9 +607,6 @@
{ "tx_carrier_errors" },
{ "tx_excess_deferral" },
{ "tx_retry_error" },
-   { "tx_deferral" },
-   { "tx_packets" },
-   { "tx_pause" },
{ "rx_frame_error" },
{ "rx_extra_byte" },
{ "rx_late_collision" },
@@ -620,11 +619,17 @@
{ "rx_unicast" },
{ "rx_multicast" },
{ "rx_broadcast" },
+   { "rx_packets" },
+   { "rx_errors_total" },
+   { "tx_errors_total" },
+
+   /* version 2 stats */
+   { "tx_deferral" },
+   { "tx_packets" },
{ "rx_bytes" },
+   { "tx_pause" },
{ "rx_pause" },
-   { "rx_drop_frame" },
-   { "rx_packets" },
-   { "rx_errors_total" }
+   { "rx_drop_frame" }
 };
 
 struct nv_ethtool_stats {
@@ -637,9 +642,6 @@
u64 tx_carrier_errors;
u64 tx_excess_deferral;
u64 tx_retry_error;
-   u64 tx_deferral;
-   u64 tx_packets;
-   u64 tx_pause;
u64 rx_frame_error;
u64 rx_extra_byte;
u64 rx_late_collision;
@@ -652,13 +654,22 @@
u64 rx_unicast;
u64 rx_multicast;
u64 rx_broadcast;
+   u64 rx_packets;
+   u64 rx_errors_total;
+   u64 tx_errors_total;
+
+   /* version 2 stats */
+   u64 tx_deferral;
+   u64 tx_packets;
u64 rx_bytes;
+   u64 tx_pause;
u64 rx_pause;
u64 rx_drop_frame;
-   u64 rx_packets;
-   u64 rx_errors_total;
 };
 
+#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct 
nv_ethtool_stats)/sizeof(u64))
+#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
+
 /* diagnostics */
 #define NV_TEST_COUNT_BASE 3
 #define NV_TEST_COUNT_EXTENDED 4
@@ -1275,6 +1286,61 @@
pci_push(base);
 }
 
+static void nv_get_hw_stats(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   np->estats.tx_bytes += readl(base + NvRegTxCnt);
+   np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt);
+   np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt);
+   np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt);
+   np->estats.tx_late_collision += readl(base + NvRegTxLateCol);
+   np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow);
+   np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier);
+   np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef);
+   np->estats.tx_retry_error += readl(base + NvRegTxRetryErr);
+   np->estats.rx_frame_error += readl(base + NvRegRxFrameErr);
+   np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte);
+   np->estats.rx_late_collision += readl(base + NvRegRxLateCol);
+   np->estats.rx_runt += readl(base + NvRegRxRunt);
+   np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong);
+   np->estats.rx_over_errors += readl(base + NvRegRxOverflow);
+   np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr);
+   np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr);
+   np->estats.rx_length_error += readl(base + NvRegRxLenErr);
+   np->estats.rx_unic

[PATCH 9/12] forcedeth: irq data path optimization

2007-01-21 Thread Ayaz Abdulla

This patch optimizes the irq data paths and cleans up the code.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-19 11:11:35.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-19 11:13:25.0 -0500
@@ -2777,7 +2777,6 @@
events = readl(base + NvRegMSIXIrqStatus) & 
NVREG_IRQSTAT_MASK;
writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
}
-   pci_push(base);
dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
if (!(events & np->irqmask))
break;
@@ -2786,22 +2785,46 @@
nv_tx_done(dev);
spin_unlock(&np->lock);
 
-   if (events & NVREG_IRQ_LINK) {
+#ifdef CONFIG_FORCEDETH_NAPI
+   if (events & NVREG_IRQ_RX_ALL) {
+   netif_rx_schedule(dev);
+
+   /* Disable furthur receive irq's */
+   spin_lock(&np->lock);
+   np->irqmask &= ~NVREG_IRQ_RX_ALL;
+
+   if (np->msi_flags & NV_MSI_X_ENABLED)
+   writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
+   else
+   writel(np->irqmask, base + NvRegIrqMask);
+   spin_unlock(&np->lock);
+   }
+#else
+   if (nv_rx_process(dev, dev->weight)) {
+   if (unlikely(nv_alloc_rx(dev))) {
+   spin_lock(&np->lock);
+   if (!np->in_shutdown)
+   mod_timer(&np->oom_kick, jiffies + 
OOM_REFILL);
+   spin_unlock(&np->lock);
+   }
+   }
+#endif
+   if (unlikely(events & NVREG_IRQ_LINK)) {
spin_lock(&np->lock);
nv_link_irq(dev);
spin_unlock(&np->lock);
}
-   if (np->need_linktimer && time_after(jiffies, 
np->link_timeout)) {
+   if (unlikely(np->need_linktimer && time_after(jiffies, 
np->link_timeout))) {
spin_lock(&np->lock);
nv_linkchange(dev);
spin_unlock(&np->lock);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
-   if (events & (NVREG_IRQ_TX_ERR)) {
+   if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. 
Probably TX fail.\n",
dev->name, events);
}
-   if (events & (NVREG_IRQ_UNKNOWN)) {
+   if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
printk(KERN_DEBUG "%s: received irq with unknown events 
0x%x. Please report\n",
dev->name, events);
}
@@ -2822,30 +2845,7 @@
spin_unlock(&np->lock);
break;
}
-#ifdef CONFIG_FORCEDETH_NAPI
-   if (events & NVREG_IRQ_RX_ALL) {
-   netif_rx_schedule(dev);
-
-   /* Disable furthur receive irq's */
-   spin_lock(&np->lock);
-   np->irqmask &= ~NVREG_IRQ_RX_ALL;
-
-   if (np->msi_flags & NV_MSI_X_ENABLED)
-   writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-   else
-   writel(np->irqmask, base + NvRegIrqMask);
-   spin_unlock(&np->lock);
-   }
-#else
-   nv_rx_process(dev, dev->weight);
-   if (nv_alloc_rx(dev)) {
-   spin_lock(&np->lock);
-   if (!np->in_shutdown)
-   mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-   spin_unlock(&np->lock);
-   }
-#endif
-   if (i > max_interrupt_work) {
+   if (unlikely(i > max_interrupt_work)) {
spin_lock(&np->lock);
/* disable interrupts on the nic */
if (!(np->msi_flags & NV_MSI_X_ENABLED))
@@ -2869,6 +2869,13 @@
return IRQ_RETVAL(i);
 }
 
+#define TX_WORK_PER_LOOP  64
+#define RX_WORK_PER_LOOP  64
+/**
+ * All _optimized functions are used to help increase performance
+ * (reduce CPU and increase throughput). They use descripter version 3,
+ * compiler directives, and reduce memory 

[PATCH 0/12] forcedeth: optimization fixup

2007-01-21 Thread Ayaz Abdulla

A few fixes have been made based on Jeff's comments. Resending patchs 5-12.

Ayaz
-
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


[PATCH 7/12] forcedeth: tx data path optimization

2007-01-21 Thread Ayaz Abdulla

This patch optimizes the tx data paths and cleans up the code (removes
vlan from descr1/2 since only valid for desc3, changes to make code
easier to read, etc).

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig/drivers/net/forcedeth.c2007-01-19 11:03:43.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-19 11:07:48.0 -0500
@@ -1563,7 +1563,6 @@
u32 size = skb->len-skb->data_len;
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & 
(NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
-   u32 tx_flags_vlan = 0;
struct ring_desc* put_tx;
struct ring_desc* start_tx;
struct ring_desc* prev_tx;
@@ -1576,7 +1575,7 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if (empty_slots <= entries) {
+   if (unlikely(empty_slots <= entries)) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
np->tx_stop = 1;
@@ -1596,12 +1595,13 @@
np->put_tx_ctx->dma_len = bcnt;
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
+
tx_flags = np->tx_flags;
offset += bcnt;
size -= bcnt;
-   if (put_tx++ == np->last_tx.orig)
+   if (unlikely(put_tx++ == np->last_tx.orig))
put_tx = np->first_tx.orig;
-   if (np->put_tx_ctx++ == np->last_tx_ctx)
+   if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
 
@@ -1618,14 +1618,14 @@
np->put_tx_ctx->dma = pci_map_page(np->pci_dev, 
frag->page, frag->page_offset+offset, bcnt,
   PCI_DMA_TODEVICE);
np->put_tx_ctx->dma_len = bcnt;
-
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
+
offset += bcnt;
size -= bcnt;
-   if (put_tx++ == np->last_tx.orig)
+   if (unlikely(put_tx++ == np->last_tx.orig))
put_tx = np->first_tx.orig;
-   if (np->put_tx_ctx++ == np->last_tx_ctx)
+   if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
}
@@ -1642,11 +1642,6 @@
tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
 NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
 
-   /* vlan tag */
-   if (np->vlangrp && vlan_tx_tag_present(skb)) {
-   tx_flags_vlan = NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb);
-   }
-
spin_lock_irq(&np->lock);
 
/* set tx flags */
@@ -1669,7 +1664,6 @@
 
dev->trans_start = jiffies;
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + 
NvRegTxRxControl);
-   pci_push(get_hwbase(dev));
return NETDEV_TX_OK;
 }
 
@@ -1677,7 +1671,7 @@
 {
struct fe_priv *np = netdev_priv(dev);
u32 tx_flags = 0;
-   u32 tx_flags_extra = NV_TX2_LASTPACKET;
+   u32 tx_flags_extra;
unsigned int fragments = skb_shinfo(skb)->nr_frags;
unsigned int i;
u32 offset = 0;
@@ -1685,7 +1679,6 @@
u32 size = skb->len-skb->data_len;
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & 
(NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
-   u32 tx_flags_vlan = 0;
struct ring_desc_ex* put_tx;
struct ring_desc_ex* start_tx;
struct ring_desc_ex* prev_tx;
@@ -1698,7 +1691,7 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if (empty_slots <= entries) {
+   if (unlikely(empty_slots <= entries)) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
np->tx_stop = 1;
@@ -1719,12 +1712,13 @@
put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0FF

[PATCH 8/12] forcedeth: rx data path optimization

2007-01-21 Thread Ayaz Abdulla

This patch optimizes the rx data paths and cleans up the code.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>
--- orig/drivers/net/forcedeth.c2007-01-19 11:08:24.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-19 11:11:04.0 -0500
@@ -1317,9 +1317,9 @@
np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
wmb();
np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX_AVAIL);
-   if (np->put_rx.orig++ == np->last_rx.orig)
+   if (unlikely(np->put_rx.orig++ == np->last_rx.orig))
np->put_rx.orig = np->first_rx.orig;
-   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
} else {
return 1;
@@ -1349,9 +1349,9 @@
np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
wmb();
np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX2_AVAIL);
-   if (np->put_rx.ex++ == np->last_rx.ex)
+   if (unlikely(np->put_rx.ex++ == np->last_rx.ex))
np->put_rx.ex = np->first_rx.ex;
-   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
} else {
return 1;
@@ -2046,24 +2046,17 @@
 {
struct fe_priv *np = netdev_priv(dev);
u32 flags;
-   u32 vlanflags = 0;
-   int count;
-
-   for (count = 0; count < limit; ++count) {
-   struct sk_buff *skb;
-   int len;
-
-   if (np->get_rx.orig == np->put_rx.orig)
-   break;  /* we scanned the whole ring - do not continue 
*/
-   flags = le32_to_cpu(np->get_rx.orig->flaglen);
-   len = nv_descr_getlength(np->get_rx.orig, np->desc_ver);
+   u32 rx_processed_cnt = 0;
+   struct sk_buff *skb;
+   int len;
+
+   while((np->get_rx.orig != np->put_rx.orig) &&
+ !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) 
&&
+   (rx_processed_cnt++ < limit)) {
 
dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
dev->name, flags);
 
-   if (flags & NV_RX_AVAIL)
-   break;  /* still owned by hardware, */
-
/*
 * the packet is for us - immediately tear down the pci mapping.
 * TODO: check if a prefetch of the first cacheline improves
@@ -2087,99 +2080,80 @@
}
/* look at what we actually got: */
if (np->desc_ver == DESC_VER_1) {
-   if (!(flags & NV_RX_DESCRIPTORVALID)) {
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-
-   if (flags & NV_RX_ERROR) {
-   if (flags & NV_RX_MISSEDFRAME) {
-   np->stats.rx_missed_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & 
(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_CRCERR) {
-   np->stats.rx_crc_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_OVERFLOW) {
-   np->stats.rx_over_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_ERROR4) {
-   len = nv_getlen(dev, skb->data, l

[PATCH 6/12] forcedeth: tx limiting

2007-01-21 Thread Ayaz Abdulla

This patch optimizes the logic for tx limiting. It adds a flag to check
on the completion side instead of recalculating the number of empty
slots. Also, it removes the fields that were previous used for limiting
since they have no value.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-19 11:01:30.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-19 11:03:13.0 -0500
@@ -518,12 +518,6 @@
 #define TX_RING_MIN64
 #define RING_MAX_DESC_VER_11024
 #define RING_MAX_DESC_VER_2_3  16384
-/*
- * Difference between the get and put pointers for the tx ring.
- * This is used to throttle the amount of data outstanding in the
- * tx ring.
- */
-#define TX_LIMIT_DIFFERENCE1
 
 /* rx/tx mac addr + type + vlan + align + slack*/
 #define NV_RX_HEADERS  (64)
@@ -777,8 +771,7 @@
union ring_type tx_ring;
u32 tx_flags;
int tx_ring_size;
-   int tx_limit_start;
-   int tx_limit_stop;
+   int tx_stop;
 
/* vlan fields */
struct vlan_group *vlangrp;
@@ -1583,9 +1576,10 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if ((empty_slots - np->tx_limit_stop) <= entries) {
+   if (empty_slots <= entries) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
+   np->tx_stop = 1;
spin_unlock_irq(&np->lock);
return NETDEV_TX_BUSY;
}
@@ -1704,9 +1698,10 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if ((empty_slots - np->tx_limit_stop) <= entries) {
+   if (empty_slots <= entries) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
+   np->tx_stop = 1;
spin_unlock_irq(&np->lock);
return NETDEV_TX_BUSY;
}
@@ -1813,6 +1808,7 @@
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct sk_buff *skb;
+   struct ring_desc* orig_get_tx = np->get_tx.orig;
 
while (np->get_tx.orig != np->put_tx.orig) {
flags = le32_to_cpu(np->get_tx.orig->flaglen);
@@ -1858,8 +1854,10 @@
if (np->get_tx_ctx++ == np->last_tx_ctx)
np->get_tx_ctx = np->first_tx_ctx;
}
-   if (nv_get_empty_tx_slots(np) > np->tx_limit_start)
+   if ((np->tx_stop == 1) && (np->get_tx.orig != orig_get_tx)) {
+   np->tx_stop = 0;
netif_wake_queue(dev);
+   }
 }
 
 static void nv_tx_done_optimized(struct net_device *dev)
@@ -1867,6 +1865,7 @@
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct sk_buff *skb;
+   struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
 
while (np->get_tx.ex == np->put_tx.ex) {
flags = le32_to_cpu(np->get_tx.ex->flaglen);
@@ -1895,8 +1894,10 @@
if (np->get_tx_ctx++ == np->last_tx_ctx)
np->get_tx_ctx = np->first_tx_ctx;
}
-   if (nv_get_empty_tx_slots(np) > np->tx_limit_start)
+   if ((np->tx_stop == 1) && (np->get_tx.ex != orig_get_tx)) {
+   np->tx_stop = 0;
netif_wake_queue(dev);
+   }
 }
 
 /*
@@ -4001,8 +4002,6 @@
/* set new values */
np->rx_ring_size = ring->rx_pending;
np->tx_ring_size = ring->tx_pending;
-   np->tx_limit_stop = TX_LIMIT_DIFFERENCE;
-   np->tx_limit_start = TX_LIMIT_DIFFERENCE;
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->rx_ring.orig = (struct ring_desc*)rxtx_ring;
np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size];
@@ -4967,8 +4966,6 @@
 
np->rx_ring_size = RX_RING_DEFAULT;
np->tx_ring_size = TX_RING_DEFAULT;
-   np->tx_limit_stop = TX_LIMIT_DIFFERENCE;
-   np->tx_limit_start = TX_LIMIT_DIFFERENCE;
 
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->rx_ring.orig = pci_alloc_consistent(pci_dev,


Re: [PATCH 10/12] forcedeth: tx max work

2007-01-19 Thread Ayaz Abdulla

Jeff Garzik wrote:

Ayaz Abdulla wrote:
 > This patch adds a limit to how much tx work can be done in each
 > iteration of tx processing.
 >
 > Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

What about the "tail end" of the work, when the limit is reached?

Remember that delaying the completion of TX's too long increases latency.

It seems to me that this patch needs a timer or somesuch, to guarantee
that TX completions are not delayed too long in the worst case.


Yes, you are right.
There is a timer interrupt that fires in throughput mode every 10ms (in 
cpu mode it fires at approx every 130us). I can use that to clean out 
any uncompleted TXs. Let me know if 10ms is not too late for worst case 
tx completion.




Jeff




-
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


[PATCH 6/12] forcedeth: tx limiting

2007-01-09 Thread Ayaz Abdulla
This patch optimizes the logic for tx limiting. It adds a flag to check 
on the completion side instead of recalculating the number of empty 
slots. Also, it removes the fields that were previous used for limiting 
since they have no value.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 11:12:15.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 11:12:10.0 -0500
@@ -518,12 +518,6 @@
 #define TX_RING_MIN64
 #define RING_MAX_DESC_VER_11024
 #define RING_MAX_DESC_VER_2_3  16384
-/*
- * Difference between the get and put pointers for the tx ring.
- * This is used to throttle the amount of data outstanding in the
- * tx ring.
- */
-#define TX_LIMIT_DIFFERENCE1
 
 /* rx/tx mac addr + type + vlan + align + slack*/
 #define NV_RX_HEADERS  (64)
@@ -777,8 +771,7 @@
union ring_type tx_ring;
u32 tx_flags;
int tx_ring_size;
-   int tx_limit_start;
-   int tx_limit_stop;
+   int tx_stop;
 
/* vlan fields */
struct vlan_group *vlangrp;
@@ -1583,9 +1576,10 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if ((empty_slots - np->tx_limit_stop) <= entries) {
+   if (empty_slots <= entries) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
+   np->tx_stop = 1;
spin_unlock_irq(&np->lock);
return NETDEV_TX_BUSY;
}
@@ -1704,9 +1698,10 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if ((empty_slots - np->tx_limit_stop) <= entries) {
+   if (empty_slots <= entries) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
+   np->tx_stop = 1;
spin_unlock_irq(&np->lock);
return NETDEV_TX_BUSY;
}
@@ -1813,6 +1808,7 @@
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct sk_buff *skb;
+   struct ring_desc* orig_get_tx = np->get_tx.orig;
 
while (np->get_tx.orig != np->put_tx.orig) {
flags = le32_to_cpu(np->get_tx.orig->flaglen);
@@ -1858,8 +1854,10 @@
if (np->get_tx_ctx++ == np->last_tx_ctx)
np->get_tx_ctx = np->first_tx_ctx;
}
-   if (nv_get_empty_tx_slots(np) > np->tx_limit_start)
+   if ((np->tx_stop == 1) && (np->get_tx.orig != orig_get_tx)) {
+   np->tx_stop = 0;
netif_wake_queue(dev);
+   }
 }
 
 static void nv_tx_done_optimized(struct net_device *dev)
@@ -1867,6 +1865,7 @@
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct sk_buff *skb;
+   struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
 
while (np->get_tx.ex == np->put_tx.ex) {
flags = le32_to_cpu(np->get_tx.ex->flaglen);
@@ -1895,8 +1894,10 @@
if (np->get_tx_ctx++ == np->last_tx_ctx)
np->get_tx_ctx = np->first_tx_ctx;
}
-   if (nv_get_empty_tx_slots(np) > np->tx_limit_start)
+   if ((np->tx_stop == 1) && (np->get_tx.ex != orig_get_tx)) {
+   np->tx_stop = 0;
netif_wake_queue(dev);
+   }
 }
 
 /*
@@ -4001,8 +4002,6 @@
/* set new values */
np->rx_ring_size = ring->rx_pending;
np->tx_ring_size = ring->tx_pending;
-   np->tx_limit_stop = TX_LIMIT_DIFFERENCE;
-   np->tx_limit_start = TX_LIMIT_DIFFERENCE;
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->rx_ring.orig = (struct ring_desc*)rxtx_ring;
np->tx_ring.orig = &np->rx_ring.orig[np->rx_ring_size];
@@ -4967,8 +4966,6 @@
 
np->rx_ring_size = RX_RING_DEFAULT;
np->tx_ring_size = TX_RING_DEFAULT;
-   np->tx_limit_stop = TX_LIMIT_DIFFERENCE;
-   np->tx_limit_start = TX_LIMIT_DIFFERENCE;
 
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
np->rx_ring.orig = pci_alloc_consistent(pci_dev,


[PATCH 9/12] forcedeth: irq data path optimization

2007-01-09 Thread Ayaz Abdulla

This patch optimizes the irq data paths and cleans up the code.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>


--- orig/drivers/net/forcedeth.c2007-01-08 20:33:47.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 20:33:39.0 -0500
@@ -2777,7 +2777,6 @@
events = readl(base + NvRegMSIXIrqStatus) & 
NVREG_IRQSTAT_MASK;
writel(NVREG_IRQSTAT_MASK, base + NvRegMSIXIrqStatus);
}
-   pci_push(base);
dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events);
if (!(events & np->irqmask))
break;
@@ -2786,22 +2785,46 @@
nv_tx_done(dev);
spin_unlock(&np->lock);
 
-   if (events & NVREG_IRQ_LINK) {
+#ifdef CONFIG_FORCEDETH_NAPI
+   if (events & NVREG_IRQ_RX_ALL) {
+   netif_rx_schedule(dev);
+
+   /* Disable furthur receive irq's */
+   spin_lock(&np->lock);
+   np->irqmask &= ~NVREG_IRQ_RX_ALL;
+
+   if (np->msi_flags & NV_MSI_X_ENABLED)
+   writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
+   else
+   writel(np->irqmask, base + NvRegIrqMask);
+   spin_unlock(&np->lock);
+   }
+#else
+   if (nv_rx_process(dev, dev->weight)) {
+   if (unlikely(nv_alloc_rx(dev))) {
+   spin_lock(&np->lock);
+   if (!np->in_shutdown)
+   mod_timer(&np->oom_kick, jiffies + 
OOM_REFILL);
+   spin_unlock(&np->lock);
+   }
+   }
+#endif
+   if (unlikely(events & NVREG_IRQ_LINK)) {
spin_lock(&np->lock);
nv_link_irq(dev);
spin_unlock(&np->lock);
}
-   if (np->need_linktimer && time_after(jiffies, 
np->link_timeout)) {
+   if (unlikely(np->need_linktimer && time_after(jiffies, 
np->link_timeout))) {
spin_lock(&np->lock);
nv_linkchange(dev);
spin_unlock(&np->lock);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
-   if (events & (NVREG_IRQ_TX_ERR)) {
+   if (unlikely(events & (NVREG_IRQ_TX_ERR))) {
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. 
Probably TX fail.\n",
dev->name, events);
}
-   if (events & (NVREG_IRQ_UNKNOWN)) {
+   if (unlikely(events & (NVREG_IRQ_UNKNOWN))) {
printk(KERN_DEBUG "%s: received irq with unknown events 
0x%x. Please report\n",
dev->name, events);
}
@@ -2822,30 +2845,7 @@
spin_unlock(&np->lock);
break;
}
-#ifdef CONFIG_FORCEDETH_NAPI
-   if (events & NVREG_IRQ_RX_ALL) {
-   netif_rx_schedule(dev);
-
-   /* Disable furthur receive irq's */
-   spin_lock(&np->lock);
-   np->irqmask &= ~NVREG_IRQ_RX_ALL;
-
-   if (np->msi_flags & NV_MSI_X_ENABLED)
-   writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
-   else
-   writel(np->irqmask, base + NvRegIrqMask);
-   spin_unlock(&np->lock);
-   }
-#else
-   nv_rx_process(dev, dev->weight);
-   if (nv_alloc_rx(dev)) {
-   spin_lock(&np->lock);
-   if (!np->in_shutdown)
-   mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-   spin_unlock(&np->lock);
-   }
-#endif
-   if (i > max_interrupt_work) {
+   if (unlikely(i > max_interrupt_work)) {
spin_lock(&np->lock);
/* disable interrupts on the nic */
if (!(np->msi_flags & NV_MSI_X_ENABLED))
@@ -2869,6 +2869,13 @@
return IRQ_RETVAL(i);
 }
 
+#define TX_WORK_PER_LOOP  64
+#define RX_WORK_PER_LOOP  64
+/**
+ * All _optimized functions are used to help increase performance
+ * (reduce CPU and increase throughput). They use descripter version 3,
+ * compiler directives, and reduce memory 

[PATCH 4/12] forcedeth: rx skb recycle

2007-01-09 Thread Ayaz Abdulla
This patch removes the code that recycled the skb on error. This will 
help in reducing the branches in the main data paths.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-07 22:31:14.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-07 23:07:19.0 -0500
@@ -1330,36 +1330,32 @@
break;
}
 
-   if (np->put_rx_ctx->skb == NULL) {
-
-   skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
-   if (!skb)
-   return 1;
-
+   skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
+   if (skb) {
skb->dev = dev;
np->put_rx_ctx->skb = skb;
+   np->put_rx_ctx->dma = pci_map_single(np->pci_dev, 
skb->data,
+
skb->end-skb->data, PCI_DMA_FROMDEVICE);
+   np->put_rx_ctx->dma_len = skb->end-skb->data;
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == 
DESC_VER_2) {
+   np->put_rx.orig->buf = 
cpu_to_le32(np->put_rx_ctx->dma);
+   wmb();
+   np->put_rx.orig->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL);
+   if (np->put_rx.orig++ == np->last_rx.orig)
+   np->put_rx.orig = np->first_rx.orig;
+   } else {
+   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
+   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
+   wmb();
+   np->put_rx.ex->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL);
+   if (np->put_rx.ex++ == np->last_rx.ex)
+   np->put_rx.ex = np->first_rx.ex;
+   }
+   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   np->put_rx_ctx = np->first_rx_ctx;
} else {
-   skb = np->put_rx_ctx->skb;
-   }
-   np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data,
-   skb->end-skb->data, PCI_DMA_FROMDEVICE);
-   np->put_rx_ctx->dma_len = skb->end-skb->data;
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
-   wmb();
-   np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX_AVAIL);
-   if (np->put_rx.orig++ == np->last_rx.orig)
-   np->put_rx.orig = np->first_rx.orig;
-   } else {
-   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
-   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
-   wmb();
-   np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX2_AVAIL);
-   if (np->put_rx.ex++ == np->last_rx.ex)
-   np->put_rx.ex = np->first_rx.ex;
+   return 1;
}
-   if (np->put_rx_ctx++ == np->last_rx_ctx)
-   np->put_rx_ctx = np->first_rx_ctx;
}
return 0;
 }
@@ -1948,6 +1944,8 @@
pci_unmap_single(np->pci_dev, np->get_rx_ctx->dma,
np->get_rx_ctx->dma_len,
PCI_DMA_FROMDEVICE);
+   skb = np->get_rx_ctx->skb;
+   np->get_rx_ctx->skb = NULL;
 
{
int j;
@@ -1955,39 +1953,46 @@
for (j=0; j<64; j++) {
if ((j%16) == 0)
dprintk("\n%03x:", j);
-   dprintk(" %02x", ((unsigned 
char*)np->get_rx_ctx->skb->data)[j]);
+   dprintk(" %02x", ((unsigned 
char*)skb->data)[j]);
}
dprintk("\n");
}
/* look at what we actually got: */
if (np->desc_ver == DESC_VER_1) {
-   if (!(flags & NV_RX_DESCRIPTORVALID))
+   if (!(flags & 

[PATCH 2/12] forcedeth: ring access

2007-01-09 Thread Ayaz Abdulla
This patch modifys ring access by using pointers. This avoids computing 
the current index and avoids accessing the base address of the rings.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 13:31:01.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 13:30:55.0 -0500
@@ -691,6 +691,12 @@
{ 0,0 }
 };
 
+struct nv_skb_map {
+   struct sk_buff *skb;
+   dma_addr_t dma;
+   unsigned int dma_len;
+};
+
 /*
  * SMP locking:
  * All hardware access under dev->priv->lock, except the performance
@@ -741,10 +747,12 @@
/* rx specific fields.
 * Locking: Within irq hander or disable_irq+spin_lock(&np->lock);
 */
+   union ring_type get_rx, put_rx, first_rx, last_rx;
+   struct nv_skb_map *get_rx_ctx, *put_rx_ctx;
+   struct nv_skb_map *first_rx_ctx, *last_rx_ctx;
+   struct nv_skb_map *rx_skb;
+
union ring_type rx_ring;
-   unsigned int cur_rx, refill_rx;
-   struct sk_buff **rx_skbuff;
-   dma_addr_t *rx_dma;
unsigned int rx_buf_sz;
unsigned int pkt_limit;
struct timer_list oom_kick;
@@ -761,11 +769,12 @@
/*
 * tx specific fields.
 */
+   union ring_type get_tx, put_tx, first_tx, last_tx;
+   struct nv_skb_map *get_tx_ctx, *put_tx_ctx;
+   struct nv_skb_map *first_tx_ctx, *last_tx_ctx;
+   struct nv_skb_map *tx_skb;
+
union ring_type tx_ring;
-   unsigned int next_tx, nic_tx;
-   struct sk_buff **tx_skbuff;
-   dma_addr_t *tx_dma;
-   unsigned int *tx_dma_len;
u32 tx_flags;
int tx_ring_size;
int tx_limit_start;
@@ -921,16 +930,10 @@
pci_free_consistent(np->pci_dev, sizeof(struct 
ring_desc_ex) * (np->rx_ring_size + np->tx_ring_size),
np->rx_ring.ex, np->ring_addr);
}
-   if (np->rx_skbuff)
-   kfree(np->rx_skbuff);
-   if (np->rx_dma)
-   kfree(np->rx_dma);
-   if (np->tx_skbuff)
-   kfree(np->tx_skbuff);
-   if (np->tx_dma)
-   kfree(np->tx_dma);
-   if (np->tx_dma_len)
-   kfree(np->tx_dma_len);
+   if (np->rx_skb)
+   kfree(np->rx_skb);
+   if (np->tx_skb)
+   kfree(np->tx_skb);
 }
 
 static int using_multi_irqs(struct net_device *dev)
@@ -1304,43 +1307,60 @@
 static int nv_alloc_rx(struct net_device *dev)
 {
struct fe_priv *np = netdev_priv(dev);
-   unsigned int refill_rx = np->refill_rx;
-   int nr;
+   union ring_type less_rx;
 
-   while (np->cur_rx != refill_rx) {
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+   less_rx.orig = np->get_rx.orig;
+   if (less_rx.orig-- == np->first_rx.orig)
+   less_rx.orig = np->last_rx.orig;
+   } else {
+   less_rx.ex = np->get_rx.ex;
+   if (less_rx.ex-- == np->first_rx.ex)
+   less_rx.ex = np->last_rx.ex;
+   }
+
+   while (1) {
struct sk_buff *skb;
 
-   nr = refill_rx % np->rx_ring_size;
-   if (np->rx_skbuff[nr] == NULL) {
+   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+   if (np->put_rx.orig == less_rx.orig)
+   break;
+   } else {
+   if (np->put_rx.ex == less_rx.ex)
+   break;
+   }
+
+   if (np->put_rx_ctx->skb == NULL) {
 
skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
if (!skb)
-   break;
+   return 1;
 
skb->dev = dev;
-   np->rx_skbuff[nr] = skb;
+   np->put_rx_ctx->skb = skb;
} else {
-   skb = np->rx_skbuff[nr];
+   skb = np->put_rx_ctx->skb;
}
-   np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data,
+   np->put_rx_ctx->dma = pci_map_single(np->pci_dev, skb->data,
skb->end-skb->data, PCI_DMA_FROMDEVICE);
+   np->put_rx_ctx->dma_len = skb->end-skb->data;
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   np->rx_ring.orig[nr].buf = cpu_to_le32(np->rx_dma[nr]);
+   np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
wmb();
-   np->rx_ring.orig[nr].flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL);
+

[PATCH 3/12] forcedeth: tx locking

2007-01-09 Thread Ayaz Abdulla
This patch reduces the amount of code within the lock to only the 
critical sections.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-07 22:30:08.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-07 22:30:02.0 -0500
@@ -1569,12 +1569,11 @@
   ((skb_shinfo(skb)->frags[i].size & 
(NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
}
 
-   spin_lock_irq(&np->lock);
-
empty_slots = nv_get_empty_tx_slots(np);
if ((empty_slots - np->tx_limit_stop) <= entries) {
-   spin_unlock_irq(&np->lock);
+   spin_lock_irq(&np->lock);
netif_stop_queue(dev);
+   spin_unlock_irq(&np->lock);
return NETDEV_TX_BUSY;
}
 
@@ -1669,6 +1668,8 @@
tx_flags_vlan = NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb);
}
 
+   spin_lock_irq(&np->lock);
+
/* set tx flags */
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
start_tx.orig->flaglen |= cpu_to_le32(tx_flags | 
tx_flags_extra);
@@ -1679,6 +1680,7 @@
np->put_tx.ex = put_tx.ex;
}
 
+   spin_unlock_irq(&np->lock);
 
dprintk(KERN_DEBUG "%s: nv_start_xmit: entries %d queued for 
transmission. tx_flags_extra: %x\n",
dev->name, entries, tx_flags_extra);
@@ -1693,7 +1695,6 @@
}
 
dev->trans_start = jiffies;
-   spin_unlock_irq(&np->lock);
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + 
NvRegTxRxControl);
pci_push(get_hwbase(dev));
return NETDEV_TX_OK;


[PATCH 12/12] forcedeth: statistics optimization

2007-01-09 Thread Ayaz Abdulla
This patch optimizes the data paths that can support hw counters. It 
removes the sw counted statistics.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 18:32:08.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 18:42:58.0 -0500
@@ -1351,10 +1351,19 @@
 {
struct fe_priv *np = netdev_priv(dev);
 
-   /* It seems that the nic always generates interrupts and doesn't
-* accumulate errors internally. Thus the current values in np->stats
-* are already up to date.
-*/
+   /* If the nic supports hw counters then retrieve latest values */
+   if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
+   nv_get_hw_stats(dev);
+
+   /* copy to net_device stats */
+   np->stats.tx_bytes = np->estats.tx_bytes;
+   np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
+   np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
+   np->stats.rx_crc_errors = np->estats.rx_crc_errors;
+   np->stats.rx_over_errors = np->estats.rx_over_errors;
+   np->stats.rx_errors = np->estats.rx_errors_total;
+   np->stats.tx_errors = np->estats.tx_errors_total;
+   }
return &np->stats;
 }
 
@@ -1944,16 +1953,8 @@
np->get_tx_ctx->dma = 0;
 
if (flags & NV_TX2_LASTPACKET) {
-   if (flags & NV_TX2_ERROR) {
-   if (flags & NV_TX2_UNDERFLOW)
-   np->stats.tx_fifo_errors++;
-   if (flags & NV_TX2_CARRIERLOST)
-   np->stats.tx_carrier_errors++;
-   np->stats.tx_errors++;
-   } else {
+   if (!(flags & NV_TX2_ERROR))
np->stats.tx_packets++;
-   np->stats.tx_bytes += np->get_tx_ctx->skb->len;
-   }
dev_kfree_skb_any(np->get_tx_ctx->skb);
np->get_tx_ctx->skb = NULL;
}
@@ -2290,7 +2291,6 @@
if (flags & NV_RX2_ERROR4) {
len = nv_getlen(dev, skb->data, len);
if (len < 0) {
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}
@@ -2303,11 +2303,6 @@
}
/* the rest are hard errors */
else {
-   if (flags & NV_RX2_CRCERR)
-   np->stats.rx_crc_errors++;
-   if (flags & NV_RX2_OVERFLOW)
-   np->stats.rx_over_errors++;
-   np->stats.rx_errors++;
dev_kfree_skb(skb);
goto next_pkt;
}


[PATCH 1/12] forcedeth: dma access

2007-01-09 Thread Ayaz Abdulla
This patch allows the hardware to fetch the tx and rx ring descriptors 
with 64 bytes per access instead of 32 bytes.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-07 15:10:15.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-07 15:10:28.0 -0500
@@ -304,8 +304,8 @@
 #define NVREG_TXRXCTL_RESET0x0010
 #define NVREG_TXRXCTL_RXCHECK  0x0400
 #define NVREG_TXRXCTL_DESC_1   0
-#define NVREG_TXRXCTL_DESC_2   0x02100
-#define NVREG_TXRXCTL_DESC_3   0x02200
+#define NVREG_TXRXCTL_DESC_2   0x002100
+#define NVREG_TXRXCTL_DESC_3   0xc02200
 #define NVREG_TXRXCTL_VLANSTRIP 0x00040
 #define NVREG_TXRXCTL_VLANINS  0x00080
NvRegTxRingPhysAddrHigh = 0x148,


[PATCH 11/12] forcedeth: statistics supported

2007-01-09 Thread Ayaz Abdulla
This patch introduces hw statistics for older devices that supported it. 
It breaks up the counters supported into separate versions.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 20:35:53.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 20:36:17.0 -0500
@@ -173,9 +173,10 @@
 #define DEV_HAS_MSI_X   0x0080  /* device supports MSI-X */
 #define DEV_HAS_POWER_CNTRL 0x0100  /* device supports power savings */
 #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS  0x0400  /* device supports hw statistics */
-#define DEV_HAS_TEST_EXTENDED   0x0800  /* device supports extended diagnostic 
test */
-#define DEV_HAS_MGMT_UNIT   0x1000  /* device supports management unit */
+#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics 
version 1 */
+#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics 
version 2 */
+#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic 
test */
+#define DEV_HAS_MGMT_UNIT   0x2000  /* device supports management unit */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -487,7 +488,8 @@
 
 /* Miscelaneous hardware related defines: */
 #define NV_PCI_REGSZ_VER1  0x270
-#define NV_PCI_REGSZ_VER2  0x604
+#define NV_PCI_REGSZ_VER2  0x2d4
+#define NV_PCI_REGSZ_VER3  0x604
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -605,9 +607,6 @@
{ "tx_carrier_errors" },
{ "tx_excess_deferral" },
{ "tx_retry_error" },
-   { "tx_deferral" },
-   { "tx_packets" },
-   { "tx_pause" },
{ "rx_frame_error" },
{ "rx_extra_byte" },
{ "rx_late_collision" },
@@ -620,11 +619,17 @@
{ "rx_unicast" },
{ "rx_multicast" },
{ "rx_broadcast" },
+   { "rx_packets" },
+   { "rx_errors_total" },
+   { "tx_errors_total" },
+
+   /* version 2 stats */
+   { "tx_deferral" },
+   { "tx_packets" },
{ "rx_bytes" },
+   { "tx_pause" },
{ "rx_pause" },
-   { "rx_drop_frame" },
-   { "rx_packets" },
-   { "rx_errors_total" }
+   { "rx_drop_frame" }
 };
 
 struct nv_ethtool_stats {
@@ -637,9 +642,6 @@
u64 tx_carrier_errors;
u64 tx_excess_deferral;
u64 tx_retry_error;
-   u64 tx_deferral;
-   u64 tx_packets;
-   u64 tx_pause;
u64 rx_frame_error;
u64 rx_extra_byte;
u64 rx_late_collision;
@@ -652,13 +654,22 @@
u64 rx_unicast;
u64 rx_multicast;
u64 rx_broadcast;
+   u64 rx_packets;
+   u64 rx_errors_total;
+   u64 tx_errors_total;
+
+   /* version 2 stats */
+   u64 tx_deferral;
+   u64 tx_packets;
u64 rx_bytes;
+   u64 tx_pause;
u64 rx_pause;
u64 rx_drop_frame;
-   u64 rx_packets;
-   u64 rx_errors_total;
 };
 
+#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct 
nv_ethtool_stats)/sizeof(u64))
+#define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
+
 /* diagnostics */
 #define NV_TEST_COUNT_BASE 3
 #define NV_TEST_COUNT_EXTENDED 4
@@ -1275,6 +1286,61 @@
pci_push(base);
 }
 
+static void nv_get_hw_stats(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   np->estats.tx_bytes += readl(base + NvRegTxCnt);
+   np->estats.tx_zero_rexmt += readl(base + NvRegTxZeroReXmt);
+   np->estats.tx_one_rexmt += readl(base + NvRegTxOneReXmt);
+   np->estats.tx_many_rexmt += readl(base + NvRegTxManyReXmt);
+   np->estats.tx_late_collision += readl(base + NvRegTxLateCol);
+   np->estats.tx_fifo_errors += readl(base + NvRegTxUnderflow);
+   np->estats.tx_carrier_errors += readl(base + NvRegTxLossCarrier);
+   np->estats.tx_excess_deferral += readl(base + NvRegTxExcessDef);
+   np->estats.tx_retry_error += readl(base + NvRegTxRetryErr);
+   np->estats.rx_frame_error += readl(base + NvRegRxFrameErr);
+   np->estats.rx_extra_byte += readl(base + NvRegRxExtraByte);
+   np->estats.rx_late_collision += readl(base + NvRegRxLateCol);
+   np->estats.rx_runt += readl(base + NvRegRxRunt);
+   np->estats.rx_frame_too_long += readl(base + NvRegRxFrameTooLong);
+   np->estats.rx_over_errors += readl(base + NvRegRxOverflow);
+   np->estats.rx_crc_errors += readl(base + NvRegRxFCSErr);
+   np->estats.rx_frame_align_error += readl(base + NvRegRxFrameAlignErr);
+   np->estats.rx_length_error += readl(base + NvRegRxLenErr);
+   np->estats.rx_unic

[PATCH 10/12] forcedeth: tx max work

2007-01-09 Thread Ayaz Abdulla
This patch adds a limit to how much tx work can be done in each 
iteration of tx processing.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 20:34:35.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 20:35:22.0 -0500
@@ -1859,14 +1859,15 @@
}
 }
 
-static void nv_tx_done_optimized(struct net_device *dev)
+static void nv_tx_done_optimized(struct net_device *dev, int limit)
 {
struct fe_priv *np = netdev_priv(dev);
u32 flags;
struct ring_desc_ex* orig_get_tx = np->get_tx.ex;
 
while ((np->get_tx.ex != np->put_tx.ex) &&
-  !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID)) {
+  !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX_VALID) &&
+  (limit-- > 0)) {
 
dprintk(KERN_DEBUG "%s: nv_tx_done_optimized: flags 0x%x.\n",
dev->name, flags);
@@ -1973,7 +1974,7 @@
if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
nv_tx_done(dev);
else
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, np->tx_ring_size);
 
/* 3) if there are dead entries: clear everything */
if (np->get_tx_ctx != np->put_tx_ctx) {
@@ -2899,7 +2900,7 @@
break;
 
spin_lock(&np->lock);
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock(&np->lock);
 
 #ifdef CONFIG_FORCEDETH_NAPI
@@ -3006,7 +3007,7 @@
break;
 
spin_lock_irqsave(&np->lock, flags);
-   nv_tx_done_optimized(dev);
+   nv_tx_done_optimized(dev, TX_WORK_PER_LOOP);
spin_unlock_irqrestore(&np->lock, flags);
 
if (unlikely(events & (NVREG_IRQ_TX_ERR))) {


[PATCH 7/12] forcedeth: tx data path optimization

2007-01-09 Thread Ayaz Abdulla
This patch optimizes the tx data paths and cleans up the code (removes 
vlan from descr1/2 since only valid for desc3, changes to make code 
easier to read, etc).


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 14:05:28.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 14:05:19.0 -0500
@@ -1563,7 +1563,6 @@
u32 size = skb->len-skb->data_len;
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & 
(NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
-   u32 tx_flags_vlan = 0;
struct ring_desc* put_tx;
struct ring_desc* start_tx;
struct ring_desc* prev_tx;
@@ -1576,7 +1575,7 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if (empty_slots <= entries) {
+   if (unlikely(empty_slots <= entries)) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
np->tx_stop = 1;
@@ -1596,12 +1595,13 @@
np->put_tx_ctx->dma_len = bcnt;
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
+
tx_flags = np->tx_flags;
offset += bcnt;
size -= bcnt;
-   if (put_tx++ == np->last_tx.orig)
+   if (unlikely(put_tx++ == np->last_tx.orig))
put_tx = np->first_tx.orig;
-   if (np->put_tx_ctx++ == np->last_tx_ctx)
+   if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
 
@@ -1618,14 +1618,14 @@
np->put_tx_ctx->dma = pci_map_page(np->pci_dev, 
frag->page, frag->page_offset+offset, bcnt,
   PCI_DMA_TODEVICE);
np->put_tx_ctx->dma_len = bcnt;
-
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
+
offset += bcnt;
size -= bcnt;
-   if (put_tx++ == np->last_tx.orig)
+   if (unlikely(put_tx++ == np->last_tx.orig))
put_tx = np->first_tx.orig;
-   if (np->put_tx_ctx++ == np->last_tx_ctx)
+   if (unlikely(np->put_tx_ctx++ == np->last_tx_ctx))
np->put_tx_ctx = np->first_tx_ctx;
} while (size);
}
@@ -1642,11 +1642,6 @@
tx_flags_extra = skb->ip_summed == CHECKSUM_PARTIAL ?
 NV_TX2_CHECKSUM_L3 | NV_TX2_CHECKSUM_L4 : 0;
 
-   /* vlan tag */
-   if (np->vlangrp && vlan_tx_tag_present(skb)) {
-   tx_flags_vlan = NV_TX3_VLAN_TAG_PRESENT | vlan_tx_tag_get(skb);
-   }
-
spin_lock_irq(&np->lock);
 
/* set tx flags */
@@ -1669,7 +1664,6 @@
 
dev->trans_start = jiffies;
writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + 
NvRegTxRxControl);
-   pci_push(get_hwbase(dev));
return NETDEV_TX_OK;
 }
 
@@ -1677,7 +1671,7 @@
 {
struct fe_priv *np = netdev_priv(dev);
u32 tx_flags = 0;
-   u32 tx_flags_extra = NV_TX2_LASTPACKET;
+   u32 tx_flags_extra;
unsigned int fragments = skb_shinfo(skb)->nr_frags;
unsigned int i;
u32 offset = 0;
@@ -1685,7 +1679,6 @@
u32 size = skb->len-skb->data_len;
u32 entries = (size >> NV_TX2_TSO_MAX_SHIFT) + ((size & 
(NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
u32 empty_slots;
-   u32 tx_flags_vlan = 0;
struct ring_desc_ex* put_tx;
struct ring_desc_ex* start_tx;
struct ring_desc_ex* prev_tx;
@@ -1698,7 +1691,7 @@
}
 
empty_slots = nv_get_empty_tx_slots(np);
-   if (empty_slots <= entries) {
+   if (unlikely(empty_slots <= entries)) {
spin_lock_irq(&np->lock);
netif_stop_queue(dev);
np->tx_stop = 1;
@@ -1719,12 +1712,13 @@
put_tx->bufhigh = cpu_to_le64(np->put_tx_ctx->dma) >> 32;
put_tx->buflow = cpu_to_le64(np->put_tx_ctx->dma) & 0x0;
put_tx->flaglen = cpu_to_le32((bcnt-1) | tx_flags);
-   tx_flags = np->tx_flags;
+
+   tx_flags = NV_TX2_VALID;
offset += bcnt;
size -= bcnt;
-   if (put_tx++ == np->last_tx.ex)
+   if (unlikely(put_tx++ == np->last_tx.ex))
put_tx = np->first_tx.ex;
-   if (np->put_tx_ctx++ == np->last_tx_ctx)
+   if (unlikely

[PATCH 8/12] forcedeth: rx data path optimization

2007-01-09 Thread Ayaz Abdulla

This patch optimizes the rx data paths and cleans up the code.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 14:06:32.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 14:18:37.0 -0500
@@ -1317,9 +1317,9 @@
np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
wmb();
np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX_AVAIL);
-   if (np->put_rx.orig++ == np->last_rx.orig)
+   if (unlikely(np->put_rx.orig++ == np->last_rx.orig))
np->put_rx.orig = np->first_rx.orig;
-   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
} else {
return 1;
@@ -1349,9 +1349,9 @@
np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
wmb();
np->put_rx.ex->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX2_AVAIL);
-   if (np->put_rx.ex++ == np->last_rx.ex)
+   if (unlikely(np->put_rx.ex++ == np->last_rx.ex))
np->put_rx.ex = np->first_rx.ex;
-   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   if (unlikely(np->put_rx_ctx++ == np->last_rx_ctx))
np->put_rx_ctx = np->first_rx_ctx;
} else {
return 1;
@@ -2046,24 +2046,17 @@
 {
struct fe_priv *np = netdev_priv(dev);
u32 flags;
-   u32 vlanflags = 0;
-   int count;
-
-   for (count = 0; count < limit; ++count) {
-   struct sk_buff *skb;
-   int len;
-
-   if (np->get_rx.orig == np->put_rx.orig)
-   break;  /* we scanned the whole ring - do not continue 
*/
-   flags = le32_to_cpu(np->get_rx.orig->flaglen);
-   len = nv_descr_getlength(np->get_rx.orig, np->desc_ver);
+   u32 rx_processed_cnt = 0;
+   struct sk_buff *skb;
+   int len;
+
+   while((np->get_rx.orig != np->put_rx.orig) &&
+ !((flags = le32_to_cpu(np->get_rx.orig->flaglen)) & NV_RX_AVAIL) 
&&
+   (rx_processed_cnt++ < limit)) {
 
dprintk(KERN_DEBUG "%s: nv_rx_process: flags 0x%x.\n",
dev->name, flags);
 
-   if (flags & NV_RX_AVAIL)
-   break;  /* still owned by hardware, */
-
/*
 * the packet is for us - immediately tear down the pci mapping.
 * TODO: check if a prefetch of the first cacheline improves
@@ -2087,99 +2080,80 @@
}
/* look at what we actually got: */
if (np->desc_ver == DESC_VER_1) {
-   if (!(flags & NV_RX_DESCRIPTORVALID)) {
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-
-   if (flags & NV_RX_ERROR) {
-   if (flags & NV_RX_MISSEDFRAME) {
-   np->stats.rx_missed_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & 
(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) {
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_CRCERR) {
-   np->stats.rx_crc_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_OVERFLOW) {
-   np->stats.rx_over_errors++;
-   np->stats.rx_errors++;
-   dev_kfree_skb(skb);
-   goto next_pkt;
-   }
-   if (flags & NV_RX_ERROR4) {
-   len = nv_getlen(dev, skb->data, l

[PATCH 0/12] forcedeth optimizations

2007-01-09 Thread Ayaz Abdulla
This set of patches contains optimizations for the forcedeth driver that 
help reduce CPU utilization and increase throughput, especially for 
small packet sizes.


The main changes include ring accessing, tx locking, optimizing code 
branches, remove descriptor checks in data paths, reducing memory 
accesses, etc.


Please provide feedback and comments.
[Note that some patches might not have apparent benefits by themselves. 
Some patches are just stepping stones for following patches]


Thanks,
Ayaz

-
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


[PATCH 5/12] forcedeth: optimized routines

2007-01-09 Thread Ayaz Abdulla
This patch breaks up the routines into two versions, one for legacy 
descriptor versions (ver 1 and ver 2) and one for desc ver 3. This will 
make the new desc functions more leaner and further reductions will be 
made in next few patches.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig/drivers/net/forcedeth.c2007-01-08 10:47:16.0 -0500
+++ new/drivers/net/forcedeth.c 2007-01-08 10:46:59.0 -0500
@@ -1307,50 +1307,57 @@
 static int nv_alloc_rx(struct net_device *dev)
 {
struct fe_priv *np = netdev_priv(dev);
-   union ring_type less_rx;
+   struct ring_desc* less_rx;
 
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   less_rx.orig = np->get_rx.orig;
-   if (less_rx.orig-- == np->first_rx.orig)
-   less_rx.orig = np->last_rx.orig;
-   } else {
-   less_rx.ex = np->get_rx.ex;
-   if (less_rx.ex-- == np->first_rx.ex)
-   less_rx.ex = np->last_rx.ex;
-   }
+   less_rx = np->get_rx.orig;
+   if (less_rx-- == np->first_rx.orig)
+   less_rx = np->last_rx.orig;
 
-   while (1) {
-   struct sk_buff *skb;
-
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
-   if (np->put_rx.orig == less_rx.orig)
-   break;
+   while (np->put_rx.orig != less_rx) {
+   struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 
NV_RX_ALLOC_PAD);
+   if (skb) {
+   skb->dev = dev;
+   np->put_rx_ctx->skb = skb;
+   np->put_rx_ctx->dma = pci_map_single(np->pci_dev, 
skb->data,
+
skb->end-skb->data, PCI_DMA_FROMDEVICE);
+   np->put_rx_ctx->dma_len = skb->end-skb->data;
+   np->put_rx.orig->buf = cpu_to_le32(np->put_rx_ctx->dma);
+   wmb();
+   np->put_rx.orig->flaglen = cpu_to_le32(np->rx_buf_sz | 
NV_RX_AVAIL);
+   if (np->put_rx.orig++ == np->last_rx.orig)
+   np->put_rx.orig = np->first_rx.orig;
+   if (np->put_rx_ctx++ == np->last_rx_ctx)
+   np->put_rx_ctx = np->first_rx_ctx;
} else {
-   if (np->put_rx.ex == less_rx.ex)
-   break;
+   return 1;
}
+   }
+   return 0;
+}
+
+static int nv_alloc_rx_optimized(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   struct ring_desc_ex* less_rx;
+
+   less_rx = np->get_rx.ex;
+   if (less_rx-- == np->first_rx.ex)
+   less_rx = np->last_rx.ex;
 
-   skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD);
+   while (np->put_rx.ex != less_rx) {
+   struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 
NV_RX_ALLOC_PAD);
if (skb) {
skb->dev = dev;
np->put_rx_ctx->skb = skb;
np->put_rx_ctx->dma = pci_map_single(np->pci_dev, 
skb->data,
 
skb->end-skb->data, PCI_DMA_FROMDEVICE);
np->put_rx_ctx->dma_len = skb->end-skb->data;
-   if (np->desc_ver == DESC_VER_1 || np->desc_ver == 
DESC_VER_2) {
-   np->put_rx.orig->buf = 
cpu_to_le32(np->put_rx_ctx->dma);
-   wmb();
-   np->put_rx.orig->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL);
-   if (np->put_rx.orig++ == np->last_rx.orig)
-   np->put_rx.orig = np->first_rx.orig;
-   } else {
-   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
-   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
-   wmb();
-   np->put_rx.ex->flaglen = 
cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL);
-   if (np->put_rx.ex++ == np->last_rx.ex)
-   np->put_rx.ex = np->first_rx.ex;
-   }
+   np->put_rx.ex->bufhigh = 
cpu_to_le64(np->put_rx_ctx->dma) >> 32;
+   np->put_rx.ex->buflow = 
cpu_to_le64(np->put_rx_ctx->dma) & 0x0;
+   w

[PATCH] forcedeth: sideband management fix

2007-01-03 Thread Ayaz Abdulla
This patch contains a fix that implements proper communication with the 
sideband management unit. Also, it makes sure that the speed is 
correctly set for gigabit phys in the case where sideband mgmt unit 
initialized the phy. Refer to bug #7684 for more details.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2003-02-20 02:47:09.0 -0500
+++ new-2.6/drivers/net/forcedeth.c 2003-02-20 02:47:18.0 -0500
@@ -234,6 +234,7 @@
 #define NVREG_XMITCTL_HOST_SEMA_MASK   0xf000
 #define NVREG_XMITCTL_HOST_SEMA_ACQ0xf000
 #define NVREG_XMITCTL_HOST_LOADED  0x4000
+#define NVREG_XMITCTL_TX_PATH_EN   0x0100
NvRegTransmitterStatus = 0x088,
 #define NVREG_XMITSTAT_BUSY0x01
 
@@ -249,6 +250,7 @@
 #define NVREG_OFFLOAD_NORMAL   RX_NIC_BUFSIZE
NvRegReceiverControl = 0x094,
 #define NVREG_RCVCTL_START 0x01
+#define NVREG_RCVCTL_RX_PATH_EN0x0100
NvRegReceiverStatus = 0x98,
 #define NVREG_RCVSTAT_BUSY 0x01
 
@@ -1169,16 +1171,21 @@
 {
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+   u32 rx_ctrl = readl(base + NvRegReceiverControl);
 
dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
/* Already running? Stop it. */
-   if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
-   writel(0, base + NvRegReceiverControl);
+   if ((readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) && 
!np->mac_in_use) {
+   rx_ctrl &= ~NVREG_RCVCTL_START;
+   writel(rx_ctrl, base + NvRegReceiverControl);
pci_push(base);
}
writel(np->linkspeed, base + NvRegLinkSpeed);
pci_push(base);
-   writel(NVREG_RCVCTL_START, base + NvRegReceiverControl);
+rx_ctrl |= NVREG_RCVCTL_START;
+if (np->mac_in_use)
+   rx_ctrl &= ~NVREG_RCVCTL_RX_PATH_EN;
+   writel(rx_ctrl, base + NvRegReceiverControl);
dprintk(KERN_DEBUG "%s: nv_start_rx to duplex %d, speed 0x%08x.\n",
dev->name, np->duplex, np->linkspeed);
pci_push(base);
@@ -1186,39 +1193,59 @@
 
 static void nv_stop_rx(struct net_device *dev)
 {
+   struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+   u32 rx_ctrl = readl(base + NvRegReceiverControl);
 
dprintk(KERN_DEBUG "%s: nv_stop_rx\n", dev->name);
-   writel(0, base + NvRegReceiverControl);
+   if (!np->mac_in_use)
+   rx_ctrl &= ~NVREG_RCVCTL_START;
+   else
+   rx_ctrl |= NVREG_RCVCTL_RX_PATH_EN;
+   writel(rx_ctrl, base + NvRegReceiverControl);
reg_delay(dev, NvRegReceiverStatus, NVREG_RCVSTAT_BUSY, 0,
NV_RXSTOP_DELAY1, NV_RXSTOP_DELAY1MAX,
KERN_INFO "nv_stop_rx: ReceiverStatus remained busy");
 
udelay(NV_RXSTOP_DELAY2);
-   writel(0, base + NvRegLinkSpeed);
+   if (!np->mac_in_use)
+   writel(0, base + NvRegLinkSpeed);
 }
 
 static void nv_start_tx(struct net_device *dev)
 {
+   struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+   u32 tx_ctrl = readl(base + NvRegTransmitterControl);
 
dprintk(KERN_DEBUG "%s: nv_start_tx\n", dev->name);
-   writel(NVREG_XMITCTL_START, base + NvRegTransmitterControl);
+   tx_ctrl |= NVREG_XMITCTL_START;
+   if (np->mac_in_use)
+   tx_ctrl &= ~NVREG_XMITCTL_TX_PATH_EN;
+   writel(tx_ctrl, base + NvRegTransmitterControl);
pci_push(base);
 }
 
 static void nv_stop_tx(struct net_device *dev)
 {
+   struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+   u32 tx_ctrl = readl(base + NvRegTransmitterControl);
 
dprintk(KERN_DEBUG "%s: nv_stop_tx\n", dev->name);
-   writel(0, base + NvRegTransmitterControl);
+   if (!np->mac_in_use)
+   tx_ctrl &= ~NVREG_XMITCTL_START;
+   else
+   tx_ctrl |= NVREG_XMITCTL_TX_PATH_EN;
+   writel(tx_ctrl, base + NvRegTransmitterControl);
reg_delay(dev, NvRegTransmitterStatus, NVREG_XMITSTAT_BUSY, 0,
NV_TXSTOP_DELAY1, NV_TXSTOP_DELAY1MAX,
KERN_INFO "nv_stop_tx: TransmitterStatus remained 
busy");
 
udelay(NV_TXSTOP_DELAY2);
-   writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
+   if (!np->mac_in_use)
+   writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV,
+  base + NvRegTransmitPoll);
 }
 
 static void nv_txrx_reset(struct net_device *dev)
@@ -4146,20 +4173,6 @@
return 0;
 }
 
-/* Indicate to mgmt unit whether driver is loaded o

[PATCH] forcedeth: modified comment header

2006-12-19 Thread Ayaz Abdulla

This patch removes comment that forcedeth is not supported by NVIDIA.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-12-19 23:16:38.0 -0500
+++ new-2.6/drivers/net/forcedeth.c 2006-12-19 23:19:28.0 -0500
@@ -3,8 +3,7 @@
  *
  * Note: This driver is a cleanroom reimplementation based on reverse
  *  engineered documentation written by Carl-Daniel Hailfinger
- *  and Andrew de Quincey. It's neither supported nor endorsed
- *  by NVIDIA Corp. Use at your own risk.
+ *  and Andrew de Quincey.
  *
  * NVIDIA, nForce and other NVIDIA marks are trademarks or registered
  * trademarks of NVIDIA Corporation in the United States and other
@@ -14,7 +13,7 @@
  * Copyright (C) 2004 Andrew de Quincey (wol support)
  * Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
  * IRQ rate fixes, bigendian fixes, cleanups, verification)
- * Copyright (c) 2004 NVIDIA Corporation
+ * Copyright (c) 2004,5,6 NVIDIA Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by


Re: [PATCH 1/2] forcedeth: add new NVIDIA pci ids

2006-10-30 Thread Ayaz Abdulla

Mgmt unit set was created first. However, it should not matter.

Ayaz


Jeff Garzik wrote:

You sent two pairs of patches, both labelled "1/2" and "2/2".

Which pair should go first, the pci ids or mgmt unit?
Or does it matter?

Jeff





---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


[PATCH 1/2] forcedeth: add new NVIDIA pci ids

2006-10-30 Thread Ayaz Abdulla

This patch adds pci device ids for the NVIDIA MCP67 chip.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- a/include/linux/pci_ids.h   2006-10-30 17:22:09.0 -0500
+++ b/include/linux/pci_ids.h   2006-10-30 17:22:17.0 -0500
@@ -1213,6 +1213,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_21  0x0451
 #define PCI_DEVICE_ID_NVIDIA_NVENET_22  0x0452
 #define PCI_DEVICE_ID_NVIDIA_NVENET_23  0x0453
+#define PCI_DEVICE_ID_NVIDIA_NVENET_24  0x054C
+#define PCI_DEVICE_ID_NVIDIA_NVENET_25  0x054D
+#define PCI_DEVICE_ID_NVIDIA_NVENET_26  0x054E
+#define PCI_DEVICE_ID_NVIDIA_NVENET_27  0x054F
 
 #define PCI_VENDOR_ID_IMS  0x10e0
 #define PCI_DEVICE_ID_IMS_TT1280x9128


[PATC 2/2] forcedeth: add support for new mcp67 device

2006-10-30 Thread Ayaz Abdulla

This patch adds support for the new mcp67 device into forcedeth.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-10-30 16:26:57.0 -0500
+++ new-2.6/drivers/net/forcedeth.c 2006-10-30 17:08:46.0 -0500
@@ -4927,6 +4927,22 @@
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_23),
.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
},
+   {   /* MCP67 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_24),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP67 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_25),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP67 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_26),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
+   {   /* MCP67 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_27),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+   },
{0,},
 };
 


[PATCH 1/2] forcedeth: add mgmt unit support

2006-10-30 Thread Ayaz Abdulla
This patch adds support for the mgmt unit in certain chipsets. The MAC 
and the mgmt unit share the PHY and therefore proper intialization 
procedures are needed for them to maintain coexistense.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-10-30 16:03:56.0 -0500
+++ new-2.6/drivers/net/forcedeth.c 2006-10-30 16:04:03.0 -0500
@@ -110,6 +110,7 @@
  * 0.55: 22 Mar 2006: Add flow control (pause frame).
  * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support.
  * 0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.
+ * 0.58: 30 Oct 2006: Added support for sideband management unit.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -126,7 +127,7 @@
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION  "0.57"
+#define FORCEDETH_VERSION  "0.58"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -174,6 +175,7 @@
 #define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
 #define DEV_HAS_STATISTICS  0x0400  /* device supports hw statistics */
 #define DEV_HAS_TEST_EXTENDED   0x0800  /* device supports extended diagnostic 
test */
+#define DEV_HAS_MGMT_UNIT   0x1000  /* device supports management unit */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -222,6 +224,15 @@
 #define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01
+#define NVREG_XMITCTL_MGMT_ST  0x4000
+#define NVREG_XMITCTL_SYNC_MASK0x000f
+#define NVREG_XMITCTL_SYNC_NOT_READY   0x0
+#define NVREG_XMITCTL_SYNC_PHY_INIT0x0004
+#define NVREG_XMITCTL_MGMT_SEMA_MASK   0x0f00
+#define NVREG_XMITCTL_MGMT_SEMA_FREE   0x0
+#define NVREG_XMITCTL_HOST_SEMA_MASK   0xf000
+#define NVREG_XMITCTL_HOST_SEMA_ACQ0xf000
+#define NVREG_XMITCTL_HOST_LOADED  0x4000
NvRegTransmitterStatus = 0x088,
 #define NVREG_XMITSTAT_BUSY0x01
 
@@ -304,8 +315,8 @@
 #define NVREG_MIISTAT_LINKCHANGE   0x0008
 #define NVREG_MIISTAT_MASK 0x000f
 #define NVREG_MIISTAT_MASK20x000f
-   NvRegUnknownSetupReg4 = 0x184,
-#define NVREG_UNKSETUP4_VAL8
+   NvRegMIIMask = 0x184,
+#define NVREG_MII_LINKCHANGE   0x0008
 
NvRegAdapterControl = 0x188,
 #define NVREG_ADAPTCTL_START   0x02
@@ -719,6 +730,7 @@
u32 driver_data;
u32 register_size;
int rx_csum;
+   u32 mac_in_use;
 
void __iomem *base;
 
@@ -4030,6 +4042,54 @@
/* nothing to do */
 };
 
+/* The mgmt unit and driver use a semaphore to access the phy during init */
+static int nv_mgmt_acquire_sema(struct net_device *dev)
+{
+   u8 __iomem *base = get_hwbase(dev);
+   int i;
+   u32 tx_ctrl, mgmt_sema;
+
+   for (i = 0; i < 10; i++) {
+   mgmt_sema = readl(base + NvRegTransmitterControl) & 
NVREG_XMITCTL_MGMT_SEMA_MASK;
+   if (mgmt_sema == NVREG_XMITCTL_MGMT_SEMA_FREE)
+   break;
+   msleep(500);
+   }
+
+   if (mgmt_sema != NVREG_XMITCTL_MGMT_SEMA_FREE)
+   return 0;
+
+   for (i = 0; i < 2; i++) {
+   tx_ctrl = readl(base + NvRegTransmitterControl);
+   tx_ctrl |= NVREG_XMITCTL_HOST_SEMA_ACQ;
+   writel(tx_ctrl, base + NvRegTransmitterControl);
+
+   /* verify that semaphore was acquired */
+   tx_ctrl = readl(base + NvRegTransmitterControl);
+   if (((tx_ctrl & NVREG_XMITCTL_HOST_SEMA_MASK) == 
NVREG_XMITCTL_HOST_SEMA_ACQ) &&
+   ((tx_ctrl & NVREG_XMITCTL_MGMT_SEMA_MASK) == 
NVREG_XMITCTL_MGMT_SEMA_FREE))
+   return 1;
+   else
+   udelay(50);
+   }
+
+   return 0;
+}
+
+/* Indicate to mgmt unit whether driver is loaded or not */
+static void nv_mgmt_driver_loaded(struct net_device *dev, int loaded)
+{
+   u8 __iomem *base = get_hwbase(dev);
+   u32 tx_ctrl;
+
+   tx_ctrl = readl(base + NvRegTransmitterControl);
+   if (loaded)
+   tx_ctrl |= NVREG_XMITCTL_HOST_LOADED;
+   else
+   tx_ctrl &= ~NVREG_XMITCTL_HOST_LOADED;
+   writel(tx_ctrl, base + NvRegTransmitterControl);
+}
+
 static int nv_open(struct net_device *dev)
 {
struct fe_priv *np = netdev_priv(dev);
@@ -4085,7 +4145,7 @@
NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
 
-   writel(0, base + NvRegUnknownSetupReg4);
+   writel(0, base + NvRegMIIMask);
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
 
@@ -4111,7 +4171,7 @@
writel((np->phyaddr << 
NVREG_ADAPTCTL_P

[PATCH 2/2] forcedeth: add recoverable error support

2006-10-30 Thread Ayaz Abdulla
This patch adds support to recover from a previously fatal MAC error. In 
the past the MAC would be hung on an internal fatal error. On new 
chipsets, the MAC has the ability to enter a non-fatal state and allow 
the driver to re-init it.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-10-30 16:07:05.0 -0500
+++ new-2.6/drivers/net/forcedeth.c 2006-10-30 16:23:43.0 -0500
@@ -111,6 +111,7 @@
  * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support.
  * 0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.
  * 0.58: 30 Oct 2006: Added support for sideband management unit.
+ * 0.59: 30 Oct 2006: Added support for recoverable error.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -127,7 +128,7 @@
 #else
 #define DRIVERNAPI
 #endif
-#define FORCEDETH_VERSION  "0.58"
+#define FORCEDETH_VERSION  "0.59"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -180,7 +181,7 @@
 enum {
NvRegIrqStatus = 0x000,
 #define NVREG_IRQSTAT_MIIEVENT 0x040
-#define NVREG_IRQSTAT_MASK 0x1ff
+#define NVREG_IRQSTAT_MASK 0x81ff
NvRegIrqMask = 0x004,
 #define NVREG_IRQ_RX_ERROR 0x0001
 #define NVREG_IRQ_RX   0x0002
@@ -191,15 +192,16 @@
 #define NVREG_IRQ_LINK 0x0040
 #define NVREG_IRQ_RX_FORCED0x0080
 #define NVREG_IRQ_TX_FORCED0x0100
+#define NVREG_IRQ_RECOVER_ERROR0x8000
 #define NVREG_IRQMASK_THROUGHPUT   0x00df
 #define NVREG_IRQMASK_CPU  0x0040
 #define NVREG_IRQ_TX_ALL   
(NVREG_IRQ_TX_ERR|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_FORCED)
 #define NVREG_IRQ_RX_ALL   
(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_RX_FORCED)
-#define NVREG_IRQ_OTHER(NVREG_IRQ_TIMER|NVREG_IRQ_LINK)
+#define NVREG_IRQ_OTHER
(NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RECOVER_ERROR)
 
 #define NVREG_IRQ_UNKNOWN  
(~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \

NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_RX_FORCED| \
-   NVREG_IRQ_TX_FORCED))
+   
NVREG_IRQ_TX_FORCED|NVREG_IRQ_RECOVER_ERROR))
 
NvRegUnknownSetupReg6 = 0x008,
 #define NVREG_UNKSETUP6_VAL3
@@ -718,6 +720,7 @@
unsigned int phy_model;
u16 gigabit;
int intr_test;
+   int recover_error;
 
/* General data: RO fields */
dma_addr_t ring_addr;
@@ -2455,6 +2458,23 @@
printk(KERN_DEBUG "%s: received irq with unknown events 
0x%x. Please report\n",
dev->name, events);
}
+   if (unlikely(events & NVREG_IRQ_RECOVER_ERROR)) {
+   spin_lock(&np->lock);
+   /* disable interrupts on the nic */
+   if (!(np->msi_flags & NV_MSI_X_ENABLED))
+   writel(0, base + NvRegIrqMask);
+   else
+   writel(np->irqmask, base + NvRegIrqMask);
+   pci_push(base);
+
+   if (!np->in_shutdown) {
+   np->nic_poll_irq = np->irqmask;
+   np->recover_error = 1;
+   mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+   }
+   spin_unlock(&np->lock);
+   break;
+   }
 #ifdef CONFIG_FORCEDETH_NAPI
if (events & NVREG_IRQ_RX_ALL) {
netif_rx_schedule(dev);
@@ -2685,6 +2705,20 @@
spin_unlock_irqrestore(&np->lock, flags);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
+   if (events & NVREG_IRQ_RECOVER_ERROR) {
+   spin_lock_irq(&np->lock);
+   /* disable interrupts on the nic */
+   writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
+   pci_push(base);
+
+   if (!np->in_shutdown) {
+   np->nic_poll_irq |= NVREG_IRQ_OTHER;
+   np->recover_error = 1;
+   mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+   }
+   spin_unlock_irq(&np->lock);
+   break;
+   }
if (events & (NVREG_IRQ_UNKNOWN)) {
printk(KERN_DEBUG "%s: received irq wit

[PATCH 2/2] forcedeth: mac address corrected

2006-07-31 Thread Ayaz Abdulla
This patch will correct the mac address and set a flag to indicate that 
it is already corrected in case nv_probe is called again. For example, 
when you use kexec to restart the kernel.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-07-06 15:06:27.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-07-06 15:06:58.0 -0400
@@ -109,6 +109,7 @@
  * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup.
  * 0.55: 22 Mar 2006: Add flow control (pause frame).
  * 0.56: 22 Mar 2006: Additional ethtool config and moduleparam support.
+ * 0.57: 14 May 2006: Mac address set in probe/remove and order 
corrections.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -120,7 +121,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.56"
+#define FORCEDETH_VERSION  "0.57"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -262,7 +263,8 @@
NvRegRingSizes = 0x108,
 #define NVREG_RINGSZ_TXSHIFT 0
 #define NVREG_RINGSZ_RXSHIFT 16
-   NvRegUnknownTransmitterReg = 0x10c,
+   NvRegTransmitPoll = 0x10c,
+#define NVREG_TRANSMITPOLL_MAC_ADDR_REV0x8000
NvRegLinkSpeed = 0x110,
 #define NVREG_LINKSPEED_FORCE 0x1
 #define NVREG_LINKSPEED_10 1000
@@ -1178,7 +1180,7 @@
KERN_INFO "nv_stop_tx: TransmitterStatus remained 
busy");
 
udelay(NV_TXSTOP_DELAY2);
-   writel(0, base + NvRegUnknownTransmitterReg);
+   writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
 }
 
 static void nv_txrx_reset(struct net_device *dev)
@@ -3917,7 +3919,7 @@
oom = nv_init_ring(dev);
 
writel(0, base + NvRegLinkSpeed);
-   writel(0, base + NvRegUnknownTransmitterReg);
+   writel(readl(base + NvRegTransmitPoll) & 
NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll);
nv_txrx_reset(dev);
writel(0, base + NvRegUnknownSetupReg6);
 
@@ -4082,7 +4084,7 @@
unsigned long addr;
u8 __iomem *base;
int err, i;
-   u32 powerstate;
+   u32 powerstate, txreg;
 
dev = alloc_etherdev(sizeof(struct fe_priv));
err = -ENOMEM;
@@ -4269,12 +4271,30 @@
np->orig_mac[0] = readl(base + NvRegMacAddrA);
np->orig_mac[1] = readl(base + NvRegMacAddrB);
 
-   dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
-   dev->dev_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
-   dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
-   dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
-   dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
-   dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
+   /* check the workaround bit for correct mac address order */
+   txreg = readl(base + NvRegTransmitPoll);
+   if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+   /* mac address is already in correct order */
+   dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
+   dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
+   dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
+   dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
+   dev->dev_addr[4] = (np->orig_mac[1] >>  0) & 0xff;
+   dev->dev_addr[5] = (np->orig_mac[1] >>  8) & 0xff;
+   } else {
+   /* need to reverse mac address to correct order */
+   dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
+   dev->dev_addr[1] = (np->orig_mac[1] >>  0) & 0xff;
+   dev->dev_addr[2] = (np->orig_mac[0] >> 24) & 0xff;
+   dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
+   dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
+   dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
+   /* set permanent address to be correct aswell */
+   np->orig_mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] 
<< 8) +
+   (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24);
+   np->orig_mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] 
<< 8);
+   writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + 
NvRegTransmitPoll);
+   }
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
if (!is_valid_ether_addr(dev->perm_addr)) {


[PATCH 1/2] forcedeth: move mac address setup/teardown

2006-07-31 Thread Ayaz Abdulla
This patch moves the mac address setup/teardown to the 
nv_probe/nv_remove functions. This fixes WOL wakeup since on nv_close we 
would reverse the mac address. Also, bonding driver will reset address 
after nv_close is called.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-07-06 15:05:31.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-07-06 15:05:54.0 -0400
@@ -3895,10 +3895,9 @@
 
dprintk(KERN_DEBUG "nv_open: begin\n");
 
-   /* 1) erase previous misconfiguration */
+   /* erase previous misconfiguration */
if (np->driver_data & DEV_HAS_POWER_CNTRL)
nv_mac_reset(dev);
-   /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */
writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
writel(0, base + NvRegMulticastAddrB);
writel(0, base + NvRegMulticastMaskA);
@@ -3913,7 +3912,7 @@
if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE)
writel(NVREG_TX_PAUSEFRAME_DISABLE,  base + NvRegTxPauseFrame);
 
-   /* 2) initialize descriptor rings */
+   /* initialize descriptor rings */
set_bufsize(dev);
oom = nv_init_ring(dev);
 
@@ -3924,15 +3923,11 @@
 
np->in_shutdown = 0;
 
-   /* 3) set mac address */
-   nv_copy_mac_to_hw(dev);
-
-   /* 4) give hw rings */
+   /* give hw rings */
setup_hw_rings(dev, NV_SETUP_RX_RING | NV_SETUP_TX_RING);
writel( ((np->rx_ring_size-1) << NVREG_RINGSZ_RXSHIFT) + 
((np->tx_ring_size-1) << NVREG_RINGSZ_TXSHIFT),
base + NvRegRingSizes);
 
-   /* 5) continue setup */
writel(np->linkspeed, base + NvRegLinkSpeed);
if (np->desc_ver == DESC_VER_1)
writel(NVREG_TX_WM_DESC1_DEFAULT, base + NvRegTxWatermark);
@@ -3950,7 +3945,6 @@
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
 
-   /* 6) continue setup */
writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
writel(readl(base + NvRegTransmitterStatus), base + 
NvRegTransmitterStatus);
writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags);
@@ -4076,12 +4070,6 @@
if (np->wolenabled)
nv_start_rx(dev);
 
-   /* special op: write back the misordered MAC address - otherwise
-* the next nv_probe would see a wrong address.
-*/
-   writel(np->orig_mac[0], base + NvRegMacAddrA);
-   writel(np->orig_mac[1], base + NvRegMacAddrB);
-
/* FIXME: power down nic */
 
return 0;
@@ -4309,6 +4297,9 @@
dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 
+   /* set mac address */
+   nv_copy_mac_to_hw(dev);
+
/* disable WOL */
writel(0, base + NvRegWakeUpFlags);
np->wolenabled = 0;
@@ -4421,9 +4412,17 @@
 static void __devexit nv_remove(struct pci_dev *pci_dev)
 {
struct net_device *dev = pci_get_drvdata(pci_dev);
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
 
unregister_netdev(dev);
 
+   /* special op: write back the misordered MAC address - otherwise
+* the next nv_probe would see a wrong address.
+*/
+   writel(np->orig_mac[0], base + NvRegMacAddrA);
+   writel(np->orig_mac[1], base + NvRegMacAddrB);
+
/* free all structures */
free_rings(dev);
iounmap(get_hwbase(dev));


[PATCH 2/2] forcedeth: watermark fixup

2006-07-06 Thread Ayaz Abdulla
This patch defines the watermark registers and fixes up the use of this 
register.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-07-06 15:04:39.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-07-06 15:05:00.0 -0400
@@ -271,8 +271,10 @@
 #define NVREG_LINKSPEED_MASK   (0xFFF)
NvRegUnknownSetupReg5 = 0x130,
 #define NVREG_UNKSETUP5_BIT31  (1<<31)
-   NvRegUnknownSetupReg3 = 0x13c,
-#define NVREG_UNKSETUP3_VAL1   0x200010
+   NvRegTxWatermark = 0x13c,
+#define NVREG_TX_WM_DESC1_DEFAULT  0x0200010
+#define NVREG_TX_WM_DESC2_3_DEFAULT0x1e08000
+#define NVREG_TX_WM_DESC2_3_1000   0xfe08000
NvRegTxRxControl = 0x144,
 #define NVREG_TXRXCTL_KICK 0x0001
 #define NVREG_TXRXCTL_BIT1 0x0002
@@ -660,7 +662,7 @@
{ NvRegMisc1, 0x03c },
{ NvRegOffloadConfig, 0x03ff },
{ NvRegMulticastAddrA, 0x },
-   { NvRegUnknownSetupReg3, 0x0ff },
+   { NvRegTxWatermark, 0x0ff },
{ NvRegWakeUpFlags, 0x0 },
{ 0,0 }
 };
@@ -2257,6 +2259,16 @@
}
writel(txreg, base + NvRegTxDeferral);
 
+   if (np->desc_ver == DESC_VER_1) {
+   txreg = NVREG_TX_WM_DESC1_DEFAULT;
+   } else {
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000)
+   txreg = NVREG_TX_WM_DESC2_3_1000;
+   else
+   txreg = NVREG_TX_WM_DESC2_3_DEFAULT;
+   }
+   writel(txreg, base + NvRegTxWatermark);
+
writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
base + NvRegMisc1);
pci_push(base);
@@ -3922,7 +3934,10 @@
 
/* 5) continue setup */
writel(np->linkspeed, base + NvRegLinkSpeed);
-   writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
+   if (np->desc_ver == DESC_VER_1)
+   writel(NVREG_TX_WM_DESC1_DEFAULT, base + NvRegTxWatermark);
+   else
+   writel(NVREG_TX_WM_DESC2_3_DEFAULT, base + NvRegTxWatermark);
writel(np->txrxctl_bits, base + NvRegTxRxControl);
writel(np->vlanctl_bits, base + NvRegVlanControl);
pci_push(base);


[PATCH 1/2] forcedeth: deferral fixup

2006-07-06 Thread Ayaz Abdulla
This patch adds the definition for the deferral registers and fixes up 
the use of these registers.


Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-07-06 15:03:45.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-07-06 15:03:55.0 -0400
@@ -240,10 +240,12 @@
 #define NVREG_RNDSEED_FORCE2   0x2d00
 #define NVREG_RNDSEED_FORCE3   0x7400
 
-   NvRegUnknownSetupReg1 = 0xA0,
-#define NVREG_UNKSETUP1_VAL0x16070f
-   NvRegUnknownSetupReg2 = 0xA4,
-#define NVREG_UNKSETUP2_VAL0x16
+   NvRegTxDeferral = 0xA0,
+#define NVREG_TX_DEFERRAL_DEFAULT  0x15050f
+#define NVREG_TX_DEFERRAL_RGMII_10_100 0x16070f
+#define NVREG_TX_DEFERRAL_RGMII_1000   0x14050f
+   NvRegRxDeferral = 0xA4,
+#define NVREG_RX_DEFERRAL_DEFAULT  0x16
NvRegMacAddrA = 0xA8,
NvRegMacAddrB = 0xAC,
NvRegMulticastAddrA = 0xB0,
@@ -2127,7 +2129,7 @@
int newdup = np->duplex;
int mii_status;
int retval = 0;
-   u32 control_1000, status_1000, phyreg, pause_flags;
+   u32 control_1000, status_1000, phyreg, pause_flags, txreg;
 
/* BMSR_LSTATUS is latched, read it twice:
 * we want the current value.
@@ -2245,6 +2247,16 @@
phyreg |= PHY_1000;
writel(phyreg, base + NvRegPhyInterface);
 
+   if (phyreg & PHY_RGMII) {
+   if ((np->linkspeed & NVREG_LINKSPEED_MASK) == 
NVREG_LINKSPEED_1000)
+   txreg = NVREG_TX_DEFERRAL_RGMII_1000;
+   else
+   txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+   } else {
+   txreg = NVREG_TX_DEFERRAL_DEFAULT;
+   }
+   writel(txreg, base + NvRegTxDeferral);
+
writel(NVREG_MISC1_FORCE | ( np->duplex ? 0 : NVREG_MISC1_HD),
base + NvRegMisc1);
pci_push(base);
@@ -3932,8 +3944,8 @@
writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus);
get_random_bytes(&i, sizeof(i));
writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + 
NvRegRandomSeed);
-   writel(NVREG_UNKSETUP1_VAL, base + NvRegUnknownSetupReg1);
-   writel(NVREG_UNKSETUP2_VAL, base + NvRegUnknownSetupReg2);
+   writel(NVREG_TX_DEFERRAL_DEFAULT, base + NvRegTxDeferral);
+   writel(NVREG_RX_DEFERRAL_DEFAULT, base + NvRegRxDeferral);
if (poll_interval == -1) {
if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT)
writel(NVREG_POLL_DEFAULT_THROUGHPUT, base + 
NvRegPollingInterval);


[PATCH 1/2] pci_ids: add new device ids

2006-05-25 Thread Ayaz Abdulla

This patch adds new device ids for MCP61 and MCP65 chips.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- a/include/linux/pci_ids.h   2006-05-25 13:02:56.0 -0400
+++ b/include/linux/pci_ids.h   2006-05-25 13:03:09.0 -0400
@@ -1182,6 +1182,14 @@
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_14  0x0372
 #define PCI_DEVICE_ID_NVIDIA_NVENET_15  0x0373
+#define PCI_DEVICE_ID_NVIDIA_NVENET_16  0x03E5
+#define PCI_DEVICE_ID_NVIDIA_NVENET_17  0x03E6
+#define PCI_DEVICE_ID_NVIDIA_NVENET_18  0x03EE
+#define PCI_DEVICE_ID_NVIDIA_NVENET_19  0x03EF
+#define PCI_DEVICE_ID_NVIDIA_NVENET_20  0x0450
+#define PCI_DEVICE_ID_NVIDIA_NVENET_21  0x0451
+#define PCI_DEVICE_ID_NVIDIA_NVENET_22  0x0452
+#define PCI_DEVICE_ID_NVIDIA_NVENET_23  0x0453
 
 #define PCI_VENDOR_ID_IMS  0x10e0
 #define PCI_DEVICE_ID_IMS_TT1280x9128


[PATCH 2/2] forcedeth: add support for new device ids

2006-05-25 Thread Ayaz Abdulla

This patch adds support for the new chips MCP61 and MCP65.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>

--- orig-2.6/drivers/net/forcedeth.c2006-05-25 13:01:03.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-05-25 13:02:23.0 -0400
@@ -109,6 +109,7 @@
  * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup.
  * 0.55: 22 Mar 2006: Add flow control (pause frame).
  * 0.56: 22 Mar 2006: Additional ethtool and moduleparam support.
+ * 0.57: 25 May 2006: Support for MCP61 and MCP65 added.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -120,7 +121,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.56"
+#define FORCEDETH_VERSION  "0.57"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -4677,6 +4678,38 @@
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_15),
.driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
},
+   {   /* MCP61 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_16),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP61 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_17),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP61 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_18),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP61 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_19),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP65 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_20),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP65 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_21),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP65 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_22),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
+   {   /* MCP65 Ethernet Controller */
+   PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, 
PCI_DEVICE_ID_NVIDIA_NVENET_23),
+   .driver_data = 
DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS|DEV_HAS_TEST_EXTENDED,
+   },
{0,},
 };
 


Re: Linux v2.6.17-rc4

2006-05-14 Thread Ayaz Abdulla



Alistair John Strachan wrote:

On Friday 12 May 2006 00:44, Linus Torvalds wrote:


Ok, I've let the release time between -rc's slide a bit too much again,
but -rc4 is out there, and this is the time to hunker down for 2.6.17.

If you know of any regressions, please holler now, so that we don't miss
them.

-rc4 itself is mainly random driver fixes (sound, infiniband, scsi,
network drivers), but some splice fixes too and some arch (arm, powerpc,
mips) updates. Shortlog follows,



Linus,

I've got an oops in the forcedeth driver on shutdown. Sorry for the crappy 
camera phone pictures, this board doesn't have RS232 ports:


http://devzero.co.uk/~alistair/oops-20060512/

It was initially difficult to reproduce, but I found I could do so reliably if 
I ssh'ed into the box and halted it remotely, then it would always oops on 
shutdown. I assume this is because the driver is still active when something 
happens to it during halt.


There's been just a single commit since -rc3:

forcedeth: fix multi irq issues
ebf34c9b6fcd22338ef764b039b3ac55ed0e297b

However, it could have just been hidden since before -rc3, so I'll try to work 
backwards if nobody has any immediate ideas..




The interrupt handler could be called during the same time (on different 
cpu) the dev->stop function is clearing out the rings (nv_txrx_reset).


-
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


RE: pci_enable_msix throws up error

2006-05-04 Thread Ayaz Abdulla
I noticed the same behaviour, i.e. can not use both MSI and MSIX without
rebooting.

I had sent a message to the maintainer of the MSI/MSIX source a few
months ago and got a response that they were working on fixing it. Not
sure what the progress is on it.

Ayaz

nvpublic
-Original Message-
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]
On Behalf Of Ravinandan Arakali
Sent: Thursday, May 04, 2006 4:16 PM
To: linux-kernel@vger.kernel.org
Cc: Ananda. Raju; netdev@vger.kernel.org; Leonid Grossman
Subject: pci_enable_msix throws up error


Hi,
I am seeing the following problem with MSI/MSI-X.

Note: I am copying netdev since other network drivers use
this feature and somebody on the list could throw light.

Our 10G network card(Xframe II) supports MSI and MSI-X.
When I load/unload the driver with MSI support followed
by an attempt to load with MSI-X, I get the following
message from pci_enable_msix:

"Can't enable MSI-X.  Device already has an MSI vector assigned"

I seem to be doing the correct things when unloading the
MSI driver. Basically, I do free_irq() followed by pci_disable_msi().
Any idea what I am missing ?

Further analysis:
Looking at the code, the following check(when it finds a match) in
msi_lookup_vector(called by pci_enable_msix) seems to throw up this
message:
if (!msi_desc[vector] || msi_desc[vector]->dev != dev ||
msi_desc[vector]->msi_attrib.type != type ||
msi_desc[vector]->msi_attrib.default_vector != dev->irq)

pci_enable_msi, on successful completion will populate the
fields in msi_desc. But neither pci_disable_msi nor free_irq
seems to undo/unpopulate the msi_desc table.
Could this be the cause for the problem ?

Thanks,
Ravi


-
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
-
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


[PATCH 3/4] forcedeth: fix initialization

2006-04-05 Thread Ayaz Abdulla

This patch fixes the nic initialization. If the nic was in low power
mode, it brings it back to normal power. Also, it utilizes a new
hardware reset during the init.

I am resending based on feedback, I corrected the register size mapping
(again) and delay after posted write.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>




---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig-2.6/drivers/net/forcedeth.c2006-04-05 20:45:01.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-04-05 20:45:14.0 -0400
@@ -107,6 +107,7 @@
  * 0.52: 20 Jan 2006: Add MSI/MSIX support.
  * 0.53: 20 Jan 2006: Add flow control (pause frame).
  * 0.54: 20 Jan 2006: Additional ethtool and moduleparam support.
+ * 0.55: 19 Mar 2006: Fix init from low power mode and add hw reset.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -118,7 +119,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.54"
+#define FORCEDETH_VERSION  "0.55"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -165,6 +166,7 @@
 #define DEV_HAS_PAUSEFRAME_TX   0x0100  /* device supports tx pause frames */
 #define DEV_HAS_STATISTICS  0x0200  /* device supports hw statistics */
 #define DEV_HAS_TEST_EXTENDED   0x0400  /* device supports extended diagnostic 
test */
+#define DEV_HAS_POWER_CNTRL 0x0800  /* device supports power savings */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -209,6 +211,8 @@
 #define NVREG_MISC1_HD 0x02
 #define NVREG_MISC1_FORCE  0x3b0f3c
 
+   NvRegMacReset = 0x3c,
+#define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01
NvRegTransmitterStatus = 0x088,
@@ -365,6 +369,10 @@
NvRegMSIXMap0 = 0x3e0,
NvRegMSIXMap1 = 0x3e4,
NvRegMSIXIrqStatus = 0x3f0,
+
+   NvRegPowerState2 = 0x600,
+#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
+#define NVREG_POWERSTATE2_POWERUP_REV_A3   0x0001
 };
 
 /* Big endian: should work, but is untested */
@@ -453,7 +461,8 @@
 #define NV_RX3_VLAN_TAG_MASK   (0x)
 
 /* Miscelaneous hardware related defines: */
-#define NV_PCI_REGSZ   0x270
+#define NV_PCI_REGSZ_VER1  0x270
+#define NV_PCI_REGSZ_VER2  0x604
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -470,6 +479,7 @@
 #define NV_MIIBUSY_DELAY   50
 #define NV_MIIPHY_DELAY10
 #define NV_MIIPHY_DELAYMAX 1
+#define NV_MAC_RESET_DELAY 64
 
 #define NV_WAKEUPPATTERNS  5
 #define NV_WAKEUPMASKENTRIES   4
@@ -700,6 +710,7 @@
u32 txrxctl_bits;
u32 vlanctl_bits;
u32 driver_data;
+   u32 register_size;
 
void __iomem *base;
 
@@ -1314,6 +1325,24 @@
pci_push(base);
 }
 
+static void nv_mac_reset(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+   writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, 
base + NvRegTxRxControl);
+   pci_push(base);
+   writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(0, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
+   pci_push(base);
+}
+
 /*
  * nv_get_stats: dev->get_stats function
  * Get latest stats value from the nic.
@@ -1726,7 +1755,7 @@
dev->name, (unsigned long)np->ring_addr,
np->next_tx, np->nic_tx);
printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
-   for (i=0;i<0x400;i+= 32) {
+   for (i=0;i<=np->register_size;i+= 32) {
printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x 
%08x %08x\n",
i,
readl(base + i + 0), readl(base + i + 
4),
@@ -3202,11 +3231,11 @@
 }
 
 #define FORCEDETH_REGS_VER 1
-#define FORCEDETH_REGS_SIZE0x400 /* 256 32-bit registers */
 
 static int nv_get_regs_len(struct net_device *dev)
 {
-   retur

Re: [PATCH 2/4] forcedeth: add support for configuration

2006-04-05 Thread Ayaz Abdulla



Manfred Spraul wrote:

Ayaz Abdulla wrote:




Ayaz Abdulla wrote:




Manfred Spraul wrote:


Ayaz Abdulla wrote:


This patch adds support for configuration of various parameters. This
includes module parameters and ethtool commands.




+
+if (netif_running(dev)) {
+nv_start_rx(dev);
+nv_start_tx(dev);
+nv_enable_irq(dev);
+}
+
 

Why no spin_lock() calls? Otherwise start_xmit could be running 
concurrently, or the irq handler could run if the interrupt is shared.




You are correct about irq handler for shared interrupt. I call 
netif_carrier_off() so the xmit routine should not be called.




Actually, I take that back. Irq is disabled, so this is ok.



I was afraid of two races:
a) a concurrent ifdown - someone closes a network device during an 
ethtool -s command. dev_close() clears the __LINK_STATE_START bit. If 
that happens, then the first call of netif_runnig() would return true 
and the second false, which would leak the locks.
I've checked the locking: both dev_close() and dev_ethtool run under 
rtnl_lock(), which is a mutex. Thus the race doesn't exist.


b) I prefer simple locking rules - e.g. all calls to nv_start_tx() under 
spinlock. You broke that "rule". But it's ok, it's only a question of 
personal preference.


Thus: I take back my objection.

But I have a new one: where is the netif_carrier_on()? The test case 
would be a change of the pause settings with autonegotiation off. 
nv_set_pauseparam() calls netif_carrier_off() - and I don't see the 
corresponding netif_carrier_on().




When interrupts are re-enabled (after the new configuration is set), the 
nv_linkchange function will be called (due to link timer firing every 
second) and make the appropriate netif_carrier_XX() call.


One optimization could to be just call nv_linkchange() directly instead 
of calling nv_update_linkspeed().



--
   Manfred


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


[PATCH 4/4] forcedeth: fix multi irq issues

2006-04-04 Thread Ayaz Abdulla

This patch fixes the issues with multiple irqs.

I am resending based on feedback. I decoupled the dma mask for 
consistent memory and fixed leak with multiple irq in error path.


Thanks to Manfred for catching the spin lock problem.

Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig-2.6/drivers/net/forcedeth.c2006-04-04 15:26:18.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-04-04 15:26:27.0 -0400
@@ -108,6 +108,7 @@
  * 0.53: 20 Jan 2006: Add flow control (pause frame).
  * 0.54: 20 Jan 2006: Additional ethtool and moduleparam support.
  * 0.55: 19 Mar 2006: Fix init from low power mode and add hw reset.
+ * 0.56: 21 Mar 2006: Fix spin locks for multi irqs and cleanup.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -119,7 +120,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.55"
+#define FORCEDETH_VERSION  "0.56"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -1014,14 +1015,27 @@
kfree(np->tx_dma_len);
 }
 
-static void nv_enable_irq(struct net_device *dev)
+static int using_multi_irqs(struct net_device *dev)
 {
struct fe_priv *np = get_nvpriv(dev);
 
if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
((np->msi_flags & NV_MSI_X_ENABLED) && 
-((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
-   enable_irq(dev->irq);
+((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1)))
+   return 0;
+   else
+   return 1;
+}
+
+static void nv_enable_irq(struct net_device *dev)
+{
+   struct fe_priv *np = get_nvpriv(dev);
+
+   if (!using_multi_irqs(dev)) {
+   if (np->msi_flags & NV_MSI_X_ENABLED)
+   enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
+   else
+   enable_irq(dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1033,10 +1047,11 @@
 {
struct fe_priv *np = get_nvpriv(dev);
 
-   if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
-   ((np->msi_flags & NV_MSI_X_ENABLED) && 
-((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
-   disable_irq(dev->irq);
+   if (!using_multi_irqs(dev)) {
+   if (np->msi_flags & NV_MSI_X_ENABLED)
+   
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
+   else
+   disable_irq(dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1044,6 +1059,7 @@
}
 }
 
+/* In MSIX mode, a write to irqmask behaves as XOR */
 static void nv_enable_hw_interrupts(struct net_device *dev, u32 mask)
 {
u8 __iomem *base = get_hwbase(dev);
@@ -1413,24 +1429,25 @@
struct net_device *dev = (struct net_device *) data;
struct fe_priv *np = netdev_priv(dev);
 
-
-   if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
-   ((np->msi_flags & NV_MSI_X_ENABLED) && 
-((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
-   disable_irq(dev->irq);
+   if (!using_multi_irqs(dev)) {
+   if (np->msi_flags & NV_MSI_X_ENABLED)
+   
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
+   else
+   disable_irq(dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
if (nv_alloc_rx(dev)) {
-   spin_lock(&np->lock);
+   spin_lock_irq(&np->lock);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-   spin_unlock(&np->lock);
+   spin_unlock_irq(&np->lock);
}
-   if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
-   ((np->msi_flags & NV_MSI_X_ENABLED) && 
-((np->msi_flags & NV_

[PATCH 3/4] forcedeth: fix initialization (current)

2006-04-04 Thread Ayaz Abdulla

This patch fixes the nic initialization. If the nic was in low power
mode, it brings it back to normal power. Also, it utilizes a new
hardware reset during the init.

I am resending based on feedback, I corrected the register size mapping 
and delay after posted write.



Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig-2.6/drivers/net/forcedeth.c2006-04-04 14:14:16.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-04-04 14:26:44.0 -0400
@@ -107,6 +107,7 @@
  * 0.52: 20 Jan 2006: Add MSI/MSIX support.
  * 0.53: 20 Jan 2006: Add flow control (pause frame).
  * 0.54: 20 Jan 2006: Additional ethtool and moduleparam support.
+ * 0.55: 19 Mar 2006: Fix init from low power mode and add hw reset.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -118,7 +119,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.54"
+#define FORCEDETH_VERSION  "0.55"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -165,6 +166,7 @@
 #define DEV_HAS_PAUSEFRAME_TX   0x0100  /* device supports tx pause frames */
 #define DEV_HAS_STATISTICS  0x0200  /* device supports hw statistics */
 #define DEV_HAS_TEST_EXTENDED   0x0400  /* device supports extended diagnostic 
test */
+#define DEV_HAS_POWER_CNTRL 0x0800  /* device supports power savings */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -209,6 +211,8 @@
 #define NVREG_MISC1_HD 0x02
 #define NVREG_MISC1_FORCE  0x3b0f3c
 
+   NvRegMacReset = 0x3c,
+#define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01
NvRegTransmitterStatus = 0x088,
@@ -365,6 +369,10 @@
NvRegMSIXMap0 = 0x3e0,
NvRegMSIXMap1 = 0x3e4,
NvRegMSIXIrqStatus = 0x3f0,
+
+   NvRegPowerState2 = 0x600,
+#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
+#define NVREG_POWERSTATE2_POWERUP_REV_A3   0x0001
 };
 
 /* Big endian: should work, but is untested */
@@ -453,7 +461,8 @@
 #define NV_RX3_VLAN_TAG_MASK   (0x)
 
 /* Miscelaneous hardware related defines: */
-#define NV_PCI_REGSZ   0x270
+#define NV_PCI_REGSZ_VER1  0x270
+#define NV_PCI_REGSZ_VER2  0x600
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -470,6 +479,7 @@
 #define NV_MIIBUSY_DELAY   50
 #define NV_MIIPHY_DELAY10
 #define NV_MIIPHY_DELAYMAX 1
+#define NV_MAC_RESET_DELAY 64
 
 #define NV_WAKEUPPATTERNS  5
 #define NV_WAKEUPMASKENTRIES   4
@@ -700,6 +710,7 @@
u32 txrxctl_bits;
u32 vlanctl_bits;
u32 driver_data;
+   u32 register_size;
 
void __iomem *base;
 
@@ -1314,6 +1325,24 @@
pci_push(base);
 }
 
+static void nv_mac_reset(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+   writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, 
base + NvRegTxRxControl);
+   pci_push(base);
+   writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(0, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
+   pci_push(base);
+}
+
 /*
  * nv_get_stats: dev->get_stats function
  * Get latest stats value from the nic.
@@ -1726,7 +1755,7 @@
dev->name, (unsigned long)np->ring_addr,
np->next_tx, np->nic_tx);
printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
-   for (i=0;i<0x400;i+= 32) {
+   for (i=0;i<=np->register_size;i+= 32) {
printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x 
%08x %08x\n",
i,
readl(base + i + 0), readl(base + i + 
4),
@@ -3202,11 +3231,11 @@
 }
 
 #define FORCEDETH_REGS_VER 1
-#define FORCEDETH_REGS_SIZE0x400 /* 256 32-bit registers */
 
 static int nv_get_regs_len(struct net_device *dev)
 {
-   retur

Re: [PATCH 2/4] forcedeth: fix initialization

2006-04-04 Thread Ayaz Abdulla
Ignore this...the patch number is wrong...I am resending it. Sorry for 
the confusion,


Ayaz Abdulla wrote:

This patch fixes the nic initialization. If the nic was in low power
mode, it brings it back to normal power. Also, it utilizes a new
hardware reset during the init.

I am resending based on feedback, I corrected the register size mapping 
and delay after posted write.



Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>




--- orig-2.6/drivers/net/forcedeth.c2006-04-04 14:14:16.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-04-04 14:26:44.0 -0400
@@ -107,6 +107,7 @@
  * 0.52: 20 Jan 2006: Add MSI/MSIX support.
  * 0.53: 20 Jan 2006: Add flow control (pause frame).
  * 0.54: 20 Jan 2006: Additional ethtool and moduleparam support.
+ * 0.55: 19 Mar 2006: Fix init from low power mode and add hw reset.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -118,7 +119,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.54"
+#define FORCEDETH_VERSION  "0.55"
 #define DRV_NAME   "forcedeth"
 
 #include 

@@ -165,6 +166,7 @@
 #define DEV_HAS_PAUSEFRAME_TX   0x0100  /* device supports tx pause frames */
 #define DEV_HAS_STATISTICS  0x0200  /* device supports hw statistics */
 #define DEV_HAS_TEST_EXTENDED   0x0400  /* device supports extended diagnostic 
test */
+#define DEV_HAS_POWER_CNTRL 0x0800  /* device supports power savings */
 
 enum {

NvRegIrqStatus = 0x000,
@@ -209,6 +211,8 @@
 #define NVREG_MISC1_HD 0x02
 #define NVREG_MISC1_FORCE  0x3b0f3c
 
+	NvRegMacReset = 0x3c,

+#define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01
NvRegTransmitterStatus = 0x088,
@@ -365,6 +369,10 @@
NvRegMSIXMap0 = 0x3e0,
NvRegMSIXMap1 = 0x3e4,
NvRegMSIXIrqStatus = 0x3f0,
+
+   NvRegPowerState2 = 0x600,
+#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
+#define NVREG_POWERSTATE2_POWERUP_REV_A3   0x0001
 };
 
 /* Big endian: should work, but is untested */

@@ -453,7 +461,8 @@
 #define NV_RX3_VLAN_TAG_MASK   (0x)
 
 /* Miscelaneous hardware related defines: */

-#define NV_PCI_REGSZ   0x270
+#define NV_PCI_REGSZ_VER1  0x270
+#define NV_PCI_REGSZ_VER2  0x600
 
 /* various timeout delays: all in usec */

 #define NV_TXRX_RESET_DELAY4
@@ -470,6 +479,7 @@
 #define NV_MIIBUSY_DELAY   50
 #define NV_MIIPHY_DELAY10
 #define NV_MIIPHY_DELAYMAX 1
+#define NV_MAC_RESET_DELAY 64
 
 #define NV_WAKEUPPATTERNS	5

 #define NV_WAKEUPMASKENTRIES   4
@@ -700,6 +710,7 @@
u32 txrxctl_bits;
u32 vlanctl_bits;
u32 driver_data;
+   u32 register_size;
 
 	void __iomem *base;
 
@@ -1314,6 +1325,24 @@

pci_push(base);
 }
 
+static void nv_mac_reset(struct net_device *dev)

+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+   writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, 
base + NvRegTxRxControl);
+   pci_push(base);
+   writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(0, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
+   pci_push(base);
+}
+
 /*
  * nv_get_stats: dev->get_stats function
  * Get latest stats value from the nic.
@@ -1726,7 +1755,7 @@
dev->name, (unsigned long)np->ring_addr,
np->next_tx, np->nic_tx);
printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
-   for (i=0;i<0x400;i+= 32) {
+   for (i=0;i<=np->register_size;i+= 32) {
printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x 
%08x\n",
i,
readl(base + i + 0), readl(base + i + 
4),
@@ -3202,11 +3231,11 @@
 }
 
 #define FORCEDETH_REGS_VER	1

-#define FORCEDETH_REGS_SIZE0x400 /* 256 32-bit registers */
 
 static int nv_get_regs_len(struct net_device *dev)

 {
-   return FORCEDETH_REGS_SIZE;
+   struct fe_priv *np = netdev_priv(dev);
+   return np->register_size;
 }
 
 static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)

@@ -3218,7 +3247,7 @@
 
 	regs->version = FORCEDETH_REGS_VER;

spin_lock_irq(&np->lock);
-   for (

[PATCH 2/4] forcedeth: fix initialization

2006-04-04 Thread Ayaz Abdulla

This patch fixes the nic initialization. If the nic was in low power
mode, it brings it back to normal power. Also, it utilizes a new
hardware reset during the init.

I am resending based on feedback, I corrected the register size mapping 
and delay after posted write.



Signed-Off-By: Ayaz Abdulla <[EMAIL PROTECTED]>


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
--- orig-2.6/drivers/net/forcedeth.c2006-04-04 14:14:16.0 -0400
+++ new-2.6/drivers/net/forcedeth.c 2006-04-04 14:26:44.0 -0400
@@ -107,6 +107,7 @@
  * 0.52: 20 Jan 2006: Add MSI/MSIX support.
  * 0.53: 20 Jan 2006: Add flow control (pause frame).
  * 0.54: 20 Jan 2006: Additional ethtool and moduleparam support.
+ * 0.55: 19 Mar 2006: Fix init from low power mode and add hw reset.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -118,7 +119,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION  "0.54"
+#define FORCEDETH_VERSION  "0.55"
 #define DRV_NAME   "forcedeth"
 
 #include 
@@ -165,6 +166,7 @@
 #define DEV_HAS_PAUSEFRAME_TX   0x0100  /* device supports tx pause frames */
 #define DEV_HAS_STATISTICS  0x0200  /* device supports hw statistics */
 #define DEV_HAS_TEST_EXTENDED   0x0400  /* device supports extended diagnostic 
test */
+#define DEV_HAS_POWER_CNTRL 0x0800  /* device supports power savings */
 
 enum {
NvRegIrqStatus = 0x000,
@@ -209,6 +211,8 @@
 #define NVREG_MISC1_HD 0x02
 #define NVREG_MISC1_FORCE  0x3b0f3c
 
+   NvRegMacReset = 0x3c,
+#define NVREG_MAC_RESET_ASSERT 0x0F3
NvRegTransmitterControl = 0x084,
 #define NVREG_XMITCTL_START0x01
NvRegTransmitterStatus = 0x088,
@@ -365,6 +369,10 @@
NvRegMSIXMap0 = 0x3e0,
NvRegMSIXMap1 = 0x3e4,
NvRegMSIXIrqStatus = 0x3f0,
+
+   NvRegPowerState2 = 0x600,
+#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11
+#define NVREG_POWERSTATE2_POWERUP_REV_A3   0x0001
 };
 
 /* Big endian: should work, but is untested */
@@ -453,7 +461,8 @@
 #define NV_RX3_VLAN_TAG_MASK   (0x)
 
 /* Miscelaneous hardware related defines: */
-#define NV_PCI_REGSZ   0x270
+#define NV_PCI_REGSZ_VER1  0x270
+#define NV_PCI_REGSZ_VER2  0x600
 
 /* various timeout delays: all in usec */
 #define NV_TXRX_RESET_DELAY4
@@ -470,6 +479,7 @@
 #define NV_MIIBUSY_DELAY   50
 #define NV_MIIPHY_DELAY10
 #define NV_MIIPHY_DELAYMAX 1
+#define NV_MAC_RESET_DELAY 64
 
 #define NV_WAKEUPPATTERNS  5
 #define NV_WAKEUPMASKENTRIES   4
@@ -700,6 +710,7 @@
u32 txrxctl_bits;
u32 vlanctl_bits;
u32 driver_data;
+   u32 register_size;
 
void __iomem *base;
 
@@ -1314,6 +1325,24 @@
pci_push(base);
 }
 
+static void nv_mac_reset(struct net_device *dev)
+{
+   struct fe_priv *np = netdev_priv(dev);
+   u8 __iomem *base = get_hwbase(dev);
+
+   dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+   writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, 
base + NvRegTxRxControl);
+   pci_push(base);
+   writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(0, base + NvRegMacReset);
+   pci_push(base);
+   udelay(NV_MAC_RESET_DELAY);
+   writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
+   pci_push(base);
+}
+
 /*
  * nv_get_stats: dev->get_stats function
  * Get latest stats value from the nic.
@@ -1726,7 +1755,7 @@
dev->name, (unsigned long)np->ring_addr,
np->next_tx, np->nic_tx);
printk(KERN_INFO "%s: Dumping tx registers\n", dev->name);
-   for (i=0;i<0x400;i+= 32) {
+   for (i=0;i<=np->register_size;i+= 32) {
printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x 
%08x %08x\n",
i,
readl(base + i + 0), readl(base + i + 
4),
@@ -3202,11 +3231,11 @@
 }
 
 #define FORCEDETH_REGS_VER 1
-#define FORCEDETH_REGS_SIZE0x400 /* 256 32-bit registers */
 
 static int nv_get_regs_len(struct net_device *dev)
 {
-   retur

Re: [PATCH 2/4] forcedeth: add support for configuration

2006-04-04 Thread Ayaz Abdulla



Ayaz Abdulla wrote:



Manfred Spraul wrote:


Ayaz Abdulla wrote:


This patch adds support for configuration of various parameters. This
includes module parameters and ethtool commands.




+
+if (netif_running(dev)) {
+nv_start_rx(dev);
+nv_start_tx(dev);
+nv_enable_irq(dev);
+}
+
 

Why no spin_lock() calls? Otherwise start_xmit could be running 
concurrently, or the irq handler could run if the interrupt is shared.




You are correct about irq handler for shared interrupt. I call 
netif_carrier_off() so the xmit routine should not be called.




Actually, I take that back. Irq is disabled, so this is ok.


+if (netif_running(dev)) {
+nv_disable_irq(dev);
+spin_lock_bh(&dev->xmit_lock);
+spin_lock(&np->lock);
+/* stop engines */
+nv_stop_rx(dev);
+nv_stop_tx(dev);
+nv_txrx_reset(dev);
+/* drain queues */
+nv_drain_rx(dev);
+nv_drain_tx(dev);
+/* delete queues */
+free_rings(dev);
+}
[snip]
+
+if (netif_running(dev)) {
 


[snip]


+   +/* restart engines */
+nv_start_rx(dev);
+nv_start_tx(dev);
+spin_unlock(&np->lock);
+spin_unlock_bh(&dev->xmit_lock);
+nv_enable_irq(dev);
+}
 


Dito: We might miss the spin_unlock.



I don't understand this comment...what do you mean by we will miss the 
spin_unlock?


+static int nv_set_pauseparam(struct net_device *dev, struct 
ethtool_pauseparam* pause)

+{
+struct fe_priv *np = netdev_priv(dev);
+int adv, bmcr;
+
+if ((!np->autoneg && np->duplex == 0) ||
+(np->autoneg && !pause->autoneg && np->duplex == 0)) {
+printk(KERN_INFO "%s: can not set pause settings when forced 
link is in half duplex.\n", +   dev->name);
 

printk's due to invalid ethtool commands. Really the right thing (tm) 
to do?

Jeff?


+nv_disable_hw_interrupts(dev, NVREG_IRQ_TIMER);
 


If the timer is disabled, does it disable all periodic interrupts?
So far there were always a few interrupts per second, even if the nic 
was totally idle.
If this really disables all periodic interrupts, then the LINK_TIMEOUT 
code must be replaced with a proper timer, not juse a check within the 
irq handler.




This code first enables the periodic interrupt and then disables it. It 
is in the context of diagnostic test.


In general, the periodic timer interrupt is always enabled when we care 
about the link state. The nic only has one periodic timer interrupt.



+if (dma_64bit) {
+if (pci_set_dma_mask(pci_dev, 0x007fULL)) {
+printk(KERN_INFO "forcedeth: 64-bit DMA failed, 
using 32-bit addressing for device %s.\n",

+   pci_name(pci_dev));
} else {
-dev->features |= NETIF_F_HIGHDMA;
-printk(KERN_INFO "forcedeth: using HIGHDMA\n");
+if (pci_set_consistent_dma_mask(pci_dev, 
0x007fULL)) {
+printk(KERN_INFO "forcedeth: 64-bit DMA 
(consistent) failed for device %s.\n",

+   pci_name(pci_dev));
+goto out_relreg;
+} else {
+dev->features |= NETIF_F_HIGHDMA;
+printk(KERN_INFO "forcedeth: using HIGHDMA\n");
+}
 

The consistend dma mask is independant from the NETIF_F_HIGHDMA 
setting. We should avoid to move bugs around.



Yes, I will fix it.



+   if 
(request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, 
&nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) {
+   printk(KERN_INFO "forcedeth: 
request_irq failed for rx %d\n", ret);

+   pci_disable_msix(np->pci_dev);
+   np->msi_flags &= 
~NV_MSI_X_ENABLED;

+   return 1;
+   }
+   /* Request irq for tx handling */
+   if 
(request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, 
&nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) {
+   printk(KERN_INFO "forcedeth: 
request_irq failed for tx %d\n", ret);

+   pci_disable_msix(np->pci_dev);
+   np->msi_flags &= 
~NV_MSI_X_ENABLED;

+   return 1;
+   }




Dito: this can leak interrupts.


Yes, I will fix it.



---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential in

Re: [PATCH 4/4] forcedeth: fix multi irq issues

2006-04-01 Thread Ayaz Abdulla



Manfred Spraul wrote:

Ayaz Abdulla wrote:


if (nv_alloc_rx(dev)) {
-spin_lock(&np->lock);
+spin_lock_irqsave(&np->lock, flags);
 


Tiny point:
there is not need for irqsave(): we are in timer context, that guarantees:
- bottom half disabled
- interrupts enabled

Just use spin_lock_irq() and spin_unlock_irq().



I was assuming this function is called either from within irq handler or 
timer expiry and thats why I used "irqsave". But if interrupts are 
disabled in timer context, I can change the code.



@@ -2882,11 +2900,12 @@
writel(mask, base + NvRegIrqMask);
pci_push(base);
 

[within nv_do_nic_poll(): reenable the interrupts that were disabled to 
prevent a livelock within the irq handler]




That is what I am doing. The mask field is set to the appropriate 
interrupts that we want to re-enable.



I still don't understand how this works for the msi-x case:
nv_nic_irq_tx writes NVREG_IRQ_TX_ALL to NvRegIrqMask to disable the tx 
interrupts.
nv_do_nic_poll does exactly the same thing, and this should reenable 
them. Is that correct?

If yes, please add a comment.


That is how the msi-x interrupt masking works. It is XOR logic. I can 
add a comment.




--
   Manfred
-
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


---
This email message is for the sole use of the intended recipient(s) and may 
contain
confidential information.  Any unauthorized review, use, disclosure or 
distribution
is prohibited.  If you are not the intended recipient, please contact the 
sender by
reply email and destroy all copies of the original message.
---
-
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


  1   2   >