aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorMike McCormack <mikem@ring3k.org>2010-02-12 01:58:03 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-12 19:21:02 -0500
commit200ac492b3c366346fcabd11897fadbd1a7a6599 (patch)
tree1dbf91be83168ca6ec6d3612544d58ca3f96fac6 /drivers/net/sky2.c
parent39ef110ba859f44efeb9a88d0e85316cd1bbecda (diff)
sky2: Allocate initial skbs in sky2_alloc_buffers
Allocate everything in one place so there's a single point of failure in sky2_up, and sky2_rx_start can no longer fail. Don't leave the hardware in a partially initialized state in the case rx ring allocation fails. As with the old code, the rx ring still needs to be fully allocated for sky2_up to succeed. Signed-off-by: Mike McCormack <mikem@ring3k.org> Acked-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index c5de65c6f6e1..493a82018cbd 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -1363,8 +1363,32 @@ static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
1363 sky2_put_idx(sky2->hw, rxq, sky2->rx_put); 1363 sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
1364} 1364}
1365 1365
1366static int sky2_alloc_rx_skbs(struct sky2_port *sky2)
1367{
1368 struct sky2_hw *hw = sky2->hw;
1369 unsigned i;
1370
1371 sky2->rx_data_size = sky2_get_rx_data_size(sky2);
1372
1373 /* Fill Rx ring */
1374 for (i = 0; i < sky2->rx_pending; i++) {
1375 struct rx_ring_info *re = sky2->rx_ring + i;
1376
1377 re->skb = sky2_rx_alloc(sky2);
1378 if (!re->skb)
1379 return -ENOMEM;
1380
1381 if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
1382 dev_kfree_skb(re->skb);
1383 re->skb = NULL;
1384 return -ENOMEM;
1385 }
1386 }
1387 return 0;
1388}
1389
1366/* 1390/*
1367 * Allocate and setup receiver buffer pool. 1391 * Setup receiver buffer pool.
1368 * Normal case this ends up creating one list element for skb 1392 * Normal case this ends up creating one list element for skb
1369 * in the receive ring. Worst case if using large MTU and each 1393 * in the receive ring. Worst case if using large MTU and each
1370 * allocation falls on a different 64 bit region, that results 1394 * allocation falls on a different 64 bit region, that results
@@ -1372,7 +1396,7 @@ static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
1372 * One element is used for checksum enable/disable, and one 1396 * One element is used for checksum enable/disable, and one
1373 * extra to avoid wrap. 1397 * extra to avoid wrap.
1374 */ 1398 */
1375static int sky2_rx_start(struct sky2_port *sky2) 1399static void sky2_rx_start(struct sky2_port *sky2)
1376{ 1400{
1377 struct sky2_hw *hw = sky2->hw; 1401 struct sky2_hw *hw = sky2->hw;
1378 struct rx_ring_info *re; 1402 struct rx_ring_info *re;
@@ -1398,22 +1422,9 @@ static int sky2_rx_start(struct sky2_port *sky2)
1398 if (!(hw->flags & SKY2_HW_NEW_LE)) 1422 if (!(hw->flags & SKY2_HW_NEW_LE))
1399 rx_set_checksum(sky2); 1423 rx_set_checksum(sky2);
1400 1424
1401 sky2->rx_data_size = sky2_get_rx_data_size(sky2); 1425 /* submit Rx ring */
1402
1403 /* Fill Rx ring */
1404 for (i = 0; i < sky2->rx_pending; i++) { 1426 for (i = 0; i < sky2->rx_pending; i++) {
1405 re = sky2->rx_ring + i; 1427 re = sky2->rx_ring + i;
1406
1407 re->skb = sky2_rx_alloc(sky2);
1408 if (!re->skb)
1409 goto nomem;
1410
1411 if (sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size)) {
1412 dev_kfree_skb(re->skb);
1413 re->skb = NULL;
1414 goto nomem;
1415 }
1416
1417 sky2_rx_submit(sky2, re); 1428 sky2_rx_submit(sky2, re);
1418 } 1429 }
1419 1430
@@ -1455,13 +1466,6 @@ static int sky2_rx_start(struct sky2_port *sky2)
1455 sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST), 1466 sky2_write32(hw, Q_ADDR(txqaddr[sky2->port], Q_TEST),
1456 TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN); 1467 TBMU_TEST_HOME_ADD_FIX_EN | TBMU_TEST_ROUTING_ADD_FIX_EN);
1457 } 1468 }
1458
1459
1460
1461 return 0;
1462nomem:
1463 sky2_rx_clean(sky2);
1464 return -ENOMEM;
1465} 1469}
1466 1470
1467static int sky2_alloc_buffers(struct sky2_port *sky2) 1471static int sky2_alloc_buffers(struct sky2_port *sky2)
@@ -1492,7 +1496,7 @@ static int sky2_alloc_buffers(struct sky2_port *sky2)
1492 if (!sky2->rx_ring) 1496 if (!sky2->rx_ring)
1493 goto nomem; 1497 goto nomem;
1494 1498
1495 return 0; 1499 return sky2_alloc_rx_skbs(sky2);
1496nomem: 1500nomem:
1497 return -ENOMEM; 1501 return -ENOMEM;
1498} 1502}
@@ -1501,6 +1505,8 @@ static void sky2_free_buffers(struct sky2_port *sky2)
1501{ 1505{
1502 struct sky2_hw *hw = sky2->hw; 1506 struct sky2_hw *hw = sky2->hw;
1503 1507
1508 sky2_rx_clean(sky2);
1509
1504 if (sky2->rx_le) { 1510 if (sky2->rx_le) {
1505 pci_free_consistent(hw->pdev, RX_LE_BYTES, 1511 pci_free_consistent(hw->pdev, RX_LE_BYTES,
1506 sky2->rx_le, sky2->rx_le_map); 1512 sky2->rx_le, sky2->rx_le_map);
@@ -1590,9 +1596,7 @@ static int sky2_up(struct net_device *dev)
1590 sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL); 1596 sky2_set_vlan_mode(hw, port, sky2->vlgrp != NULL);
1591#endif 1597#endif
1592 1598
1593 err = sky2_rx_start(sky2); 1599 sky2_rx_start(sky2);
1594 if (err)
1595 goto err_out;
1596 1600
1597 /* Enable interrupts from phy/mac for port */ 1601 /* Enable interrupts from phy/mac for port */
1598 imask = sky2_read32(hw, B0_IMSK); 1602 imask = sky2_read32(hw, B0_IMSK);
@@ -1960,8 +1964,6 @@ static int sky2_down(struct net_device *dev)
1960 /* Free any pending frames stuck in HW queue */ 1964 /* Free any pending frames stuck in HW queue */
1961 sky2_tx_complete(sky2, sky2->tx_prod); 1965 sky2_tx_complete(sky2, sky2->tx_prod);
1962 1966
1963 sky2_rx_clean(sky2);
1964
1965 sky2_free_buffers(sky2); 1967 sky2_free_buffers(sky2);
1966 1968
1967 return 0; 1969 return 0;
@@ -2257,7 +2259,11 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
2257 2259
2258 sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD); 2260 sky2_write8(hw, RB_ADDR(rxqaddr[port], RB_CTRL), RB_ENA_OP_MD);
2259 2261
2260 err = sky2_rx_start(sky2); 2262 err = sky2_alloc_rx_skbs(sky2);
2263 if (!err)
2264 sky2_rx_start(sky2);
2265 else
2266 sky2_rx_clean(sky2);
2261 sky2_write32(hw, B0_IMSK, imask); 2267 sky2_write32(hw, B0_IMSK, imask);
2262 2268
2263 sky2_read32(hw, B0_Y2_SP_LISR); 2269 sky2_read32(hw, B0_Y2_SP_LISR);