Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-2.6-microblaze.git] / drivers / net / ethernet / stmicro / stmmac / stmmac_ethtool.c
index 814879f..9e54f95 100644 (file)
@@ -440,6 +440,33 @@ static int stmmac_nway_reset(struct net_device *dev)
        return phylink_ethtool_nway_reset(priv->phylink);
 }
 
+static void stmmac_get_ringparam(struct net_device *netdev,
+                                struct ethtool_ringparam *ring)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+
+       ring->rx_max_pending = DMA_MAX_RX_SIZE;
+       ring->tx_max_pending = DMA_MAX_TX_SIZE;
+       ring->rx_pending = priv->dma_rx_size;
+       ring->tx_pending = priv->dma_tx_size;
+}
+
+static int stmmac_set_ringparam(struct net_device *netdev,
+                               struct ethtool_ringparam *ring)
+{
+       if (ring->rx_mini_pending || ring->rx_jumbo_pending ||
+           ring->rx_pending < DMA_MIN_RX_SIZE ||
+           ring->rx_pending > DMA_MAX_RX_SIZE ||
+           !is_power_of_2(ring->rx_pending) ||
+           ring->tx_pending < DMA_MIN_TX_SIZE ||
+           ring->tx_pending > DMA_MAX_TX_SIZE ||
+           !is_power_of_2(ring->tx_pending))
+               return -EINVAL;
+
+       return stmmac_reinit_ringparam(netdev, ring->rx_pending,
+                                      ring->tx_pending);
+}
+
 static void
 stmmac_get_pauseparam(struct net_device *netdev,
                      struct ethtool_pauseparam *pause)
@@ -843,6 +870,30 @@ static int stmmac_set_rxfh(struct net_device *dev, const u32 *indir,
                                    priv->plat->rx_queues_to_use);
 }
 
+static void stmmac_get_channels(struct net_device *dev,
+                               struct ethtool_channels *chan)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       chan->rx_count = priv->plat->rx_queues_to_use;
+       chan->tx_count = priv->plat->tx_queues_to_use;
+       chan->max_rx = priv->dma_cap.number_rx_queues;
+       chan->max_tx = priv->dma_cap.number_tx_queues;
+}
+
+static int stmmac_set_channels(struct net_device *dev,
+                              struct ethtool_channels *chan)
+{
+       struct stmmac_priv *priv = netdev_priv(dev);
+
+       if (chan->rx_count > priv->dma_cap.number_rx_queues ||
+           chan->tx_count > priv->dma_cap.number_tx_queues ||
+           !chan->rx_count || !chan->tx_count)
+               return -EINVAL;
+
+       return stmmac_reinit_queues(dev, chan->rx_count, chan->tx_count);
+}
+
 static int stmmac_get_ts_info(struct net_device *dev,
                              struct ethtool_ts_info *info)
 {
@@ -926,6 +977,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
        .get_regs_len = stmmac_ethtool_get_regs_len,
        .get_link = ethtool_op_get_link,
        .nway_reset = stmmac_nway_reset,
+       .get_ringparam = stmmac_get_ringparam,
+       .set_ringparam = stmmac_set_ringparam,
        .get_pauseparam = stmmac_get_pauseparam,
        .set_pauseparam = stmmac_set_pauseparam,
        .self_test = stmmac_selftest_run,
@@ -944,6 +997,8 @@ static const struct ethtool_ops stmmac_ethtool_ops = {
        .get_ts_info = stmmac_get_ts_info,
        .get_coalesce = stmmac_get_coalesce,
        .set_coalesce = stmmac_set_coalesce,
+       .get_channels = stmmac_get_channels,
+       .set_channels = stmmac_set_channels,
        .get_tunable = stmmac_get_tunable,
        .set_tunable = stmmac_set_tunable,
        .get_link_ksettings = stmmac_ethtool_get_link_ksettings,