From: Mark Blasko <[email protected]> Abstract control plane operations into a control operations interface. This decouples the core driver logic from the AQ implementation.
Store the ops table pointer in a per-process struct gve_process_private attached to eth_dev->process_private instead of in struct gve_priv: dev_private is shared with secondary processes, which may map the driver at a different address. Functions that only have struct gve_priv look up their ethdev through a new port_id field. Align AdminQ function parameters to match control operations signatures: - gve_adminq_configure_device_resources(): read counter array and IRQ doorbell DMA addresses/counts directly from struct gve_priv (wired to the get_interrupt_dbs control op). - gve_adminq_get_ptype_map_dqo(): populate priv->ptype_lut_dqo directly from struct gve_priv (wired to the get_ptype_map control op). Move the AdminQ driver compatibility check from gve_init_priv() into gve_adminq_get_device_properties(). Since gve_init_priv() skips get_device_properties on device reset, the check now only runs at probe time and is no longer repeated after a reset. Move the max_tx_queues and max_rx_queues register reads from gve_dev_init() into gve_adminq_get_device_properties(), as maximum queue counts are retrieved via get_device_properties in mailbox mode. Signed-off-by: Mark Blasko <[email protected]> Signed-off-by: Joshua Washington <[email protected]> --- v3: - Store the control ops table pointer in eth_dev->process_private (struct gve_process_private) instead of in dev_private, which is shared with secondary processes. Add port_id to struct gve_priv so functions that only have priv can reach it. - Mention in the commit message that the driver compatibility check no longer runs on device reset. - Only mark query_rss as optional and drop the set_mtu NULL check. --- drivers/net/gve/base/gve_adminq.c | 18 ++-- drivers/net/gve/base/gve_adminq.h | 9 +- drivers/net/gve/gve_ethdev.c | 163 ++++++++++++++++++++++-------- drivers/net/gve/gve_ethdev.h | 41 ++++++++ drivers/net/gve/gve_flow_rule.c | 11 +- drivers/net/gve/gve_rx.c | 3 +- drivers/net/gve/gve_rx_dqo.c | 3 +- drivers/net/gve/gve_tx.c | 3 +- drivers/net/gve/gve_tx_dqo.c | 3 +- 9 files changed, 186 insertions(+), 68 deletions(-) diff --git a/drivers/net/gve/base/gve_adminq.c b/drivers/net/gve/base/gve_adminq.c index 89bf669c24..74b9a0125c 100644 --- a/drivers/net/gve/base/gve_adminq.c +++ b/drivers/net/gve/base/gve_adminq.c @@ -664,11 +664,7 @@ int gve_adminq_report_nic_timestamp(struct gve_priv *priv, dma_addr_t nic_ts_rep * gve arranges the msix vectors so that the management vector is last. */ #define GVE_NTFY_BLK_BASE_MSIX_IDX 0 -int gve_adminq_configure_device_resources(struct gve_priv *priv, - dma_addr_t counter_array_bus_addr, - u32 num_counters, - dma_addr_t db_array_bus_addr, - u32 num_ntfy_blks) +int gve_adminq_configure_device_resources(struct gve_priv *priv) { union gve_adminq_command cmd; @@ -676,10 +672,10 @@ int gve_adminq_configure_device_resources(struct gve_priv *priv, cmd.opcode = cpu_to_be32(GVE_ADMINQ_CONFIGURE_DEVICE_RESOURCES); cmd.configure_device_resources = (struct gve_adminq_configure_device_resources) { - .counter_array = cpu_to_be64(counter_array_bus_addr), - .num_counters = cpu_to_be32(num_counters), - .irq_db_addr = cpu_to_be64(db_array_bus_addr), - .num_irq_dbs = cpu_to_be32(num_ntfy_blks), + .counter_array = cpu_to_be64(priv->cnt_array_mz->iova), + .num_counters = cpu_to_be32(priv->num_event_counters), + .irq_db_addr = cpu_to_be64(priv->irq_dbs_mz->iova), + .num_irq_dbs = cpu_to_be32(priv->num_ntfy_blks), .irq_db_stride = cpu_to_be32(sizeof(*priv->irq_dbs)), .ntfy_blk_msix_base_idx = cpu_to_be32(GVE_NTFY_BLK_BASE_MSIX_IDX), @@ -1198,9 +1194,9 @@ int gve_adminq_report_link_speed(struct gve_priv *priv) return err; } -int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv, - struct gve_ptype_lut *ptype_lut) +int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv) { + struct gve_ptype_lut *ptype_lut = priv->ptype_lut_dqo; struct gve_dma_mem ptype_map_dma_mem; struct gve_ptype_map *ptype_map; union gve_adminq_command cmd; diff --git a/drivers/net/gve/base/gve_adminq.h b/drivers/net/gve/base/gve_adminq.h index 954be39fbf..5002cdf783 100644 --- a/drivers/net/gve/base/gve_adminq.h +++ b/drivers/net/gve/base/gve_adminq.h @@ -523,11 +523,7 @@ int gve_adminq_alloc(struct gve_priv *priv); void gve_adminq_free(struct gve_priv *priv); void gve_adminq_release(struct gve_priv *priv); int gve_adminq_describe_device(struct gve_priv *priv); -int gve_adminq_configure_device_resources(struct gve_priv *priv, - dma_addr_t counter_array_bus_addr, - u32 num_counters, - dma_addr_t db_array_bus_addr, - u32 num_ntfy_blks); +int gve_adminq_configure_device_resources(struct gve_priv *priv); int gve_adminq_deconfigure_device_resources(struct gve_priv *priv); int gve_adminq_create_tx_queues(struct gve_priv *priv, u32 num_queues); int gve_adminq_destroy_tx_queues(struct gve_priv *priv, u32 queue_id); @@ -542,8 +538,7 @@ int gve_adminq_report_stats(struct gve_priv *priv, u64 stats_report_len, int gve_adminq_report_link_speed(struct gve_priv *priv); struct gve_ptype_lut; -int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv, - struct gve_ptype_lut *ptype_lut); +int gve_adminq_get_ptype_map_dqo(struct gve_priv *priv); int gve_adminq_verify_driver_compatibility(struct gve_priv *priv, u64 driver_info_len, diff --git a/drivers/net/gve/gve_ethdev.c b/drivers/net/gve/gve_ethdev.c index 80623979a8..ecf4247c19 100644 --- a/drivers/net/gve/gve_ethdev.c +++ b/drivers/net/gve/gve_ethdev.c @@ -153,10 +153,13 @@ gve_setup_queue_page_list(struct gve_priv *priv, uint16_t queue_id, bool is_rx, uint32_t num_pages) { const char *queue_type_string = is_rx ? "rx" : "tx"; + struct gve_process_private *process_priv; char qpl_name[RTE_MEMZONE_NAMESIZE]; struct gve_queue_page_list *qpl; int err; + process_priv = rte_eth_devices[priv->port_id].process_private; + /* Allocate a new QPL. */ snprintf(qpl_name, sizeof(qpl_name), "gve_%s_%s_qpl%d", priv->pci_dev->device.name, queue_type_string, queue_id); @@ -181,7 +184,7 @@ gve_setup_queue_page_list(struct gve_priv *priv, uint16_t queue_id, bool is_rx, priv->max_registered_pages); goto cleanup_qpl; } - err = gve_adminq_register_page_list(priv, qpl); + err = process_priv->ctrl_ops->register_page_list(priv, qpl); if (err) { PMD_DRV_LOG(ERR, "Failed to register %s qpl for queue %hu.", @@ -200,7 +203,11 @@ int gve_teardown_queue_page_list(struct gve_priv *priv, struct gve_queue_page_list *qpl) { - int err = gve_adminq_unregister_page_list(priv, qpl->id); + struct gve_process_private *process_priv; + int err; + + process_priv = rte_eth_devices[priv->port_id].process_private; + err = process_priv->ctrl_ops->unregister_page_list(priv, qpl->id); if (err) { PMD_DRV_LOG(CRIT, "Unable to unregister qpl %d!", qpl->id); return err; @@ -213,6 +220,7 @@ gve_teardown_queue_page_list(struct gve_priv *priv, static int gve_dev_configure(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; int err; @@ -239,7 +247,7 @@ gve_dev_configure(struct rte_eth_dev *dev) gve_init_rss_config_from_priv(priv, &update_reta_config); gve_generate_rss_reta(dev, &update_reta_config); - err = gve_adminq_configure_rss(priv, &update_reta_config); + err = process_priv->ctrl_ops->configure_rss(priv, &update_reta_config); if (err) PMD_DRV_LOG(ERR, "Could not reconfigure RSS redirection table."); @@ -256,6 +264,7 @@ gve_dev_configure(struct rte_eth_dev *dev) static int gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; struct rte_eth_link link; int err; @@ -270,7 +279,7 @@ gve_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complete) } else { link.link_status = RTE_ETH_LINK_UP; PMD_DRV_LOG(DEBUG, "Get link status from hw"); - err = gve_adminq_report_link_speed(priv); + err = process_priv->ctrl_ops->report_link_speed(priv); if (err) { PMD_DRV_LOG(ERR, "Failed to get link speed."); priv->link_speed = RTE_ETH_SPEED_NUM_UNKNOWN; @@ -359,6 +368,7 @@ gve_get_imissed_from_nic(struct rte_eth_dev *dev) static int gve_start_queues(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; uint16_t num_queues; uint16_t i; @@ -366,7 +376,7 @@ gve_start_queues(struct rte_eth_dev *dev) num_queues = dev->data->nb_tx_queues; priv->txqs = (struct gve_tx_queue **)dev->data->tx_queues; - ret = gve_adminq_create_tx_queues(priv, num_queues); + ret = process_priv->ctrl_ops->create_tx_queues(priv, num_queues); if (ret != 0) { PMD_DRV_LOG(ERR, "Failed to create %u tx queues.", num_queues); return ret; @@ -384,7 +394,7 @@ gve_start_queues(struct rte_eth_dev *dev) num_queues = dev->data->nb_rx_queues; priv->rxqs = (struct gve_rx_queue **)dev->data->rx_queues; - ret = gve_adminq_create_rx_queues(priv, num_queues); + ret = process_priv->ctrl_ops->create_rx_queues(priv, num_queues); if (ret != 0) { PMD_DRV_LOG(ERR, "Failed to create %u rx queues.", num_queues); goto err_tx; @@ -422,6 +432,7 @@ gve_start_queues(struct rte_eth_dev *dev) static int gve_dev_start(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv; int ret; @@ -450,11 +461,12 @@ gve_dev_start(struct rte_eth_dev *dev) "Failed to allocate region for stats reporting."); return ret; } - ret = gve_adminq_report_stats(priv, priv->stats_report_len, + ret = process_priv->ctrl_ops->setup_stats_report(priv, + priv->stats_report_len, priv->stats_report_mem->iova, GVE_STATS_REPORT_TIMER_PERIOD); if (ret != 0) { - PMD_DRV_LOG(ERR, "gve_adminq_report_stats command failed."); + PMD_DRV_LOG(ERR, "setup_stats_report command failed."); return ret; } } @@ -467,6 +479,7 @@ gve_dev_start(struct rte_eth_dev *dev) static void gve_read_nic_clock(void *arg) { + struct gve_process_private *process_priv; struct gve_priv *priv = arg; uint32_t fails; uint64_t ts; @@ -475,10 +488,12 @@ gve_read_nic_clock(void *arg) if (!priv || !priv->nic_ts_report_mz) return; + process_priv = rte_eth_devices[priv->port_id].process_private; + pthread_mutex_lock(&priv->nic_ts_lock); memset(priv->nic_ts_report, 0, sizeof(struct gve_nic_ts_report)); - err = gve_adminq_report_nic_timestamp(priv, priv->nic_ts_report_mz->iova); + err = process_priv->ctrl_ops->report_nic_timestamp(priv, priv->nic_ts_report_mz->iova); if (err == 0) { ts = be64_to_cpu(priv->nic_ts_report->nic_timestamp); pthread_mutex_unlock(&priv->nic_ts_lock); @@ -678,11 +693,14 @@ gve_teardown_flow_subsystem(struct gve_priv *priv) static void gve_teardown_device_resources(struct gve_priv *priv) { + struct gve_process_private *process_priv; int err; + process_priv = rte_eth_devices[priv->port_id].process_private; + /* Tell device its resources are being freed */ if (gve_get_device_resources_ok(priv)) { - err = gve_adminq_deconfigure_device_resources(priv); + err = process_priv->ctrl_ops->free_db_resources(priv); if (err) PMD_DRV_LOG(ERR, "Could not deconfigure device resources: err=%d", @@ -706,11 +724,15 @@ gve_teardown_device_resources(struct gve_priv *priv) static int gve_dev_close(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; int err = 0; - if (rte_eal_process_type() != RTE_PROC_PRIMARY) + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + free(dev->process_private); + dev->process_private = NULL; return 0; + } if (dev->data->dev_started) { err = gve_dev_stop(dev); @@ -723,19 +745,23 @@ gve_dev_close(struct rte_eth_dev *dev) gve_free_queues(dev); gve_teardown_device_resources(priv); - gve_adminq_free(priv); + process_priv->ctrl_ops->free_ctrl_plane(priv); pthread_mutex_destroy(&priv->flow_rule_lock); pthread_mutex_destroy(&priv->nic_ts_lock); dev->data->mac_addrs = NULL; + free(dev->process_private); + dev->process_private = NULL; + return err; } static int gve_dev_reset(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; int err; @@ -757,7 +783,7 @@ gve_dev_reset(struct rte_eth_dev *dev) */ gve_free_queues(dev); gve_teardown_device_resources(priv); - gve_adminq_free(priv); + process_priv->ctrl_ops->free_ctrl_plane(priv); err = gve_init_priv(priv, true); if (err != 0) { @@ -953,6 +979,7 @@ gve_dev_stats_reset(struct rte_eth_dev *dev) static int gve_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; int err; @@ -968,7 +995,7 @@ gve_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu) return -EBUSY; } - err = gve_adminq_set_mtu(priv, mtu); + err = process_priv->ctrl_ops->set_mtu(priv, mtu); if (err) { PMD_DRV_LOG(ERR, "Failed to set mtu as %u err = %d", mtu, err); return err; @@ -1098,6 +1125,7 @@ static int gve_rss_hash_update(struct rte_eth_dev *dev, struct rte_eth_rss_conf *rss_conf) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; struct gve_rss_config gve_rss_conf; int rss_reta_size; @@ -1158,7 +1186,7 @@ gve_rss_hash_update(struct rte_eth_dev *dev, memcpy(gve_rss_conf.indir, priv->rss_config.indir, gve_rss_conf.indir_size * sizeof(*priv->rss_config.indir)); - err = gve_adminq_configure_rss(priv, &gve_rss_conf); + err = process_priv->ctrl_ops->configure_rss(priv, &gve_rss_conf); if (!err) gve_update_priv_rss_config(priv, &gve_rss_conf); @@ -1198,6 +1226,7 @@ static int gve_rss_reta_update(struct rte_eth_dev *dev, struct rte_eth_rss_reta_entry64 *reta_conf, uint16_t reta_size) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; struct gve_rss_config gve_rss_conf; int table_id; @@ -1234,7 +1263,7 @@ gve_rss_reta_update(struct rte_eth_dev *dev, table_id++; } - err = gve_adminq_configure_rss(priv, &gve_rss_conf); + err = process_priv->ctrl_ops->configure_rss(priv, &gve_rss_conf); if (err) PMD_DRV_LOG(ERR, "Problem configuring RSS with device."); else @@ -1300,6 +1329,7 @@ gve_flow_ops_get(struct rte_eth_dev *dev, const struct rte_flow_ops **ops) static int gve_read_clock(struct rte_eth_dev *dev, uint64_t *clock) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; uint64_t ts; int err; @@ -1311,7 +1341,7 @@ gve_read_clock(struct rte_eth_dev *dev, uint64_t *clock) return -EIO; pthread_mutex_lock(&priv->nic_ts_lock); - err = gve_adminq_report_nic_timestamp(priv, priv->nic_ts_report_mz->iova); + err = process_priv->ctrl_ops->report_nic_timestamp(priv, priv->nic_ts_report_mz->iova); if (err != 0) { pthread_mutex_unlock(&priv->nic_ts_lock); return err; @@ -1428,10 +1458,13 @@ gve_setup_nic_timestamp(struct gve_priv *priv) static int gve_setup_device_resources(struct gve_priv *priv) { + struct gve_process_private *process_priv; char z_name[RTE_MEMZONE_NAMESIZE]; const struct rte_memzone *mz; int err = 0; + process_priv = rte_eth_devices[priv->port_id].process_private; + snprintf(z_name, sizeof(z_name), "gve_%s_cnt_arr", priv->pci_dev->device.name); mz = rte_memzone_reserve_aligned(z_name, priv->num_event_counters * sizeof(*priv->cnt_array), @@ -1457,11 +1490,7 @@ gve_setup_device_resources(struct gve_priv *priv) priv->irq_dbs = (struct gve_irq_db *)mz->addr; priv->irq_dbs_mz = mz; - err = gve_adminq_configure_device_resources(priv, - priv->cnt_array_mz->iova, - priv->num_event_counters, - priv->irq_dbs_mz->iova, - priv->num_ntfy_blks); + err = process_priv->ctrl_ops->get_interrupt_dbs(priv); if (unlikely(err)) { PMD_DRV_LOG(ERR, "Could not config device resources: err=%d", err); goto free_irq_dbs; @@ -1474,7 +1503,7 @@ gve_setup_device_resources(struct gve_priv *priv) err = -ENOMEM; goto free_irq_dbs; } - err = gve_adminq_get_ptype_map_dqo(priv, priv->ptype_lut_dqo); + err = process_priv->ctrl_ops->get_ptype_map(priv); if (unlikely(err)) { PMD_DRV_LOG(ERR, "Failed to get ptype map: err=%d", err); goto free_ptype_lut; @@ -1563,21 +1592,59 @@ gve_stop_dev_status_polling(struct rte_eth_dev *dev) } static int -gve_init_priv(struct gve_priv *priv, bool skip_describe_device) +gve_adminq_get_device_properties(struct gve_priv *priv) { - int num_ntfy; int err; - /* Set up the adminq */ - err = gve_adminq_alloc(priv); + err = gve_verify_driver_compatibility(priv); if (err) { - PMD_DRV_LOG(ERR, "Failed to alloc admin queue: err=%d", err); + PMD_DRV_LOG(ERR, "Could not verify driver compatibility: err=%d", err); return err; } - err = gve_verify_driver_compatibility(priv); + + /* Get max queues to alloc etherdev */ + priv->max_nb_txq = ioread32be(&priv->reg_bar0->max_tx_queues); + priv->max_nb_rxq = ioread32be(&priv->reg_bar0->max_rx_queues); + + return gve_adminq_describe_device(priv); +} + +static const struct gve_ctrl_ops gve_adminq_ops = { + .init_ctrl_plane = gve_adminq_alloc, + .free_ctrl_plane = gve_adminq_free, + .get_device_properties = gve_adminq_get_device_properties, + .get_ptype_map = gve_adminq_get_ptype_map_dqo, + .get_interrupt_dbs = gve_adminq_configure_device_resources, + .create_tx_queues = gve_adminq_create_tx_queues, + .destroy_tx_queues = gve_adminq_destroy_tx_queues, + .create_rx_queues = gve_adminq_create_rx_queues, + .destroy_rx_queues = gve_adminq_destroy_rx_queues, + .report_link_speed = gve_adminq_report_link_speed, + .configure_rss = gve_adminq_configure_rss, + .add_flow_rule = gve_adminq_add_flow_rule, + .del_flow_rule = gve_adminq_del_flow_rule, + .reset_flow_rules = gve_adminq_reset_flow_rules, + .free_db_resources = gve_adminq_deconfigure_device_resources, + .setup_stats_report = gve_adminq_report_stats, + .report_nic_timestamp = gve_adminq_report_nic_timestamp, + .set_mtu = gve_adminq_set_mtu, + .register_page_list = gve_adminq_register_page_list, + .unregister_page_list = gve_adminq_unregister_page_list, +}; + +static int +gve_init_priv(struct gve_priv *priv, bool skip_describe_device) +{ + struct gve_process_private *process_priv; + int num_ntfy; + int err; + + process_priv = rte_eth_devices[priv->port_id].process_private; + + err = process_priv->ctrl_ops->init_ctrl_plane(priv); if (err) { - PMD_DRV_LOG(ERR, "Could not verify driver compatibility: err=%d", err); - goto free_adminq; + PMD_DRV_LOG(ERR, "Failed to alloc control plane: err=%d", err); + return err; } if (skip_describe_device) @@ -1587,7 +1654,7 @@ gve_init_priv(struct gve_priv *priv, bool skip_describe_device) gve_set_default_ring_size_bounds(priv); /* Get the initial information we need from the device */ - err = gve_adminq_describe_device(priv); + err = process_priv->ctrl_ops->get_device_properties(priv); if (err) { PMD_DRV_LOG(ERR, "Could not get device information: err=%d", err); goto free_adminq; @@ -1637,7 +1704,7 @@ gve_init_priv(struct gve_priv *priv, bool skip_describe_device) if (!err) return 0; free_adminq: - gve_adminq_free(priv); + process_priv->ctrl_ops->free_ctrl_plane(priv); return err; } @@ -1645,13 +1712,21 @@ static int gve_dev_init(struct rte_eth_dev *eth_dev) { struct gve_priv *priv = eth_dev->data->dev_private; - int max_tx_queues, max_rx_queues; + struct gve_process_private *process_priv; struct rte_pci_device *pci_dev; struct gve_registers *reg_bar; pthread_mutexattr_t mutexattr; rte_be32_t *db_bar; int err; + process_priv = calloc(1, sizeof(struct gve_process_private)); + if (!process_priv) { + PMD_DRV_LOG(ERR, "Failed to alloc process_private"); + return -ENOMEM; + } + process_priv->ctrl_ops = &gve_adminq_ops; + eth_dev->process_private = process_priv; + if (rte_eal_process_type() != RTE_PROC_PRIMARY) { if (gve_is_gqi(priv)) { gve_set_rx_function(eth_dev); @@ -1670,28 +1745,25 @@ gve_dev_init(struct rte_eth_dev *eth_dev) reg_bar = pci_dev->mem_resource[GVE_REG_BAR].addr; if (!reg_bar) { PMD_DRV_LOG(ERR, "Failed to map pci bar!"); - return -ENOMEM; + err = -ENOMEM; + goto free_process_priv; } db_bar = pci_dev->mem_resource[GVE_DB_BAR].addr; if (!db_bar) { PMD_DRV_LOG(ERR, "Failed to map doorbell bar!"); - return -ENOMEM; + err = -ENOMEM; + goto free_process_priv; } gve_write_version(®_bar->driver_version); - /* Get max queues to alloc etherdev */ - max_tx_queues = ioread32be(®_bar->max_tx_queues); - max_rx_queues = ioread32be(®_bar->max_rx_queues); priv->reg_bar0 = reg_bar; priv->db_bar2 = db_bar; priv->pci_dev = pci_dev; + priv->port_id = eth_dev->data->port_id; priv->state_flags = 0x0; - priv->max_nb_txq = max_tx_queues; - priv->max_nb_rxq = max_rx_queues; - pthread_mutexattr_init(&mutexattr); pthread_mutexattr_setpshared(&mutexattr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&priv->flow_rule_lock, &mutexattr); @@ -1703,7 +1775,7 @@ gve_dev_init(struct rte_eth_dev *eth_dev) if (err) { pthread_mutex_destroy(&priv->flow_rule_lock); pthread_mutex_destroy(&priv->nic_ts_lock); - return err; + goto free_process_priv; } if (gve_is_gqi(priv)) { @@ -1719,6 +1791,11 @@ gve_dev_init(struct rte_eth_dev *eth_dev) eth_dev->data->mac_addrs = &priv->dev_addr; return 0; + +free_process_priv: + free(eth_dev->process_private); + eth_dev->process_private = NULL; + return err; } static int diff --git a/drivers/net/gve/gve_ethdev.h b/drivers/net/gve/gve_ethdev.h index c9a176ff17..7dbc1753a5 100644 --- a/drivers/net/gve/gve_ethdev.h +++ b/drivers/net/gve/gve_ethdev.h @@ -272,6 +272,46 @@ struct gve_flow { extern const struct rte_flow_ops gve_flow_ops; +struct gve_priv; +struct gve_flow_rule_params; + +struct gve_ctrl_ops { + int (*init_ctrl_plane)(struct gve_priv *priv); + void (*free_ctrl_plane)(struct gve_priv *priv); + int (*get_device_properties)(struct gve_priv *priv); + int (*get_ptype_map)(struct gve_priv *priv); + int (*get_interrupt_dbs)(struct gve_priv *priv); + int (*create_tx_queues)(struct gve_priv *priv, uint32_t num_queues); + int (*destroy_tx_queues)(struct gve_priv *priv, uint32_t num_queues); + int (*create_rx_queues)(struct gve_priv *priv, uint32_t num_queues); + int (*destroy_rx_queues)(struct gve_priv *priv, uint32_t num_queues); + int (*report_link_speed)(struct gve_priv *priv); + int (*configure_rss)(struct gve_priv *priv, + struct gve_rss_config *rss_conf); + int (*add_flow_rule)(struct gve_priv *priv, + struct gve_flow_rule_params *rule, uint32_t loc); + int (*del_flow_rule)(struct gve_priv *priv, uint32_t loc); + int (*reset_flow_rules)(struct gve_priv *priv); + int (*free_db_resources)(struct gve_priv *priv); + int (*setup_stats_report)(struct gve_priv *priv, + uint64_t stats_report_len, + dma_addr_t stats_report_addr, + uint64_t interval_ms); + int (*report_nic_timestamp)(struct gve_priv *priv, dma_addr_t dma_addr); + int (*set_mtu)(struct gve_priv *priv, uint64_t mtu); + int (*register_page_list)(struct gve_priv *priv, + struct gve_queue_page_list *qpl); + int (*unregister_page_list)(struct gve_priv *priv, + uint32_t page_list_id); + + /* Optional, may be NULL. Callers must check before use. */ + int (*query_rss)(struct gve_priv *priv); +}; + +struct gve_process_private { + const struct gve_ctrl_ops *ctrl_ops; +}; + struct gve_priv { struct gve_irq_db *irq_dbs; /* array of num_ntfy_blks */ const struct rte_memzone *irq_dbs_mz; @@ -310,6 +350,7 @@ struct gve_priv { struct gve_registers __iomem *reg_bar0; /* see gve_register.h */ rte_be32_t __iomem *db_bar2; /* "array" of doorbells */ struct rte_pci_device *pci_dev; + uint16_t port_id; /* Admin queue - see gve_adminq.h*/ union gve_adminq_command *adminq; diff --git a/drivers/net/gve/gve_flow_rule.c b/drivers/net/gve/gve_flow_rule.c index 1266e197ea..aec039c32b 100644 --- a/drivers/net/gve/gve_flow_rule.c +++ b/drivers/net/gve/gve_flow_rule.c @@ -446,11 +446,14 @@ gve_flow_free_bmp(struct gve_priv *priv) int gve_free_flow_rules(struct gve_priv *priv) { + struct gve_process_private *process_priv; struct gve_flow *flow; int err = 0; + process_priv = rte_eth_devices[priv->port_id].process_private; + if (!TAILQ_EMPTY(&priv->active_flows)) { - err = gve_adminq_reset_flow_rules(priv); + err = process_priv->ctrl_ops->reset_flow_rules(priv); if (err) { PMD_DRV_LOG(ERR, "Failed to reset flow rules, internal device err=%d", @@ -475,6 +478,7 @@ gve_create_flow_rule(struct rte_eth_dev *dev, const struct rte_flow_action actions[], struct rte_flow_error *error) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; struct gve_flow_rule_params rule = {0}; uint64_t slab_bits = 0; @@ -516,7 +520,7 @@ gve_create_flow_rule(struct rte_eth_dev *dev, goto free_flow_and_unlock; } - err = gve_adminq_add_flow_rule(priv, &rule, flow->rule_id); + err = process_priv->ctrl_ops->add_flow_rule(priv, &rule, flow->rule_id); if (err) { rte_bitmap_set(priv->avail_flow_rule_bmp, flow->rule_id); rte_flow_error_set(error, -err, @@ -541,6 +545,7 @@ static int gve_destroy_flow_rule(struct rte_eth_dev *dev, struct rte_flow *flow_handle, struct rte_flow_error *error) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *priv = dev->data->dev_private; struct gve_flow *flow; bool flow_rule_active; @@ -588,7 +593,7 @@ gve_destroy_flow_rule(struct rte_eth_dev *dev, struct rte_flow *flow_handle, goto unlock; } - err = gve_adminq_del_flow_rule(priv, flow->rule_id); + err = process_priv->ctrl_ops->del_flow_rule(priv, flow->rule_id); if (err) { rte_flow_error_set(error, -err, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, diff --git a/drivers/net/gve/gve_rx.c b/drivers/net/gve/gve_rx.c index d14902c662..472d8406ba 100644 --- a/drivers/net/gve/gve_rx.c +++ b/drivers/net/gve/gve_rx.c @@ -518,6 +518,7 @@ gve_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) void gve_stop_rx_queues(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *hw = dev->data->dev_private; uint16_t i; int err; @@ -525,7 +526,7 @@ gve_stop_rx_queues(struct rte_eth_dev *dev) if (!gve_is_gqi(hw)) return gve_stop_rx_queues_dqo(dev); - err = gve_adminq_destroy_rx_queues(hw, dev->data->nb_rx_queues); + err = process_priv->ctrl_ops->destroy_rx_queues(hw, dev->data->nb_rx_queues); if (err != 0) PMD_DRV_LOG(WARNING, "failed to destroy rxqs"); diff --git a/drivers/net/gve/gve_rx_dqo.c b/drivers/net/gve/gve_rx_dqo.c index 3665d9e4cd..1f901c5fd4 100644 --- a/drivers/net/gve/gve_rx_dqo.c +++ b/drivers/net/gve/gve_rx_dqo.c @@ -556,11 +556,12 @@ gve_rx_queue_stop_dqo(struct rte_eth_dev *dev, uint16_t rx_queue_id) void gve_stop_rx_queues_dqo(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *hw = dev->data->dev_private; uint16_t i; int err; - err = gve_adminq_destroy_rx_queues(hw, dev->data->nb_rx_queues); + err = process_priv->ctrl_ops->destroy_rx_queues(hw, dev->data->nb_rx_queues); if (err != 0) PMD_DRV_LOG(WARNING, "failed to destroy rxqs"); diff --git a/drivers/net/gve/gve_tx.c b/drivers/net/gve/gve_tx.c index c0400b07bf..568e948daa 100644 --- a/drivers/net/gve/gve_tx.c +++ b/drivers/net/gve/gve_tx.c @@ -725,6 +725,7 @@ gve_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) void gve_stop_tx_queues(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *hw = dev->data->dev_private; uint16_t i; int err; @@ -732,7 +733,7 @@ gve_stop_tx_queues(struct rte_eth_dev *dev) if (!gve_is_gqi(hw)) return gve_stop_tx_queues_dqo(dev); - err = gve_adminq_destroy_tx_queues(hw, dev->data->nb_tx_queues); + err = process_priv->ctrl_ops->destroy_tx_queues(hw, dev->data->nb_tx_queues); if (err != 0) PMD_DRV_LOG(WARNING, "failed to destroy txqs"); diff --git a/drivers/net/gve/gve_tx_dqo.c b/drivers/net/gve/gve_tx_dqo.c index 5c03d3d1a2..0b4d6074ab 100644 --- a/drivers/net/gve/gve_tx_dqo.c +++ b/drivers/net/gve/gve_tx_dqo.c @@ -608,11 +608,12 @@ gve_tx_queue_stop_dqo(struct rte_eth_dev *dev, uint16_t tx_queue_id) void gve_stop_tx_queues_dqo(struct rte_eth_dev *dev) { + struct gve_process_private *process_priv = dev->process_private; struct gve_priv *hw = dev->data->dev_private; uint16_t i; int err; - err = gve_adminq_destroy_tx_queues(hw, dev->data->nb_tx_queues); + err = process_priv->ctrl_ops->destroy_tx_queues(hw, dev->data->nb_tx_queues); if (err != 0) PMD_DRV_LOG(WARNING, "failed to destroy txqs"); -- 2.56.0.170.g584c36229d-goog

