aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2014-08-12 04:35:19 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-13 23:04:46 -0400
commit10545937e866ccdbb7ab583031dbdcc6b14e4eb4 (patch)
tree7b9254702b49e25ada44dc95c72688c63ce2a5ce /drivers/net/ethernet
parent3791b3f6fb74d265c93d493d9bbf29c1e769ceae (diff)
myri10ge: check for DMA mapping errors
On IOMMU systems DMA mapping can fail, we need to check for that possibility. Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/myricom/myri10ge/myri10ge.c88
1 files changed, 58 insertions, 30 deletions
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
index 69c26f04d8ce..679db026f4be 100644
--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c
@@ -873,6 +873,10 @@ static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
873 return -ENOMEM; 873 return -ENOMEM;
874 dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, 874 dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
875 DMA_BIDIRECTIONAL); 875 DMA_BIDIRECTIONAL);
876 if (unlikely(pci_dma_mapping_error(mgp->pdev, dmatest_bus))) {
877 __free_page(dmatest_page);
878 return -ENOMEM;
879 }
876 880
877 /* Run a small DMA test. 881 /* Run a small DMA test.
878 * The magic multipliers to the length tell the firmware 882 * The magic multipliers to the length tell the firmware
@@ -1294,6 +1298,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
1294 int bytes, int watchdog) 1298 int bytes, int watchdog)
1295{ 1299{
1296 struct page *page; 1300 struct page *page;
1301 dma_addr_t bus;
1297 int idx; 1302 int idx;
1298#if MYRI10GE_ALLOC_SIZE > 4096 1303#if MYRI10GE_ALLOC_SIZE > 4096
1299 int end_offset; 1304 int end_offset;
@@ -1318,11 +1323,21 @@ myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
1318 rx->watchdog_needed = 1; 1323 rx->watchdog_needed = 1;
1319 return; 1324 return;
1320 } 1325 }
1326
1327 bus = pci_map_page(mgp->pdev, page, 0,
1328 MYRI10GE_ALLOC_SIZE,
1329 PCI_DMA_FROMDEVICE);
1330 if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
1331 __free_pages(page, MYRI10GE_ALLOC_ORDER);
1332 if (rx->fill_cnt - rx->cnt < 16)
1333 rx->watchdog_needed = 1;
1334 return;
1335 }
1336
1321 rx->page = page; 1337 rx->page = page;
1322 rx->page_offset = 0; 1338 rx->page_offset = 0;
1323 rx->bus = pci_map_page(mgp->pdev, page, 0, 1339 rx->bus = bus;
1324 MYRI10GE_ALLOC_SIZE, 1340
1325 PCI_DMA_FROMDEVICE);
1326 } 1341 }
1327 rx->info[idx].page = rx->page; 1342 rx->info[idx].page = rx->page;
1328 rx->info[idx].page_offset = rx->page_offset; 1343 rx->info[idx].page_offset = rx->page_offset;
@@ -2764,6 +2779,35 @@ myri10ge_submit_req(struct myri10ge_tx_buf *tx, struct mcp_kreq_ether_send *src,
2764 mb(); 2779 mb();
2765} 2780}
2766 2781
2782static void myri10ge_unmap_tx_dma(struct myri10ge_priv *mgp,
2783 struct myri10ge_tx_buf *tx, int idx)
2784{
2785 unsigned int len;
2786 int last_idx;
2787
2788 /* Free any DMA resources we've alloced and clear out the skb slot */
2789 last_idx = (idx + 1) & tx->mask;
2790 idx = tx->req & tx->mask;
2791 do {
2792 len = dma_unmap_len(&tx->info[idx], len);
2793 if (len) {
2794 if (tx->info[idx].skb != NULL)
2795 pci_unmap_single(mgp->pdev,
2796 dma_unmap_addr(&tx->info[idx],
2797 bus), len,
2798 PCI_DMA_TODEVICE);
2799 else
2800 pci_unmap_page(mgp->pdev,
2801 dma_unmap_addr(&tx->info[idx],
2802 bus), len,
2803 PCI_DMA_TODEVICE);
2804 dma_unmap_len_set(&tx->info[idx], len, 0);
2805 tx->info[idx].skb = NULL;
2806 }
2807 idx = (idx + 1) & tx->mask;
2808 } while (idx != last_idx);
2809}
2810
2767/* 2811/*
2768 * Transmit a packet. We need to split the packet so that a single 2812 * Transmit a packet. We need to split the packet so that a single
2769 * segment does not cross myri10ge->tx_boundary, so this makes segment 2813 * segment does not cross myri10ge->tx_boundary, so this makes segment
@@ -2787,7 +2831,7 @@ static netdev_tx_t myri10ge_xmit(struct sk_buff *skb,
2787 u32 low; 2831 u32 low;
2788 __be32 high_swapped; 2832 __be32 high_swapped;
2789 unsigned int len; 2833 unsigned int len;
2790 int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments; 2834 int idx, avail, frag_cnt, frag_idx, count, mss, max_segments;
2791 u16 pseudo_hdr_offset, cksum_offset, queue; 2835 u16 pseudo_hdr_offset, cksum_offset, queue;
2792 int cum_len, seglen, boundary, rdma_count; 2836 int cum_len, seglen, boundary, rdma_count;
2793 u8 flags, odd_flag; 2837 u8 flags, odd_flag;
@@ -2884,9 +2928,12 @@ again:
2884 2928
2885 /* map the skb for DMA */ 2929 /* map the skb for DMA */
2886 len = skb_headlen(skb); 2930 len = skb_headlen(skb);
2931 bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
2932 if (unlikely(pci_dma_mapping_error(mgp->pdev, bus)))
2933 goto drop;
2934
2887 idx = tx->req & tx->mask; 2935 idx = tx->req & tx->mask;
2888 tx->info[idx].skb = skb; 2936 tx->info[idx].skb = skb;
2889 bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE);
2890 dma_unmap_addr_set(&tx->info[idx], bus, bus); 2937 dma_unmap_addr_set(&tx->info[idx], bus, bus);
2891 dma_unmap_len_set(&tx->info[idx], len, len); 2938 dma_unmap_len_set(&tx->info[idx], len, len);
2892 2939
@@ -2985,12 +3032,16 @@ again:
2985 break; 3032 break;
2986 3033
2987 /* map next fragment for DMA */ 3034 /* map next fragment for DMA */
2988 idx = (count + tx->req) & tx->mask;
2989 frag = &skb_shinfo(skb)->frags[frag_idx]; 3035 frag = &skb_shinfo(skb)->frags[frag_idx];
2990 frag_idx++; 3036 frag_idx++;
2991 len = skb_frag_size(frag); 3037 len = skb_frag_size(frag);
2992 bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len, 3038 bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len,
2993 DMA_TO_DEVICE); 3039 DMA_TO_DEVICE);
3040 if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) {
3041 myri10ge_unmap_tx_dma(mgp, tx, idx);
3042 goto drop;
3043 }
3044 idx = (count + tx->req) & tx->mask;
2994 dma_unmap_addr_set(&tx->info[idx], bus, bus); 3045 dma_unmap_addr_set(&tx->info[idx], bus, bus);
2995 dma_unmap_len_set(&tx->info[idx], len, len); 3046 dma_unmap_len_set(&tx->info[idx], len, len);
2996 } 3047 }
@@ -3021,31 +3072,8 @@ again:
3021 return NETDEV_TX_OK; 3072 return NETDEV_TX_OK;
3022 3073
3023abort_linearize: 3074abort_linearize:
3024 /* Free any DMA resources we've alloced and clear out the skb 3075 myri10ge_unmap_tx_dma(mgp, tx, idx);
3025 * slot so as to not trip up assertions, and to avoid a
3026 * double-free if linearizing fails */
3027 3076
3028 last_idx = (idx + 1) & tx->mask;
3029 idx = tx->req & tx->mask;
3030 tx->info[idx].skb = NULL;
3031 do {
3032 len = dma_unmap_len(&tx->info[idx], len);
3033 if (len) {
3034 if (tx->info[idx].skb != NULL)
3035 pci_unmap_single(mgp->pdev,
3036 dma_unmap_addr(&tx->info[idx],
3037 bus), len,
3038 PCI_DMA_TODEVICE);
3039 else
3040 pci_unmap_page(mgp->pdev,
3041 dma_unmap_addr(&tx->info[idx],
3042 bus), len,
3043 PCI_DMA_TODEVICE);
3044 dma_unmap_len_set(&tx->info[idx], len, 0);
3045 tx->info[idx].skb = NULL;
3046 }
3047 idx = (idx + 1) & tx->mask;
3048 } while (idx != last_idx);
3049 if (skb_is_gso(skb)) { 3077 if (skb_is_gso(skb)) {
3050 netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n"); 3078 netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n");
3051 goto drop; 3079 goto drop;