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.c30
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 6926ebedfdc9..dc5f051005fa 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -73,8 +73,8 @@
73 (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP)) 73 (BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
74#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1)) 74#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
75 75
76#define RX_PKT_OFFSET 30 76#define RX_PKT_OFFSET (RX_HEADER_LEN + 2)
77#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64) 77#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET)
78 78
79/* minimum number of free TX descriptors required to wake up TX process */ 79/* minimum number of free TX descriptors required to wake up TX process */
80#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4) 80#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
@@ -679,10 +679,10 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
679 dev_kfree_skb_any(skb); 679 dev_kfree_skb_any(skb);
680 return -ENOMEM; 680 return -ENOMEM;
681 } 681 }
682 bp->force_copybreak = 1;
682 } 683 }
683 684
684 rh = (struct rx_header *) skb->data; 685 rh = (struct rx_header *) skb->data;
685 skb_reserve(skb, RX_PKT_OFFSET);
686 686
687 rh->len = 0; 687 rh->len = 0;
688 rh->flags = 0; 688 rh->flags = 0;
@@ -693,13 +693,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
693 if (src_map != NULL) 693 if (src_map != NULL)
694 src_map->skb = NULL; 694 src_map->skb = NULL;
695 695
696 ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET)); 696 ctrl = (DESC_CTRL_LEN & RX_PKT_BUF_SZ);
697 if (dest_idx == (B44_RX_RING_SIZE - 1)) 697 if (dest_idx == (B44_RX_RING_SIZE - 1))
698 ctrl |= DESC_CTRL_EOT; 698 ctrl |= DESC_CTRL_EOT;
699 699
700 dp = &bp->rx_ring[dest_idx]; 700 dp = &bp->rx_ring[dest_idx];
701 dp->ctrl = cpu_to_le32(ctrl); 701 dp->ctrl = cpu_to_le32(ctrl);
702 dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset); 702 dp->addr = cpu_to_le32((u32) mapping + bp->dma_offset);
703 703
704 if (bp->flags & B44_FLAG_RX_RING_HACK) 704 if (bp->flags & B44_FLAG_RX_RING_HACK)
705 b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma, 705 b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
@@ -801,7 +801,7 @@ static int b44_rx(struct b44 *bp, int budget)
801 /* Omit CRC. */ 801 /* Omit CRC. */
802 len -= 4; 802 len -= 4;
803 803
804 if (len > RX_COPY_THRESHOLD) { 804 if (!bp->force_copybreak && len > RX_COPY_THRESHOLD) {
805 int skb_size; 805 int skb_size;
806 skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); 806 skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
807 if (skb_size < 0) 807 if (skb_size < 0)
@@ -809,8 +809,8 @@ static int b44_rx(struct b44 *bp, int budget)
809 ssb_dma_unmap_single(bp->sdev, map, 809 ssb_dma_unmap_single(bp->sdev, map,
810 skb_size, DMA_FROM_DEVICE); 810 skb_size, DMA_FROM_DEVICE);
811 /* Leave out rx_header */ 811 /* Leave out rx_header */
812 skb_put(skb, len + RX_PKT_OFFSET); 812 skb_put(skb, len + RX_PKT_OFFSET);
813 skb_pull(skb, RX_PKT_OFFSET); 813 skb_pull(skb, RX_PKT_OFFSET);
814 } else { 814 } else {
815 struct sk_buff *copy_skb; 815 struct sk_buff *copy_skb;
816 816
@@ -1264,8 +1264,14 @@ static void b44_clear_stats(struct b44 *bp)
1264static void b44_chip_reset(struct b44 *bp, int reset_kind) 1264static void b44_chip_reset(struct b44 *bp, int reset_kind)
1265{ 1265{
1266 struct ssb_device *sdev = bp->sdev; 1266 struct ssb_device *sdev = bp->sdev;
1267 bool was_enabled;
1267 1268
1268 if (ssb_device_is_enabled(bp->sdev)) { 1269 was_enabled = ssb_device_is_enabled(bp->sdev);
1270
1271 ssb_device_enable(bp->sdev, 0);
1272 ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
1273
1274 if (was_enabled) {
1269 bw32(bp, B44_RCV_LAZY, 0); 1275 bw32(bp, B44_RCV_LAZY, 0);
1270 bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE); 1276 bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
1271 b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1); 1277 b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
@@ -1277,10 +1283,8 @@ static void b44_chip_reset(struct b44 *bp, int reset_kind)
1277 } 1283 }
1278 bw32(bp, B44_DMARX_CTRL, 0); 1284 bw32(bp, B44_DMARX_CTRL, 0);
1279 bp->rx_prod = bp->rx_cons = 0; 1285 bp->rx_prod = bp->rx_cons = 0;
1280 } else 1286 }
1281 ssb_pcicore_dev_irqvecs_enable(&sdev->bus->pcicore, sdev);
1282 1287
1283 ssb_device_enable(bp->sdev, 0);
1284 b44_clear_stats(bp); 1288 b44_clear_stats(bp);
1285 1289
1286 /* 1290 /*
@@ -2153,6 +2157,7 @@ static int __devinit b44_init_one(struct ssb_device *sdev,
2153 bp = netdev_priv(dev); 2157 bp = netdev_priv(dev);
2154 bp->sdev = sdev; 2158 bp->sdev = sdev;
2155 bp->dev = dev; 2159 bp->dev = dev;
2160 bp->force_copybreak = 0;
2156 2161
2157 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE); 2162 bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
2158 2163
@@ -2235,6 +2240,7 @@ static void __devexit b44_remove_one(struct ssb_device *sdev)
2235 struct net_device *dev = ssb_get_drvdata(sdev); 2240 struct net_device *dev = ssb_get_drvdata(sdev);
2236 2241
2237 unregister_netdev(dev); 2242 unregister_netdev(dev);
2243 ssb_device_disable(sdev, 0);
2238 ssb_bus_may_powerdown(sdev->bus); 2244 ssb_bus_may_powerdown(sdev->bus);
2239 free_netdev(dev); 2245 free_netdev(dev);
2240 ssb_pcihost_set_power_state(sdev, PCI_D3hot); 2246 ssb_pcihost_set_power_state(sdev, PCI_D3hot);