diff options
Diffstat (limited to 'drivers/net/forcedeth.c')
-rw-r--r-- | drivers/net/forcedeth.c | 173 |
1 files changed, 121 insertions, 52 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index feb5b223cd60..5669b95162b3 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -107,6 +107,7 @@ | |||
107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. | 107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. |
108 | * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. | 108 | * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. |
109 | * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. | 109 | * 0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup. |
110 | * 0.55: 22 Mar 2006: Add flow control (pause frame). | ||
110 | * | 111 | * |
111 | * Known bugs: | 112 | * Known bugs: |
112 | * We suspect that on some hardware no TX done interrupts are generated. | 113 | * We suspect that on some hardware no TX done interrupts are generated. |
@@ -118,7 +119,7 @@ | |||
118 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 119 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
119 | * superfluous timer interrupts from the nic. | 120 | * superfluous timer interrupts from the nic. |
120 | */ | 121 | */ |
121 | #define FORCEDETH_VERSION "0.54" | 122 | #define FORCEDETH_VERSION "0.55" |
122 | #define DRV_NAME "forcedeth" | 123 | #define DRV_NAME "forcedeth" |
123 | 124 | ||
124 | #include <linux/module.h> | 125 | #include <linux/module.h> |
@@ -163,6 +164,7 @@ | |||
163 | #define DEV_HAS_MSI 0x0040 /* device supports MSI */ | 164 | #define DEV_HAS_MSI 0x0040 /* device supports MSI */ |
164 | #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ | 165 | #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ |
165 | #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ | 166 | #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ |
167 | #define DEV_HAS_PAUSEFRAME_TX 0x0200 /* device supports tx pause frames */ | ||
166 | 168 | ||
167 | enum { | 169 | enum { |
168 | NvRegIrqStatus = 0x000, | 170 | NvRegIrqStatus = 0x000, |
@@ -203,6 +205,7 @@ enum { | |||
203 | NvRegMSIIrqMask = 0x030, | 205 | NvRegMSIIrqMask = 0x030, |
204 | #define NVREG_MSI_VECTOR_0_ENABLED 0x01 | 206 | #define NVREG_MSI_VECTOR_0_ENABLED 0x01 |
205 | NvRegMisc1 = 0x080, | 207 | NvRegMisc1 = 0x080, |
208 | #define NVREG_MISC1_PAUSE_TX 0x01 | ||
206 | #define NVREG_MISC1_HD 0x02 | 209 | #define NVREG_MISC1_HD 0x02 |
207 | #define NVREG_MISC1_FORCE 0x3b0f3c | 210 | #define NVREG_MISC1_FORCE 0x3b0f3c |
208 | 211 | ||
@@ -214,7 +217,8 @@ enum { | |||
214 | #define NVREG_XMITSTAT_BUSY 0x01 | 217 | #define NVREG_XMITSTAT_BUSY 0x01 |
215 | 218 | ||
216 | NvRegPacketFilterFlags = 0x8c, | 219 | NvRegPacketFilterFlags = 0x8c, |
217 | #define NVREG_PFF_ALWAYS 0x7F0008 | 220 | #define NVREG_PFF_PAUSE_RX 0x08 |
221 | #define NVREG_PFF_ALWAYS 0x7F0000 | ||
218 | #define NVREG_PFF_PROMISC 0x80 | 222 | #define NVREG_PFF_PROMISC 0x80 |
219 | #define NVREG_PFF_MYADDR 0x20 | 223 | #define NVREG_PFF_MYADDR 0x20 |
220 | 224 | ||
@@ -277,6 +281,9 @@ enum { | |||
277 | #define NVREG_TXRXCTL_VLANINS 0x00080 | 281 | #define NVREG_TXRXCTL_VLANINS 0x00080 |
278 | NvRegTxRingPhysAddrHigh = 0x148, | 282 | NvRegTxRingPhysAddrHigh = 0x148, |
279 | NvRegRxRingPhysAddrHigh = 0x14C, | 283 | NvRegRxRingPhysAddrHigh = 0x14C, |
284 | NvRegTxPauseFrame = 0x170, | ||
285 | #define NVREG_TX_PAUSEFRAME_DISABLE 0x1ff0080 | ||
286 | #define NVREG_TX_PAUSEFRAME_ENABLE 0x0c00030 | ||
280 | NvRegMIIStatus = 0x180, | 287 | NvRegMIIStatus = 0x180, |
281 | #define NVREG_MIISTAT_ERROR 0x0001 | 288 | #define NVREG_MIISTAT_ERROR 0x0001 |
282 | #define NVREG_MIISTAT_LINKCHANGE 0x0008 | 289 | #define NVREG_MIISTAT_LINKCHANGE 0x0008 |
@@ -451,7 +458,7 @@ typedef union _ring_type { | |||
451 | 458 | ||
452 | #define RX_RING 128 | 459 | #define RX_RING 128 |
453 | #define TX_RING 256 | 460 | #define TX_RING 256 |
454 | /* | 461 | /* |
455 | * If your nic mysteriously hangs then try to reduce the limits | 462 | * If your nic mysteriously hangs then try to reduce the limits |
456 | * to 1/0: It might be required to set NV_TX_LASTPACKET in the | 463 | * to 1/0: It might be required to set NV_TX_LASTPACKET in the |
457 | * last valid ring entry. But this would be impossible to | 464 | * last valid ring entry. But this would be impossible to |
@@ -473,7 +480,7 @@ typedef union _ring_type { | |||
473 | #define POLL_WAIT (1+HZ/100) | 480 | #define POLL_WAIT (1+HZ/100) |
474 | #define LINK_TIMEOUT (3*HZ) | 481 | #define LINK_TIMEOUT (3*HZ) |
475 | 482 | ||
476 | /* | 483 | /* |
477 | * desc_ver values: | 484 | * desc_ver values: |
478 | * The nic supports three different descriptor types: | 485 | * The nic supports three different descriptor types: |
479 | * - DESC_VER_1: Original | 486 | * - DESC_VER_1: Original |
@@ -506,13 +513,10 @@ typedef union _ring_type { | |||
506 | #define PHY_1000 0x2 | 513 | #define PHY_1000 0x2 |
507 | #define PHY_HALF 0x100 | 514 | #define PHY_HALF 0x100 |
508 | 515 | ||
509 | /* FIXME: MII defines that should be added to <linux/mii.h> */ | 516 | #define NV_PAUSEFRAME_RX_CAPABLE 0x0001 |
510 | #define MII_1000BT_CR 0x09 | 517 | #define NV_PAUSEFRAME_TX_CAPABLE 0x0002 |
511 | #define MII_1000BT_SR 0x0a | 518 | #define NV_PAUSEFRAME_RX_ENABLE 0x0004 |
512 | #define ADVERTISE_1000FULL 0x0200 | 519 | #define NV_PAUSEFRAME_TX_ENABLE 0x0008 |
513 | #define ADVERTISE_1000HALF 0x0100 | ||
514 | #define LPA_1000FULL 0x0800 | ||
515 | #define LPA_1000HALF 0x0400 | ||
516 | 520 | ||
517 | /* MSI/MSI-X defines */ | 521 | /* MSI/MSI-X defines */ |
518 | #define NV_MSI_X_MAX_VECTORS 8 | 522 | #define NV_MSI_X_MAX_VECTORS 8 |
@@ -602,6 +606,9 @@ struct fe_priv { | |||
602 | /* msi/msi-x fields */ | 606 | /* msi/msi-x fields */ |
603 | u32 msi_flags; | 607 | u32 msi_flags; |
604 | struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; | 608 | struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS]; |
609 | |||
610 | /* flow control */ | ||
611 | u32 pause_flags; | ||
605 | }; | 612 | }; |
606 | 613 | ||
607 | /* | 614 | /* |
@@ -612,7 +619,7 @@ static int max_interrupt_work = 5; | |||
612 | 619 | ||
613 | /* | 620 | /* |
614 | * Optimization can be either throuput mode or cpu mode | 621 | * Optimization can be either throuput mode or cpu mode |
615 | * | 622 | * |
616 | * Throughput Mode: Every tx and rx packet will generate an interrupt. | 623 | * Throughput Mode: Every tx and rx packet will generate an interrupt. |
617 | * CPU Mode: Interrupts are controlled by a timer. | 624 | * CPU Mode: Interrupts are controlled by a timer. |
618 | */ | 625 | */ |
@@ -860,7 +867,7 @@ static int phy_init(struct net_device *dev) | |||
860 | 867 | ||
861 | /* set advertise register */ | 868 | /* set advertise register */ |
862 | reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); | 869 | reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
863 | reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|0x800|0x400); | 870 | reg |= (ADVERTISE_10HALF|ADVERTISE_10FULL|ADVERTISE_100HALF|ADVERTISE_100FULL|ADVERTISE_PAUSE_ASYM|ADVERTISE_PAUSE_CAP); |
864 | if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { | 871 | if (mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg)) { |
865 | printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); | 872 | printk(KERN_INFO "%s: phy write to advertise failed.\n", pci_name(np->pci_dev)); |
866 | return PHY_ERROR; | 873 | return PHY_ERROR; |
@@ -873,14 +880,14 @@ static int phy_init(struct net_device *dev) | |||
873 | mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); | 880 | mii_status = mii_rw(dev, np->phyaddr, MII_BMSR, MII_READ); |
874 | if (mii_status & PHY_GIGABIT) { | 881 | if (mii_status & PHY_GIGABIT) { |
875 | np->gigabit = PHY_GIGABIT; | 882 | np->gigabit = PHY_GIGABIT; |
876 | mii_control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); | 883 | mii_control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); |
877 | mii_control_1000 &= ~ADVERTISE_1000HALF; | 884 | mii_control_1000 &= ~ADVERTISE_1000HALF; |
878 | if (phyinterface & PHY_RGMII) | 885 | if (phyinterface & PHY_RGMII) |
879 | mii_control_1000 |= ADVERTISE_1000FULL; | 886 | mii_control_1000 |= ADVERTISE_1000FULL; |
880 | else | 887 | else |
881 | mii_control_1000 &= ~ADVERTISE_1000FULL; | 888 | mii_control_1000 &= ~ADVERTISE_1000FULL; |
882 | 889 | ||
883 | if (mii_rw(dev, np->phyaddr, MII_1000BT_CR, mii_control_1000)) { | 890 | if (mii_rw(dev, np->phyaddr, MII_CTRL1000, mii_control_1000)) { |
884 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); | 891 | printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev)); |
885 | return PHY_ERROR; | 892 | return PHY_ERROR; |
886 | } | 893 | } |
@@ -918,6 +925,8 @@ static int phy_init(struct net_device *dev) | |||
918 | return PHY_ERROR; | 925 | return PHY_ERROR; |
919 | } | 926 | } |
920 | } | 927 | } |
928 | /* some phys clear out pause advertisment on reset, set it back */ | ||
929 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg); | ||
921 | 930 | ||
922 | /* restart auto negotiation */ | 931 | /* restart auto negotiation */ |
923 | mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | 932 | mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
@@ -1110,7 +1119,7 @@ static void nv_do_rx_refill(unsigned long data) | |||
1110 | } | 1119 | } |
1111 | } | 1120 | } |
1112 | 1121 | ||
1113 | static void nv_init_rx(struct net_device *dev) | 1122 | static void nv_init_rx(struct net_device *dev) |
1114 | { | 1123 | { |
1115 | struct fe_priv *np = netdev_priv(dev); | 1124 | struct fe_priv *np = netdev_priv(dev); |
1116 | int i; | 1125 | int i; |
@@ -1174,7 +1183,7 @@ static void nv_drain_tx(struct net_device *dev) | |||
1174 | { | 1183 | { |
1175 | struct fe_priv *np = netdev_priv(dev); | 1184 | struct fe_priv *np = netdev_priv(dev); |
1176 | unsigned int i; | 1185 | unsigned int i; |
1177 | 1186 | ||
1178 | for (i = 0; i < TX_RING; i++) { | 1187 | for (i = 0; i < TX_RING; i++) { |
1179 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) | 1188 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
1180 | np->tx_ring.orig[i].FlagLen = 0; | 1189 | np->tx_ring.orig[i].FlagLen = 0; |
@@ -1320,7 +1329,7 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1320 | } else { | 1329 | } else { |
1321 | np->tx_ring.ex[start_nr].TxVlan = cpu_to_le32(tx_flags_vlan); | 1330 | np->tx_ring.ex[start_nr].TxVlan = cpu_to_le32(tx_flags_vlan); |
1322 | np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); | 1331 | np->tx_ring.ex[start_nr].FlagLen |= cpu_to_le32(tx_flags | tx_flags_extra); |
1323 | } | 1332 | } |
1324 | 1333 | ||
1325 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n", | 1334 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet %d (entries %d) queued for transmission. tx_flags_extra: %x\n", |
1326 | dev->name, np->next_tx, entries, tx_flags_extra); | 1335 | dev->name, np->next_tx, entries, tx_flags_extra); |
@@ -1395,7 +1404,7 @@ static void nv_tx_done(struct net_device *dev) | |||
1395 | } else { | 1404 | } else { |
1396 | np->stats.tx_packets++; | 1405 | np->stats.tx_packets++; |
1397 | np->stats.tx_bytes += skb->len; | 1406 | np->stats.tx_bytes += skb->len; |
1398 | } | 1407 | } |
1399 | } | 1408 | } |
1400 | } | 1409 | } |
1401 | nv_release_txskb(dev, i); | 1410 | nv_release_txskb(dev, i); |
@@ -1441,7 +1450,7 @@ static void nv_tx_timeout(struct net_device *dev) | |||
1441 | for (i=0;i<TX_RING;i+= 4) { | 1450 | for (i=0;i<TX_RING;i+= 4) { |
1442 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { | 1451 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
1443 | printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", | 1452 | printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", |
1444 | i, | 1453 | i, |
1445 | le32_to_cpu(np->tx_ring.orig[i].PacketBuffer), | 1454 | le32_to_cpu(np->tx_ring.orig[i].PacketBuffer), |
1446 | le32_to_cpu(np->tx_ring.orig[i].FlagLen), | 1455 | le32_to_cpu(np->tx_ring.orig[i].FlagLen), |
1447 | le32_to_cpu(np->tx_ring.orig[i+1].PacketBuffer), | 1456 | le32_to_cpu(np->tx_ring.orig[i+1].PacketBuffer), |
@@ -1452,7 +1461,7 @@ static void nv_tx_timeout(struct net_device *dev) | |||
1452 | le32_to_cpu(np->tx_ring.orig[i+3].FlagLen)); | 1461 | le32_to_cpu(np->tx_ring.orig[i+3].FlagLen)); |
1453 | } else { | 1462 | } else { |
1454 | printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", | 1463 | printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", |
1455 | i, | 1464 | i, |
1456 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferHigh), | 1465 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferHigh), |
1457 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferLow), | 1466 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferLow), |
1458 | le32_to_cpu(np->tx_ring.ex[i].FlagLen), | 1467 | le32_to_cpu(np->tx_ring.ex[i].FlagLen), |
@@ -1550,7 +1559,6 @@ static void nv_rx_process(struct net_device *dev) | |||
1550 | u32 Flags; | 1559 | u32 Flags; |
1551 | u32 vlanflags = 0; | 1560 | u32 vlanflags = 0; |
1552 | 1561 | ||
1553 | |||
1554 | for (;;) { | 1562 | for (;;) { |
1555 | struct sk_buff *skb; | 1563 | struct sk_buff *skb; |
1556 | int len; | 1564 | int len; |
@@ -1901,7 +1909,9 @@ static int nv_update_linkspeed(struct net_device *dev) | |||
1901 | { | 1909 | { |
1902 | struct fe_priv *np = netdev_priv(dev); | 1910 | struct fe_priv *np = netdev_priv(dev); |
1903 | u8 __iomem *base = get_hwbase(dev); | 1911 | u8 __iomem *base = get_hwbase(dev); |
1904 | int adv, lpa; | 1912 | int adv = 0; |
1913 | int lpa = 0; | ||
1914 | int adv_lpa, adv_pause, lpa_pause; | ||
1905 | int newls = np->linkspeed; | 1915 | int newls = np->linkspeed; |
1906 | int newdup = np->duplex; | 1916 | int newdup = np->duplex; |
1907 | int mii_status; | 1917 | int mii_status; |
@@ -1954,8 +1964,8 @@ static int nv_update_linkspeed(struct net_device *dev) | |||
1954 | 1964 | ||
1955 | retval = 1; | 1965 | retval = 1; |
1956 | if (np->gigabit == PHY_GIGABIT) { | 1966 | if (np->gigabit == PHY_GIGABIT) { |
1957 | control_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); | 1967 | control_1000 = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); |
1958 | status_1000 = mii_rw(dev, np->phyaddr, MII_1000BT_SR, MII_READ); | 1968 | status_1000 = mii_rw(dev, np->phyaddr, MII_STAT1000, MII_READ); |
1959 | 1969 | ||
1960 | if ((control_1000 & ADVERTISE_1000FULL) && | 1970 | if ((control_1000 & ADVERTISE_1000FULL) && |
1961 | (status_1000 & LPA_1000FULL)) { | 1971 | (status_1000 & LPA_1000FULL)) { |
@@ -1973,21 +1983,21 @@ static int nv_update_linkspeed(struct net_device *dev) | |||
1973 | dev->name, adv, lpa); | 1983 | dev->name, adv, lpa); |
1974 | 1984 | ||
1975 | /* FIXME: handle parallel detection properly */ | 1985 | /* FIXME: handle parallel detection properly */ |
1976 | lpa = lpa & adv; | 1986 | adv_lpa = lpa & adv; |
1977 | if (lpa & LPA_100FULL) { | 1987 | if (adv_lpa & LPA_100FULL) { |
1978 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; | 1988 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; |
1979 | newdup = 1; | 1989 | newdup = 1; |
1980 | } else if (lpa & LPA_100HALF) { | 1990 | } else if (adv_lpa & LPA_100HALF) { |
1981 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; | 1991 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_100; |
1982 | newdup = 0; | 1992 | newdup = 0; |
1983 | } else if (lpa & LPA_10FULL) { | 1993 | } else if (adv_lpa & LPA_10FULL) { |
1984 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; | 1994 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
1985 | newdup = 1; | 1995 | newdup = 1; |
1986 | } else if (lpa & LPA_10HALF) { | 1996 | } else if (adv_lpa & LPA_10HALF) { |
1987 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; | 1997 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
1988 | newdup = 0; | 1998 | newdup = 0; |
1989 | } else { | 1999 | } else { |
1990 | dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, lpa); | 2000 | dprintk(KERN_DEBUG "%s: bad ability %04x - falling back to 10HD.\n", dev->name, adv_lpa); |
1991 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; | 2001 | newls = NVREG_LINKSPEED_FORCE|NVREG_LINKSPEED_10; |
1992 | newdup = 0; | 2002 | newdup = 0; |
1993 | } | 2003 | } |
@@ -2030,6 +2040,56 @@ set_speed: | |||
2030 | writel(np->linkspeed, base + NvRegLinkSpeed); | 2040 | writel(np->linkspeed, base + NvRegLinkSpeed); |
2031 | pci_push(base); | 2041 | pci_push(base); |
2032 | 2042 | ||
2043 | /* setup pause frame based on advertisement and link partner */ | ||
2044 | np->pause_flags &= ~(NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE); | ||
2045 | |||
2046 | if (np->duplex != 0) { | ||
2047 | adv_pause = adv & (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM); | ||
2048 | lpa_pause = lpa & (LPA_PAUSE_CAP| LPA_PAUSE_ASYM); | ||
2049 | |||
2050 | switch (adv_pause) { | ||
2051 | case (ADVERTISE_PAUSE_CAP): | ||
2052 | if (lpa_pause & LPA_PAUSE_CAP) { | ||
2053 | np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE; | ||
2054 | } | ||
2055 | break; | ||
2056 | case (ADVERTISE_PAUSE_ASYM): | ||
2057 | if (lpa_pause == (LPA_PAUSE_CAP| LPA_PAUSE_ASYM)) | ||
2058 | { | ||
2059 | np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE; | ||
2060 | } | ||
2061 | break; | ||
2062 | case (ADVERTISE_PAUSE_CAP| ADVERTISE_PAUSE_ASYM): | ||
2063 | if (lpa_pause & LPA_PAUSE_CAP) | ||
2064 | { | ||
2065 | np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE | NV_PAUSEFRAME_RX_ENABLE; | ||
2066 | } | ||
2067 | if (lpa_pause == LPA_PAUSE_ASYM) | ||
2068 | { | ||
2069 | np->pause_flags |= NV_PAUSEFRAME_RX_ENABLE; | ||
2070 | } | ||
2071 | break; | ||
2072 | } | ||
2073 | } | ||
2074 | |||
2075 | if (np->pause_flags & NV_PAUSEFRAME_RX_CAPABLE) { | ||
2076 | u32 pff = readl(base + NvRegPacketFilterFlags) & ~NVREG_PFF_PAUSE_RX; | ||
2077 | if (np->pause_flags & NV_PAUSEFRAME_RX_ENABLE) | ||
2078 | writel(pff|NVREG_PFF_PAUSE_RX, base + NvRegPacketFilterFlags); | ||
2079 | else | ||
2080 | writel(pff, base + NvRegPacketFilterFlags); | ||
2081 | } | ||
2082 | if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) { | ||
2083 | u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX; | ||
2084 | if (np->pause_flags & NV_PAUSEFRAME_TX_ENABLE) { | ||
2085 | writel(NVREG_TX_PAUSEFRAME_ENABLE, base + NvRegTxPauseFrame); | ||
2086 | writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1); | ||
2087 | } else { | ||
2088 | writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); | ||
2089 | writel(regmisc, base + NvRegMisc1); | ||
2090 | } | ||
2091 | } | ||
2092 | |||
2033 | return retval; | 2093 | return retval; |
2034 | } | 2094 | } |
2035 | 2095 | ||
@@ -2090,7 +2150,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) | |||
2090 | spin_lock(&np->lock); | 2150 | spin_lock(&np->lock); |
2091 | nv_tx_done(dev); | 2151 | nv_tx_done(dev); |
2092 | spin_unlock(&np->lock); | 2152 | spin_unlock(&np->lock); |
2093 | 2153 | ||
2094 | nv_rx_process(dev); | 2154 | nv_rx_process(dev); |
2095 | if (nv_alloc_rx(dev)) { | 2155 | if (nv_alloc_rx(dev)) { |
2096 | spin_lock(&np->lock); | 2156 | spin_lock(&np->lock); |
@@ -2098,7 +2158,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) | |||
2098 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | 2158 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
2099 | spin_unlock(&np->lock); | 2159 | spin_unlock(&np->lock); |
2100 | } | 2160 | } |
2101 | 2161 | ||
2102 | if (events & NVREG_IRQ_LINK) { | 2162 | if (events & NVREG_IRQ_LINK) { |
2103 | spin_lock(&np->lock); | 2163 | spin_lock(&np->lock); |
2104 | nv_link_irq(dev); | 2164 | nv_link_irq(dev); |
@@ -2163,7 +2223,7 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data, struct pt_regs *regs) | |||
2163 | spin_lock_irq(&np->lock); | 2223 | spin_lock_irq(&np->lock); |
2164 | nv_tx_done(dev); | 2224 | nv_tx_done(dev); |
2165 | spin_unlock_irq(&np->lock); | 2225 | spin_unlock_irq(&np->lock); |
2166 | 2226 | ||
2167 | if (events & (NVREG_IRQ_TX_ERR)) { | 2227 | if (events & (NVREG_IRQ_TX_ERR)) { |
2168 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", | 2228 | dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n", |
2169 | dev->name, events); | 2229 | dev->name, events); |
@@ -2206,7 +2266,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) | |||
2206 | dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); | 2266 | dprintk(KERN_DEBUG "%s: rx irq: %08x\n", dev->name, events); |
2207 | if (!(events & np->irqmask)) | 2267 | if (!(events & np->irqmask)) |
2208 | break; | 2268 | break; |
2209 | 2269 | ||
2210 | nv_rx_process(dev); | 2270 | nv_rx_process(dev); |
2211 | if (nv_alloc_rx(dev)) { | 2271 | if (nv_alloc_rx(dev)) { |
2212 | spin_lock_irq(&np->lock); | 2272 | spin_lock_irq(&np->lock); |
@@ -2214,7 +2274,7 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data, struct pt_regs *regs) | |||
2214 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | 2274 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); |
2215 | spin_unlock_irq(&np->lock); | 2275 | spin_unlock_irq(&np->lock); |
2216 | } | 2276 | } |
2217 | 2277 | ||
2218 | if (i > max_interrupt_work) { | 2278 | if (i > max_interrupt_work) { |
2219 | spin_lock_irq(&np->lock); | 2279 | spin_lock_irq(&np->lock); |
2220 | /* disable interrupts on the nic */ | 2280 | /* disable interrupts on the nic */ |
@@ -2253,7 +2313,7 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data, struct pt_regs *regs) | |||
2253 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); | 2313 | dprintk(KERN_DEBUG "%s: irq: %08x\n", dev->name, events); |
2254 | if (!(events & np->irqmask)) | 2314 | if (!(events & np->irqmask)) |
2255 | break; | 2315 | break; |
2256 | 2316 | ||
2257 | if (events & NVREG_IRQ_LINK) { | 2317 | if (events & NVREG_IRQ_LINK) { |
2258 | spin_lock_irq(&np->lock); | 2318 | spin_lock_irq(&np->lock); |
2259 | nv_link_irq(dev); | 2319 | nv_link_irq(dev); |
@@ -2326,7 +2386,7 @@ static void nv_do_nic_poll(unsigned long data) | |||
2326 | np->nic_poll_irq = 0; | 2386 | np->nic_poll_irq = 0; |
2327 | 2387 | ||
2328 | /* FIXME: Do we need synchronize_irq(dev->irq) here? */ | 2388 | /* FIXME: Do we need synchronize_irq(dev->irq) here? */ |
2329 | 2389 | ||
2330 | writel(mask, base + NvRegIrqMask); | 2390 | writel(mask, base + NvRegIrqMask); |
2331 | pci_push(base); | 2391 | pci_push(base); |
2332 | 2392 | ||
@@ -2441,7 +2501,7 @@ static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
2441 | if (adv & ADVERTISE_100FULL) | 2501 | if (adv & ADVERTISE_100FULL) |
2442 | ecmd->advertising |= ADVERTISED_100baseT_Full; | 2502 | ecmd->advertising |= ADVERTISED_100baseT_Full; |
2443 | if (np->autoneg && np->gigabit == PHY_GIGABIT) { | 2503 | if (np->autoneg && np->gigabit == PHY_GIGABIT) { |
2444 | adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); | 2504 | adv = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); |
2445 | if (adv & ADVERTISE_1000FULL) | 2505 | if (adv & ADVERTISE_1000FULL) |
2446 | ecmd->advertising |= ADVERTISED_1000baseT_Full; | 2506 | ecmd->advertising |= ADVERTISED_1000baseT_Full; |
2447 | } | 2507 | } |
@@ -2505,23 +2565,23 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
2505 | 2565 | ||
2506 | /* advertise only what has been requested */ | 2566 | /* advertise only what has been requested */ |
2507 | adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); | 2567 | adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
2508 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); | 2568 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); |
2509 | if (ecmd->advertising & ADVERTISED_10baseT_Half) | 2569 | if (ecmd->advertising & ADVERTISED_10baseT_Half) |
2510 | adv |= ADVERTISE_10HALF; | 2570 | adv |= ADVERTISE_10HALF; |
2511 | if (ecmd->advertising & ADVERTISED_10baseT_Full) | 2571 | if (ecmd->advertising & ADVERTISED_10baseT_Full) |
2512 | adv |= ADVERTISE_10FULL; | 2572 | adv |= ADVERTISE_10FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
2513 | if (ecmd->advertising & ADVERTISED_100baseT_Half) | 2573 | if (ecmd->advertising & ADVERTISED_100baseT_Half) |
2514 | adv |= ADVERTISE_100HALF; | 2574 | adv |= ADVERTISE_100HALF; |
2515 | if (ecmd->advertising & ADVERTISED_100baseT_Full) | 2575 | if (ecmd->advertising & ADVERTISED_100baseT_Full) |
2516 | adv |= ADVERTISE_100FULL; | 2576 | adv |= ADVERTISE_100FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
2517 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); | 2577 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); |
2518 | 2578 | ||
2519 | if (np->gigabit == PHY_GIGABIT) { | 2579 | if (np->gigabit == PHY_GIGABIT) { |
2520 | adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); | 2580 | adv = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); |
2521 | adv &= ~ADVERTISE_1000FULL; | 2581 | adv &= ~ADVERTISE_1000FULL; |
2522 | if (ecmd->advertising & ADVERTISED_1000baseT_Full) | 2582 | if (ecmd->advertising & ADVERTISED_1000baseT_Full) |
2523 | adv |= ADVERTISE_1000FULL; | 2583 | adv |= ADVERTISE_1000FULL; |
2524 | mii_rw(dev, np->phyaddr, MII_1000BT_CR, adv); | 2584 | mii_rw(dev, np->phyaddr, MII_CTRL1000, adv); |
2525 | } | 2585 | } |
2526 | 2586 | ||
2527 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | 2587 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
@@ -2534,22 +2594,22 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
2534 | np->autoneg = 0; | 2594 | np->autoneg = 0; |
2535 | 2595 | ||
2536 | adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); | 2596 | adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ); |
2537 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4); | 2597 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); |
2538 | if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF) | 2598 | if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF) |
2539 | adv |= ADVERTISE_10HALF; | 2599 | adv |= ADVERTISE_10HALF; |
2540 | if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL) | 2600 | if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL) |
2541 | adv |= ADVERTISE_10FULL; | 2601 | adv |= ADVERTISE_10FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
2542 | if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF) | 2602 | if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF) |
2543 | adv |= ADVERTISE_100HALF; | 2603 | adv |= ADVERTISE_100HALF; |
2544 | if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) | 2604 | if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL) |
2545 | adv |= ADVERTISE_100FULL; | 2605 | adv |= ADVERTISE_100FULL | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; |
2546 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); | 2606 | mii_rw(dev, np->phyaddr, MII_ADVERTISE, adv); |
2547 | np->fixed_mode = adv; | 2607 | np->fixed_mode = adv; |
2548 | 2608 | ||
2549 | if (np->gigabit == PHY_GIGABIT) { | 2609 | if (np->gigabit == PHY_GIGABIT) { |
2550 | adv = mii_rw(dev, np->phyaddr, MII_1000BT_CR, MII_READ); | 2610 | adv = mii_rw(dev, np->phyaddr, MII_CTRL1000, MII_READ); |
2551 | adv &= ~ADVERTISE_1000FULL; | 2611 | adv &= ~ADVERTISE_1000FULL; |
2552 | mii_rw(dev, np->phyaddr, MII_1000BT_CR, adv); | 2612 | mii_rw(dev, np->phyaddr, MII_CTRL1000, adv); |
2553 | } | 2613 | } |
2554 | 2614 | ||
2555 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | 2615 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); |
@@ -2829,6 +2889,9 @@ static int nv_open(struct net_device *dev) | |||
2829 | 2889 | ||
2830 | writel(0, base + NvRegAdapterControl); | 2890 | writel(0, base + NvRegAdapterControl); |
2831 | 2891 | ||
2892 | if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) | ||
2893 | writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); | ||
2894 | |||
2832 | /* 2) initialize descriptor rings */ | 2895 | /* 2) initialize descriptor rings */ |
2833 | set_bufsize(dev); | 2896 | set_bufsize(dev); |
2834 | oom = nv_init_ring(dev); | 2897 | oom = nv_init_ring(dev); |
@@ -3114,6 +3177,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
3114 | np->msi_flags |= NV_MSI_X_CAPABLE; | 3177 | np->msi_flags |= NV_MSI_X_CAPABLE; |
3115 | } | 3178 | } |
3116 | 3179 | ||
3180 | np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE; | ||
3181 | if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) { | ||
3182 | np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE; | ||
3183 | } | ||
3184 | |||
3185 | |||
3117 | err = -ENOMEM; | 3186 | err = -ENOMEM; |
3118 | np->base = ioremap(addr, np->register_size); | 3187 | np->base = ioremap(addr, np->register_size); |
3119 | if (!np->base) | 3188 | if (!np->base) |
@@ -3260,7 +3329,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
3260 | pci_name(pci_dev)); | 3329 | pci_name(pci_dev)); |
3261 | goto out_freering; | 3330 | goto out_freering; |
3262 | } | 3331 | } |
3263 | 3332 | ||
3264 | /* reset it */ | 3333 | /* reset it */ |
3265 | phy_init(dev); | 3334 | phy_init(dev); |
3266 | 3335 | ||
@@ -3374,11 +3443,11 @@ static struct pci_device_id pci_tbl[] = { | |||
3374 | }, | 3443 | }, |
3375 | { /* MCP55 Ethernet Controller */ | 3444 | { /* MCP55 Ethernet Controller */ |
3376 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), | 3445 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), |
3377 | .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, | 3446 | .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, |
3378 | }, | 3447 | }, |
3379 | { /* MCP55 Ethernet Controller */ | 3448 | { /* MCP55 Ethernet Controller */ |
3380 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), | 3449 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), |
3381 | .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, | 3450 | .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, |
3382 | }, | 3451 | }, |
3383 | {0,}, | 3452 | {0,}, |
3384 | }; | 3453 | }; |