Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b033281f authored by Michael Chan's avatar Michael Chan Committed by David S. Miller
Browse files

bnx2: Add support for ethtool --show-channels|--set-channels



Allow the user to override the default number of RSS/TSS rings.

Signed-off-by: default avatarMichael Chan <mchan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b9d6d2db
Loading
Loading
Loading
Loading
+90 −9
Original line number Diff line number Diff line
@@ -6246,7 +6246,16 @@ static int
bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
{
	int cpus = num_online_cpus();
	int msix_vecs = min(cpus + 1, RX_MAX_RINGS);
	int msix_vecs;

	if (!bp->num_req_rx_rings)
		msix_vecs = max(cpus + 1, bp->num_req_tx_rings);
	else if (!bp->num_req_tx_rings)
		msix_vecs = max(cpus, bp->num_req_rx_rings);
	else
		msix_vecs = max(bp->num_req_rx_rings, bp->num_req_tx_rings);

	msix_vecs = min(msix_vecs, RX_MAX_RINGS);

	bp->irq_tbl[0].handler = bnx2_interrupt;
	strcpy(bp->irq_tbl[0].name, bp->dev->name);
@@ -6270,10 +6279,18 @@ bnx2_setup_int_mode(struct bnx2 *bp, int dis_msi)
		}
	}

	if (!bp->num_req_tx_rings)
		bp->num_tx_rings = rounddown_pow_of_two(bp->irq_nvecs);
	netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings);
	else
		bp->num_tx_rings = min(bp->irq_nvecs, bp->num_req_tx_rings);

	if (!bp->num_req_rx_rings)
		bp->num_rx_rings = bp->irq_nvecs;
	else
		bp->num_rx_rings = min(bp->irq_nvecs, bp->num_req_rx_rings);

	netif_set_real_num_tx_queues(bp->dev, bp->num_tx_rings);

	return netif_set_real_num_rx_queues(bp->dev, bp->num_rx_rings);
}

@@ -7162,7 +7179,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
}

static int
bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx, bool reset_irq)
{
	if (netif_running(bp->dev)) {
		/* Reset will erase chipset stats; save them */
@@ -7170,7 +7187,12 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)

		bnx2_netif_stop(bp, true);
		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
		if (reset_irq) {
			bnx2_free_irq(bp);
			bnx2_del_napi(bp);
		} else {
			__bnx2_free_irq(bp);
		}
		bnx2_free_skbs(bp);
		bnx2_free_mem(bp);
	}
@@ -7179,9 +7201,16 @@ bnx2_change_ring_size(struct bnx2 *bp, u32 rx, u32 tx)
	bp->tx_ring_size = tx;

	if (netif_running(bp->dev)) {
		int rc;
		int rc = 0;

		if (reset_irq) {
			rc = bnx2_setup_int_mode(bp, disable_msi);
			bnx2_init_napi(bp);
		}

		if (!rc)
			rc = bnx2_alloc_mem(bp);

		if (!rc)
			rc = bnx2_request_irq(bp);

@@ -7217,7 +7246,8 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)

		return -EINVAL;
	}
	rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending);
	rc = bnx2_change_ring_size(bp, ering->rx_pending, ering->tx_pending,
				   false);
	return rc;
}

@@ -7605,6 +7635,54 @@ bnx2_set_features(struct net_device *dev, netdev_features_t features)
	return 0;
}

static void bnx2_get_channels(struct net_device *dev,
			      struct ethtool_channels *channels)
{
	struct bnx2 *bp = netdev_priv(dev);
	u32 max_rx_rings = 1;
	u32 max_tx_rings = 1;

	if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
		max_rx_rings = RX_MAX_RINGS;
		max_tx_rings = TX_MAX_RINGS;
	}

	channels->max_rx = max_rx_rings;
	channels->max_tx = max_tx_rings;
	channels->max_other = 0;
	channels->max_combined = 0;
	channels->rx_count = bp->num_rx_rings;
	channels->tx_count = bp->num_tx_rings;
	channels->other_count = 0;
	channels->combined_count = 0;
}

static int bnx2_set_channels(struct net_device *dev,
			      struct ethtool_channels *channels)
{
	struct bnx2 *bp = netdev_priv(dev);
	u32 max_rx_rings = 1;
	u32 max_tx_rings = 1;
	int rc = 0;

	if ((bp->flags & BNX2_FLAG_MSIX_CAP) && !disable_msi) {
		max_rx_rings = RX_MAX_RINGS;
		max_tx_rings = TX_MAX_RINGS;
	}
	if (channels->rx_count > max_rx_rings ||
	    channels->tx_count > max_tx_rings)
		return -EINVAL;

	bp->num_req_rx_rings = channels->rx_count;
	bp->num_req_tx_rings = channels->tx_count;

	if (netif_running(dev))
		rc = bnx2_change_ring_size(bp, bp->rx_ring_size,
					   bp->tx_ring_size, true);

	return rc;
}

static const struct ethtool_ops bnx2_ethtool_ops = {
	.get_settings		= bnx2_get_settings,
	.set_settings		= bnx2_set_settings,
@@ -7629,6 +7707,8 @@ static const struct ethtool_ops bnx2_ethtool_ops = {
	.set_phys_id		= bnx2_set_phys_id,
	.get_ethtool_stats	= bnx2_get_ethtool_stats,
	.get_sset_count		= bnx2_get_sset_count,
	.get_channels		= bnx2_get_channels,
	.set_channels		= bnx2_set_channels,
};

/* Called with rtnl_lock */
@@ -7710,7 +7790,8 @@ bnx2_change_mtu(struct net_device *dev, int new_mtu)
		return -EINVAL;

	dev->mtu = new_mtu;
	return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size);
	return bnx2_change_ring_size(bp, bp->rx_ring_size, bp->tx_ring_size,
				     false);
}

#ifdef CONFIG_NET_POLL_CONTROLLER
+3 −0
Original line number Diff line number Diff line
@@ -6933,6 +6933,9 @@ struct bnx2 {
	u8			num_tx_rings;
	u8			num_rx_rings;

	int			num_req_tx_rings;
	int			num_req_rx_rings;

	u32 			leds_save;
	u32			idle_chk_status_idx;