aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-11-17 19:47:21 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-18 17:26:26 -0500
commit4018517a1a69a85c3d61b20fa02f187b80773137 (patch)
tree08209615ff38b6c9e9af994c7360976e0a494ac6 /drivers/net/wireless/iwlwifi/iwl-agn.c
parent8e3bad65a59915f2ddc40f62a180ad81695d8440 (diff)
iwlagn: fix RX skb alignment
So I dug deeper into the DMA problems I had with iwlagn and a kind soul helped me in that he said something about pci-e alignment and mentioned the iwl_rx_allocate function to check for crossing 4KB boundaries. Since there's 8KB A-MPDU support, crossing 4k boundaries didn't seem like something the device would fail with, but when I looked into the function for a minute anyway I stumbled over this little gem: BUG_ON(rxb->dma_addr & (~DMA_BIT_MASK(36) & 0xff)); Clearly, that is a totally bogus check, one would hope the compiler removes it entirely. (Think about it) After fixing it, I obviously ran into it, nothing guarantees the alignment the way you want it, because of the way skbs and their headroom are allocated. I won't explain that here nor double-check that I'm right, that goes beyond what most of the CC'ed people care about. So then I came up with the patch below, and so far my system has survived minutes with 64K pages, when it would previously fail in seconds. And I haven't seen a single instance of the TX bug either. But when you see the patch it'll be pretty obvious to you why. This should fix the following reported kernel bugs: http://bugzilla.kernel.org/show_bug.cgi?id=11596 http://bugzilla.kernel.org/show_bug.cgi?id=11393 http://bugzilla.kernel.org/show_bug.cgi?id=11983 I haven't checked if there are any elsewhere, but I suppose RHBZ will have a few instances too... I'd like to ask anyone who is CC'ed (those are people I know ran into the bug) to try this patch. I am convinced that this patch is correct in spirit, but I haven't understood why, for example, there are so many unmap calls. I'm not entirely convinced that this is the only bug leading to the TX reply errors. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 6751bb2b8ae2..444c5cc05f03 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1384,7 +1384,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
1384 1384
1385 rxq->queue[i] = NULL; 1385 rxq->queue[i] = NULL;
1386 1386
1387 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->dma_addr, 1387 pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->aligned_dma_addr,
1388 priv->hw_params.rx_buf_size, 1388 priv->hw_params.rx_buf_size,
1389 PCI_DMA_FROMDEVICE); 1389 PCI_DMA_FROMDEVICE);
1390 pkt = (struct iwl_rx_packet *)rxb->skb->data; 1390 pkt = (struct iwl_rx_packet *)rxb->skb->data;
@@ -1436,8 +1436,8 @@ void iwl_rx_handle(struct iwl_priv *priv)
1436 rxb->skb = NULL; 1436 rxb->skb = NULL;
1437 } 1437 }
1438 1438
1439 pci_unmap_single(priv->pci_dev, rxb->dma_addr, 1439 pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
1440 priv->hw_params.rx_buf_size, 1440 priv->hw_params.rx_buf_size + 256,
1441 PCI_DMA_FROMDEVICE); 1441 PCI_DMA_FROMDEVICE);
1442 spin_lock_irqsave(&rxq->lock, flags); 1442 spin_lock_irqsave(&rxq->lock, flags);
1443 list_add_tail(&rxb->list, &priv->rxq.rx_used); 1443 list_add_tail(&rxb->list, &priv->rxq.rx_used);