diff options
author | Gabor Juhos <juhosg@openwrt.org> | 2011-05-31 22:53:10 +0000 |
---|---|---|
committer | Gabor Juhos <juhosg@openwrt.org> | 2011-05-31 22:53:10 +0000 |
commit | a45026d4cbf838a6e404b73e0240f56e66be18ea (patch) | |
tree | 828abbeaf58d10205101f751194426a135f1a365 /target/linux | |
parent | 4d55ed1dc2afcd3f28a3f15b6d0d6696e6702f50 (diff) | |
download | upstream-a45026d4cbf838a6e404b73e0240f56e66be18ea.tar.gz upstream-a45026d4cbf838a6e404b73e0240f56e66be18ea.tar.bz2 upstream-a45026d4cbf838a6e404b73e0240f56e66be18ea.zip |
ar71xx: ag71xx: make ring sizes configurable via ethtool
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@27041 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h | 3 | ||||
-rw-r--r-- | target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c | 53 |
2 files changed, 56 insertions, 0 deletions
diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h index 64a82f1f25..1025bb4c49 100644 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h +++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx.h @@ -57,6 +57,9 @@ #define AG71XX_TX_RING_SIZE_DEFAULT 64 #define AG71XX_RX_RING_SIZE_DEFAULT 128 +#define AG71XX_TX_RING_SIZE_MAX 256 +#define AG71XX_RX_RING_SIZE_MAX 256 + #ifdef CONFIG_AG71XX_DEBUG #define DBG(fmt, args...) printk(KERN_DEBUG fmt, ## args) #else diff --git a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c index 1f1c6aa776..498fbed1ff 100644 --- a/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c +++ b/target/linux/ar71xx/files/drivers/net/ag71xx/ag71xx_ethtool.c @@ -61,11 +61,64 @@ static void ag71xx_ethtool_set_msglevel(struct net_device *dev, u32 msg_level) ag->msg_enable = msg_level; } +static void ag71xx_ethtool_get_ringparam(struct net_device *dev, + struct ethtool_ringparam *er) +{ + struct ag71xx *ag = netdev_priv(dev); + + er->tx_max_pending = AG71XX_TX_RING_SIZE_MAX; + er->rx_max_pending = AG71XX_RX_RING_SIZE_MAX; + er->rx_mini_max_pending = 0; + er->rx_jumbo_max_pending = 0; + + er->tx_pending = ag->tx_ring.size; + er->rx_pending = ag->rx_ring.size; + er->rx_mini_pending = 0; + er->rx_jumbo_pending = 0; +} + +static int ag71xx_ethtool_set_ringparam(struct net_device *dev, + struct ethtool_ringparam *er) +{ + struct ag71xx *ag = netdev_priv(dev); + unsigned tx_size; + unsigned rx_size; + int err; + + if (er->rx_mini_pending != 0|| + er->rx_jumbo_pending != 0 || + er->rx_pending == 0 || + er->tx_pending == 0) + return -EINVAL; + + tx_size = er->tx_pending < AG71XX_TX_RING_SIZE_MAX ? + er->tx_pending : AG71XX_TX_RING_SIZE_MAX; + + rx_size = er->rx_pending < AG71XX_RX_RING_SIZE_MAX ? + er->rx_pending : AG71XX_RX_RING_SIZE_MAX; + + if (netif_running(dev)) { + err = dev->netdev_ops->ndo_stop(dev); + if (err) + return err; + } + + ag->tx_ring.size = tx_size; + ag->rx_ring.size = rx_size; + + if (netif_running(dev)) + err = dev->netdev_ops->ndo_open(dev); + + return err; +} + struct ethtool_ops ag71xx_ethtool_ops = { .set_settings = ag71xx_ethtool_set_settings, .get_settings = ag71xx_ethtool_get_settings, .get_drvinfo = ag71xx_ethtool_get_drvinfo, .get_msglevel = ag71xx_ethtool_get_msglevel, .set_msglevel = ag71xx_ethtool_set_msglevel, + .get_ringparam = ag71xx_ethtool_get_ringparam, + .set_ringparam = ag71xx_ethtool_set_ringparam, .get_link = ethtool_op_get_link, }; |