1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

modules/mqnic: Implement ethtool ringparam API

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2023-05-03 01:22:12 -07:00
parent 21b8d164cf
commit 3302c1f832
4 changed files with 105 additions and 4 deletions

View File

@ -478,6 +478,9 @@ struct mqnic_priv {
u32 txq_count;
u32 rxq_count;
u32 tx_ring_size;
u32 rx_ring_size;
struct rw_semaphore txq_table_sem;
struct radix_tree_root txq_table;

View File

@ -58,6 +58,94 @@ static void mqnic_get_drvinfo(struct net_device *ndev,
strscpy(drvinfo->bus_info, dev_name(mdev->dev), sizeof(drvinfo->bus_info));
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
static void mqnic_get_ringparam(struct net_device *ndev,
struct ethtool_ringparam *param,
struct kernel_ethtool_ringparam *kernel_param,
struct netlink_ext_ack *ext_ack)
#else
static void mqnic_get_ringparam(struct net_device *ndev,
struct ethtool_ringparam *param)
#endif
{
struct mqnic_priv *priv = netdev_priv(ndev);
memset(param, 0, sizeof(*param));
param->rx_max_pending = MQNIC_MAX_RX_RING_SZ;
param->tx_max_pending = MQNIC_MAX_TX_RING_SZ;
param->rx_pending = priv->rx_ring_size;
param->tx_pending = priv->tx_ring_size;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
memset(kernel_param, 0, sizeof(*kernel_param));
kernel_param->cqe_size = MQNIC_CPL_SIZE;
#endif
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 17, 0)
static int mqnic_set_ringparam(struct net_device *ndev,
struct ethtool_ringparam *param,
struct kernel_ethtool_ringparam *kernel_param,
struct netlink_ext_ack *ext_ack)
#else
static int mqnic_set_ringparam(struct net_device *ndev,
struct ethtool_ringparam *param)
#endif
{
struct mqnic_priv *priv = netdev_priv(ndev);
u32 tx_ring_size, rx_ring_size;
int port_up = priv->port_up;
int ret = 0;
if (param->rx_mini_pending || param->rx_jumbo_pending)
return -EINVAL;
if (param->rx_pending < MQNIC_MIN_RX_RING_SZ)
return -EINVAL;
if (param->rx_pending > MQNIC_MAX_RX_RING_SZ)
return -EINVAL;
if (param->tx_pending < MQNIC_MIN_TX_RING_SZ)
return -EINVAL;
if (param->tx_pending > MQNIC_MAX_TX_RING_SZ)
return -EINVAL;
rx_ring_size = roundup_pow_of_two(param->rx_pending);
tx_ring_size = roundup_pow_of_two(param->tx_pending);
if (rx_ring_size == priv->rx_ring_size &&
tx_ring_size == priv->tx_ring_size)
return 0;
dev_info(priv->dev, "New TX ring size: %d", tx_ring_size);
dev_info(priv->dev, "New RX ring size: %d", rx_ring_size);
mutex_lock(&priv->mdev->state_lock);
if (port_up)
mqnic_stop_port(ndev);
priv->tx_ring_size = tx_ring_size;
priv->rx_ring_size = rx_ring_size;
if (port_up) {
ret = mqnic_start_port(ndev);
if (ret)
dev_err(priv->dev, "%s: Failed to start port on interface %d netdev %d: %d",
__func__, priv->interface->index, priv->index, ret);
}
mutex_unlock(&priv->mdev->state_lock);
return ret;
}
static int mqnic_get_ts_info(struct net_device *ndev,
struct ethtool_ts_info *info)
{
@ -343,6 +431,8 @@ static int mqnic_get_module_eeprom_by_page(struct net_device *ndev,
const struct ethtool_ops mqnic_ethtool_ops = {
.get_drvinfo = mqnic_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ringparam = mqnic_get_ringparam,
.set_ringparam = mqnic_set_ringparam,
.get_ts_info = mqnic_get_ts_info,
.get_module_info = mqnic_get_module_info,
.get_module_eeprom = mqnic_get_module_eeprom,

View File

@ -52,6 +52,11 @@
#define MQNIC_MAX_RXQ 8192
#define MQNIC_MAX_RX_CQ MQNIC_MAX_RXQ
#define MQNIC_MIN_TX_RING_SZ (4096/16)
#define MQNIC_MAX_TX_RING_SZ 32768
#define MQNIC_MIN_RX_RING_SZ (4096/16)
#define MQNIC_MAX_RX_RING_SZ 32768
#define MQNIC_MAX_I2C_ADAPTERS 4
#define MQNIC_BOARD_ID_NETFPGA_SUME 0x10ee7028

View File

@ -64,7 +64,7 @@ int mqnic_start_port(struct net_device *ndev)
goto fail;
}
ret = mqnic_open_cq(cq, iface->eq[k % iface->eq_count], mqnic_num_rxq_entries, 0);
ret = mqnic_open_cq(cq, iface->eq[k % iface->eq_count], priv->rx_ring_size, 0);
if (ret) {
mqnic_destroy_cq(cq);
goto fail;
@ -93,7 +93,7 @@ int mqnic_start_port(struct net_device *ndev)
else
q->page_order = ilog2((ndev->mtu + ETH_HLEN + PAGE_SIZE - 1) / PAGE_SIZE - 1) + 1;
ret = mqnic_open_rx_ring(q, priv, cq, mqnic_num_rxq_entries, 1);
ret = mqnic_open_rx_ring(q, priv, cq, priv->rx_ring_size, 1);
if (ret) {
mqnic_destroy_rx_ring(q);
mqnic_destroy_cq(cq);
@ -119,7 +119,7 @@ int mqnic_start_port(struct net_device *ndev)
goto fail;
}
ret = mqnic_open_cq(cq, iface->eq[k % iface->eq_count], mqnic_num_txq_entries, 1);
ret = mqnic_open_cq(cq, iface->eq[k % iface->eq_count], priv->tx_ring_size, 1);
if (ret) {
mqnic_destroy_cq(cq);
goto fail;
@ -144,7 +144,7 @@ int mqnic_start_port(struct net_device *ndev)
q->tx_queue = netdev_get_tx_queue(ndev, k);
ret = mqnic_open_tx_ring(q, priv, cq, mqnic_num_txq_entries, desc_block_size);
ret = mqnic_open_tx_ring(q, priv, cq, priv->tx_ring_size, desc_block_size);
if (ret) {
mqnic_destroy_tx_ring(q);
mqnic_destroy_cq(cq);
@ -566,6 +566,9 @@ struct net_device *mqnic_create_netdev(struct mqnic_if *interface, int index, in
priv->txq_count = mqnic_res_get_count(interface->txq_res);
priv->rxq_count = mqnic_res_get_count(interface->rxq_res);
priv->tx_ring_size = mqnic_num_txq_entries;
priv->rx_ring_size = mqnic_num_rxq_entries;
init_rwsem(&priv->txq_table_sem);
INIT_RADIX_TREE(&priv->txq_table, GFP_KERNEL);