Commit bcab6782 authored by Luo bin's avatar Luo bin Committed by David S. Miller
Browse files

hinic: add set_ringparam ethtool_ops support



support to change TX/RX queue depth with ethtool -G

Signed-off-by: default avatarLuo bin <luobin9@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5a46b062
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -69,6 +69,8 @@ struct hinic_dev {

	struct hinic_txq                *txqs;
	struct hinic_rxq                *rxqs;
	u16				sq_depth;
	u16				rq_depth;

	struct hinic_txq_stats          tx_stats;
	struct hinic_rxq_stats          rx_stats;
+74 −4
Original line number Diff line number Diff line
@@ -538,12 +538,81 @@ static void hinic_get_drvinfo(struct net_device *netdev,
static void hinic_get_ringparam(struct net_device *netdev,
				struct ethtool_ringparam *ring)
{
	ring->rx_max_pending = HINIC_RQ_DEPTH;
	ring->tx_max_pending = HINIC_SQ_DEPTH;
	ring->rx_pending = HINIC_RQ_DEPTH;
	ring->tx_pending = HINIC_SQ_DEPTH;
	struct hinic_dev *nic_dev = netdev_priv(netdev);

	ring->rx_max_pending = HINIC_MAX_QUEUE_DEPTH;
	ring->tx_max_pending = HINIC_MAX_QUEUE_DEPTH;
	ring->rx_pending = nic_dev->rq_depth;
	ring->tx_pending = nic_dev->sq_depth;
}

static int check_ringparam_valid(struct hinic_dev *nic_dev,
				 struct ethtool_ringparam *ring)
{
	if (ring->rx_jumbo_pending || ring->rx_mini_pending) {
		netif_err(nic_dev, drv, nic_dev->netdev,
			  "Unsupported rx_jumbo_pending/rx_mini_pending\n");
		return -EINVAL;
	}

	if (ring->tx_pending > HINIC_MAX_QUEUE_DEPTH ||
	    ring->tx_pending < HINIC_MIN_QUEUE_DEPTH ||
	    ring->rx_pending > HINIC_MAX_QUEUE_DEPTH ||
	    ring->rx_pending < HINIC_MIN_QUEUE_DEPTH) {
		netif_err(nic_dev, drv, nic_dev->netdev,
			  "Queue depth out of range [%d-%d]\n",
			  HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH);
		return -EINVAL;
	}

	return 0;
}

static int hinic_set_ringparam(struct net_device *netdev,
			       struct ethtool_ringparam *ring)
{
	struct hinic_dev *nic_dev = netdev_priv(netdev);
	u16 new_sq_depth, new_rq_depth;
	int err;

	err = check_ringparam_valid(nic_dev, ring);
	if (err)
		return err;

	new_sq_depth = (u16)(1U << (u16)ilog2(ring->tx_pending));
	new_rq_depth = (u16)(1U << (u16)ilog2(ring->rx_pending));

	if (new_sq_depth == nic_dev->sq_depth &&
	    new_rq_depth == nic_dev->rq_depth)
		return 0;

	netif_info(nic_dev, drv, netdev,
		   "Change Tx/Rx ring depth from %d/%d to %d/%d\n",
		   nic_dev->sq_depth, nic_dev->rq_depth,
		   new_sq_depth, new_rq_depth);

	nic_dev->sq_depth = new_sq_depth;
	nic_dev->rq_depth = new_rq_depth;

	if (netif_running(netdev)) {
		netif_info(nic_dev, drv, netdev, "Restarting netdev\n");
		err = hinic_close(netdev);
		if (err) {
			netif_err(nic_dev, drv, netdev,
				  "Failed to close netdev\n");
			return -EFAULT;
		}

		err = hinic_open(netdev);
		if (err) {
			netif_err(nic_dev, drv, netdev,
				  "Failed to open netdev\n");
			return -EFAULT;
		}
	}

	return 0;
}
static void hinic_get_channels(struct net_device *netdev,
			       struct ethtool_channels *channels)
{
@@ -1148,6 +1217,7 @@ static const struct ethtool_ops hinic_ethtool_ops = {
	.get_drvinfo = hinic_get_drvinfo,
	.get_link = ethtool_op_get_link,
	.get_ringparam = hinic_get_ringparam,
	.set_ringparam = hinic_set_ringparam,
	.get_channels = hinic_get_channels,
	.get_rxnfc = hinic_get_rxnfc,
	.set_rxnfc = hinic_set_rxnfc,
+7 −4
Original line number Diff line number Diff line
@@ -269,8 +269,8 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev)
 *
 * Return 0 - Success, negative - Failure
 **/
static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth,
			 unsigned int sq_depth)
static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth,
			 unsigned int rq_depth)
{
	struct hinic_hwif *hwif = hwdev->hwif;
	struct hinic_cmd_hw_ioctxt hw_ioctxt;
@@ -435,7 +435,7 @@ static int get_base_qpn(struct hinic_hwdev *hwdev, u16 *base_qpn)
 *
 * Return 0 - Success, negative - Failure
 **/
int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth)
{
	struct hinic_func_to_io *func_to_io = &hwdev->func_to_io;
	struct hinic_cap *nic_cap = &hwdev->nic_cap;
@@ -458,6 +458,9 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)

	ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
	func_to_io->hwdev = hwdev;
	func_to_io->sq_depth = sq_depth;
	func_to_io->rq_depth = rq_depth;

	err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
			    ceq_msix_entries);
	if (err) {
@@ -482,7 +485,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
		hinic_db_state_set(hwif, HINIC_DB_ENABLE);
	}

	err = set_hw_ioctxt(hwdev, HINIC_SQ_DEPTH, HINIC_RQ_DEPTH);
	err = set_hw_ioctxt(hwdev, sq_depth, rq_depth);
	if (err) {
		dev_err(&pdev->dev, "Failed to set HW IO ctxt\n");
		goto err_hw_ioctxt;
+1 −1
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ int hinic_hilink_msg_cmd(struct hinic_hwdev *hwdev, enum hinic_hilink_cmd cmd,
			 void *buf_in, u16 in_size, void *buf_out,
			 u16 *out_size);

int hinic_hwdev_ifup(struct hinic_hwdev *hwdev);
int hinic_hwdev_ifup(struct hinic_hwdev *hwdev, u16 sq_depth, u16 rq_depth);

void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev);

+2 −2
Original line number Diff line number Diff line
@@ -282,7 +282,7 @@ static int init_qp(struct hinic_func_to_io *func_to_io,

	err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->sq_wq[q_id],
				HINIC_SQ_WQEBB_SIZE, HINIC_SQ_PAGE_SIZE,
				HINIC_SQ_DEPTH, HINIC_SQ_WQE_MAX_SIZE);
				func_to_io->sq_depth, HINIC_SQ_WQE_MAX_SIZE);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate WQ for SQ\n");
		return err;
@@ -290,7 +290,7 @@ static int init_qp(struct hinic_func_to_io *func_to_io,

	err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->rq_wq[q_id],
				HINIC_RQ_WQEBB_SIZE, HINIC_RQ_PAGE_SIZE,
				HINIC_RQ_DEPTH, HINIC_RQ_WQE_SIZE);
				func_to_io->rq_depth, HINIC_RQ_WQE_SIZE);
	if (err) {
		dev_err(&pdev->dev, "Failed to allocate WQ for RQ\n");
		goto err_rq_alloc;
Loading