diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2009-02-12 09:07:37 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:43:56 -0500 |
commit | e7d2f4dbd9224ba50d6d5331bb0538d2ce9027f8 (patch) | |
tree | 6ebbb38ee9761a0fc0d594d6e9e81c122d6eb890 /drivers/net/mv643xx_eth.c | |
parent | 3e5080344e95c0861a7ca494288593023ee383c6 (diff) |
mv643xx_eth: implement ethtool rx/tx ring size query and resizing
Rename the mp->default_[rt]x_ring_size variables to ->[rt]x_ring_size,
allow them to be read via the standard ethtool ->get_ringparam() op,
and add a ->set_ringparam() op to allow resizing them at run time.
Signed-off-by: Lennert Buytenhek <buytenh@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index c32d623061d9..89eaf3b3c760 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -286,6 +286,9 @@ struct mv643xx_eth_shared_private { | |||
286 | #define TX_BW_CONTROL_OLD_LAYOUT 1 | 286 | #define TX_BW_CONTROL_OLD_LAYOUT 1 |
287 | #define TX_BW_CONTROL_NEW_LAYOUT 2 | 287 | #define TX_BW_CONTROL_NEW_LAYOUT 2 |
288 | 288 | ||
289 | static int mv643xx_eth_open(struct net_device *dev); | ||
290 | static int mv643xx_eth_stop(struct net_device *dev); | ||
291 | |||
289 | 292 | ||
290 | /* per-port *****************************************************************/ | 293 | /* per-port *****************************************************************/ |
291 | struct mib_counters { | 294 | struct mib_counters { |
@@ -385,7 +388,7 @@ struct mv643xx_eth_private { | |||
385 | /* | 388 | /* |
386 | * RX state. | 389 | * RX state. |
387 | */ | 390 | */ |
388 | int default_rx_ring_size; | 391 | int rx_ring_size; |
389 | unsigned long rx_desc_sram_addr; | 392 | unsigned long rx_desc_sram_addr; |
390 | int rx_desc_sram_size; | 393 | int rx_desc_sram_size; |
391 | int rxq_count; | 394 | int rxq_count; |
@@ -395,7 +398,7 @@ struct mv643xx_eth_private { | |||
395 | /* | 398 | /* |
396 | * TX state. | 399 | * TX state. |
397 | */ | 400 | */ |
398 | int default_tx_ring_size; | 401 | int tx_ring_size; |
399 | unsigned long tx_desc_sram_addr; | 402 | unsigned long tx_desc_sram_addr; |
400 | int tx_desc_sram_size; | 403 | int tx_desc_sram_size; |
401 | int txq_count; | 404 | int txq_count; |
@@ -907,7 +910,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force) | |||
907 | 910 | ||
908 | if (skb != NULL) { | 911 | if (skb != NULL) { |
909 | if (skb_queue_len(&mp->rx_recycle) < | 912 | if (skb_queue_len(&mp->rx_recycle) < |
910 | mp->default_rx_ring_size && | 913 | mp->rx_ring_size && |
911 | skb_recycle_check(skb, mp->skb_size + | 914 | skb_recycle_check(skb, mp->skb_size + |
912 | dma_get_cache_alignment() - 1)) | 915 | dma_get_cache_alignment() - 1)) |
913 | __skb_queue_head(&mp->rx_recycle, skb); | 916 | __skb_queue_head(&mp->rx_recycle, skb); |
@@ -1485,6 +1488,46 @@ mv643xx_eth_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) | |||
1485 | return 0; | 1488 | return 0; |
1486 | } | 1489 | } |
1487 | 1490 | ||
1491 | static void | ||
1492 | mv643xx_eth_get_ringparam(struct net_device *dev, struct ethtool_ringparam *er) | ||
1493 | { | ||
1494 | struct mv643xx_eth_private *mp = netdev_priv(dev); | ||
1495 | |||
1496 | er->rx_max_pending = 4096; | ||
1497 | er->tx_max_pending = 4096; | ||
1498 | er->rx_mini_max_pending = 0; | ||
1499 | er->rx_jumbo_max_pending = 0; | ||
1500 | |||
1501 | er->rx_pending = mp->rx_ring_size; | ||
1502 | er->tx_pending = mp->tx_ring_size; | ||
1503 | er->rx_mini_pending = 0; | ||
1504 | er->rx_jumbo_pending = 0; | ||
1505 | } | ||
1506 | |||
1507 | static int | ||
1508 | mv643xx_eth_set_ringparam(struct net_device *dev, struct ethtool_ringparam *er) | ||
1509 | { | ||
1510 | struct mv643xx_eth_private *mp = netdev_priv(dev); | ||
1511 | |||
1512 | if (er->rx_mini_pending || er->rx_jumbo_pending) | ||
1513 | return -EINVAL; | ||
1514 | |||
1515 | mp->rx_ring_size = er->rx_pending < 4096 ? er->rx_pending : 4096; | ||
1516 | mp->tx_ring_size = er->tx_pending < 4096 ? er->tx_pending : 4096; | ||
1517 | |||
1518 | if (netif_running(dev)) { | ||
1519 | mv643xx_eth_stop(dev); | ||
1520 | if (mv643xx_eth_open(dev)) { | ||
1521 | dev_printk(KERN_ERR, &dev->dev, | ||
1522 | "fatal error on re-opening device after " | ||
1523 | "ring param change\n"); | ||
1524 | return -ENOMEM; | ||
1525 | } | ||
1526 | } | ||
1527 | |||
1528 | return 0; | ||
1529 | } | ||
1530 | |||
1488 | static void mv643xx_eth_get_strings(struct net_device *dev, | 1531 | static void mv643xx_eth_get_strings(struct net_device *dev, |
1489 | uint32_t stringset, uint8_t *data) | 1532 | uint32_t stringset, uint8_t *data) |
1490 | { | 1533 | { |
@@ -1541,6 +1584,8 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops = { | |||
1541 | .get_link = mv643xx_eth_get_link, | 1584 | .get_link = mv643xx_eth_get_link, |
1542 | .get_coalesce = mv643xx_eth_get_coalesce, | 1585 | .get_coalesce = mv643xx_eth_get_coalesce, |
1543 | .set_coalesce = mv643xx_eth_set_coalesce, | 1586 | .set_coalesce = mv643xx_eth_set_coalesce, |
1587 | .get_ringparam = mv643xx_eth_get_ringparam, | ||
1588 | .set_ringparam = mv643xx_eth_set_ringparam, | ||
1544 | .set_sg = ethtool_op_set_sg, | 1589 | .set_sg = ethtool_op_set_sg, |
1545 | .get_strings = mv643xx_eth_get_strings, | 1590 | .get_strings = mv643xx_eth_get_strings, |
1546 | .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, | 1591 | .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, |
@@ -1732,7 +1777,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) | |||
1732 | 1777 | ||
1733 | rxq->index = index; | 1778 | rxq->index = index; |
1734 | 1779 | ||
1735 | rxq->rx_ring_size = mp->default_rx_ring_size; | 1780 | rxq->rx_ring_size = mp->rx_ring_size; |
1736 | 1781 | ||
1737 | rxq->rx_desc_count = 0; | 1782 | rxq->rx_desc_count = 0; |
1738 | rxq->rx_curr_desc = 0; | 1783 | rxq->rx_curr_desc = 0; |
@@ -1832,7 +1877,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) | |||
1832 | 1877 | ||
1833 | txq->index = index; | 1878 | txq->index = index; |
1834 | 1879 | ||
1835 | txq->tx_ring_size = mp->default_tx_ring_size; | 1880 | txq->tx_ring_size = mp->tx_ring_size; |
1836 | 1881 | ||
1837 | txq->tx_desc_count = 0; | 1882 | txq->tx_desc_count = 0; |
1838 | txq->tx_curr_desc = 0; | 1883 | txq->tx_curr_desc = 0; |
@@ -2597,17 +2642,17 @@ static void set_params(struct mv643xx_eth_private *mp, | |||
2597 | else | 2642 | else |
2598 | uc_addr_get(mp, dev->dev_addr); | 2643 | uc_addr_get(mp, dev->dev_addr); |
2599 | 2644 | ||
2600 | mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE; | 2645 | mp->rx_ring_size = DEFAULT_RX_QUEUE_SIZE; |
2601 | if (pd->rx_queue_size) | 2646 | if (pd->rx_queue_size) |
2602 | mp->default_rx_ring_size = pd->rx_queue_size; | 2647 | mp->rx_ring_size = pd->rx_queue_size; |
2603 | mp->rx_desc_sram_addr = pd->rx_sram_addr; | 2648 | mp->rx_desc_sram_addr = pd->rx_sram_addr; |
2604 | mp->rx_desc_sram_size = pd->rx_sram_size; | 2649 | mp->rx_desc_sram_size = pd->rx_sram_size; |
2605 | 2650 | ||
2606 | mp->rxq_count = pd->rx_queue_count ? : 1; | 2651 | mp->rxq_count = pd->rx_queue_count ? : 1; |
2607 | 2652 | ||
2608 | mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE; | 2653 | mp->tx_ring_size = DEFAULT_TX_QUEUE_SIZE; |
2609 | if (pd->tx_queue_size) | 2654 | if (pd->tx_queue_size) |
2610 | mp->default_tx_ring_size = pd->tx_queue_size; | 2655 | mp->tx_ring_size = pd->tx_queue_size; |
2611 | mp->tx_desc_sram_addr = pd->tx_sram_addr; | 2656 | mp->tx_desc_sram_addr = pd->tx_sram_addr; |
2612 | mp->tx_desc_sram_size = pd->tx_sram_size; | 2657 | mp->tx_desc_sram_size = pd->tx_sram_size; |
2613 | 2658 | ||