diff options
| author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:47:18 -0500 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-06 13:47:18 -0500 | 
| commit | 8755e568250ecd3149ecd3495d8070f3a5384f73 (patch) | |
| tree | 26e76b657020cd864b3e6fbfcee9ca86a96059c2 /drivers/net/forcedeth.c | |
| parent | e33f6635da037ed4d2634ee6bdf5c4d601946c18 (diff) | |
| parent | 655d2ce073f5927194dbc28d2bd3c062a4a3caac (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (35 commits)
  virtio net: fix oops on interface-up
  Fix PHY Lib support for gianfar and ucc_geth
  forcedeth: preserve registers
  forcedeth: phy status fix
  forcedeth: restart tx/rx
  ipvs: Make wrr "no available servers" error message rate-limited
  [PPPOL2TP]: Label unused warning when CONFIG_PROC_FS is not set.
  [NET_SCHED]: cls_flow: support classification based on VLAN tag
  [VLAN]: Constify skb argument to vlan_get_tag()
  [NET_SCHED]: cls_flow: fix key mask validity check
  [NET_SCHED]: em_meta: fix compile warning
  b43: Fix DMA for 30/32-bit DMA engines
  b43: fix build with CONFIG_SSB_PCIHOST=n
  mac80211: Is not EXPERIMENTAL anymore
  iwl3945-base.c: fix off-by-one errors
  b43legacy: fix DMA slot resource leakage
  b43legacy: drop packets we are not able to encrypt
  b43legacy: fix suspend/resume
  b43legacy: fix PIO crash
  Generic HDLC - use random_ether_addr()
  ...
Diffstat (limited to 'drivers/net/forcedeth.c')
| -rw-r--r-- | drivers/net/forcedeth.c | 49 | 
1 files changed, 41 insertions, 8 deletions
| diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 36342230a6de..d4843d014bc9 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
| @@ -323,8 +323,8 @@ enum { | |||
| 323 | NvRegMIIStatus = 0x180, | 323 | NvRegMIIStatus = 0x180, | 
| 324 | #define NVREG_MIISTAT_ERROR 0x0001 | 324 | #define NVREG_MIISTAT_ERROR 0x0001 | 
| 325 | #define NVREG_MIISTAT_LINKCHANGE 0x0008 | 325 | #define NVREG_MIISTAT_LINKCHANGE 0x0008 | 
| 326 | #define NVREG_MIISTAT_MASK 0x000f | 326 | #define NVREG_MIISTAT_MASK_RW 0x0007 | 
| 327 | #define NVREG_MIISTAT_MASK2 0x000f | 327 | #define NVREG_MIISTAT_MASK_ALL 0x000f | 
| 328 | NvRegMIIMask = 0x184, | 328 | NvRegMIIMask = 0x184, | 
| 329 | #define NVREG_MII_LINKCHANGE 0x0008 | 329 | #define NVREG_MII_LINKCHANGE 0x0008 | 
| 330 | 330 | ||
| @@ -624,6 +624,9 @@ union ring_type { | |||
| 624 | #define NV_MSI_X_VECTOR_TX 0x1 | 624 | #define NV_MSI_X_VECTOR_TX 0x1 | 
| 625 | #define NV_MSI_X_VECTOR_OTHER 0x2 | 625 | #define NV_MSI_X_VECTOR_OTHER 0x2 | 
| 626 | 626 | ||
| 627 | #define NV_RESTART_TX 0x1 | ||
| 628 | #define NV_RESTART_RX 0x2 | ||
| 629 | |||
| 627 | /* statistics */ | 630 | /* statistics */ | 
| 628 | struct nv_ethtool_str { | 631 | struct nv_ethtool_str { | 
| 629 | char name[ETH_GSTRING_LEN]; | 632 | char name[ETH_GSTRING_LEN]; | 
| @@ -1061,7 +1064,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value) | |||
| 1061 | u32 reg; | 1064 | u32 reg; | 
| 1062 | int retval; | 1065 | int retval; | 
| 1063 | 1066 | ||
| 1064 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 1067 | writel(NVREG_MIISTAT_MASK_RW, base + NvRegMIIStatus); | 
| 1065 | 1068 | ||
| 1066 | reg = readl(base + NvRegMIIControl); | 1069 | reg = readl(base + NvRegMIIControl); | 
| 1067 | if (reg & NVREG_MIICTL_INUSE) { | 1070 | if (reg & NVREG_MIICTL_INUSE) { | 
| @@ -1432,16 +1435,30 @@ static void nv_mac_reset(struct net_device *dev) | |||
| 1432 | { | 1435 | { | 
| 1433 | struct fe_priv *np = netdev_priv(dev); | 1436 | struct fe_priv *np = netdev_priv(dev); | 
| 1434 | u8 __iomem *base = get_hwbase(dev); | 1437 | u8 __iomem *base = get_hwbase(dev); | 
| 1438 | u32 temp1, temp2, temp3; | ||
| 1435 | 1439 | ||
| 1436 | dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); | 1440 | dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); | 
| 1441 | |||
| 1437 | writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); | 1442 | writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); | 
| 1438 | pci_push(base); | 1443 | pci_push(base); | 
| 1444 | |||
| 1445 | /* save registers since they will be cleared on reset */ | ||
| 1446 | temp1 = readl(base + NvRegMacAddrA); | ||
| 1447 | temp2 = readl(base + NvRegMacAddrB); | ||
| 1448 | temp3 = readl(base + NvRegTransmitPoll); | ||
| 1449 | |||
| 1439 | writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); | 1450 | writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); | 
| 1440 | pci_push(base); | 1451 | pci_push(base); | 
| 1441 | udelay(NV_MAC_RESET_DELAY); | 1452 | udelay(NV_MAC_RESET_DELAY); | 
| 1442 | writel(0, base + NvRegMacReset); | 1453 | writel(0, base + NvRegMacReset); | 
| 1443 | pci_push(base); | 1454 | pci_push(base); | 
| 1444 | udelay(NV_MAC_RESET_DELAY); | 1455 | udelay(NV_MAC_RESET_DELAY); | 
| 1456 | |||
| 1457 | /* restore saved registers */ | ||
| 1458 | writel(temp1, base + NvRegMacAddrA); | ||
| 1459 | writel(temp2, base + NvRegMacAddrB); | ||
| 1460 | writel(temp3, base + NvRegTransmitPoll); | ||
| 1461 | |||
| 1445 | writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); | 1462 | writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); | 
| 1446 | pci_push(base); | 1463 | pci_push(base); | 
| 1447 | } | 1464 | } | 
| @@ -2767,6 +2784,7 @@ static int nv_update_linkspeed(struct net_device *dev) | |||
| 2767 | int mii_status; | 2784 | int mii_status; | 
| 2768 | int retval = 0; | 2785 | int retval = 0; | 
| 2769 | u32 control_1000, status_1000, phyreg, pause_flags, txreg; | 2786 | u32 control_1000, status_1000, phyreg, pause_flags, txreg; | 
| 2787 | u32 txrxFlags = 0; | ||
| 2770 | 2788 | ||
| 2771 | /* BMSR_LSTATUS is latched, read it twice: | 2789 | /* BMSR_LSTATUS is latched, read it twice: | 
| 2772 | * we want the current value. | 2790 | * we want the current value. | 
| @@ -2862,6 +2880,16 @@ set_speed: | |||
| 2862 | np->duplex = newdup; | 2880 | np->duplex = newdup; | 
| 2863 | np->linkspeed = newls; | 2881 | np->linkspeed = newls; | 
| 2864 | 2882 | ||
| 2883 | /* The transmitter and receiver must be restarted for safe update */ | ||
| 2884 | if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) { | ||
| 2885 | txrxFlags |= NV_RESTART_TX; | ||
| 2886 | nv_stop_tx(dev); | ||
| 2887 | } | ||
| 2888 | if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) { | ||
| 2889 | txrxFlags |= NV_RESTART_RX; | ||
| 2890 | nv_stop_rx(dev); | ||
| 2891 | } | ||
| 2892 | |||
| 2865 | if (np->gigabit == PHY_GIGABIT) { | 2893 | if (np->gigabit == PHY_GIGABIT) { | 
| 2866 | phyreg = readl(base + NvRegRandomSeed); | 2894 | phyreg = readl(base + NvRegRandomSeed); | 
| 2867 | phyreg &= ~(0x3FF00); | 2895 | phyreg &= ~(0x3FF00); | 
| @@ -2950,6 +2978,11 @@ set_speed: | |||
| 2950 | } | 2978 | } | 
| 2951 | nv_update_pause(dev, pause_flags); | 2979 | nv_update_pause(dev, pause_flags); | 
| 2952 | 2980 | ||
| 2981 | if (txrxFlags & NV_RESTART_TX) | ||
| 2982 | nv_start_tx(dev); | ||
| 2983 | if (txrxFlags & NV_RESTART_RX) | ||
| 2984 | nv_start_rx(dev); | ||
| 2985 | |||
| 2953 | return retval; | 2986 | return retval; | 
| 2954 | } | 2987 | } | 
| 2955 | 2988 | ||
| @@ -2976,7 +3009,7 @@ static void nv_link_irq(struct net_device *dev) | |||
| 2976 | u32 miistat; | 3009 | u32 miistat; | 
| 2977 | 3010 | ||
| 2978 | miistat = readl(base + NvRegMIIStatus); | 3011 | miistat = readl(base + NvRegMIIStatus); | 
| 2979 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 3012 | writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus); | 
| 2980 | dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat); | 3013 | dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat); | 
| 2981 | 3014 | ||
| 2982 | if (miistat & (NVREG_MIISTAT_LINKCHANGE)) | 3015 | if (miistat & (NVREG_MIISTAT_LINKCHANGE)) | 
| @@ -4851,7 +4884,7 @@ static int nv_open(struct net_device *dev) | |||
| 4851 | 4884 | ||
| 4852 | writel(0, base + NvRegMIIMask); | 4885 | writel(0, base + NvRegMIIMask); | 
| 4853 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 4886 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 
| 4854 | writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); | 4887 | writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); | 
| 4855 | 4888 | ||
| 4856 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); | 4889 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); | 
| 4857 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); | 4890 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); | 
| @@ -4889,7 +4922,7 @@ static int nv_open(struct net_device *dev) | |||
| 4889 | 4922 | ||
| 4890 | nv_disable_hw_interrupts(dev, np->irqmask); | 4923 | nv_disable_hw_interrupts(dev, np->irqmask); | 
| 4891 | pci_push(base); | 4924 | pci_push(base); | 
| 4892 | writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus); | 4925 | writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); | 
| 4893 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 4926 | writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus); | 
| 4894 | pci_push(base); | 4927 | pci_push(base); | 
| 4895 | 4928 | ||
| @@ -4912,7 +4945,7 @@ static int nv_open(struct net_device *dev) | |||
| 4912 | { | 4945 | { | 
| 4913 | u32 miistat; | 4946 | u32 miistat; | 
| 4914 | miistat = readl(base + NvRegMIIStatus); | 4947 | miistat = readl(base + NvRegMIIStatus); | 
| 4915 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 4948 | writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); | 
| 4916 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); | 4949 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); | 
| 4917 | } | 4950 | } | 
| 4918 | /* set linkspeed to invalid value, thus force nv_update_linkspeed | 4951 | /* set linkspeed to invalid value, thus force nv_update_linkspeed | 
| @@ -5280,7 +5313,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
| 5280 | phystate &= ~NVREG_ADAPTCTL_RUNNING; | 5313 | phystate &= ~NVREG_ADAPTCTL_RUNNING; | 
| 5281 | writel(phystate, base + NvRegAdapterControl); | 5314 | writel(phystate, base + NvRegAdapterControl); | 
| 5282 | } | 5315 | } | 
| 5283 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 5316 | writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus); | 
| 5284 | 5317 | ||
| 5285 | if (id->driver_data & DEV_HAS_MGMT_UNIT) { | 5318 | if (id->driver_data & DEV_HAS_MGMT_UNIT) { | 
| 5286 | /* management unit running on the mac? */ | 5319 | /* management unit running on the mac? */ | 
