diff options
-rw-r--r-- | drivers/net/b44.c | 156 | ||||
-rw-r--r-- | drivers/net/b44.h | 74 |
2 files changed, 148 insertions, 82 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 0ee3e27969c6..ecc2e32c38c1 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -102,14 +102,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); | |||
102 | static void b44_halt(struct b44 *); | 102 | static void b44_halt(struct b44 *); |
103 | static void b44_init_rings(struct b44 *); | 103 | static void b44_init_rings(struct b44 *); |
104 | static void b44_init_hw(struct b44 *); | 104 | static void b44_init_hw(struct b44 *); |
105 | static int b44_poll(struct net_device *dev, int *budget); | ||
106 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
107 | static void b44_poll_controller(struct net_device *dev); | ||
108 | #endif | ||
109 | 105 | ||
110 | static int dma_desc_align_mask; | 106 | static int dma_desc_align_mask; |
111 | static int dma_desc_sync_size; | 107 | static int dma_desc_sync_size; |
112 | 108 | ||
109 | static const char b44_gstrings[][ETH_GSTRING_LEN] = { | ||
110 | #define _B44(x...) # x, | ||
111 | B44_STAT_REG_DECLARE | ||
112 | #undef _B44 | ||
113 | }; | ||
114 | |||
113 | static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, | 115 | static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, |
114 | dma_addr_t dma_base, | 116 | dma_addr_t dma_base, |
115 | unsigned long offset, | 117 | unsigned long offset, |
@@ -502,7 +504,10 @@ static void b44_stats_update(struct b44 *bp) | |||
502 | for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { | 504 | for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { |
503 | *val++ += br32(bp, reg); | 505 | *val++ += br32(bp, reg); |
504 | } | 506 | } |
505 | val = &bp->hw_stats.rx_good_octets; | 507 | |
508 | /* Pad */ | ||
509 | reg += 8*4UL; | ||
510 | |||
506 | for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { | 511 | for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { |
507 | *val++ += br32(bp, reg); | 512 | *val++ += br32(bp, reg); |
508 | } | 513 | } |
@@ -653,7 +658,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
653 | 658 | ||
654 | /* Hardware bug work-around, the chip is unable to do PCI DMA | 659 | /* Hardware bug work-around, the chip is unable to do PCI DMA |
655 | to/from anything above 1GB :-( */ | 660 | to/from anything above 1GB :-( */ |
656 | if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { | 661 | if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { |
657 | /* Sigh... */ | 662 | /* Sigh... */ |
658 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); | 663 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); |
659 | dev_kfree_skb_any(skb); | 664 | dev_kfree_skb_any(skb); |
@@ -663,7 +668,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
663 | mapping = pci_map_single(bp->pdev, skb->data, | 668 | mapping = pci_map_single(bp->pdev, skb->data, |
664 | RX_PKT_BUF_SZ, | 669 | RX_PKT_BUF_SZ, |
665 | PCI_DMA_FROMDEVICE); | 670 | PCI_DMA_FROMDEVICE); |
666 | if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { | 671 | if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { |
667 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); | 672 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); |
668 | dev_kfree_skb_any(skb); | 673 | dev_kfree_skb_any(skb); |
669 | return -ENOMEM; | 674 | return -ENOMEM; |
@@ -890,11 +895,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
890 | { | 895 | { |
891 | struct net_device *dev = dev_id; | 896 | struct net_device *dev = dev_id; |
892 | struct b44 *bp = netdev_priv(dev); | 897 | struct b44 *bp = netdev_priv(dev); |
893 | unsigned long flags; | ||
894 | u32 istat, imask; | 898 | u32 istat, imask; |
895 | int handled = 0; | 899 | int handled = 0; |
896 | 900 | ||
897 | spin_lock_irqsave(&bp->lock, flags); | 901 | spin_lock(&bp->lock); |
898 | 902 | ||
899 | istat = br32(bp, B44_ISTAT); | 903 | istat = br32(bp, B44_ISTAT); |
900 | imask = br32(bp, B44_IMASK); | 904 | imask = br32(bp, B44_IMASK); |
@@ -920,7 +924,7 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
920 | bw32(bp, B44_ISTAT, istat); | 924 | bw32(bp, B44_ISTAT, istat); |
921 | br32(bp, B44_ISTAT); | 925 | br32(bp, B44_ISTAT); |
922 | } | 926 | } |
923 | spin_unlock_irqrestore(&bp->lock, flags); | 927 | spin_unlock(&bp->lock); |
924 | return IRQ_RETVAL(handled); | 928 | return IRQ_RETVAL(handled); |
925 | } | 929 | } |
926 | 930 | ||
@@ -948,6 +952,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
948 | { | 952 | { |
949 | struct b44 *bp = netdev_priv(dev); | 953 | struct b44 *bp = netdev_priv(dev); |
950 | struct sk_buff *bounce_skb; | 954 | struct sk_buff *bounce_skb; |
955 | int rc = NETDEV_TX_OK; | ||
951 | dma_addr_t mapping; | 956 | dma_addr_t mapping; |
952 | u32 len, entry, ctrl; | 957 | u32 len, entry, ctrl; |
953 | 958 | ||
@@ -957,29 +962,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
957 | /* This is a hard error, log it. */ | 962 | /* This is a hard error, log it. */ |
958 | if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { | 963 | if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { |
959 | netif_stop_queue(dev); | 964 | netif_stop_queue(dev); |
960 | spin_unlock_irq(&bp->lock); | ||
961 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", | 965 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", |
962 | dev->name); | 966 | dev->name); |
963 | return 1; | 967 | goto err_out; |
964 | } | 968 | } |
965 | 969 | ||
966 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); | 970 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); |
967 | if(mapping+len > B44_DMA_MASK) { | 971 | if (mapping + len > B44_DMA_MASK) { |
968 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ | 972 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ |
969 | pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); | 973 | pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); |
970 | 974 | ||
971 | bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, | 975 | bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, |
972 | GFP_ATOMIC|GFP_DMA); | 976 | GFP_ATOMIC|GFP_DMA); |
973 | if (!bounce_skb) | 977 | if (!bounce_skb) |
974 | return NETDEV_TX_BUSY; | 978 | goto err_out; |
975 | 979 | ||
976 | mapping = pci_map_single(bp->pdev, bounce_skb->data, | 980 | mapping = pci_map_single(bp->pdev, bounce_skb->data, |
977 | len, PCI_DMA_TODEVICE); | 981 | len, PCI_DMA_TODEVICE); |
978 | if(mapping+len > B44_DMA_MASK) { | 982 | if (mapping + len > B44_DMA_MASK) { |
979 | pci_unmap_single(bp->pdev, mapping, | 983 | pci_unmap_single(bp->pdev, mapping, |
980 | len, PCI_DMA_TODEVICE); | 984 | len, PCI_DMA_TODEVICE); |
981 | dev_kfree_skb_any(bounce_skb); | 985 | dev_kfree_skb_any(bounce_skb); |
982 | return NETDEV_TX_BUSY; | 986 | goto err_out; |
983 | } | 987 | } |
984 | 988 | ||
985 | memcpy(skb_put(bounce_skb, len), skb->data, skb->len); | 989 | memcpy(skb_put(bounce_skb, len), skb->data, skb->len); |
@@ -1019,11 +1023,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1019 | if (TX_BUFFS_AVAIL(bp) < 1) | 1023 | if (TX_BUFFS_AVAIL(bp) < 1) |
1020 | netif_stop_queue(dev); | 1024 | netif_stop_queue(dev); |
1021 | 1025 | ||
1026 | dev->trans_start = jiffies; | ||
1027 | |||
1028 | out_unlock: | ||
1022 | spin_unlock_irq(&bp->lock); | 1029 | spin_unlock_irq(&bp->lock); |
1023 | 1030 | ||
1024 | dev->trans_start = jiffies; | 1031 | return rc; |
1025 | 1032 | ||
1026 | return 0; | 1033 | err_out: |
1034 | rc = NETDEV_TX_BUSY; | ||
1035 | goto out_unlock; | ||
1027 | } | 1036 | } |
1028 | 1037 | ||
1029 | static int b44_change_mtu(struct net_device *dev, int new_mtu) | 1038 | static int b44_change_mtu(struct net_device *dev, int new_mtu) |
@@ -1097,8 +1106,7 @@ static void b44_free_rings(struct b44 *bp) | |||
1097 | * | 1106 | * |
1098 | * The chip has been shut down and the driver detached from | 1107 | * The chip has been shut down and the driver detached from |
1099 | * the networking, so no interrupts or new tx packets will | 1108 | * the networking, so no interrupts or new tx packets will |
1100 | * end up in the driver. bp->lock is not held and we are not | 1109 | * end up in the driver. |
1101 | * in an interrupt context and thus may sleep. | ||
1102 | */ | 1110 | */ |
1103 | static void b44_init_rings(struct b44 *bp) | 1111 | static void b44_init_rings(struct b44 *bp) |
1104 | { | 1112 | { |
@@ -1170,16 +1178,14 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1170 | int size; | 1178 | int size; |
1171 | 1179 | ||
1172 | size = B44_RX_RING_SIZE * sizeof(struct ring_info); | 1180 | size = B44_RX_RING_SIZE * sizeof(struct ring_info); |
1173 | bp->rx_buffers = kmalloc(size, GFP_KERNEL); | 1181 | bp->rx_buffers = kzalloc(size, GFP_KERNEL); |
1174 | if (!bp->rx_buffers) | 1182 | if (!bp->rx_buffers) |
1175 | goto out_err; | 1183 | goto out_err; |
1176 | memset(bp->rx_buffers, 0, size); | ||
1177 | 1184 | ||
1178 | size = B44_TX_RING_SIZE * sizeof(struct ring_info); | 1185 | size = B44_TX_RING_SIZE * sizeof(struct ring_info); |
1179 | bp->tx_buffers = kmalloc(size, GFP_KERNEL); | 1186 | bp->tx_buffers = kzalloc(size, GFP_KERNEL); |
1180 | if (!bp->tx_buffers) | 1187 | if (!bp->tx_buffers) |
1181 | goto out_err; | 1188 | goto out_err; |
1182 | memset(bp->tx_buffers, 0, size); | ||
1183 | 1189 | ||
1184 | size = DMA_TABLE_BYTES; | 1190 | size = DMA_TABLE_BYTES; |
1185 | bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); | 1191 | bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); |
@@ -1190,10 +1196,10 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1190 | struct dma_desc *rx_ring; | 1196 | struct dma_desc *rx_ring; |
1191 | dma_addr_t rx_ring_dma; | 1197 | dma_addr_t rx_ring_dma; |
1192 | 1198 | ||
1193 | if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) | 1199 | rx_ring = kzalloc(size, GFP_KERNEL); |
1200 | if (!rx_ring) | ||
1194 | goto out_err; | 1201 | goto out_err; |
1195 | 1202 | ||
1196 | memset(rx_ring, 0, size); | ||
1197 | rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, | 1203 | rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, |
1198 | DMA_TABLE_BYTES, | 1204 | DMA_TABLE_BYTES, |
1199 | DMA_BIDIRECTIONAL); | 1205 | DMA_BIDIRECTIONAL); |
@@ -1216,10 +1222,10 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1216 | struct dma_desc *tx_ring; | 1222 | struct dma_desc *tx_ring; |
1217 | dma_addr_t tx_ring_dma; | 1223 | dma_addr_t tx_ring_dma; |
1218 | 1224 | ||
1219 | if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) | 1225 | tx_ring = kzalloc(size, GFP_KERNEL); |
1226 | if (!tx_ring) | ||
1220 | goto out_err; | 1227 | goto out_err; |
1221 | 1228 | ||
1222 | memset(tx_ring, 0, size); | ||
1223 | tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, | 1229 | tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, |
1224 | DMA_TABLE_BYTES, | 1230 | DMA_TABLE_BYTES, |
1225 | DMA_TO_DEVICE); | 1231 | DMA_TO_DEVICE); |
@@ -1382,13 +1388,7 @@ static int b44_open(struct net_device *dev) | |||
1382 | 1388 | ||
1383 | err = b44_alloc_consistent(bp); | 1389 | err = b44_alloc_consistent(bp); |
1384 | if (err) | 1390 | if (err) |
1385 | return err; | 1391 | goto out; |
1386 | |||
1387 | err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); | ||
1388 | if (err) | ||
1389 | goto err_out_free; | ||
1390 | |||
1391 | spin_lock_irq(&bp->lock); | ||
1392 | 1392 | ||
1393 | b44_init_rings(bp); | 1393 | b44_init_rings(bp); |
1394 | b44_init_hw(bp); | 1394 | b44_init_hw(bp); |
@@ -1397,7 +1397,13 @@ static int b44_open(struct net_device *dev) | |||
1397 | netif_carrier_off(dev); | 1397 | netif_carrier_off(dev); |
1398 | b44_check_phy(bp); | 1398 | b44_check_phy(bp); |
1399 | 1399 | ||
1400 | spin_unlock_irq(&bp->lock); | 1400 | err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); |
1401 | if (unlikely(err < 0)) { | ||
1402 | b44_chip_reset(bp); | ||
1403 | b44_free_rings(bp); | ||
1404 | b44_free_consistent(bp); | ||
1405 | goto out; | ||
1406 | } | ||
1401 | 1407 | ||
1402 | init_timer(&bp->timer); | 1408 | init_timer(&bp->timer); |
1403 | bp->timer.expires = jiffies + HZ; | 1409 | bp->timer.expires = jiffies + HZ; |
@@ -1406,11 +1412,7 @@ static int b44_open(struct net_device *dev) | |||
1406 | add_timer(&bp->timer); | 1412 | add_timer(&bp->timer); |
1407 | 1413 | ||
1408 | b44_enable_ints(bp); | 1414 | b44_enable_ints(bp); |
1409 | 1415 | out: | |
1410 | return 0; | ||
1411 | |||
1412 | err_out_free: | ||
1413 | b44_free_consistent(bp); | ||
1414 | return err; | 1416 | return err; |
1415 | } | 1417 | } |
1416 | 1418 | ||
@@ -1525,8 +1527,6 @@ static void __b44_set_rx_mode(struct net_device *dev) | |||
1525 | { | 1527 | { |
1526 | struct b44 *bp = netdev_priv(dev); | 1528 | struct b44 *bp = netdev_priv(dev); |
1527 | u32 val; | 1529 | u32 val; |
1528 | int i=0; | ||
1529 | unsigned char zero[6] = {0,0,0,0,0,0}; | ||
1530 | 1530 | ||
1531 | val = br32(bp, B44_RXCONFIG); | 1531 | val = br32(bp, B44_RXCONFIG); |
1532 | val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); | 1532 | val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); |
@@ -1534,14 +1534,17 @@ static void __b44_set_rx_mode(struct net_device *dev) | |||
1534 | val |= RXCONFIG_PROMISC; | 1534 | val |= RXCONFIG_PROMISC; |
1535 | bw32(bp, B44_RXCONFIG, val); | 1535 | bw32(bp, B44_RXCONFIG, val); |
1536 | } else { | 1536 | } else { |
1537 | unsigned char zero[6] = {0, 0, 0, 0, 0, 0}; | ||
1538 | int i = 0; | ||
1539 | |||
1537 | __b44_set_mac_addr(bp); | 1540 | __b44_set_mac_addr(bp); |
1538 | 1541 | ||
1539 | if (dev->flags & IFF_ALLMULTI) | 1542 | if (dev->flags & IFF_ALLMULTI) |
1540 | val |= RXCONFIG_ALLMULTI; | 1543 | val |= RXCONFIG_ALLMULTI; |
1541 | else | 1544 | else |
1542 | i=__b44_load_mcast(bp, dev); | 1545 | i = __b44_load_mcast(bp, dev); |
1543 | 1546 | ||
1544 | for(;i<64;i++) { | 1547 | for (; i < 64; i++) { |
1545 | __b44_cam_write(bp, zero, i); | 1548 | __b44_cam_write(bp, zero, i); |
1546 | } | 1549 | } |
1547 | bw32(bp, B44_RXCONFIG, val); | 1550 | bw32(bp, B44_RXCONFIG, val); |
@@ -1773,6 +1776,37 @@ static int b44_set_pauseparam(struct net_device *dev, | |||
1773 | return 0; | 1776 | return 0; |
1774 | } | 1777 | } |
1775 | 1778 | ||
1779 | static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
1780 | { | ||
1781 | switch(stringset) { | ||
1782 | case ETH_SS_STATS: | ||
1783 | memcpy(data, *b44_gstrings, sizeof(b44_gstrings)); | ||
1784 | break; | ||
1785 | } | ||
1786 | } | ||
1787 | |||
1788 | static int b44_get_stats_count(struct net_device *dev) | ||
1789 | { | ||
1790 | return ARRAY_SIZE(b44_gstrings); | ||
1791 | } | ||
1792 | |||
1793 | static void b44_get_ethtool_stats(struct net_device *dev, | ||
1794 | struct ethtool_stats *stats, u64 *data) | ||
1795 | { | ||
1796 | struct b44 *bp = netdev_priv(dev); | ||
1797 | u32 *val = &bp->hw_stats.tx_good_octets; | ||
1798 | u32 i; | ||
1799 | |||
1800 | spin_lock_irq(&bp->lock); | ||
1801 | |||
1802 | b44_stats_update(bp); | ||
1803 | |||
1804 | for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) | ||
1805 | *data++ = *val++; | ||
1806 | |||
1807 | spin_unlock_irq(&bp->lock); | ||
1808 | } | ||
1809 | |||
1776 | static struct ethtool_ops b44_ethtool_ops = { | 1810 | static struct ethtool_ops b44_ethtool_ops = { |
1777 | .get_drvinfo = b44_get_drvinfo, | 1811 | .get_drvinfo = b44_get_drvinfo, |
1778 | .get_settings = b44_get_settings, | 1812 | .get_settings = b44_get_settings, |
@@ -1785,6 +1819,9 @@ static struct ethtool_ops b44_ethtool_ops = { | |||
1785 | .set_pauseparam = b44_set_pauseparam, | 1819 | .set_pauseparam = b44_set_pauseparam, |
1786 | .get_msglevel = b44_get_msglevel, | 1820 | .get_msglevel = b44_get_msglevel, |
1787 | .set_msglevel = b44_set_msglevel, | 1821 | .set_msglevel = b44_set_msglevel, |
1822 | .get_strings = b44_get_strings, | ||
1823 | .get_stats_count = b44_get_stats_count, | ||
1824 | .get_ethtool_stats = b44_get_ethtool_stats, | ||
1788 | .get_perm_addr = ethtool_op_get_perm_addr, | 1825 | .get_perm_addr = ethtool_op_get_perm_addr, |
1789 | }; | 1826 | }; |
1790 | 1827 | ||
@@ -1893,9 +1930,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev, | |||
1893 | 1930 | ||
1894 | err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); | 1931 | err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); |
1895 | if (err) { | 1932 | if (err) { |
1896 | printk(KERN_ERR PFX "No usable DMA configuration, " | 1933 | printk(KERN_ERR PFX "No usable DMA configuration, " |
1897 | "aborting.\n"); | 1934 | "aborting.\n"); |
1898 | goto err_out_free_res; | 1935 | goto err_out_free_res; |
1899 | } | 1936 | } |
1900 | 1937 | ||
1901 | b44reg_base = pci_resource_start(pdev, 0); | 1938 | b44reg_base = pci_resource_start(pdev, 0); |
@@ -1917,10 +1954,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev, | |||
1917 | bp = netdev_priv(dev); | 1954 | bp = netdev_priv(dev); |
1918 | bp->pdev = pdev; | 1955 | bp->pdev = pdev; |
1919 | bp->dev = dev; | 1956 | bp->dev = dev; |
1920 | if (b44_debug >= 0) | 1957 | |
1921 | bp->msg_enable = (1 << b44_debug) - 1; | 1958 | bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE); |
1922 | else | ||
1923 | bp->msg_enable = B44_DEF_MSG_ENABLE; | ||
1924 | 1959 | ||
1925 | spin_lock_init(&bp->lock); | 1960 | spin_lock_init(&bp->lock); |
1926 | 1961 | ||
@@ -2010,17 +2045,14 @@ err_out_disable_pdev: | |||
2010 | static void __devexit b44_remove_one(struct pci_dev *pdev) | 2045 | static void __devexit b44_remove_one(struct pci_dev *pdev) |
2011 | { | 2046 | { |
2012 | struct net_device *dev = pci_get_drvdata(pdev); | 2047 | struct net_device *dev = pci_get_drvdata(pdev); |
2048 | struct b44 *bp = netdev_priv(dev); | ||
2013 | 2049 | ||
2014 | if (dev) { | 2050 | unregister_netdev(dev); |
2015 | struct b44 *bp = netdev_priv(dev); | 2051 | iounmap(bp->regs); |
2016 | 2052 | free_netdev(dev); | |
2017 | unregister_netdev(dev); | 2053 | pci_release_regions(pdev); |
2018 | iounmap(bp->regs); | 2054 | pci_disable_device(pdev); |
2019 | free_netdev(dev); | 2055 | pci_set_drvdata(pdev, NULL); |
2020 | pci_release_regions(pdev); | ||
2021 | pci_disable_device(pdev); | ||
2022 | pci_set_drvdata(pdev, NULL); | ||
2023 | } | ||
2024 | } | 2056 | } |
2025 | 2057 | ||
2026 | static int b44_suspend(struct pci_dev *pdev, pm_message_t state) | 2058 | static int b44_suspend(struct pci_dev *pdev, pm_message_t state) |
diff --git a/drivers/net/b44.h b/drivers/net/b44.h index 593cb0ad4100..7afeaf608232 100644 --- a/drivers/net/b44.h +++ b/drivers/net/b44.h | |||
@@ -346,29 +346,63 @@ struct ring_info { | |||
346 | 346 | ||
347 | #define B44_MCAST_TABLE_SIZE 32 | 347 | #define B44_MCAST_TABLE_SIZE 32 |
348 | 348 | ||
349 | #define B44_STAT_REG_DECLARE \ | ||
350 | _B44(tx_good_octets) \ | ||
351 | _B44(tx_good_pkts) \ | ||
352 | _B44(tx_octets) \ | ||
353 | _B44(tx_pkts) \ | ||
354 | _B44(tx_broadcast_pkts) \ | ||
355 | _B44(tx_multicast_pkts) \ | ||
356 | _B44(tx_len_64) \ | ||
357 | _B44(tx_len_65_to_127) \ | ||
358 | _B44(tx_len_128_to_255) \ | ||
359 | _B44(tx_len_256_to_511) \ | ||
360 | _B44(tx_len_512_to_1023) \ | ||
361 | _B44(tx_len_1024_to_max) \ | ||
362 | _B44(tx_jabber_pkts) \ | ||
363 | _B44(tx_oversize_pkts) \ | ||
364 | _B44(tx_fragment_pkts) \ | ||
365 | _B44(tx_underruns) \ | ||
366 | _B44(tx_total_cols) \ | ||
367 | _B44(tx_single_cols) \ | ||
368 | _B44(tx_multiple_cols) \ | ||
369 | _B44(tx_excessive_cols) \ | ||
370 | _B44(tx_late_cols) \ | ||
371 | _B44(tx_defered) \ | ||
372 | _B44(tx_carrier_lost) \ | ||
373 | _B44(tx_pause_pkts) \ | ||
374 | _B44(rx_good_octets) \ | ||
375 | _B44(rx_good_pkts) \ | ||
376 | _B44(rx_octets) \ | ||
377 | _B44(rx_pkts) \ | ||
378 | _B44(rx_broadcast_pkts) \ | ||
379 | _B44(rx_multicast_pkts) \ | ||
380 | _B44(rx_len_64) \ | ||
381 | _B44(rx_len_65_to_127) \ | ||
382 | _B44(rx_len_128_to_255) \ | ||
383 | _B44(rx_len_256_to_511) \ | ||
384 | _B44(rx_len_512_to_1023) \ | ||
385 | _B44(rx_len_1024_to_max) \ | ||
386 | _B44(rx_jabber_pkts) \ | ||
387 | _B44(rx_oversize_pkts) \ | ||
388 | _B44(rx_fragment_pkts) \ | ||
389 | _B44(rx_missed_pkts) \ | ||
390 | _B44(rx_crc_align_errs) \ | ||
391 | _B44(rx_undersize) \ | ||
392 | _B44(rx_crc_errs) \ | ||
393 | _B44(rx_align_errs) \ | ||
394 | _B44(rx_symbol_errs) \ | ||
395 | _B44(rx_pause_pkts) \ | ||
396 | _B44(rx_nonpause_pkts) | ||
397 | |||
349 | /* SW copy of device statistics, kept up to date by periodic timer | 398 | /* SW copy of device statistics, kept up to date by periodic timer |
350 | * which probes HW values. Must have same relative layout as HW | 399 | * which probes HW values. Check b44_stats_update if you mess with |
351 | * register above, because b44_stats_update depends upon this. | 400 | * the layout |
352 | */ | 401 | */ |
353 | struct b44_hw_stats { | 402 | struct b44_hw_stats { |
354 | u32 tx_good_octets, tx_good_pkts, tx_octets; | 403 | #define _B44(x) u32 x; |
355 | u32 tx_pkts, tx_broadcast_pkts, tx_multicast_pkts; | 404 | B44_STAT_REG_DECLARE |
356 | u32 tx_len_64, tx_len_65_to_127, tx_len_128_to_255; | 405 | #undef _B44 |
357 | u32 tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max; | ||
358 | u32 tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts; | ||
359 | u32 tx_underruns, tx_total_cols, tx_single_cols; | ||
360 | u32 tx_multiple_cols, tx_excessive_cols, tx_late_cols; | ||
361 | u32 tx_defered, tx_carrier_lost, tx_pause_pkts; | ||
362 | u32 __pad1[8]; | ||
363 | |||
364 | u32 rx_good_octets, rx_good_pkts, rx_octets; | ||
365 | u32 rx_pkts, rx_broadcast_pkts, rx_multicast_pkts; | ||
366 | u32 rx_len_64, rx_len_65_to_127, rx_len_128_to_255; | ||
367 | u32 rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max; | ||
368 | u32 rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts; | ||
369 | u32 rx_missed_pkts, rx_crc_align_errs, rx_undersize; | ||
370 | u32 rx_crc_errs, rx_align_errs, rx_symbol_errs; | ||
371 | u32 rx_pause_pkts, rx_nonpause_pkts; | ||
372 | }; | 406 | }; |
373 | 407 | ||
374 | struct b44 { | 408 | struct b44 { |