|
@@ -10239,11 +10239,15 @@ static bool tg3_enable_msix(struct tg3 *tp)
|
|
|
int i, rc;
|
|
|
struct msix_entry msix_ent[tp->irq_max];
|
|
|
|
|
|
- tp->rxq_cnt = netif_get_num_default_rss_queues();
|
|
|
+ tp->txq_cnt = tp->txq_req;
|
|
|
+ tp->rxq_cnt = tp->rxq_req;
|
|
|
+ if (!tp->rxq_cnt)
|
|
|
+ tp->rxq_cnt = netif_get_num_default_rss_queues();
|
|
|
if (tp->rxq_cnt > tp->rxq_max)
|
|
|
tp->rxq_cnt = tp->rxq_max;
|
|
|
- if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
|
|
|
- GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
|
|
|
+ if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
|
|
|
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
|
|
|
+ !tp->txq_req)
|
|
|
tp->txq_cnt = min(tp->rxq_cnt, tp->txq_max);
|
|
|
|
|
|
tp->irq_cnt = tg3_irq_count(tp);
|
|
@@ -11384,6 +11388,58 @@ static int tg3_set_rxfh_indir(struct net_device *dev, const u32 *indir)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void tg3_get_channels(struct net_device *dev,
|
|
|
+ struct ethtool_channels *channel)
|
|
|
+{
|
|
|
+ struct tg3 *tp = netdev_priv(dev);
|
|
|
+ u32 deflt_qs = netif_get_num_default_rss_queues();
|
|
|
+
|
|
|
+ channel->max_rx = tp->rxq_max;
|
|
|
+ channel->max_tx = tp->txq_max;
|
|
|
+
|
|
|
+ if (netif_running(dev)) {
|
|
|
+ channel->rx_count = tp->rxq_cnt;
|
|
|
+ channel->tx_count = tp->txq_cnt;
|
|
|
+ } else {
|
|
|
+ if (tp->rxq_req)
|
|
|
+ channel->rx_count = tp->rxq_req;
|
|
|
+ else
|
|
|
+ channel->rx_count = min(deflt_qs, tp->rxq_max);
|
|
|
+
|
|
|
+ if (tp->txq_req)
|
|
|
+ channel->tx_count = tp->txq_req;
|
|
|
+ else
|
|
|
+ channel->tx_count = min(deflt_qs, tp->txq_max);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+static int tg3_set_channels(struct net_device *dev,
|
|
|
+ struct ethtool_channels *channel)
|
|
|
+{
|
|
|
+ struct tg3 *tp = netdev_priv(dev);
|
|
|
+
|
|
|
+ if (!tg3_flag(tp, SUPPORT_MSIX))
|
|
|
+ return -EOPNOTSUPP;
|
|
|
+
|
|
|
+ if (channel->rx_count > tp->rxq_max ||
|
|
|
+ channel->tx_count > tp->txq_max)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ tp->rxq_req = channel->rx_count;
|
|
|
+ tp->txq_req = channel->tx_count;
|
|
|
+
|
|
|
+ if (!netif_running(dev))
|
|
|
+ return 0;
|
|
|
+
|
|
|
+ tg3_stop(tp);
|
|
|
+
|
|
|
+ netif_carrier_off(dev);
|
|
|
+
|
|
|
+ tg3_start(tp, true, false);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static void tg3_get_strings(struct net_device *dev, u32 stringset, u8 *buf)
|
|
|
{
|
|
|
switch (stringset) {
|
|
@@ -12632,6 +12688,8 @@ static const struct ethtool_ops tg3_ethtool_ops = {
|
|
|
.get_rxfh_indir_size = tg3_get_rxfh_indir_size,
|
|
|
.get_rxfh_indir = tg3_get_rxfh_indir,
|
|
|
.set_rxfh_indir = tg3_set_rxfh_indir,
|
|
|
+ .get_channels = tg3_get_channels,
|
|
|
+ .set_channels = tg3_set_channels,
|
|
|
.get_ts_info = ethtool_op_get_ts_info,
|
|
|
};
|
|
|
|