diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/forcedeth.c | 139 |
1 files changed, 104 insertions, 35 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 705e1229d89d..cee25fe7e19b 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 |
@@ -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 | /* |
@@ -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); |
@@ -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 | ||
@@ -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); |
@@ -2813,6 +2873,9 @@ static int nv_open(struct net_device *dev) | |||
2813 | 2873 | ||
2814 | writel(0, base + NvRegAdapterControl); | 2874 | writel(0, base + NvRegAdapterControl); |
2815 | 2875 | ||
2876 | if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) | ||
2877 | writel(NVREG_TX_PAUSEFRAME_DISABLE, base + NvRegTxPauseFrame); | ||
2878 | |||
2816 | /* 2) initialize descriptor rings */ | 2879 | /* 2) initialize descriptor rings */ |
2817 | set_bufsize(dev); | 2880 | set_bufsize(dev); |
2818 | oom = nv_init_ring(dev); | 2881 | oom = nv_init_ring(dev); |
@@ -3098,6 +3161,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
3098 | np->msi_flags |= NV_MSI_X_CAPABLE; | 3161 | np->msi_flags |= NV_MSI_X_CAPABLE; |
3099 | } | 3162 | } |
3100 | 3163 | ||
3164 | np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE; | ||
3165 | if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) { | ||
3166 | np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE; | ||
3167 | } | ||
3168 | |||
3169 | |||
3101 | err = -ENOMEM; | 3170 | err = -ENOMEM; |
3102 | np->base = ioremap(addr, np->register_size); | 3171 | np->base = ioremap(addr, np->register_size); |
3103 | if (!np->base) | 3172 | if (!np->base) |
@@ -3358,11 +3427,11 @@ static struct pci_device_id pci_tbl[] = { | |||
3358 | }, | 3427 | }, |
3359 | { /* MCP55 Ethernet Controller */ | 3428 | { /* MCP55 Ethernet Controller */ |
3360 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), | 3429 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), |
3361 | .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, | 3430 | .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, |
3362 | }, | 3431 | }, |
3363 | { /* MCP55 Ethernet Controller */ | 3432 | { /* MCP55 Ethernet Controller */ |
3364 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), | 3433 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), |
3365 | .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, | 3434 | .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, |
3366 | }, | 3435 | }, |
3367 | {0,}, | 3436 | {0,}, |
3368 | }; | 3437 | }; |