]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/netxen-handle-dma-mapping-failures.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / netxen-handle-dma-mapping-failures.patch
CommitLineData
00e5a55c
BS
1From 6f70340698333f14b1d9c9e913c5de8f66b72c55 Mon Sep 17 00:00:00 2001
2From: Dhananjay Phadke <dhananjay@netxen.com>
3Date: Wed, 14 Jan 2009 20:50:00 -0800
4Subject: netxen: handle dma mapping failures
5Acked-by: Karsten Keil <kkeil@novell.com>
6Reference: bnc#472416
7
8o Bail out if pci_map_single() fails while replenishing rx ring.
9o Drop packet if pci_map_{single,page}() fail in tx.
10
11Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
12Signed-off-by: David S. Miller <davem@davemloft.net>
13---
14 drivers/net/netxen/netxen_nic.h | 1 -
15 drivers/net/netxen/netxen_nic_init.c | 68 ++++++++++++++++------------------
16 drivers/net/netxen/netxen_nic_main.c | 38 +++++++++++++++++-
17 3 files changed, 67 insertions(+), 40 deletions(-)
18
19Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic.h
20===================================================================
21--- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic.h
22+++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic.h
23@@ -860,7 +860,6 @@ struct nx_host_rds_ring {
24 u32 skb_size;
25 struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
26 struct list_head free_list;
27- int begin_alloc;
28 };
29
30 /*
31Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_init.c
32===================================================================
33--- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic_init.c
34+++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_init.c
35@@ -308,7 +308,6 @@ int netxen_alloc_sw_resources(struct net
36 }
37 memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
38 INIT_LIST_HEAD(&rds_ring->free_list);
39- rds_ring->begin_alloc = 0;
40 /*
41 * Now go through all of them, set reference handles
42 * and put them in the queues.
43@@ -1437,7 +1436,6 @@ void netxen_post_rx_buffers(struct netxe
44 struct rcv_desc *pdesc;
45 struct netxen_rx_buffer *buffer;
46 int count = 0;
47- int index = 0;
48 netxen_ctx_msg msg = 0;
49 dma_addr_t dma;
50 struct list_head *head;
51@@ -1445,7 +1443,6 @@ void netxen_post_rx_buffers(struct netxe
52 rds_ring = &recv_ctx->rds_rings[ringid];
53
54 producer = rds_ring->producer;
55- index = rds_ring->begin_alloc;
56 head = &rds_ring->free_list;
57
58 /* We can start writing rx descriptors into the phantom memory. */
59@@ -1453,39 +1450,37 @@ void netxen_post_rx_buffers(struct netxe
60
61 skb = dev_alloc_skb(rds_ring->skb_size);
62 if (unlikely(!skb)) {
63- rds_ring->begin_alloc = index;
64 break;
65 }
66
67+ if (!adapter->ahw.cut_through)
68+ skb_reserve(skb, 2);
69+
70+ dma = pci_map_single(pdev, skb->data,
71+ rds_ring->dma_size, PCI_DMA_FROMDEVICE);
72+ if (pci_dma_mapping_error(pdev, dma)) {
73+ dev_kfree_skb_any(skb);
74+ break;
75+ }
76+
77+ count++;
78 buffer = list_entry(head->next, struct netxen_rx_buffer, list);
79 list_del(&buffer->list);
80
81- count++; /* now there should be no failure */
82- pdesc = &rds_ring->desc_head[producer];
83-
84- if (!adapter->ahw.cut_through)
85- skb_reserve(skb, 2);
86- /* This will be setup when we receive the
87- * buffer after it has been filled FSL TBD TBD
88- * skb->dev = netdev;
89- */
90- dma = pci_map_single(pdev, skb->data, rds_ring->dma_size,
91- PCI_DMA_FROMDEVICE);
92- pdesc->addr_buffer = cpu_to_le64(dma);
93 buffer->skb = skb;
94 buffer->state = NETXEN_BUFFER_BUSY;
95 buffer->dma = dma;
96+
97 /* make a rcv descriptor */
98+ pdesc = &rds_ring->desc_head[producer];
99+ pdesc->addr_buffer = cpu_to_le64(dma);
100 pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
101 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
102- DPRINTK(INFO, "done writing descripter\n");
103- producer =
104- get_next_index(producer, rds_ring->max_rx_desc_count);
105- index = get_next_index(index, rds_ring->max_rx_desc_count);
106+
107+ producer = get_next_index(producer, rds_ring->max_rx_desc_count);
108 }
109 /* if we did allocate buffers, then write the count to Phantom */
110 if (count) {
111- rds_ring->begin_alloc = index;
112 rds_ring->producer = producer;
113 /* Window = 1 */
114 adapter->pci_write_normalize(adapter,
115@@ -1524,49 +1519,50 @@ static void netxen_post_rx_buffers_nodb(
116 struct rcv_desc *pdesc;
117 struct netxen_rx_buffer *buffer;
118 int count = 0;
119- int index = 0;
120 struct list_head *head;
121+ dma_addr_t dma;
122
123 rds_ring = &recv_ctx->rds_rings[ringid];
124
125 producer = rds_ring->producer;
126- index = rds_ring->begin_alloc;
127 head = &rds_ring->free_list;
128 /* We can start writing rx descriptors into the phantom memory. */
129 while (!list_empty(head)) {
130
131 skb = dev_alloc_skb(rds_ring->skb_size);
132 if (unlikely(!skb)) {
133- rds_ring->begin_alloc = index;
134 break;
135 }
136
137+ if (!adapter->ahw.cut_through)
138+ skb_reserve(skb, 2);
139+
140+ dma = pci_map_single(pdev, skb->data,
141+ rds_ring->dma_size, PCI_DMA_FROMDEVICE);
142+ if (pci_dma_mapping_error(pdev, dma)) {
143+ dev_kfree_skb_any(skb);
144+ break;
145+ }
146+
147+ count++;
148 buffer = list_entry(head->next, struct netxen_rx_buffer, list);
149 list_del(&buffer->list);
150
151- count++; /* now there should be no failure */
152- pdesc = &rds_ring->desc_head[producer];
153- if (!adapter->ahw.cut_through)
154- skb_reserve(skb, 2);
155 buffer->skb = skb;
156 buffer->state = NETXEN_BUFFER_BUSY;
157- buffer->dma = pci_map_single(pdev, skb->data,
158- rds_ring->dma_size,
159- PCI_DMA_FROMDEVICE);
160+ buffer->dma = dma;
161
162 /* make a rcv descriptor */
163+ pdesc = &rds_ring->desc_head[producer];
164 pdesc->reference_handle = cpu_to_le16(buffer->ref_handle);
165 pdesc->buffer_length = cpu_to_le32(rds_ring->dma_size);
166 pdesc->addr_buffer = cpu_to_le64(buffer->dma);
167- producer =
168- get_next_index(producer, rds_ring->max_rx_desc_count);
169- index = get_next_index(index, rds_ring->max_rx_desc_count);
170- buffer = &rds_ring->rx_buf_arr[index];
171+
172+ producer = get_next_index(producer, rds_ring->max_rx_desc_count);
173 }
174
175 /* if we did allocate buffers, then write the count to Phantom */
176 if (count) {
177- rds_ring->begin_alloc = index;
178 rds_ring->producer = producer;
179 /* Window = 1 */
180 adapter->pci_write_normalize(adapter,
181Index: linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_main.c
182===================================================================
183--- linux-2.6.27-kketmp.orig/drivers/net/netxen/netxen_nic_main.c
184+++ linux-2.6.27-kketmp/drivers/net/netxen/netxen_nic_main.c
185@@ -1189,6 +1189,24 @@ static bool netxen_tso_check(struct net_
186 return tso;
187 }
188
189+static void
190+netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
191+ struct netxen_cmd_buffer *pbuf, int last)
192+{
193+ int k;
194+ struct netxen_skb_frag *buffrag;
195+
196+ buffrag = &pbuf->frag_array[0];
197+ pci_unmap_single(pdev, buffrag->dma,
198+ buffrag->length, PCI_DMA_TODEVICE);
199+
200+ for (k = 1; k < last; k++) {
201+ buffrag = &pbuf->frag_array[k];
202+ pci_unmap_page(pdev, buffrag->dma,
203+ buffrag->length, PCI_DMA_TODEVICE);
204+ }
205+}
206+
207 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
208 {
209 struct netxen_adapter *adapter = netdev_priv(netdev);
210@@ -1197,6 +1215,8 @@ static int netxen_nic_xmit_frame(struct
211 struct netxen_cmd_buffer *pbuf;
212 struct netxen_skb_frag *buffrag;
213 struct cmd_desc_type0 *hwdesc;
214+ struct pci_dev *pdev = adapter->pdev;
215+ dma_addr_t temp_dma;
216 int i, k;
217
218 u32 producer, consumer;
219@@ -1229,8 +1249,12 @@ static int netxen_nic_xmit_frame(struct
220 pbuf->skb = skb;
221 pbuf->frag_count = frag_count;
222 buffrag = &pbuf->frag_array[0];
223- buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len,
224+ temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
225 PCI_DMA_TODEVICE);
226+ if (pci_dma_mapping_error(pdev, temp_dma))
227+ goto drop_packet;
228+
229+ buffrag->dma = temp_dma;
230 buffrag->length = first_seg_len;
231 netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
232 netxen_set_tx_port(hwdesc, adapter->portnum);
233@@ -1242,7 +1266,6 @@ static int netxen_nic_xmit_frame(struct
234 struct skb_frag_struct *frag;
235 int len, temp_len;
236 unsigned long offset;
237- dma_addr_t temp_dma;
238
239 /* move to next desc. if there is a need */
240 if ((i & 0x3) == 0) {
241@@ -1258,8 +1281,12 @@ static int netxen_nic_xmit_frame(struct
242 offset = frag->page_offset;
243
244 temp_len = len;
245- temp_dma = pci_map_page(adapter->pdev, frag->page, offset,
246+ temp_dma = pci_map_page(pdev, frag->page, offset,
247 len, PCI_DMA_TODEVICE);
248+ if (pci_dma_mapping_error(pdev, temp_dma)) {
249+ netxen_clean_tx_dma_mapping(pdev, pbuf, i);
250+ goto drop_packet;
251+ }
252
253 buffrag++;
254 buffrag->dma = temp_dma;
255@@ -1334,6 +1361,11 @@ static int netxen_nic_xmit_frame(struct
256 netdev->trans_start = jiffies;
257
258 return NETDEV_TX_OK;
259+
260+drop_packet:
261+ adapter->stats.txdropped++;
262+ dev_kfree_skb_any(skb);
263+ return NETDEV_TX_OK;
264 }
265
266 static int netxen_nic_check_temp(struct netxen_adapter *adapter)