hinic: add set_ringparam ethtool_ops support

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

Signed-off-by: Luo bin <luobin9@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Luo bin 2020-05-13 22:37:33 +00:00 committed by David S. Miller
parent 5a46b062e2
commit bcab67822d
11 changed files with 104 additions and 15 deletions

View File

@ -69,6 +69,8 @@ struct hinic_dev {
struct hinic_txq *txqs; struct hinic_txq *txqs;
struct hinic_rxq *rxqs; struct hinic_rxq *rxqs;
u16 sq_depth;
u16 rq_depth;
struct hinic_txq_stats tx_stats; struct hinic_txq_stats tx_stats;
struct hinic_rxq_stats rx_stats; struct hinic_rxq_stats rx_stats;

View File

@ -538,12 +538,81 @@ static void hinic_get_drvinfo(struct net_device *netdev,
static void hinic_get_ringparam(struct net_device *netdev, static void hinic_get_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring) struct ethtool_ringparam *ring)
{ {
ring->rx_max_pending = HINIC_RQ_DEPTH; struct hinic_dev *nic_dev = netdev_priv(netdev);
ring->tx_max_pending = HINIC_SQ_DEPTH;
ring->rx_pending = HINIC_RQ_DEPTH; ring->rx_max_pending = HINIC_MAX_QUEUE_DEPTH;
ring->tx_pending = HINIC_SQ_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, static void hinic_get_channels(struct net_device *netdev,
struct ethtool_channels *channels) struct ethtool_channels *channels)
{ {
@ -1148,6 +1217,7 @@ static const struct ethtool_ops hinic_ethtool_ops = {
.get_drvinfo = hinic_get_drvinfo, .get_drvinfo = hinic_get_drvinfo,
.get_link = ethtool_op_get_link, .get_link = ethtool_op_get_link,
.get_ringparam = hinic_get_ringparam, .get_ringparam = hinic_get_ringparam,
.set_ringparam = hinic_set_ringparam,
.get_channels = hinic_get_channels, .get_channels = hinic_get_channels,
.get_rxnfc = hinic_get_rxnfc, .get_rxnfc = hinic_get_rxnfc,
.set_rxnfc = hinic_set_rxnfc, .set_rxnfc = hinic_set_rxnfc,

View File

@ -269,8 +269,8 @@ static int init_fw_ctxt(struct hinic_hwdev *hwdev)
* *
* Return 0 - Success, negative - Failure * Return 0 - Success, negative - Failure
**/ **/
static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int rq_depth, static int set_hw_ioctxt(struct hinic_hwdev *hwdev, unsigned int sq_depth,
unsigned int sq_depth) unsigned int rq_depth)
{ {
struct hinic_hwif *hwif = hwdev->hwif; struct hinic_hwif *hwif = hwdev->hwif;
struct hinic_cmd_hw_ioctxt hw_ioctxt; 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 * 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_func_to_io *func_to_io = &hwdev->func_to_io;
struct hinic_cap *nic_cap = &hwdev->nic_cap; 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]; ceq_msix_entries = &hwdev->msix_entries[num_aeqs];
func_to_io->hwdev = hwdev; 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, err = hinic_io_init(func_to_io, hwif, nic_cap->max_qps, num_ceqs,
ceq_msix_entries); ceq_msix_entries);
if (err) { if (err) {
@ -482,7 +485,7 @@ int hinic_hwdev_ifup(struct hinic_hwdev *hwdev)
hinic_db_state_set(hwif, HINIC_DB_ENABLE); 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) { if (err) {
dev_err(&pdev->dev, "Failed to set HW IO ctxt\n"); dev_err(&pdev->dev, "Failed to set HW IO ctxt\n");
goto err_hw_ioctxt; goto err_hw_ioctxt;

View File

@ -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, void *buf_in, u16 in_size, void *buf_out,
u16 *out_size); 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); void hinic_hwdev_ifdown(struct hinic_hwdev *hwdev);

View File

@ -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], 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_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) { if (err) {
dev_err(&pdev->dev, "Failed to allocate WQ for SQ\n"); dev_err(&pdev->dev, "Failed to allocate WQ for SQ\n");
return err; 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], 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_WQEBB_SIZE, HINIC_RQ_PAGE_SIZE,
HINIC_RQ_DEPTH, HINIC_RQ_WQE_SIZE); func_to_io->rq_depth, HINIC_RQ_WQE_SIZE);
if (err) { if (err) {
dev_err(&pdev->dev, "Failed to allocate WQ for RQ\n"); dev_err(&pdev->dev, "Failed to allocate WQ for RQ\n");
goto err_rq_alloc; goto err_rq_alloc;

View File

@ -60,6 +60,9 @@ struct hinic_func_to_io {
struct hinic_qp *qps; struct hinic_qp *qps;
u16 max_qps; u16 max_qps;
u16 sq_depth;
u16 rq_depth;
void __iomem **sq_db; void __iomem **sq_db;
void __iomem *db_base; void __iomem *db_base;

View File

@ -643,6 +643,7 @@ void hinic_sq_write_db(struct hinic_sq *sq, u16 prod_idx, unsigned int wqe_size,
/* increment prod_idx to the next */ /* increment prod_idx to the next */
prod_idx += ALIGN(wqe_size, wq->wqebb_size) / wq->wqebb_size; prod_idx += ALIGN(wqe_size, wq->wqebb_size) / wq->wqebb_size;
prod_idx = SQ_MASKED_IDX(sq, prod_idx);
wmb(); /* Write all before the doorbell */ wmb(); /* Write all before the doorbell */

View File

@ -44,6 +44,9 @@
#define HINIC_SQ_DEPTH SZ_4K #define HINIC_SQ_DEPTH SZ_4K
#define HINIC_RQ_DEPTH SZ_4K #define HINIC_RQ_DEPTH SZ_4K
#define HINIC_MAX_QUEUE_DEPTH SZ_4K
#define HINIC_MIN_QUEUE_DEPTH 128
/* In any change to HINIC_RX_BUF_SZ, HINIC_RX_BUF_SZ_IDX must be changed */ /* In any change to HINIC_RX_BUF_SZ, HINIC_RX_BUF_SZ_IDX must be changed */
#define HINIC_RX_BUF_SZ 2048 #define HINIC_RX_BUF_SZ 2048
#define HINIC_RX_BUF_SZ_IDX HINIC_RX_BUF_SZ_2048_IDX #define HINIC_RX_BUF_SZ_IDX HINIC_RX_BUF_SZ_2048_IDX

View File

@ -372,14 +372,15 @@ static void hinic_enable_rss(struct hinic_dev *nic_dev)
netif_err(nic_dev, drv, netdev, "Failed to init rss\n"); netif_err(nic_dev, drv, netdev, "Failed to init rss\n");
} }
static int hinic_open(struct net_device *netdev) int hinic_open(struct net_device *netdev)
{ {
struct hinic_dev *nic_dev = netdev_priv(netdev); struct hinic_dev *nic_dev = netdev_priv(netdev);
enum hinic_port_link_state link_state; enum hinic_port_link_state link_state;
int err, ret; int err, ret;
if (!(nic_dev->flags & HINIC_INTF_UP)) { if (!(nic_dev->flags & HINIC_INTF_UP)) {
err = hinic_hwdev_ifup(nic_dev->hwdev); err = hinic_hwdev_ifup(nic_dev->hwdev, nic_dev->sq_depth,
nic_dev->rq_depth);
if (err) { if (err) {
netif_err(nic_dev, drv, netdev, netif_err(nic_dev, drv, netdev,
"Failed - HW interface up\n"); "Failed - HW interface up\n");
@ -483,7 +484,7 @@ static int hinic_open(struct net_device *netdev)
return err; return err;
} }
static int hinic_close(struct net_device *netdev) int hinic_close(struct net_device *netdev)
{ {
struct hinic_dev *nic_dev = netdev_priv(netdev); struct hinic_dev *nic_dev = netdev_priv(netdev);
unsigned int flags; unsigned int flags;
@ -1038,6 +1039,8 @@ static int nic_dev_init(struct pci_dev *pdev)
nic_dev->rxqs = NULL; nic_dev->rxqs = NULL;
nic_dev->tx_weight = tx_weight; nic_dev->tx_weight = tx_weight;
nic_dev->rx_weight = rx_weight; nic_dev->rx_weight = rx_weight;
nic_dev->sq_depth = HINIC_SQ_DEPTH;
nic_dev->rq_depth = HINIC_RQ_DEPTH;
nic_dev->sriov_info.hwdev = hwdev; nic_dev->sriov_info.hwdev = hwdev;
nic_dev->sriov_info.pdev = pdev; nic_dev->sriov_info.pdev = pdev;

View File

@ -473,7 +473,7 @@ int hinic_set_max_qnum(struct hinic_dev *nic_dev, u8 num_rqs)
rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif); rq_num.func_id = HINIC_HWIF_FUNC_IDX(hwif);
rq_num.num_rqs = num_rqs; rq_num.num_rqs = num_rqs;
rq_num.rq_depth = ilog2(HINIC_SQ_DEPTH); rq_num.rq_depth = ilog2(nic_dev->rq_depth);
err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP, err = hinic_port_msg_cmd(hwdev, HINIC_PORT_CMD_SET_RQ_IQ_MAP,
&rq_num, sizeof(rq_num), &rq_num, sizeof(rq_num),

View File

@ -736,4 +736,8 @@ int hinic_get_hw_pause_info(struct hinic_hwdev *hwdev,
int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev, int hinic_set_hw_pause_info(struct hinic_hwdev *hwdev,
struct hinic_pause_config *pause_info); struct hinic_pause_config *pause_info);
int hinic_open(struct net_device *netdev);
int hinic_close(struct net_device *netdev);
#endif #endif