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

Commit bab748de authored by Tom Lendacky's avatar Tom Lendacky Committed by David S. Miller
Browse files

amd-xgbe: Add ethtool show/set ring parameter support



Add ethtool support to show and set the number of the Rx and Tx ring
descriptors.  Changing the ring configuration will result in a device
restart.

Signed-off-by: default avatarTom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 53a1024a
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -1426,10 +1426,8 @@ static void xgbe_stopdev(struct work_struct *work)
	netdev_alert(pdata->netdev, "device stopped\n");
}

static void xgbe_restart_dev(struct xgbe_prv_data *pdata)
void xgbe_restart_dev(struct xgbe_prv_data *pdata)
{
	DBGPR("-->xgbe_restart_dev\n");

	/* If not running, "restart" will happen on open */
	if (!netif_running(pdata->netdev))
		return;
@@ -1440,8 +1438,6 @@ static void xgbe_restart_dev(struct xgbe_prv_data *pdata)
	xgbe_free_rx_data(pdata);

	xgbe_start(pdata);

	DBGPR("<--xgbe_restart_dev\n");
}

static void xgbe_restart(struct work_struct *work)
+65 −0
Original line number Diff line number Diff line
@@ -642,6 +642,69 @@ static int xgbe_get_module_eeprom(struct net_device *netdev,
	return pdata->phy_if.module_eeprom(pdata, eeprom, data);
}

static void xgbe_get_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ringparam)
{
	struct xgbe_prv_data *pdata = netdev_priv(netdev);

	ringparam->rx_max_pending = XGBE_RX_DESC_CNT_MAX;
	ringparam->tx_max_pending = XGBE_TX_DESC_CNT_MAX;
	ringparam->rx_pending = pdata->rx_desc_count;
	ringparam->tx_pending = pdata->tx_desc_count;
}

static int xgbe_set_ringparam(struct net_device *netdev,
			      struct ethtool_ringparam *ringparam)
{
	struct xgbe_prv_data *pdata = netdev_priv(netdev);
	unsigned int rx, tx;

	if (ringparam->rx_mini_pending || ringparam->rx_jumbo_pending) {
		netdev_err(netdev, "unsupported ring parameter\n");
		return -EINVAL;
	}

	if ((ringparam->rx_pending < XGBE_RX_DESC_CNT_MIN) ||
	    (ringparam->rx_pending > XGBE_RX_DESC_CNT_MAX)) {
		netdev_err(netdev,
			   "rx ring parameter must be between %u and %u\n",
			   XGBE_RX_DESC_CNT_MIN, XGBE_RX_DESC_CNT_MAX);
		return -EINVAL;
	}

	if ((ringparam->tx_pending < XGBE_TX_DESC_CNT_MIN) ||
	    (ringparam->tx_pending > XGBE_TX_DESC_CNT_MAX)) {
		netdev_err(netdev,
			   "tx ring parameter must be between %u and %u\n",
			   XGBE_TX_DESC_CNT_MIN, XGBE_TX_DESC_CNT_MAX);
		return -EINVAL;
	}

	rx = __rounddown_pow_of_two(ringparam->rx_pending);
	if (rx != ringparam->rx_pending)
		netdev_notice(netdev,
			      "rx ring parameter rounded to power of two: %u\n",
			      rx);

	tx = __rounddown_pow_of_two(ringparam->tx_pending);
	if (tx != ringparam->tx_pending)
		netdev_notice(netdev,
			      "tx ring parameter rounded to power of two: %u\n",
			      tx);

	if ((rx == pdata->rx_desc_count) &&
	    (tx == pdata->tx_desc_count))
		goto out;

	pdata->rx_desc_count = rx;
	pdata->tx_desc_count = tx;

	xgbe_restart_dev(pdata);

out:
	return 0;
}

static const struct ethtool_ops xgbe_ethtool_ops = {
	.get_drvinfo = xgbe_get_drvinfo,
	.get_msglevel = xgbe_get_msglevel,
@@ -664,6 +727,8 @@ static const struct ethtool_ops xgbe_ethtool_ops = {
	.set_link_ksettings = xgbe_set_link_ksettings,
	.get_module_info = xgbe_get_module_info,
	.get_module_eeprom = xgbe_get_module_eeprom,
	.get_ringparam = xgbe_get_ringparam,
	.set_ringparam = xgbe_set_ringparam,
};

const struct ethtool_ops *xgbe_get_ethtool_ops(void)
+6 −0
Original line number Diff line number Diff line
@@ -144,6 +144,11 @@
#define XGBE_TX_DESC_MAX_PROC	(XGBE_TX_DESC_CNT >> 1)
#define XGBE_RX_DESC_CNT	512

#define XGBE_TX_DESC_CNT_MIN	64
#define XGBE_TX_DESC_CNT_MAX	4096
#define XGBE_RX_DESC_CNT_MIN	64
#define XGBE_RX_DESC_CNT_MAX	4096

#define XGBE_TX_MAX_BUF_SIZE	(0x3fff & ~(64 - 1))

/* Descriptors required for maximum contiguous TSO/GSO packet */
@@ -1330,6 +1335,7 @@ int xgbe_powerup(struct net_device *, unsigned int);
int xgbe_powerdown(struct net_device *, unsigned int);
void xgbe_init_rx_coalesce(struct xgbe_prv_data *);
void xgbe_init_tx_coalesce(struct xgbe_prv_data *);
void xgbe_restart_dev(struct xgbe_prv_data *pdata);

#ifdef CONFIG_DEBUG_FS
void xgbe_debugfs_init(struct xgbe_prv_data *);