aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/b44.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/b44.c')
-rw-r--r--drivers/net/b44.c77
1 files changed, 42 insertions, 35 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index c3267e4e1bb0..3d306681919e 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -2,6 +2,7 @@
2 * 2 *
3 * Copyright (C) 2002 David S. Miller (davem@redhat.com) 3 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
4 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi) 4 * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
5 * Copyright (C) 2006 Broadcom Corporation.
5 * 6 *
6 * Distribute under GPL. 7 * Distribute under GPL.
7 */ 8 */
@@ -28,8 +29,8 @@
28 29
29#define DRV_MODULE_NAME "b44" 30#define DRV_MODULE_NAME "b44"
30#define PFX DRV_MODULE_NAME ": " 31#define PFX DRV_MODULE_NAME ": "
31#define DRV_MODULE_VERSION "0.97" 32#define DRV_MODULE_VERSION "1.00"
32#define DRV_MODULE_RELDATE "Nov 30, 2005" 33#define DRV_MODULE_RELDATE "Apr 7, 2006"
33 34
34#define B44_DEF_MSG_ENABLE \ 35#define B44_DEF_MSG_ENABLE \
35 (NETIF_MSG_DRV | \ 36 (NETIF_MSG_DRV | \
@@ -136,7 +137,7 @@ static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
136 return readl(bp->regs + reg); 137 return readl(bp->regs + reg);
137} 138}
138 139
139static inline void bw32(const struct b44 *bp, 140static inline void bw32(const struct b44 *bp,
140 unsigned long reg, unsigned long val) 141 unsigned long reg, unsigned long val)
141{ 142{
142 writel(val, bp->regs + reg); 143 writel(val, bp->regs + reg);
@@ -286,13 +287,13 @@ static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
286 val |= ((u32) data[4]) << 8; 287 val |= ((u32) data[4]) << 8;
287 val |= ((u32) data[5]) << 0; 288 val |= ((u32) data[5]) << 0;
288 bw32(bp, B44_CAM_DATA_LO, val); 289 bw32(bp, B44_CAM_DATA_LO, val);
289 val = (CAM_DATA_HI_VALID | 290 val = (CAM_DATA_HI_VALID |
290 (((u32) data[0]) << 8) | 291 (((u32) data[0]) << 8) |
291 (((u32) data[1]) << 0)); 292 (((u32) data[1]) << 0));
292 bw32(bp, B44_CAM_DATA_HI, val); 293 bw32(bp, B44_CAM_DATA_HI, val);
293 bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE | 294 bw32(bp, B44_CAM_CTRL, (CAM_CTRL_WRITE |
294 (index << CAM_CTRL_INDEX_SHIFT))); 295 (index << CAM_CTRL_INDEX_SHIFT)));
295 b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1); 296 b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
296} 297}
297 298
298static inline void __b44_disable_ints(struct b44 *bp) 299static inline void __b44_disable_ints(struct b44 *bp)
@@ -410,25 +411,18 @@ static void __b44_set_flow_ctrl(struct b44 *bp, u32 pause_flags)
410 411
411static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) 412static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote)
412{ 413{
413 u32 pause_enab = bp->flags & (B44_FLAG_TX_PAUSE | 414 u32 pause_enab = 0;
414 B44_FLAG_RX_PAUSE);
415 415
416 if (local & ADVERTISE_PAUSE_CAP) { 416 /* The driver supports only rx pause by default because
417 if (local & ADVERTISE_PAUSE_ASYM) { 417 the b44 mac tx pause mechanism generates excessive
418 if (remote & LPA_PAUSE_CAP) 418 pause frames.
419 pause_enab |= (B44_FLAG_TX_PAUSE | 419 Use ethtool to turn on b44 tx pause if necessary.
420 B44_FLAG_RX_PAUSE); 420 */
421 else if (remote & LPA_PAUSE_ASYM) 421 if ((local & ADVERTISE_PAUSE_CAP) &&
422 pause_enab |= B44_FLAG_RX_PAUSE; 422 (local & ADVERTISE_PAUSE_ASYM)){
423 } else { 423 if ((remote & LPA_PAUSE_ASYM) &&
424 if (remote & LPA_PAUSE_CAP) 424 !(remote & LPA_PAUSE_CAP))
425 pause_enab |= (B44_FLAG_TX_PAUSE | 425 pause_enab |= B44_FLAG_RX_PAUSE;
426 B44_FLAG_RX_PAUSE);
427 }
428 } else if (local & ADVERTISE_PAUSE_ASYM) {
429 if ((remote & LPA_PAUSE_CAP) &&
430 (remote & LPA_PAUSE_ASYM))
431 pause_enab |= B44_FLAG_TX_PAUSE;
432 } 426 }
433 427
434 __b44_set_flow_ctrl(bp, pause_enab); 428 __b44_set_flow_ctrl(bp, pause_enab);
@@ -608,8 +602,7 @@ static void b44_tx(struct b44 *bp)
608 struct ring_info *rp = &bp->tx_buffers[cons]; 602 struct ring_info *rp = &bp->tx_buffers[cons];
609 struct sk_buff *skb = rp->skb; 603 struct sk_buff *skb = rp->skb;
610 604
611 if (unlikely(skb == NULL)) 605 BUG_ON(skb == NULL);
612 BUG();
613 606
614 pci_unmap_single(bp->pdev, 607 pci_unmap_single(bp->pdev,
615 pci_unmap_addr(rp, mapping), 608 pci_unmap_addr(rp, mapping),
@@ -1064,7 +1057,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu)
1064 spin_unlock_irq(&bp->lock); 1057 spin_unlock_irq(&bp->lock);
1065 1058
1066 b44_enable_ints(bp); 1059 b44_enable_ints(bp);
1067 1060
1068 return 0; 1061 return 0;
1069} 1062}
1070 1063
@@ -1339,6 +1332,9 @@ static int b44_set_mac_addr(struct net_device *dev, void *p)
1339 if (netif_running(dev)) 1332 if (netif_running(dev))
1340 return -EBUSY; 1333 return -EBUSY;
1341 1334
1335 if (!is_valid_ether_addr(addr->sa_data))
1336 return -EINVAL;
1337
1342 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 1338 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1343 1339
1344 spin_lock_irq(&bp->lock); 1340 spin_lock_irq(&bp->lock);
@@ -1379,7 +1375,7 @@ static void b44_init_hw(struct b44 *bp)
1379 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset); 1375 bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
1380 1376
1381 bw32(bp, B44_DMARX_PTR, bp->rx_pending); 1377 bw32(bp, B44_DMARX_PTR, bp->rx_pending);
1382 bp->rx_prod = bp->rx_pending; 1378 bp->rx_prod = bp->rx_pending;
1383 1379
1384 bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); 1380 bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
1385 1381
@@ -1551,9 +1547,9 @@ static void __b44_set_rx_mode(struct net_device *dev)
1551 val |= RXCONFIG_ALLMULTI; 1547 val |= RXCONFIG_ALLMULTI;
1552 else 1548 else
1553 i = __b44_load_mcast(bp, dev); 1549 i = __b44_load_mcast(bp, dev);
1554 1550
1555 for (; i < 64; i++) { 1551 for (; i < 64; i++) {
1556 __b44_cam_write(bp, zero, i); 1552 __b44_cam_write(bp, zero, i);
1557 } 1553 }
1558 bw32(bp, B44_RXCONFIG, val); 1554 bw32(bp, B44_RXCONFIG, val);
1559 val = br32(bp, B44_CAM_CTRL); 1555 val = br32(bp, B44_CAM_CTRL);
@@ -1735,7 +1731,7 @@ static int b44_set_ringparam(struct net_device *dev,
1735 spin_unlock_irq(&bp->lock); 1731 spin_unlock_irq(&bp->lock);
1736 1732
1737 b44_enable_ints(bp); 1733 b44_enable_ints(bp);
1738 1734
1739 return 0; 1735 return 0;
1740} 1736}
1741 1737
@@ -1780,7 +1776,7 @@ static int b44_set_pauseparam(struct net_device *dev,
1780 spin_unlock_irq(&bp->lock); 1776 spin_unlock_irq(&bp->lock);
1781 1777
1782 b44_enable_ints(bp); 1778 b44_enable_ints(bp);
1783 1779
1784 return 0; 1780 return 0;
1785} 1781}
1786 1782
@@ -1876,6 +1872,12 @@ static int __devinit b44_get_invariants(struct b44 *bp)
1876 bp->dev->dev_addr[3] = eeprom[80]; 1872 bp->dev->dev_addr[3] = eeprom[80];
1877 bp->dev->dev_addr[4] = eeprom[83]; 1873 bp->dev->dev_addr[4] = eeprom[83];
1878 bp->dev->dev_addr[5] = eeprom[82]; 1874 bp->dev->dev_addr[5] = eeprom[82];
1875
1876 if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
1877 printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
1878 return -EINVAL;
1879 }
1880
1879 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len); 1881 memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
1880 1882
1881 bp->phy_addr = eeprom[90] & 0x1f; 1883 bp->phy_addr = eeprom[90] & 0x1f;
@@ -1890,7 +1892,7 @@ static int __devinit b44_get_invariants(struct b44 *bp)
1890 bp->core_unit = ssb_core_unit(bp); 1892 bp->core_unit = ssb_core_unit(bp);
1891 bp->dma_offset = SB_PCI_DMA; 1893 bp->dma_offset = SB_PCI_DMA;
1892 1894
1893 /* XXX - really required? 1895 /* XXX - really required?
1894 bp->flags |= B44_FLAG_BUGGY_TXPTR; 1896 bp->flags |= B44_FLAG_BUGGY_TXPTR;
1895 */ 1897 */
1896out: 1898out:
@@ -1938,7 +1940,7 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
1938 "aborting.\n"); 1940 "aborting.\n");
1939 goto err_out_free_res; 1941 goto err_out_free_res;
1940 } 1942 }
1941 1943
1942 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); 1944 err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
1943 if (err) { 1945 if (err) {
1944 printk(KERN_ERR PFX "No usable DMA configuration, " 1946 printk(KERN_ERR PFX "No usable DMA configuration, "
@@ -2033,6 +2035,11 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
2033 2035
2034 pci_save_state(bp->pdev); 2036 pci_save_state(bp->pdev);
2035 2037
2038 /* Chip reset provides power to the b44 MAC & PCI cores, which
2039 * is necessary for MAC register access.
2040 */
2041 b44_chip_reset(bp);
2042
2036 printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name); 2043 printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
2037 for (i = 0; i < 6; i++) 2044 for (i = 0; i < 6; i++)
2038 printk("%2.2x%c", dev->dev_addr[i], 2045 printk("%2.2x%c", dev->dev_addr[i],
@@ -2078,10 +2085,10 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
2078 2085
2079 del_timer_sync(&bp->timer); 2086 del_timer_sync(&bp->timer);
2080 2087
2081 spin_lock_irq(&bp->lock); 2088 spin_lock_irq(&bp->lock);
2082 2089
2083 b44_halt(bp); 2090 b44_halt(bp);
2084 netif_carrier_off(bp->dev); 2091 netif_carrier_off(bp->dev);
2085 netif_device_detach(bp->dev); 2092 netif_device_detach(bp->dev);
2086 b44_free_rings(bp); 2093 b44_free_rings(bp);
2087 2094