diff options
Diffstat (limited to 'drivers/net/b44.c')
-rw-r--r-- | drivers/net/b44.c | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 5eb2ec68393f..303a8d94ad4b 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -110,6 +110,11 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl); | |||
110 | 110 | ||
111 | static void b44_halt(struct b44 *); | 111 | static void b44_halt(struct b44 *); |
112 | static void b44_init_rings(struct b44 *); | 112 | static void b44_init_rings(struct b44 *); |
113 | |||
114 | #define B44_FULL_RESET 1 | ||
115 | #define B44_FULL_RESET_SKIP_PHY 2 | ||
116 | #define B44_PARTIAL_RESET 3 | ||
117 | |||
113 | static void b44_init_hw(struct b44 *, int); | 118 | static void b44_init_hw(struct b44 *, int); |
114 | 119 | ||
115 | static int dma_desc_align_mask; | 120 | static int dma_desc_align_mask; |
@@ -752,7 +757,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
752 | dest_idx * sizeof(dest_desc), | 757 | dest_idx * sizeof(dest_desc), |
753 | DMA_BIDIRECTIONAL); | 758 | DMA_BIDIRECTIONAL); |
754 | 759 | ||
755 | pci_dma_sync_single_for_device(bp->pdev, src_desc->addr, | 760 | pci_dma_sync_single_for_device(bp->pdev, le32_to_cpu(src_desc->addr), |
756 | RX_PKT_BUF_SZ, | 761 | RX_PKT_BUF_SZ, |
757 | PCI_DMA_FROMDEVICE); | 762 | PCI_DMA_FROMDEVICE); |
758 | } | 763 | } |
@@ -884,7 +889,7 @@ static int b44_poll(struct net_device *netdev, int *budget) | |||
884 | spin_lock_irqsave(&bp->lock, flags); | 889 | spin_lock_irqsave(&bp->lock, flags); |
885 | b44_halt(bp); | 890 | b44_halt(bp); |
886 | b44_init_rings(bp); | 891 | b44_init_rings(bp); |
887 | b44_init_hw(bp, 1); | 892 | b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY); |
888 | netif_wake_queue(bp->dev); | 893 | netif_wake_queue(bp->dev); |
889 | spin_unlock_irqrestore(&bp->lock, flags); | 894 | spin_unlock_irqrestore(&bp->lock, flags); |
890 | done = 1; | 895 | done = 1; |
@@ -954,7 +959,7 @@ static void b44_tx_timeout(struct net_device *dev) | |||
954 | 959 | ||
955 | b44_halt(bp); | 960 | b44_halt(bp); |
956 | b44_init_rings(bp); | 961 | b44_init_rings(bp); |
957 | b44_init_hw(bp, 1); | 962 | b44_init_hw(bp, B44_FULL_RESET); |
958 | 963 | ||
959 | spin_unlock_irq(&bp->lock); | 964 | spin_unlock_irq(&bp->lock); |
960 | 965 | ||
@@ -1071,7 +1076,7 @@ static int b44_change_mtu(struct net_device *dev, int new_mtu) | |||
1071 | b44_halt(bp); | 1076 | b44_halt(bp); |
1072 | dev->mtu = new_mtu; | 1077 | dev->mtu = new_mtu; |
1073 | b44_init_rings(bp); | 1078 | b44_init_rings(bp); |
1074 | b44_init_hw(bp, 1); | 1079 | b44_init_hw(bp, B44_FULL_RESET); |
1075 | spin_unlock_irq(&bp->lock); | 1080 | spin_unlock_irq(&bp->lock); |
1076 | 1081 | ||
1077 | b44_enable_ints(bp); | 1082 | b44_enable_ints(bp); |
@@ -1368,12 +1373,12 @@ static int b44_set_mac_addr(struct net_device *dev, void *p) | |||
1368 | * packet processing. Invoked with bp->lock held. | 1373 | * packet processing. Invoked with bp->lock held. |
1369 | */ | 1374 | */ |
1370 | static void __b44_set_rx_mode(struct net_device *); | 1375 | static void __b44_set_rx_mode(struct net_device *); |
1371 | static void b44_init_hw(struct b44 *bp, int full_reset) | 1376 | static void b44_init_hw(struct b44 *bp, int reset_kind) |
1372 | { | 1377 | { |
1373 | u32 val; | 1378 | u32 val; |
1374 | 1379 | ||
1375 | b44_chip_reset(bp); | 1380 | b44_chip_reset(bp); |
1376 | if (full_reset) { | 1381 | if (reset_kind == B44_FULL_RESET) { |
1377 | b44_phy_reset(bp); | 1382 | b44_phy_reset(bp); |
1378 | b44_setup_phy(bp); | 1383 | b44_setup_phy(bp); |
1379 | } | 1384 | } |
@@ -1390,7 +1395,10 @@ static void b44_init_hw(struct b44 *bp, int full_reset) | |||
1390 | bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); | 1395 | bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN); |
1391 | 1396 | ||
1392 | bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ | 1397 | bw32(bp, B44_TX_WMARK, 56); /* XXX magic */ |
1393 | if (full_reset) { | 1398 | if (reset_kind == B44_PARTIAL_RESET) { |
1399 | bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | | ||
1400 | (bp->rx_offset << DMARX_CTRL_ROSHIFT))); | ||
1401 | } else { | ||
1394 | bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); | 1402 | bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE); |
1395 | bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); | 1403 | bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset); |
1396 | bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | | 1404 | bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | |
@@ -1401,9 +1409,6 @@ static void b44_init_hw(struct b44 *bp, int full_reset) | |||
1401 | bp->rx_prod = bp->rx_pending; | 1409 | bp->rx_prod = bp->rx_pending; |
1402 | 1410 | ||
1403 | bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); | 1411 | bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ); |
1404 | } else { | ||
1405 | bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE | | ||
1406 | (bp->rx_offset << DMARX_CTRL_ROSHIFT))); | ||
1407 | } | 1412 | } |
1408 | 1413 | ||
1409 | val = br32(bp, B44_ENET_CTRL); | 1414 | val = br32(bp, B44_ENET_CTRL); |
@@ -1420,7 +1425,7 @@ static int b44_open(struct net_device *dev) | |||
1420 | goto out; | 1425 | goto out; |
1421 | 1426 | ||
1422 | b44_init_rings(bp); | 1427 | b44_init_rings(bp); |
1423 | b44_init_hw(bp, 1); | 1428 | b44_init_hw(bp, B44_FULL_RESET); |
1424 | 1429 | ||
1425 | b44_check_phy(bp); | 1430 | b44_check_phy(bp); |
1426 | 1431 | ||
@@ -1629,7 +1634,7 @@ static int b44_close(struct net_device *dev) | |||
1629 | netif_poll_enable(dev); | 1634 | netif_poll_enable(dev); |
1630 | 1635 | ||
1631 | if (bp->flags & B44_FLAG_WOL_ENABLE) { | 1636 | if (bp->flags & B44_FLAG_WOL_ENABLE) { |
1632 | b44_init_hw(bp, 0); | 1637 | b44_init_hw(bp, B44_PARTIAL_RESET); |
1633 | b44_setup_wol(bp); | 1638 | b44_setup_wol(bp); |
1634 | } | 1639 | } |
1635 | 1640 | ||
@@ -1905,7 +1910,7 @@ static int b44_set_ringparam(struct net_device *dev, | |||
1905 | 1910 | ||
1906 | b44_halt(bp); | 1911 | b44_halt(bp); |
1907 | b44_init_rings(bp); | 1912 | b44_init_rings(bp); |
1908 | b44_init_hw(bp, 1); | 1913 | b44_init_hw(bp, B44_FULL_RESET); |
1909 | netif_wake_queue(bp->dev); | 1914 | netif_wake_queue(bp->dev); |
1910 | spin_unlock_irq(&bp->lock); | 1915 | spin_unlock_irq(&bp->lock); |
1911 | 1916 | ||
@@ -1948,7 +1953,7 @@ static int b44_set_pauseparam(struct net_device *dev, | |||
1948 | if (bp->flags & B44_FLAG_PAUSE_AUTO) { | 1953 | if (bp->flags & B44_FLAG_PAUSE_AUTO) { |
1949 | b44_halt(bp); | 1954 | b44_halt(bp); |
1950 | b44_init_rings(bp); | 1955 | b44_init_rings(bp); |
1951 | b44_init_hw(bp, 1); | 1956 | b44_init_hw(bp, B44_FULL_RESET); |
1952 | } else { | 1957 | } else { |
1953 | __b44_set_flow_ctrl(bp, bp->flags); | 1958 | __b44_set_flow_ctrl(bp, bp->flags); |
1954 | } | 1959 | } |
@@ -2304,7 +2309,7 @@ static int b44_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2304 | 2309 | ||
2305 | free_irq(dev->irq, dev); | 2310 | free_irq(dev->irq, dev); |
2306 | if (bp->flags & B44_FLAG_WOL_ENABLE) { | 2311 | if (bp->flags & B44_FLAG_WOL_ENABLE) { |
2307 | b44_init_hw(bp, 0); | 2312 | b44_init_hw(bp, B44_PARTIAL_RESET); |
2308 | b44_setup_wol(bp); | 2313 | b44_setup_wol(bp); |
2309 | } | 2314 | } |
2310 | pci_disable_device(pdev); | 2315 | pci_disable_device(pdev); |
@@ -2315,21 +2320,32 @@ static int b44_resume(struct pci_dev *pdev) | |||
2315 | { | 2320 | { |
2316 | struct net_device *dev = pci_get_drvdata(pdev); | 2321 | struct net_device *dev = pci_get_drvdata(pdev); |
2317 | struct b44 *bp = netdev_priv(dev); | 2322 | struct b44 *bp = netdev_priv(dev); |
2323 | int rc = 0; | ||
2318 | 2324 | ||
2319 | pci_restore_state(pdev); | 2325 | pci_restore_state(pdev); |
2320 | pci_enable_device(pdev); | 2326 | rc = pci_enable_device(pdev); |
2327 | if (rc) { | ||
2328 | printk(KERN_ERR PFX "%s: pci_enable_device failed\n", | ||
2329 | dev->name); | ||
2330 | return rc; | ||
2331 | } | ||
2332 | |||
2321 | pci_set_master(pdev); | 2333 | pci_set_master(pdev); |
2322 | 2334 | ||
2323 | if (!netif_running(dev)) | 2335 | if (!netif_running(dev)) |
2324 | return 0; | 2336 | return 0; |
2325 | 2337 | ||
2326 | if (request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev)) | 2338 | rc = request_irq(dev->irq, b44_interrupt, IRQF_SHARED, dev->name, dev); |
2339 | if (rc) { | ||
2327 | printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); | 2340 | printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name); |
2341 | pci_disable_device(pdev); | ||
2342 | return rc; | ||
2343 | } | ||
2328 | 2344 | ||
2329 | spin_lock_irq(&bp->lock); | 2345 | spin_lock_irq(&bp->lock); |
2330 | 2346 | ||
2331 | b44_init_rings(bp); | 2347 | b44_init_rings(bp); |
2332 | b44_init_hw(bp, 1); | 2348 | b44_init_hw(bp, B44_FULL_RESET); |
2333 | netif_device_attach(bp->dev); | 2349 | netif_device_attach(bp->dev); |
2334 | spin_unlock_irq(&bp->lock); | 2350 | spin_unlock_irq(&bp->lock); |
2335 | 2351 | ||