diff options
author | Bhaskar Upadhaya <bupadhaya@marvell.com> | 2021-02-10 23:28:30 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2021-02-12 01:25:05 +0300 |
commit | a0d2d97d742cc04817017e4c623256b9583a095d (patch) | |
tree | 306f917df89a48812877adf4dd53fbde606eb7da /drivers | |
parent | 961aa716235f58088e99acafbe66027d678061ce (diff) | |
download | linux-a0d2d97d742cc04817017e4c623256b9583a095d.tar.xz |
qede: add per queue coalesce support for qede driver
per queue coalescing allows better and more finegrained control
over interrupt rates.
Signed-off-by: Bhaskar Upadhaya <bupadhaya@marvell.com>
Signed-off-by: Igor Russkikh <irusskikh@marvell.com>
Signed-off-by: Ariel Elior <aelior@marvell.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c index bedbb85a179a..78ed5adee022 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c @@ -2105,6 +2105,126 @@ err: return rc; } +static int qede_set_per_coalesce(struct net_device *dev, + u32 queue, + struct ethtool_coalesce *coal) +{ + struct qede_dev *edev = netdev_priv(dev); + struct qede_fastpath *fp; + u16 rxc, txc; + int rc = 0; + + if (coal->rx_coalesce_usecs > QED_COALESCE_MAX || + coal->tx_coalesce_usecs > QED_COALESCE_MAX) { + DP_INFO(edev, + "Can't support requested %s coalesce value [max supported value %d]\n", + coal->rx_coalesce_usecs > QED_COALESCE_MAX ? "rx" + : "tx", + QED_COALESCE_MAX); + return -EINVAL; + } + + rxc = (u16)coal->rx_coalesce_usecs; + txc = (u16)coal->tx_coalesce_usecs; + + __qede_lock(edev); + if (queue >= edev->num_queues) { + DP_INFO(edev, "Invalid queue\n"); + rc = -EINVAL; + goto out; + } + + if (edev->state != QEDE_STATE_OPEN) { + rc = -EINVAL; + goto out; + } + + fp = &edev->fp_array[queue]; + + if (edev->fp_array[queue].type & QEDE_FASTPATH_RX) { + rc = edev->ops->common->set_coalesce(edev->cdev, + rxc, 0, + fp->rxq->handle); + if (rc) { + DP_INFO(edev, + "Set RX coalesce error, rc = %d\n", rc); + goto out; + } + } + + if (edev->fp_array[queue].type & QEDE_FASTPATH_TX) { + rc = edev->ops->common->set_coalesce(edev->cdev, + 0, txc, + fp->txq->handle); + if (rc) { + DP_INFO(edev, + "Set TX coalesce error, rc = %d\n", rc); + goto out; + } + } +out: + __qede_unlock(edev); + + return rc; +} + +static int qede_get_per_coalesce(struct net_device *dev, + u32 queue, + struct ethtool_coalesce *coal) +{ + void *rx_handle = NULL, *tx_handle = NULL; + struct qede_dev *edev = netdev_priv(dev); + struct qede_fastpath *fp; + u16 rx_coal, tx_coal; + int rc = 0; + + rx_coal = QED_DEFAULT_RX_USECS; + tx_coal = QED_DEFAULT_TX_USECS; + + memset(coal, 0, sizeof(struct ethtool_coalesce)); + + __qede_lock(edev); + if (queue >= edev->num_queues) { + DP_INFO(edev, "Invalid queue\n"); + rc = -EINVAL; + goto out; + } + + if (edev->state != QEDE_STATE_OPEN) { + rc = -EINVAL; + goto out; + } + + fp = &edev->fp_array[queue]; + + if (fp->type & QEDE_FASTPATH_RX) + rx_handle = fp->rxq->handle; + + rc = edev->ops->get_coalesce(edev->cdev, &rx_coal, + rx_handle); + if (rc) { + DP_INFO(edev, "Read Rx coalesce error\n"); + goto out; + } + + fp = &edev->fp_array[queue]; + if (fp->type & QEDE_FASTPATH_TX) + tx_handle = fp->txq->handle; + + rc = edev->ops->get_coalesce(edev->cdev, &tx_coal, + tx_handle); + if (rc) + DP_INFO(edev, "Read Tx coalesce error\n"); + +out: + __qede_unlock(edev); + + coal->rx_coalesce_usecs = rx_coal; + coal->tx_coalesce_usecs = tx_coal; + + return rc; +} + static const struct ethtool_ops qede_ethtool_ops = { .supported_coalesce_params = ETHTOOL_COALESCE_USECS, .get_link_ksettings = qede_get_link_ksettings, @@ -2148,6 +2268,8 @@ static const struct ethtool_ops qede_ethtool_ops = { .set_fecparam = qede_set_fecparam, .get_tunable = qede_get_tunable, .set_tunable = qede_set_tunable, + .get_per_queue_coalesce = qede_get_per_coalesce, + .set_per_queue_coalesce = qede_set_per_coalesce, .flash_device = qede_flash_device, .get_dump_flag = qede_get_dump_flag, .get_dump_data = qede_get_dump_data, @@ -2177,6 +2299,8 @@ static const struct ethtool_ops qede_vf_ethtool_ops = { .set_rxfh = qede_set_rxfh, .get_channels = qede_get_channels, .set_channels = qede_set_channels, + .get_per_queue_coalesce = qede_get_per_coalesce, + .set_per_queue_coalesce = qede_set_per_coalesce, .get_tunable = qede_get_tunable, .set_tunable = qede_set_tunable, }; |