.get_base_stats = bnxt_get_base_stats,
};
-static int bnxt_queue_mem_alloc(struct net_device *dev, void *qmem, int idx)
+static int bnxt_queue_mem_alloc(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *qmem, int idx)
{
struct bnxt_rx_ring_info *rxr, *clone;
struct bnxt *bp = netdev_priv(dev);
dst->rx_agg_bmap = src->rx_agg_bmap;
}
-static int bnxt_queue_start(struct net_device *dev, void *qmem, int idx)
+static int bnxt_queue_start(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *qmem, int idx)
{
struct bnxt *bp = netdev_priv(dev);
struct bnxt_rx_ring_info *rxr, *clone;
gve_rx_free_ring_dqo(priv, gve_per_q_mem, &cfg);
}
-static int gve_rx_queue_mem_alloc(struct net_device *dev, void *per_q_mem,
- int idx)
+static int gve_rx_queue_mem_alloc(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *per_q_mem, int idx)
{
struct gve_priv *priv = netdev_priv(dev);
struct gve_rx_alloc_rings_cfg cfg = {0};
return err;
}
-static int gve_rx_queue_start(struct net_device *dev, void *per_q_mem, int idx)
+static int gve_rx_queue_start(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *per_q_mem, int idx)
{
struct gve_priv *priv = netdev_priv(dev);
struct gve_rx_ring *gve_per_q_mem;
struct mlx5e_channel_param cparam;
};
-static int mlx5e_queue_mem_alloc(struct net_device *dev, void *newq,
- int queue_index)
+static int mlx5e_queue_mem_alloc(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *newq, int queue_index)
{
struct mlx5_qmgmt_data *new = (struct mlx5_qmgmt_data *)newq;
struct mlx5e_priv *priv = netdev_priv(dev);
return 0;
}
-static int mlx5e_queue_start(struct net_device *dev, void *newq,
- int queue_index)
+static int mlx5e_queue_start(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *newq, int queue_index)
{
struct mlx5_qmgmt_data *new = (struct mlx5_qmgmt_data *)newq;
struct mlx5e_priv *priv = netdev_priv(dev);
fbnic_wrfl(fbd);
}
-static int fbnic_queue_mem_alloc(struct net_device *dev, void *qmem, int idx)
+static int fbnic_queue_mem_alloc(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *qmem, int idx)
{
struct fbnic_net *fbn = netdev_priv(dev);
const struct fbnic_q_triad *real;
netif_wake_subqueue(fbn->netdev, nv->qt[i].sub0.q_idx);
}
-static int fbnic_queue_start(struct net_device *dev, void *qmem, int idx)
+static int fbnic_queue_start(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *qmem, int idx)
{
struct fbnic_net *fbn = netdev_priv(dev);
struct fbnic_napi_vector *nv;
};
static int
-nsim_queue_mem_alloc(struct net_device *dev, void *per_queue_mem, int idx)
+nsim_queue_mem_alloc(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
+ void *per_queue_mem, int idx)
{
struct nsim_queue_mem *qmem = per_queue_mem;
struct netdevsim *ns = netdev_priv(dev);
}
static int
-nsim_queue_start(struct net_device *dev, void *per_queue_mem, int idx)
+nsim_queue_start(struct net_device *dev, struct netdev_queue_config *qcfg,
+ void *per_queue_mem, int idx)
{
struct nsim_queue_mem *qmem = per_queue_mem;
struct netdevsim *ns = netdev_priv(dev);
u8 hds_config;
};
+struct netdev_queue_config {
+};
+
/* See the netdev.yaml spec for definition of each statistic */
struct netdev_queue_stats_rx {
u64 bytes;
* @ndo_queue_get_dma_dev: Get dma device for zero-copy operations to be used
* for this queue. Return NULL on error.
*
+ * @ndo_default_qcfg: Populate queue config struct with defaults. Optional.
+ *
* Note that @ndo_queue_mem_alloc and @ndo_queue_mem_free may be called while
* the interface is closed. @ndo_queue_start and @ndo_queue_stop will only
* be called for an interface which is open.
struct netdev_queue_mgmt_ops {
size_t ndo_queue_mem_size;
int (*ndo_queue_mem_alloc)(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
void *per_queue_mem,
int idx);
void (*ndo_queue_mem_free)(struct net_device *dev,
void *per_queue_mem);
int (*ndo_queue_start)(struct net_device *dev,
+ struct netdev_queue_config *qcfg,
void *per_queue_mem,
int idx);
int (*ndo_queue_stop)(struct net_device *dev,
void *per_queue_mem,
int idx);
+ void (*ndo_default_qcfg)(struct net_device *dev,
+ struct netdev_queue_config *qcfg);
struct device * (*ndo_queue_get_dma_dev)(struct net_device *dev,
int idx);
};
#include <linux/sysfs.h>
#include <net/xdp.h>
#include <net/page_pool/types.h>
+#include <net/netdev_queues.h>
/* This structure contains an instance of an RX queue. */
struct netdev_rx_queue {
struct xsk_buff_pool *pool;
#endif
struct napi_struct *napi;
+ struct netdev_queue_config qcfg;
struct pp_memory_provider_params mp_params;
} ____cacheline_aligned_in_smp;
}
}
+static void init_rx_queue_cfgs(struct net_device *dev)
+{
+ const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops;
+ struct netdev_rx_queue *rxq;
+ int i;
+
+ if (!qops || !qops->ndo_default_qcfg)
+ return;
+
+ for (i = 0; i < dev->num_rx_queues; i++) {
+ rxq = __netif_get_rx_queue(dev, i);
+ qops->ndo_default_qcfg(dev, &rxq->qcfg);
+ }
+}
+
/**
* register_netdevice() - register a network device
* @dev: device to register
if (!dev->name_node)
goto out;
+ init_rx_queue_cfgs(dev);
+
/* Init, if this function is available */
if (dev->netdev_ops->ndo_init) {
ret = dev->netdev_ops->ndo_init(dev);
{
struct netdev_rx_queue *rxq = __netif_get_rx_queue(dev, rxq_idx);
const struct netdev_queue_mgmt_ops *qops = dev->queue_mgmt_ops;
+ struct netdev_queue_config qcfg;
void *new_mem, *old_mem;
int err;
netdev_assert_locked(dev);
+ memset(&qcfg, 0, sizeof(qcfg));
+ if (qops->ndo_default_qcfg)
+ qops->ndo_default_qcfg(dev, &qcfg);
+
new_mem = kvzalloc(qops->ndo_queue_mem_size, GFP_KERNEL);
if (!new_mem)
return -ENOMEM;
goto err_free_new_mem;
}
- err = qops->ndo_queue_mem_alloc(dev, new_mem, rxq_idx);
+ err = qops->ndo_queue_mem_alloc(dev, &qcfg, new_mem, rxq_idx);
if (err)
goto err_free_old_mem;
if (err)
goto err_free_new_queue_mem;
- err = qops->ndo_queue_start(dev, new_mem, rxq_idx);
+ err = qops->ndo_queue_start(dev, &qcfg, new_mem, rxq_idx);
if (err)
goto err_start_queue;
} else {
kvfree(old_mem);
kvfree(new_mem);
+ rxq->qcfg = qcfg;
return 0;
err_start_queue:
* WARN if we fail to recover the old rx queue, and at least free
* old_mem so we don't also leak that.
*/
- if (qops->ndo_queue_start(dev, old_mem, rxq_idx)) {
+ if (qops->ndo_queue_start(dev, &rxq->qcfg, old_mem, rxq_idx)) {
WARN(1,
"Failed to restart old queue in error path. RX queue %d may be unhealthy.",
rxq_idx);