aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
authorDhananjay Phadke <dhananjay@netxen.com>2009-01-14 23:50:00 -0500
committerDavid S. Miller <davem@davemloft.net>2009-01-14 23:50:00 -0500
commit6f70340698333f14b1d9c9e913c5de8f66b72c55 (patch)
tree52733b9edfee2fcaa396054cbf44555b142e2fd1 /drivers/net/netxen/netxen_nic_main.c
parent03e678ee968ae54b79c1580c2935895bd863ad95 (diff)
netxen: handle dma mapping failures
o Bail out if pci_map_single() fails while replenishing rx ring. o Drop packet if pci_map_{single,page}() fail in tx. Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c38
1 files changed, 35 insertions, 3 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 9268fd2fbacf..86867405a367 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -1200,6 +1200,24 @@ static bool netxen_tso_check(struct net_device *netdev,
1200 return tso; 1200 return tso;
1201} 1201}
1202 1202
1203static void
1204netxen_clean_tx_dma_mapping(struct pci_dev *pdev,
1205 struct netxen_cmd_buffer *pbuf, int last)
1206{
1207 int k;
1208 struct netxen_skb_frag *buffrag;
1209
1210 buffrag = &pbuf->frag_array[0];
1211 pci_unmap_single(pdev, buffrag->dma,
1212 buffrag->length, PCI_DMA_TODEVICE);
1213
1214 for (k = 1; k < last; k++) {
1215 buffrag = &pbuf->frag_array[k];
1216 pci_unmap_page(pdev, buffrag->dma,
1217 buffrag->length, PCI_DMA_TODEVICE);
1218 }
1219}
1220
1203static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 1221static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1204{ 1222{
1205 struct netxen_adapter *adapter = netdev_priv(netdev); 1223 struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1208,6 +1226,8 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1208 struct netxen_cmd_buffer *pbuf; 1226 struct netxen_cmd_buffer *pbuf;
1209 struct netxen_skb_frag *buffrag; 1227 struct netxen_skb_frag *buffrag;
1210 struct cmd_desc_type0 *hwdesc; 1228 struct cmd_desc_type0 *hwdesc;
1229 struct pci_dev *pdev = adapter->pdev;
1230 dma_addr_t temp_dma;
1211 int i, k; 1231 int i, k;
1212 1232
1213 u32 producer, consumer; 1233 u32 producer, consumer;
@@ -1240,8 +1260,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1240 pbuf->skb = skb; 1260 pbuf->skb = skb;
1241 pbuf->frag_count = frag_count; 1261 pbuf->frag_count = frag_count;
1242 buffrag = &pbuf->frag_array[0]; 1262 buffrag = &pbuf->frag_array[0];
1243 buffrag->dma = pci_map_single(adapter->pdev, skb->data, first_seg_len, 1263 temp_dma = pci_map_single(pdev, skb->data, first_seg_len,
1244 PCI_DMA_TODEVICE); 1264 PCI_DMA_TODEVICE);
1265 if (pci_dma_mapping_error(pdev, temp_dma))
1266 goto drop_packet;
1267
1268 buffrag->dma = temp_dma;
1245 buffrag->length = first_seg_len; 1269 buffrag->length = first_seg_len;
1246 netxen_set_tx_frags_len(hwdesc, frag_count, skb->len); 1270 netxen_set_tx_frags_len(hwdesc, frag_count, skb->len);
1247 netxen_set_tx_port(hwdesc, adapter->portnum); 1271 netxen_set_tx_port(hwdesc, adapter->portnum);
@@ -1253,7 +1277,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1253 struct skb_frag_struct *frag; 1277 struct skb_frag_struct *frag;
1254 int len, temp_len; 1278 int len, temp_len;
1255 unsigned long offset; 1279 unsigned long offset;
1256 dma_addr_t temp_dma;
1257 1280
1258 /* move to next desc. if there is a need */ 1281 /* move to next desc. if there is a need */
1259 if ((i & 0x3) == 0) { 1282 if ((i & 0x3) == 0) {
@@ -1269,8 +1292,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1269 offset = frag->page_offset; 1292 offset = frag->page_offset;
1270 1293
1271 temp_len = len; 1294 temp_len = len;
1272 temp_dma = pci_map_page(adapter->pdev, frag->page, offset, 1295 temp_dma = pci_map_page(pdev, frag->page, offset,
1273 len, PCI_DMA_TODEVICE); 1296 len, PCI_DMA_TODEVICE);
1297 if (pci_dma_mapping_error(pdev, temp_dma)) {
1298 netxen_clean_tx_dma_mapping(pdev, pbuf, i);
1299 goto drop_packet;
1300 }
1274 1301
1275 buffrag++; 1302 buffrag++;
1276 buffrag->dma = temp_dma; 1303 buffrag->dma = temp_dma;
@@ -1345,6 +1372,11 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
1345 netdev->trans_start = jiffies; 1372 netdev->trans_start = jiffies;
1346 1373
1347 return NETDEV_TX_OK; 1374 return NETDEV_TX_OK;
1375
1376drop_packet:
1377 adapter->stats.txdropped++;
1378 dev_kfree_skb_any(skb);
1379 return NETDEV_TX_OK;
1348} 1380}
1349 1381
1350static int netxen_nic_check_temp(struct netxen_adapter *adapter) 1382static int netxen_nic_check_temp(struct netxen_adapter *adapter)