1 From 6f70340698333f14b1d9c9e913c5de8f66b72c55 Mon Sep 17 00:00:00 2001
2 From: Dhananjay Phadke <dhananjay@netxen.com>
3 Date: Wed, 14 Jan 2009 20:50:00 -0800
4 Subject: netxen: handle dma mapping failures
5 Acked-by: Karsten Keil <kkeil@novell.com>
8 o Bail out if pci_map_single() fails while replenishing rx ring.
9 o Drop packet if pci_map_{single,page}() fail in tx.
11 Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
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(-)
19 Index: 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 {
25 struct netxen_rx_buffer *rx_buf_arr; /* rx buffers for receive */
26 struct list_head free_list;
31 Index: 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
37 memset(rds_ring->rx_buf_arr, 0, RCV_BUFFSIZE);
38 INIT_LIST_HEAD(&rds_ring->free_list);
39 - rds_ring->begin_alloc = 0;
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;
48 netxen_ctx_msg msg = 0;
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];
54 producer = rds_ring->producer;
55 - index = rds_ring->begin_alloc;
56 head = &rds_ring->free_list;
58 /* We can start writing rx descriptors into the phantom memory. */
59 @@ -1453,39 +1450,37 @@ void netxen_post_rx_buffers(struct netxe
61 skb = dev_alloc_skb(rds_ring->skb_size);
63 - rds_ring->begin_alloc = index;
67 + if (!adapter->ahw.cut_through)
68 + skb_reserve(skb, 2);
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);
78 buffer = list_entry(head->next, struct netxen_rx_buffer, list);
79 list_del(&buffer->list);
81 - count++; /* now there should be no failure */
82 - pdesc = &rds_ring->desc_head[producer];
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;
90 - dma = pci_map_single(pdev, skb->data, rds_ring->dma_size,
91 - PCI_DMA_FROMDEVICE);
92 - pdesc->addr_buffer = cpu_to_le64(dma);
94 buffer->state = NETXEN_BUFFER_BUSY;
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");
104 - get_next_index(producer, rds_ring->max_rx_desc_count);
105 - index = get_next_index(index, rds_ring->max_rx_desc_count);
107 + producer = get_next_index(producer, rds_ring->max_rx_desc_count);
109 /* if we did allocate buffers, then write the count to Phantom */
111 - rds_ring->begin_alloc = index;
112 rds_ring->producer = producer;
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;
120 struct list_head *head;
123 rds_ring = &recv_ctx->rds_rings[ringid];
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)) {
131 skb = dev_alloc_skb(rds_ring->skb_size);
132 if (unlikely(!skb)) {
133 - rds_ring->begin_alloc = index;
137 + if (!adapter->ahw.cut_through)
138 + skb_reserve(skb, 2);
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);
148 buffer = list_entry(head->next, struct netxen_rx_buffer, list);
149 list_del(&buffer->list);
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);
156 buffer->state = NETXEN_BUFFER_BUSY;
157 - buffer->dma = pci_map_single(pdev, skb->data,
158 - rds_ring->dma_size,
159 - PCI_DMA_FROMDEVICE);
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);
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];
172 + producer = get_next_index(producer, rds_ring->max_rx_desc_count);
175 /* if we did allocate buffers, then write the count to Phantom */
177 - rds_ring->begin_alloc = index;
178 rds_ring->producer = producer;
180 adapter->pci_write_normalize(adapter,
181 Index: 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_
190 +netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
191 + struct netxen_cmd_buffer *pbuf, int last)
194 + struct netxen_skb_frag *buffrag;
196 + buffrag = &pbuf->frag_array[0];
197 + pci_unmap_single(pdev, buffrag->dma,
198 + buffrag->length, PCI_DMA_TODEVICE);
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);
207 static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
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;
218 u32 producer, consumer;
219 @@ -1229,8 +1249,12 @@ static int netxen_nic_xmit_frame(struct
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,
226 + if (pci_dma_mapping_error(pdev, temp_dma))
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;
236 unsigned long offset;
237 - dma_addr_t temp_dma;
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;
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);
254 buffrag->dma = temp_dma;
255 @@ -1334,6 +1361,11 @@ static int netxen_nic_xmit_frame(struct
256 netdev->trans_start = jiffies;
261 + adapter->stats.txdropped++;
262 + dev_kfree_skb_any(skb);
263 + return NETDEV_TX_OK;
266 static int netxen_nic_check_temp(struct netxen_adapter *adapter)