Commit a5886ef4 authored by Bailey Forrest's avatar Bailey Forrest Committed by David S. Miller

gve: Introduce per netdev `enum gve_queue_format`

The currently supported queue formats are:
- GQI_RDA - GQI with raw DMA addressing
- GQI_QPL - GQI with queue page list
- DQO_RDA - DQO with raw DMA addressing

The old `gve_priv.raw_addressing` value is only used for GQI_RDA, so we
remove it in favor of just checking against GQI_RDA
Signed-off-by: default avatarBailey Forrest <bcf@google.com>
Reviewed-by: default avatarWillem de Bruijn <willemb@google.com>
Reviewed-by: default avatarCatherine Sullivan <csully@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8a39d3e0
...@@ -194,6 +194,17 @@ struct gve_qpl_config { ...@@ -194,6 +194,17 @@ struct gve_qpl_config {
unsigned long *qpl_id_map; /* bitmap of used qpl ids */ unsigned long *qpl_id_map; /* bitmap of used qpl ids */
}; };
/* GVE_QUEUE_FORMAT_UNSPECIFIED must be zero since 0 is the default value
* when the entire configure_device_resources command is zeroed out and the
* queue_format is not specified.
*/
enum gve_queue_format {
GVE_QUEUE_FORMAT_UNSPECIFIED = 0x0,
GVE_GQI_RDA_FORMAT = 0x1,
GVE_GQI_QPL_FORMAT = 0x2,
GVE_DQO_RDA_FORMAT = 0x3,
};
struct gve_priv { struct gve_priv {
struct net_device *dev; struct net_device *dev;
struct gve_tx_ring *tx; /* array of tx_cfg.num_queues */ struct gve_tx_ring *tx; /* array of tx_cfg.num_queues */
...@@ -216,7 +227,6 @@ struct gve_priv { ...@@ -216,7 +227,6 @@ struct gve_priv {
u64 num_registered_pages; /* num pages registered with NIC */ u64 num_registered_pages; /* num pages registered with NIC */
u32 rx_copybreak; /* copy packets smaller than this */ u32 rx_copybreak; /* copy packets smaller than this */
u16 default_num_queues; /* default num queues to set up */ u16 default_num_queues; /* default num queues to set up */
u8 raw_addressing; /* 1 if this dev supports raw addressing, 0 otherwise */
struct gve_queue_config tx_cfg; struct gve_queue_config tx_cfg;
struct gve_queue_config rx_cfg; struct gve_queue_config rx_cfg;
...@@ -275,6 +285,8 @@ struct gve_priv { ...@@ -275,6 +285,8 @@ struct gve_priv {
/* Gvnic device link speed from hypervisor. */ /* Gvnic device link speed from hypervisor. */
u64 link_speed; u64 link_speed;
enum gve_queue_format queue_format;
}; };
enum gve_service_task_flags_bit { enum gve_service_task_flags_bit {
...@@ -454,14 +466,20 @@ static inline u32 gve_rx_idx_to_ntfy(struct gve_priv *priv, u32 queue_idx) ...@@ -454,14 +466,20 @@ static inline u32 gve_rx_idx_to_ntfy(struct gve_priv *priv, u32 queue_idx)
*/ */
static inline u32 gve_num_tx_qpls(struct gve_priv *priv) static inline u32 gve_num_tx_qpls(struct gve_priv *priv)
{ {
return priv->raw_addressing ? 0 : priv->tx_cfg.num_queues; if (priv->queue_format != GVE_GQI_QPL_FORMAT)
return 0;
return priv->tx_cfg.num_queues;
} }
/* Returns the number of rx queue page lists /* Returns the number of rx queue page lists
*/ */
static inline u32 gve_num_rx_qpls(struct gve_priv *priv) static inline u32 gve_num_rx_qpls(struct gve_priv *priv)
{ {
return priv->raw_addressing ? 0 : priv->rx_cfg.num_queues; if (priv->queue_format != GVE_GQI_QPL_FORMAT)
return 0;
return priv->rx_cfg.num_queues;
} }
/* Returns a pointer to the next available tx qpl in the list of qpls /* Returns a pointer to the next available tx qpl in the list of qpls
......
...@@ -61,7 +61,7 @@ void gve_parse_device_option(struct gve_priv *priv, ...@@ -61,7 +61,7 @@ void gve_parse_device_option(struct gve_priv *priv,
dev_info(&priv->pdev->dev, dev_info(&priv->pdev->dev,
"Gqi raw addressing device option enabled.\n"); "Gqi raw addressing device option enabled.\n");
priv->raw_addressing = 1; priv->queue_format = GVE_GQI_RDA_FORMAT;
break; break;
case GVE_DEV_OPT_ID_GQI_RDA: case GVE_DEV_OPT_ID_GQI_RDA:
if (option_length < sizeof(**dev_op_gqi_rda) || if (option_length < sizeof(**dev_op_gqi_rda) ||
...@@ -460,7 +460,8 @@ static int gve_adminq_create_tx_queue(struct gve_priv *priv, u32 queue_index) ...@@ -460,7 +460,8 @@ static int gve_adminq_create_tx_queue(struct gve_priv *priv, u32 queue_index)
u32 qpl_id; u32 qpl_id;
int err; int err;
qpl_id = priv->raw_addressing ? GVE_RAW_ADDRESSING_QPL_ID : tx->tx_fifo.qpl->id; qpl_id = priv->queue_format == GVE_GQI_RDA_FORMAT ?
GVE_RAW_ADDRESSING_QPL_ID : tx->tx_fifo.qpl->id;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.opcode = cpu_to_be32(GVE_ADMINQ_CREATE_TX_QUEUE); cmd.opcode = cpu_to_be32(GVE_ADMINQ_CREATE_TX_QUEUE);
cmd.create_tx_queue = (struct gve_adminq_create_tx_queue) { cmd.create_tx_queue = (struct gve_adminq_create_tx_queue) {
...@@ -501,7 +502,8 @@ static int gve_adminq_create_rx_queue(struct gve_priv *priv, u32 queue_index) ...@@ -501,7 +502,8 @@ static int gve_adminq_create_rx_queue(struct gve_priv *priv, u32 queue_index)
u32 qpl_id; u32 qpl_id;
int err; int err;
qpl_id = priv->raw_addressing ? GVE_RAW_ADDRESSING_QPL_ID : rx->data.qpl->id; qpl_id = priv->queue_format == GVE_GQI_RDA_FORMAT ?
GVE_RAW_ADDRESSING_QPL_ID : rx->data.qpl->id;
memset(&cmd, 0, sizeof(cmd)); memset(&cmd, 0, sizeof(cmd));
cmd.opcode = cpu_to_be32(GVE_ADMINQ_CREATE_RX_QUEUE); cmd.opcode = cpu_to_be32(GVE_ADMINQ_CREATE_RX_QUEUE);
cmd.create_rx_queue = (struct gve_adminq_create_rx_queue) { cmd.create_rx_queue = (struct gve_adminq_create_rx_queue) {
...@@ -628,7 +630,6 @@ int gve_adminq_describe_device(struct gve_priv *priv) ...@@ -628,7 +630,6 @@ int gve_adminq_describe_device(struct gve_priv *priv)
if (err) if (err)
goto free_device_descriptor; goto free_device_descriptor;
priv->raw_addressing = 0;
err = gve_process_device_options(priv, descriptor, &dev_op_gqi_rda, err = gve_process_device_options(priv, descriptor, &dev_op_gqi_rda,
&dev_op_gqi_qpl, &dev_op_dqo_rda); &dev_op_gqi_qpl, &dev_op_dqo_rda);
if (err) if (err)
...@@ -638,17 +639,19 @@ int gve_adminq_describe_device(struct gve_priv *priv) ...@@ -638,17 +639,19 @@ int gve_adminq_describe_device(struct gve_priv *priv)
* is not set to GqiRda, choose the queue format in a priority order: * is not set to GqiRda, choose the queue format in a priority order:
* DqoRda, GqiRda, GqiQpl. Use GqiQpl as default. * DqoRda, GqiRda, GqiQpl. Use GqiQpl as default.
*/ */
if (priv->raw_addressing == 1) { if (priv->queue_format == GVE_GQI_RDA_FORMAT) {
dev_info(&priv->pdev->dev, dev_info(&priv->pdev->dev,
"Driver is running with GQI RDA queue format.\n"); "Driver is running with GQI RDA queue format.\n");
} else if (dev_op_dqo_rda) { } else if (dev_op_dqo_rda) {
priv->queue_format = GVE_DQO_RDA_FORMAT;
dev_info(&priv->pdev->dev, dev_info(&priv->pdev->dev,
"Driver is running with DQO RDA queue format.\n"); "Driver is running with DQO RDA queue format.\n");
} else if (dev_op_gqi_rda) { } else if (dev_op_gqi_rda) {
priv->queue_format = GVE_GQI_RDA_FORMAT;
dev_info(&priv->pdev->dev, dev_info(&priv->pdev->dev,
"Driver is running with GQI RDA queue format.\n"); "Driver is running with GQI RDA queue format.\n");
priv->raw_addressing = 1;
} else { } else {
priv->queue_format = GVE_GQI_QPL_FORMAT;
dev_info(&priv->pdev->dev, dev_info(&priv->pdev->dev,
"Driver is running with GQI QPL queue format.\n"); "Driver is running with GQI QPL queue format.\n");
} }
......
// SPDX-License-Identifier: (GPL-2.0 OR MIT) // SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Google virtual Ethernet (gve) driver /* Google virtual Ethernet (gve) driver
* *
* Copyright (C) 2015-2019 Google, Inc. * Copyright (C) 2015-2021 Google, Inc.
*/ */
#include <linux/cpumask.h> #include <linux/cpumask.h>
...@@ -681,7 +681,7 @@ static int gve_alloc_qpls(struct gve_priv *priv) ...@@ -681,7 +681,7 @@ static int gve_alloc_qpls(struct gve_priv *priv)
int err; int err;
/* Raw addressing means no QPLs */ /* Raw addressing means no QPLs */
if (priv->raw_addressing) if (priv->queue_format == GVE_GQI_RDA_FORMAT)
return 0; return 0;
priv->qpls = kvzalloc(num_qpls * sizeof(*priv->qpls), GFP_KERNEL); priv->qpls = kvzalloc(num_qpls * sizeof(*priv->qpls), GFP_KERNEL);
...@@ -725,7 +725,7 @@ static void gve_free_qpls(struct gve_priv *priv) ...@@ -725,7 +725,7 @@ static void gve_free_qpls(struct gve_priv *priv)
int i; int i;
/* Raw addressing means no QPLs */ /* Raw addressing means no QPLs */
if (priv->raw_addressing) if (priv->queue_format == GVE_GQI_RDA_FORMAT)
return; return;
kvfree(priv->qpl_cfg.qpl_id_map); kvfree(priv->qpl_cfg.qpl_id_map);
...@@ -1088,7 +1088,7 @@ static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device) ...@@ -1088,7 +1088,7 @@ static int gve_init_priv(struct gve_priv *priv, bool skip_describe_device)
if (skip_describe_device) if (skip_describe_device)
goto setup_device; goto setup_device;
priv->raw_addressing = false; priv->queue_format = GVE_QUEUE_FORMAT_UNSPECIFIED;
/* Get the initial information we need from the device */ /* Get the initial information we need from the device */
err = gve_adminq_describe_device(priv); err = gve_adminq_describe_device(priv);
if (err) { if (err) {
...@@ -1352,6 +1352,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1352,6 +1352,7 @@ static int gve_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto abort_with_wq; goto abort_with_wq;
dev_info(&pdev->dev, "GVE version %s\n", gve_version_str); dev_info(&pdev->dev, "GVE version %s\n", gve_version_str);
dev_info(&pdev->dev, "GVE queue format %d\n", (int)priv->queue_format);
gve_clear_probe_in_progress(priv); gve_clear_probe_in_progress(priv);
queue_work(priv->gve_wq, &priv->service_task); queue_work(priv->gve_wq, &priv->service_task);
return 0; return 0;
......
...@@ -148,7 +148,7 @@ static int gve_rx_alloc_ring(struct gve_priv *priv, int idx) ...@@ -148,7 +148,7 @@ static int gve_rx_alloc_ring(struct gve_priv *priv, int idx)
slots = priv->rx_data_slot_cnt; slots = priv->rx_data_slot_cnt;
rx->mask = slots - 1; rx->mask = slots - 1;
rx->data.raw_addressing = priv->raw_addressing; rx->data.raw_addressing = priv->queue_format == GVE_GQI_RDA_FORMAT;
/* alloc rx data ring */ /* alloc rx data ring */
bytes = sizeof(*rx->data.data_ring) * slots; bytes = sizeof(*rx->data.data_ring) * slots;
......
...@@ -191,7 +191,7 @@ static int gve_tx_alloc_ring(struct gve_priv *priv, int idx) ...@@ -191,7 +191,7 @@ static int gve_tx_alloc_ring(struct gve_priv *priv, int idx)
if (!tx->desc) if (!tx->desc)
goto abort_with_info; goto abort_with_info;
tx->raw_addressing = priv->raw_addressing; tx->raw_addressing = priv->queue_format == GVE_GQI_RDA_FORMAT;
tx->dev = &priv->pdev->dev; tx->dev = &priv->pdev->dev;
if (!tx->raw_addressing) { if (!tx->raw_addressing) {
tx->tx_fifo.qpl = gve_assign_tx_qpl(priv); tx->tx_fifo.qpl = gve_assign_tx_qpl(priv);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment