diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 11:34:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-09 11:34:36 -0500 |
commit | a7c243b544c0e9f6775c2607decaa59d54fb9e11 (patch) | |
tree | 86fdb4d2d6cef932af7497f28827e7d52b29e48c /drivers/net/b44.c | |
parent | 7df446e7e043b2ba5fd5de42529f9d797e8b501a (diff) | |
parent | f406db8cba6bbce42b96490e6d31bdec229ad994 (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/b44.c')
-rw-r--r-- | drivers/net/b44.c | 177 |
1 files changed, 109 insertions, 68 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 819a17921cb9..c53848f787eb 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -28,8 +28,8 @@ | |||
28 | 28 | ||
29 | #define DRV_MODULE_NAME "b44" | 29 | #define DRV_MODULE_NAME "b44" |
30 | #define PFX DRV_MODULE_NAME ": " | 30 | #define PFX DRV_MODULE_NAME ": " |
31 | #define DRV_MODULE_VERSION "0.95" | 31 | #define DRV_MODULE_VERSION "0.96" |
32 | #define DRV_MODULE_RELDATE "Aug 3, 2004" | 32 | #define DRV_MODULE_RELDATE "Nov 8, 2005" |
33 | 33 | ||
34 | #define B44_DEF_MSG_ENABLE \ | 34 | #define B44_DEF_MSG_ENABLE \ |
35 | (NETIF_MSG_DRV | \ | 35 | (NETIF_MSG_DRV | \ |
@@ -101,14 +101,16 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); | |||
101 | static void b44_halt(struct b44 *); | 101 | static void b44_halt(struct b44 *); |
102 | static void b44_init_rings(struct b44 *); | 102 | static void b44_init_rings(struct b44 *); |
103 | static void b44_init_hw(struct b44 *); | 103 | static void b44_init_hw(struct b44 *); |
104 | static int b44_poll(struct net_device *dev, int *budget); | ||
105 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
106 | static void b44_poll_controller(struct net_device *dev); | ||
107 | #endif | ||
108 | 104 | ||
109 | static int dma_desc_align_mask; | 105 | static int dma_desc_align_mask; |
110 | static int dma_desc_sync_size; | 106 | static int dma_desc_sync_size; |
111 | 107 | ||
108 | static const char b44_gstrings[][ETH_GSTRING_LEN] = { | ||
109 | #define _B44(x...) # x, | ||
110 | B44_STAT_REG_DECLARE | ||
111 | #undef _B44 | ||
112 | }; | ||
113 | |||
112 | static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, | 114 | static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev, |
113 | dma_addr_t dma_base, | 115 | dma_addr_t dma_base, |
114 | unsigned long offset, | 116 | unsigned long offset, |
@@ -501,7 +503,10 @@ static void b44_stats_update(struct b44 *bp) | |||
501 | for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { | 503 | for (reg = B44_TX_GOOD_O; reg <= B44_TX_PAUSE; reg += 4UL) { |
502 | *val++ += br32(bp, reg); | 504 | *val++ += br32(bp, reg); |
503 | } | 505 | } |
504 | val = &bp->hw_stats.rx_good_octets; | 506 | |
507 | /* Pad */ | ||
508 | reg += 8*4UL; | ||
509 | |||
505 | for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { | 510 | for (reg = B44_RX_GOOD_O; reg <= B44_RX_NPAUSE; reg += 4UL) { |
506 | *val++ += br32(bp, reg); | 511 | *val++ += br32(bp, reg); |
507 | } | 512 | } |
@@ -652,7 +657,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
652 | 657 | ||
653 | /* Hardware bug work-around, the chip is unable to do PCI DMA | 658 | /* Hardware bug work-around, the chip is unable to do PCI DMA |
654 | to/from anything above 1GB :-( */ | 659 | to/from anything above 1GB :-( */ |
655 | if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { | 660 | if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { |
656 | /* Sigh... */ | 661 | /* Sigh... */ |
657 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); | 662 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); |
658 | dev_kfree_skb_any(skb); | 663 | dev_kfree_skb_any(skb); |
@@ -662,7 +667,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
662 | mapping = pci_map_single(bp->pdev, skb->data, | 667 | mapping = pci_map_single(bp->pdev, skb->data, |
663 | RX_PKT_BUF_SZ, | 668 | RX_PKT_BUF_SZ, |
664 | PCI_DMA_FROMDEVICE); | 669 | PCI_DMA_FROMDEVICE); |
665 | if(mapping+RX_PKT_BUF_SZ > B44_DMA_MASK) { | 670 | if (mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) { |
666 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); | 671 | pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE); |
667 | dev_kfree_skb_any(skb); | 672 | dev_kfree_skb_any(skb); |
668 | return -ENOMEM; | 673 | return -ENOMEM; |
@@ -889,11 +894,10 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
889 | { | 894 | { |
890 | struct net_device *dev = dev_id; | 895 | struct net_device *dev = dev_id; |
891 | struct b44 *bp = netdev_priv(dev); | 896 | struct b44 *bp = netdev_priv(dev); |
892 | unsigned long flags; | ||
893 | u32 istat, imask; | 897 | u32 istat, imask; |
894 | int handled = 0; | 898 | int handled = 0; |
895 | 899 | ||
896 | spin_lock_irqsave(&bp->lock, flags); | 900 | spin_lock(&bp->lock); |
897 | 901 | ||
898 | istat = br32(bp, B44_ISTAT); | 902 | istat = br32(bp, B44_ISTAT); |
899 | imask = br32(bp, B44_IMASK); | 903 | imask = br32(bp, B44_IMASK); |
@@ -904,6 +908,12 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
904 | istat &= imask; | 908 | istat &= imask; |
905 | if (istat) { | 909 | if (istat) { |
906 | handled = 1; | 910 | handled = 1; |
911 | |||
912 | if (unlikely(!netif_running(dev))) { | ||
913 | printk(KERN_INFO "%s: late interrupt.\n", dev->name); | ||
914 | goto irq_ack; | ||
915 | } | ||
916 | |||
907 | if (netif_rx_schedule_prep(dev)) { | 917 | if (netif_rx_schedule_prep(dev)) { |
908 | /* NOTE: These writes are posted by the readback of | 918 | /* NOTE: These writes are posted by the readback of |
909 | * the ISTAT register below. | 919 | * the ISTAT register below. |
@@ -916,10 +926,11 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
916 | dev->name); | 926 | dev->name); |
917 | } | 927 | } |
918 | 928 | ||
929 | irq_ack: | ||
919 | bw32(bp, B44_ISTAT, istat); | 930 | bw32(bp, B44_ISTAT, istat); |
920 | br32(bp, B44_ISTAT); | 931 | br32(bp, B44_ISTAT); |
921 | } | 932 | } |
922 | spin_unlock_irqrestore(&bp->lock, flags); | 933 | spin_unlock(&bp->lock); |
923 | return IRQ_RETVAL(handled); | 934 | return IRQ_RETVAL(handled); |
924 | } | 935 | } |
925 | 936 | ||
@@ -947,6 +958,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
947 | { | 958 | { |
948 | struct b44 *bp = netdev_priv(dev); | 959 | struct b44 *bp = netdev_priv(dev); |
949 | struct sk_buff *bounce_skb; | 960 | struct sk_buff *bounce_skb; |
961 | int rc = NETDEV_TX_OK; | ||
950 | dma_addr_t mapping; | 962 | dma_addr_t mapping; |
951 | u32 len, entry, ctrl; | 963 | u32 len, entry, ctrl; |
952 | 964 | ||
@@ -956,29 +968,28 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
956 | /* This is a hard error, log it. */ | 968 | /* This is a hard error, log it. */ |
957 | if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { | 969 | if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) { |
958 | netif_stop_queue(dev); | 970 | netif_stop_queue(dev); |
959 | spin_unlock_irq(&bp->lock); | ||
960 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", | 971 | printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n", |
961 | dev->name); | 972 | dev->name); |
962 | return 1; | 973 | goto err_out; |
963 | } | 974 | } |
964 | 975 | ||
965 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); | 976 | mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE); |
966 | if(mapping+len > B44_DMA_MASK) { | 977 | if (mapping + len > B44_DMA_MASK) { |
967 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ | 978 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ |
968 | pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); | 979 | pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE); |
969 | 980 | ||
970 | bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, | 981 | bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ, |
971 | GFP_ATOMIC|GFP_DMA); | 982 | GFP_ATOMIC|GFP_DMA); |
972 | if (!bounce_skb) | 983 | if (!bounce_skb) |
973 | return NETDEV_TX_BUSY; | 984 | goto err_out; |
974 | 985 | ||
975 | mapping = pci_map_single(bp->pdev, bounce_skb->data, | 986 | mapping = pci_map_single(bp->pdev, bounce_skb->data, |
976 | len, PCI_DMA_TODEVICE); | 987 | len, PCI_DMA_TODEVICE); |
977 | if(mapping+len > B44_DMA_MASK) { | 988 | if (mapping + len > B44_DMA_MASK) { |
978 | pci_unmap_single(bp->pdev, mapping, | 989 | pci_unmap_single(bp->pdev, mapping, |
979 | len, PCI_DMA_TODEVICE); | 990 | len, PCI_DMA_TODEVICE); |
980 | dev_kfree_skb_any(bounce_skb); | 991 | dev_kfree_skb_any(bounce_skb); |
981 | return NETDEV_TX_BUSY; | 992 | goto err_out; |
982 | } | 993 | } |
983 | 994 | ||
984 | memcpy(skb_put(bounce_skb, len), skb->data, skb->len); | 995 | memcpy(skb_put(bounce_skb, len), skb->data, skb->len); |
@@ -1018,11 +1029,16 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1018 | if (TX_BUFFS_AVAIL(bp) < 1) | 1029 | if (TX_BUFFS_AVAIL(bp) < 1) |
1019 | netif_stop_queue(dev); | 1030 | netif_stop_queue(dev); |
1020 | 1031 | ||
1032 | dev->trans_start = jiffies; | ||
1033 | |||
1034 | out_unlock: | ||
1021 | spin_unlock_irq(&bp->lock); | 1035 | spin_unlock_irq(&bp->lock); |
1022 | 1036 | ||
1023 | dev->trans_start = jiffies; | 1037 | return rc; |
1024 | 1038 | ||
1025 | return 0; | 1039 | err_out: |
1040 | rc = NETDEV_TX_BUSY; | ||
1041 | goto out_unlock; | ||
1026 | } | 1042 | } |
1027 | 1043 | ||
1028 | static int b44_change_mtu(struct net_device *dev, int new_mtu) | 1044 | static int b44_change_mtu(struct net_device *dev, int new_mtu) |
@@ -1096,8 +1112,7 @@ static void b44_free_rings(struct b44 *bp) | |||
1096 | * | 1112 | * |
1097 | * The chip has been shut down and the driver detached from | 1113 | * The chip has been shut down and the driver detached from |
1098 | * the networking, so no interrupts or new tx packets will | 1114 | * the networking, so no interrupts or new tx packets will |
1099 | * end up in the driver. bp->lock is not held and we are not | 1115 | * end up in the driver. |
1100 | * in an interrupt context and thus may sleep. | ||
1101 | */ | 1116 | */ |
1102 | static void b44_init_rings(struct b44 *bp) | 1117 | static void b44_init_rings(struct b44 *bp) |
1103 | { | 1118 | { |
@@ -1169,16 +1184,14 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1169 | int size; | 1184 | int size; |
1170 | 1185 | ||
1171 | size = B44_RX_RING_SIZE * sizeof(struct ring_info); | 1186 | size = B44_RX_RING_SIZE * sizeof(struct ring_info); |
1172 | bp->rx_buffers = kmalloc(size, GFP_KERNEL); | 1187 | bp->rx_buffers = kzalloc(size, GFP_KERNEL); |
1173 | if (!bp->rx_buffers) | 1188 | if (!bp->rx_buffers) |
1174 | goto out_err; | 1189 | goto out_err; |
1175 | memset(bp->rx_buffers, 0, size); | ||
1176 | 1190 | ||
1177 | size = B44_TX_RING_SIZE * sizeof(struct ring_info); | 1191 | size = B44_TX_RING_SIZE * sizeof(struct ring_info); |
1178 | bp->tx_buffers = kmalloc(size, GFP_KERNEL); | 1192 | bp->tx_buffers = kzalloc(size, GFP_KERNEL); |
1179 | if (!bp->tx_buffers) | 1193 | if (!bp->tx_buffers) |
1180 | goto out_err; | 1194 | goto out_err; |
1181 | memset(bp->tx_buffers, 0, size); | ||
1182 | 1195 | ||
1183 | size = DMA_TABLE_BYTES; | 1196 | size = DMA_TABLE_BYTES; |
1184 | bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); | 1197 | bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma); |
@@ -1189,10 +1202,10 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1189 | struct dma_desc *rx_ring; | 1202 | struct dma_desc *rx_ring; |
1190 | dma_addr_t rx_ring_dma; | 1203 | dma_addr_t rx_ring_dma; |
1191 | 1204 | ||
1192 | if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) | 1205 | rx_ring = kzalloc(size, GFP_KERNEL); |
1206 | if (!rx_ring) | ||
1193 | goto out_err; | 1207 | goto out_err; |
1194 | 1208 | ||
1195 | memset(rx_ring, 0, size); | ||
1196 | rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, | 1209 | rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring, |
1197 | DMA_TABLE_BYTES, | 1210 | DMA_TABLE_BYTES, |
1198 | DMA_BIDIRECTIONAL); | 1211 | DMA_BIDIRECTIONAL); |
@@ -1215,10 +1228,10 @@ static int b44_alloc_consistent(struct b44 *bp) | |||
1215 | struct dma_desc *tx_ring; | 1228 | struct dma_desc *tx_ring; |
1216 | dma_addr_t tx_ring_dma; | 1229 | dma_addr_t tx_ring_dma; |
1217 | 1230 | ||
1218 | if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL))) | 1231 | tx_ring = kzalloc(size, GFP_KERNEL); |
1232 | if (!tx_ring) | ||
1219 | goto out_err; | 1233 | goto out_err; |
1220 | 1234 | ||
1221 | memset(tx_ring, 0, size); | ||
1222 | tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, | 1235 | tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring, |
1223 | DMA_TABLE_BYTES, | 1236 | DMA_TABLE_BYTES, |
1224 | DMA_TO_DEVICE); | 1237 | DMA_TO_DEVICE); |
@@ -1381,22 +1394,21 @@ static int b44_open(struct net_device *dev) | |||
1381 | 1394 | ||
1382 | err = b44_alloc_consistent(bp); | 1395 | err = b44_alloc_consistent(bp); |
1383 | if (err) | 1396 | if (err) |
1384 | return err; | 1397 | goto out; |
1385 | |||
1386 | err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); | ||
1387 | if (err) | ||
1388 | goto err_out_free; | ||
1389 | |||
1390 | spin_lock_irq(&bp->lock); | ||
1391 | 1398 | ||
1392 | b44_init_rings(bp); | 1399 | b44_init_rings(bp); |
1393 | b44_init_hw(bp); | 1400 | b44_init_hw(bp); |
1394 | bp->flags |= B44_FLAG_INIT_COMPLETE; | ||
1395 | 1401 | ||
1396 | netif_carrier_off(dev); | 1402 | netif_carrier_off(dev); |
1397 | b44_check_phy(bp); | 1403 | b44_check_phy(bp); |
1398 | 1404 | ||
1399 | spin_unlock_irq(&bp->lock); | 1405 | err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev); |
1406 | if (unlikely(err < 0)) { | ||
1407 | b44_chip_reset(bp); | ||
1408 | b44_free_rings(bp); | ||
1409 | b44_free_consistent(bp); | ||
1410 | goto out; | ||
1411 | } | ||
1400 | 1412 | ||
1401 | init_timer(&bp->timer); | 1413 | init_timer(&bp->timer); |
1402 | bp->timer.expires = jiffies + HZ; | 1414 | bp->timer.expires = jiffies + HZ; |
@@ -1405,11 +1417,7 @@ static int b44_open(struct net_device *dev) | |||
1405 | add_timer(&bp->timer); | 1417 | add_timer(&bp->timer); |
1406 | 1418 | ||
1407 | b44_enable_ints(bp); | 1419 | b44_enable_ints(bp); |
1408 | 1420 | out: | |
1409 | return 0; | ||
1410 | |||
1411 | err_out_free: | ||
1412 | b44_free_consistent(bp); | ||
1413 | return err; | 1421 | return err; |
1414 | } | 1422 | } |
1415 | 1423 | ||
@@ -1444,6 +1452,8 @@ static int b44_close(struct net_device *dev) | |||
1444 | 1452 | ||
1445 | netif_stop_queue(dev); | 1453 | netif_stop_queue(dev); |
1446 | 1454 | ||
1455 | netif_poll_disable(dev); | ||
1456 | |||
1447 | del_timer_sync(&bp->timer); | 1457 | del_timer_sync(&bp->timer); |
1448 | 1458 | ||
1449 | spin_lock_irq(&bp->lock); | 1459 | spin_lock_irq(&bp->lock); |
@@ -1453,13 +1463,14 @@ static int b44_close(struct net_device *dev) | |||
1453 | #endif | 1463 | #endif |
1454 | b44_halt(bp); | 1464 | b44_halt(bp); |
1455 | b44_free_rings(bp); | 1465 | b44_free_rings(bp); |
1456 | bp->flags &= ~B44_FLAG_INIT_COMPLETE; | ||
1457 | netif_carrier_off(bp->dev); | 1466 | netif_carrier_off(bp->dev); |
1458 | 1467 | ||
1459 | spin_unlock_irq(&bp->lock); | 1468 | spin_unlock_irq(&bp->lock); |
1460 | 1469 | ||
1461 | free_irq(dev->irq, dev); | 1470 | free_irq(dev->irq, dev); |
1462 | 1471 | ||
1472 | netif_poll_enable(dev); | ||
1473 | |||
1463 | b44_free_consistent(bp); | 1474 | b44_free_consistent(bp); |
1464 | 1475 | ||
1465 | return 0; | 1476 | return 0; |
@@ -1524,8 +1535,6 @@ static void __b44_set_rx_mode(struct net_device *dev) | |||
1524 | { | 1535 | { |
1525 | struct b44 *bp = netdev_priv(dev); | 1536 | struct b44 *bp = netdev_priv(dev); |
1526 | u32 val; | 1537 | u32 val; |
1527 | int i=0; | ||
1528 | unsigned char zero[6] = {0,0,0,0,0,0}; | ||
1529 | 1538 | ||
1530 | val = br32(bp, B44_RXCONFIG); | 1539 | val = br32(bp, B44_RXCONFIG); |
1531 | val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); | 1540 | val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI); |
@@ -1533,14 +1542,17 @@ static void __b44_set_rx_mode(struct net_device *dev) | |||
1533 | val |= RXCONFIG_PROMISC; | 1542 | val |= RXCONFIG_PROMISC; |
1534 | bw32(bp, B44_RXCONFIG, val); | 1543 | bw32(bp, B44_RXCONFIG, val); |
1535 | } else { | 1544 | } else { |
1545 | unsigned char zero[6] = {0, 0, 0, 0, 0, 0}; | ||
1546 | int i = 0; | ||
1547 | |||
1536 | __b44_set_mac_addr(bp); | 1548 | __b44_set_mac_addr(bp); |
1537 | 1549 | ||
1538 | if (dev->flags & IFF_ALLMULTI) | 1550 | if (dev->flags & IFF_ALLMULTI) |
1539 | val |= RXCONFIG_ALLMULTI; | 1551 | val |= RXCONFIG_ALLMULTI; |
1540 | else | 1552 | else |
1541 | i=__b44_load_mcast(bp, dev); | 1553 | i = __b44_load_mcast(bp, dev); |
1542 | 1554 | ||
1543 | for(;i<64;i++) { | 1555 | for (; i < 64; i++) { |
1544 | __b44_cam_write(bp, zero, i); | 1556 | __b44_cam_write(bp, zero, i); |
1545 | } | 1557 | } |
1546 | bw32(bp, B44_RXCONFIG, val); | 1558 | bw32(bp, B44_RXCONFIG, val); |
@@ -1604,7 +1616,7 @@ static int b44_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1604 | { | 1616 | { |
1605 | struct b44 *bp = netdev_priv(dev); | 1617 | struct b44 *bp = netdev_priv(dev); |
1606 | 1618 | ||
1607 | if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) | 1619 | if (!netif_running(dev)) |
1608 | return -EAGAIN; | 1620 | return -EAGAIN; |
1609 | cmd->supported = (SUPPORTED_Autoneg); | 1621 | cmd->supported = (SUPPORTED_Autoneg); |
1610 | cmd->supported |= (SUPPORTED_100baseT_Half | | 1622 | cmd->supported |= (SUPPORTED_100baseT_Half | |
@@ -1642,7 +1654,7 @@ static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1642 | { | 1654 | { |
1643 | struct b44 *bp = netdev_priv(dev); | 1655 | struct b44 *bp = netdev_priv(dev); |
1644 | 1656 | ||
1645 | if (!(bp->flags & B44_FLAG_INIT_COMPLETE)) | 1657 | if (!netif_running(dev)) |
1646 | return -EAGAIN; | 1658 | return -EAGAIN; |
1647 | 1659 | ||
1648 | /* We do not support gigabit. */ | 1660 | /* We do not support gigabit. */ |
@@ -1772,6 +1784,37 @@ static int b44_set_pauseparam(struct net_device *dev, | |||
1772 | return 0; | 1784 | return 0; |
1773 | } | 1785 | } |
1774 | 1786 | ||
1787 | static void b44_get_strings(struct net_device *dev, u32 stringset, u8 *data) | ||
1788 | { | ||
1789 | switch(stringset) { | ||
1790 | case ETH_SS_STATS: | ||
1791 | memcpy(data, *b44_gstrings, sizeof(b44_gstrings)); | ||
1792 | break; | ||
1793 | } | ||
1794 | } | ||
1795 | |||
1796 | static int b44_get_stats_count(struct net_device *dev) | ||
1797 | { | ||
1798 | return ARRAY_SIZE(b44_gstrings); | ||
1799 | } | ||
1800 | |||
1801 | static void b44_get_ethtool_stats(struct net_device *dev, | ||
1802 | struct ethtool_stats *stats, u64 *data) | ||
1803 | { | ||
1804 | struct b44 *bp = netdev_priv(dev); | ||
1805 | u32 *val = &bp->hw_stats.tx_good_octets; | ||
1806 | u32 i; | ||
1807 | |||
1808 | spin_lock_irq(&bp->lock); | ||
1809 | |||
1810 | b44_stats_update(bp); | ||
1811 | |||
1812 | for (i = 0; i < ARRAY_SIZE(b44_gstrings); i++) | ||
1813 | *data++ = *val++; | ||
1814 | |||
1815 | spin_unlock_irq(&bp->lock); | ||
1816 | } | ||
1817 | |||
1775 | static struct ethtool_ops b44_ethtool_ops = { | 1818 | static struct ethtool_ops b44_ethtool_ops = { |
1776 | .get_drvinfo = b44_get_drvinfo, | 1819 | .get_drvinfo = b44_get_drvinfo, |
1777 | .get_settings = b44_get_settings, | 1820 | .get_settings = b44_get_settings, |
@@ -1784,6 +1827,9 @@ static struct ethtool_ops b44_ethtool_ops = { | |||
1784 | .set_pauseparam = b44_set_pauseparam, | 1827 | .set_pauseparam = b44_set_pauseparam, |
1785 | .get_msglevel = b44_get_msglevel, | 1828 | .get_msglevel = b44_get_msglevel, |
1786 | .set_msglevel = b44_set_msglevel, | 1829 | .set_msglevel = b44_set_msglevel, |
1830 | .get_strings = b44_get_strings, | ||
1831 | .get_stats_count = b44_get_stats_count, | ||
1832 | .get_ethtool_stats = b44_get_ethtool_stats, | ||
1787 | .get_perm_addr = ethtool_op_get_perm_addr, | 1833 | .get_perm_addr = ethtool_op_get_perm_addr, |
1788 | }; | 1834 | }; |
1789 | 1835 | ||
@@ -1892,9 +1938,9 @@ static int __devinit b44_init_one(struct pci_dev *pdev, | |||
1892 | 1938 | ||
1893 | err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); | 1939 | err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK); |
1894 | if (err) { | 1940 | if (err) { |
1895 | printk(KERN_ERR PFX "No usable DMA configuration, " | 1941 | printk(KERN_ERR PFX "No usable DMA configuration, " |
1896 | "aborting.\n"); | 1942 | "aborting.\n"); |
1897 | goto err_out_free_res; | 1943 | goto err_out_free_res; |
1898 | } | 1944 | } |
1899 | 1945 | ||
1900 | b44reg_base = pci_resource_start(pdev, 0); | 1946 | b44reg_base = pci_resource_start(pdev, 0); |
@@ -1916,10 +1962,8 @@ static int __devinit b44_init_one(struct pci_dev *pdev, | |||
1916 | bp = netdev_priv(dev); | 1962 | bp = netdev_priv(dev); |
1917 | bp->pdev = pdev; | 1963 | bp->pdev = pdev; |
1918 | bp->dev = dev; | 1964 | bp->dev = dev; |
1919 | if (b44_debug >= 0) | 1965 | |
1920 | bp->msg_enable = (1 << b44_debug) - 1; | 1966 | bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE); |
1921 | else | ||
1922 | bp->msg_enable = B44_DEF_MSG_ENABLE; | ||
1923 | 1967 | ||
1924 | spin_lock_init(&bp->lock); | 1968 | spin_lock_init(&bp->lock); |
1925 | 1969 | ||
@@ -2009,17 +2053,14 @@ err_out_disable_pdev: | |||
2009 | static void __devexit b44_remove_one(struct pci_dev *pdev) | 2053 | static void __devexit b44_remove_one(struct pci_dev *pdev) |
2010 | { | 2054 | { |
2011 | struct net_device *dev = pci_get_drvdata(pdev); | 2055 | struct net_device *dev = pci_get_drvdata(pdev); |
2056 | struct b44 *bp = netdev_priv(dev); | ||
2012 | 2057 | ||
2013 | if (dev) { | 2058 | unregister_netdev(dev); |
2014 | struct b44 *bp = netdev_priv(dev); | 2059 | iounmap(bp->regs); |
2015 | 2060 | free_netdev(dev); | |
2016 | unregister_netdev(dev); | 2061 | pci_release_regions(pdev); |
2017 | iounmap(bp->regs); | 2062 | pci_disable_device(pdev); |
2018 | free_netdev(dev); | 2063 | pci_set_drvdata(pdev, NULL); |
2019 | pci_release_regions(pdev); | ||
2020 | pci_disable_device(pdev); | ||
2021 | pci_set_drvdata(pdev, NULL); | ||
2022 | } | ||
2023 | } | 2064 | } |
2024 | 2065 | ||
2025 | static int b44_suspend(struct pci_dev *pdev, pm_message_t state) | 2066 | static int b44_suspend(struct pci_dev *pdev, pm_message_t state) |