[v2,32/32] net/sssnic: add VF dev support

Message ID 20230831095650.219964-33-wanry@3snic.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series Introduce sssnic PMD for 3SNIC's 9x0 serials Ethernet adapters |

Checks

Context Check Description
ci/checkpatch warning coding style issues
ci/Intel-compilation fail Compilation issues
ci/intel-Testing success Testing PASS
ci/github-robot: build success github build: passed
ci/iol-mellanox-Performance success Performance Testing PASS
ci/iol-compile-amd64-testing success Testing PASS
ci/iol-unit-amd64-testing success Testing PASS
ci/iol-unit-arm64-testing success Testing PASS
ci/iol-sample-apps-testing success Testing PASS
ci/iol-compile-arm64-testing success Testing PASS
ci/iol-broadcom-Functional success Functional Testing PASS
ci/iol-intel-Performance success Performance Testing PASS
ci/iol-intel-Functional success Functional Testing PASS
ci/iol-broadcom-Performance success Performance Testing PASS
ci/intel-Functional success Functional PASS
ci/loongarch-compilation success Compilation OK
ci/loongarch-unit-testing success Unit Testing PASS

Commit Message

Renyong Wan Aug. 31, 2023, 9:56 a.m. UTC
  From: Renyong Wan <wanry@3snic.com>

In comparison to PF, VF PMD does not support the following features:

1. link up and link down set
2. promiscuous enable and disable
3. MAC stats in extend xstats

Signed-off-by: Steven Song <steven.song@3snic.com>
Signed-off-by: Renyong Wan <wanry@3snic.com>
---
 drivers/net/sssnic/base/sssnic_api.c     | 42 +++++++++++++++++
 drivers/net/sssnic/base/sssnic_api.h     |  2 +
 drivers/net/sssnic/base/sssnic_cmd.h     |  6 +++
 drivers/net/sssnic/base/sssnic_hw.c      | 19 ++++++--
 drivers/net/sssnic/base/sssnic_hw.h      |  4 ++
 drivers/net/sssnic/sssnic_ethdev.c       | 60 +++++++++++++++++++++++-
 drivers/net/sssnic/sssnic_ethdev_stats.c | 29 ++++++++++--
 7 files changed, 153 insertions(+), 9 deletions(-)
  

Patch

diff --git a/drivers/net/sssnic/base/sssnic_api.c b/drivers/net/sssnic/base/sssnic_api.c
index 0e965442fd..2d829bc884 100644
--- a/drivers/net/sssnic/base/sssnic_api.c
+++ b/drivers/net/sssnic/base/sssnic_api.c
@@ -1899,3 +1899,45 @@  sssnic_tcam_entry_del(struct sssnic_hw *hw, uint32_t entry_idx)
 
 	return 0;
 }
+
+static int
+sssnic_vf_port_register_op(struct sssnic_hw *hw, bool op)
+{
+	int ret;
+	struct sssnic_vf_port_register_cmd cmd;
+	struct sssnic_msg msg;
+	uint32_t cmd_len;
+
+	memset(&cmd, 0, sizeof(cmd));
+	cmd.op = op ? 1 : 0;
+	cmd_len = sizeof(cmd);
+	sssnic_msg_init(&msg, (uint8_t *)&cmd, cmd_len,
+		SSSNIC_REGISTER_VF_PORT_CMD, SSSNIC_PF_FUNC_IDX(hw),
+		SSSNIC_LAN_MODULE, SSSNIC_MSG_TYPE_REQ);
+	ret = sssnic_mbox_send(hw, &msg, (uint8_t *)&cmd, &cmd_len, 0);
+	if (ret != 0) {
+		PMD_DRV_LOG(ERR, "Failed to send mbox message, ret=%d", ret);
+		return ret;
+	}
+
+	if (cmd_len == 0 || cmd.common.status != 0) {
+		PMD_DRV_LOG(ERR,
+			"Bad response to SSSNIC_REGISTER_VF_PORT_CMD, len=%u, status=%u",
+			cmd_len, cmd.common.status);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int
+sssnic_vf_port_register(struct sssnic_hw *hw)
+{
+	return sssnic_vf_port_register_op(hw, true);
+}
+
+int
+sssnic_vf_port_unregister(struct sssnic_hw *hw)
+{
+	return sssnic_vf_port_register_op(hw, false);
+}
diff --git a/drivers/net/sssnic/base/sssnic_api.h b/drivers/net/sssnic/base/sssnic_api.h
index 7a02ec61ee..2506682821 100644
--- a/drivers/net/sssnic/base/sssnic_api.h
+++ b/drivers/net/sssnic/base/sssnic_api.h
@@ -492,5 +492,7 @@  int sssnic_tcam_packet_type_filter_set(struct sssnic_hw *hw, uint8_t ptype,
 int sssnic_tcam_entry_add(struct sssnic_hw *hw,
 	struct sssnic_tcam_entry *entry);
 int sssnic_tcam_entry_del(struct sssnic_hw *hw, uint32_t entry_idx);
+int sssnic_vf_port_register(struct sssnic_hw *hw);
+int sssnic_vf_port_unregister(struct sssnic_hw *hw);
 
 #endif /* _SSSNIC_API_H_ */
diff --git a/drivers/net/sssnic/base/sssnic_cmd.h b/drivers/net/sssnic/base/sssnic_cmd.h
index c75cb0dad3..058ab298f3 100644
--- a/drivers/net/sssnic/base/sssnic_cmd.h
+++ b/drivers/net/sssnic/base/sssnic_cmd.h
@@ -505,4 +505,10 @@  struct sssnic_tcam_entry_del_cmd {
 	uint32_t num; /* number of entries to be deleted */
 };
 
+struct sssnic_vf_port_register_cmd {
+	struct sssnic_cmd_common common;
+	uint8_t op; /* 0: unregister, 1: register */
+	uint8_t resvd[39];
+};
+
 #endif /* _SSSNIC_CMD_H_ */
diff --git a/drivers/net/sssnic/base/sssnic_hw.c b/drivers/net/sssnic/base/sssnic_hw.c
index 651a0aa7ef..0edd5b9508 100644
--- a/drivers/net/sssnic/base/sssnic_hw.c
+++ b/drivers/net/sssnic/base/sssnic_hw.c
@@ -345,10 +345,16 @@  sssnic_base_init(struct sssnic_hw *hw)
 	pci_dev = hw->pci_dev;
 
 	/* get base addresses of hw registers */
-	hw->cfg_base_addr =
-		(uint8_t *)pci_dev->mem_resource[SSSNIC_PCI_BAR_CFG].addr;
-	hw->mgmt_base_addr =
-		(uint8_t *)pci_dev->mem_resource[SSSNIC_PCI_BAR_MGMT].addr;
+	if (pci_dev->id.device_id == SSSNIC_VF_DEVICE_ID) {
+		uint8_t *addr =
+			(uint8_t *)pci_dev->mem_resource[SSSNIC_VF_PCI_BAR_CFG].addr;
+		hw->cfg_base_addr = addr + SSSNIC_VF_CFG_ADDR_OFFSET;
+	} else {
+		hw->cfg_base_addr =
+			(uint8_t *)pci_dev->mem_resource[SSSNIC_PCI_BAR_CFG].addr;
+		hw->mgmt_base_addr =
+			(uint8_t *)pci_dev->mem_resource[SSSNIC_PCI_BAR_MGMT].addr;
+	}
 	hw->db_base_addr =
 		(uint8_t *)pci_dev->mem_resource[SSSNIC_PCI_BAR_DB].addr;
 	hw->db_mem_len =
@@ -365,7 +371,10 @@  sssnic_base_init(struct sssnic_hw *hw)
 		PMD_DRV_LOG(ERR, "Doorbell is not enabled!");
 		return -EBUSY;
 	}
-	sssnic_af_setup(hw);
+
+	if (SSSNIC_FUNC_TYPE(hw) != SSSNIC_FUNC_TYPE_VF)
+		sssnic_af_setup(hw);
+
 	sssnic_msix_all_disable(hw);
 	sssnic_pf_status_set(hw, SSSNIC_PF_STATUS_INIT);
 
diff --git a/drivers/net/sssnic/base/sssnic_hw.h b/drivers/net/sssnic/base/sssnic_hw.h
index 6a2d980d5a..9d8a3653a7 100644
--- a/drivers/net/sssnic/base/sssnic_hw.h
+++ b/drivers/net/sssnic/base/sssnic_hw.h
@@ -7,11 +7,15 @@ 
 
 #define SSSNIC_PCI_VENDOR_ID 0x1F3F
 #define SSSNIC_DEVICE_ID_STD 0x9020
+#define SSSNIC_VF_DEVICE_ID 0x9001
 
+#define SSSNIC_VF_PCI_BAR_CFG 0
 #define SSSNIC_PCI_BAR_CFG 1
 #define SSSNIC_PCI_BAR_MGMT 3
 #define SSSNIC_PCI_BAR_DB 4
 
+#define SSSNIC_VF_CFG_ADDR_OFFSET 0x2000
+
 #define SSSNIC_FUNC_TYPE_PF 0
 #define SSSNIC_FUNC_TYPE_VF 1
 #define SSSNIC_FUNC_TYPE_AF 2
diff --git a/drivers/net/sssnic/sssnic_ethdev.c b/drivers/net/sssnic/sssnic_ethdev.c
index 545833fb55..18d9ba7ac1 100644
--- a/drivers/net/sssnic/sssnic_ethdev.c
+++ b/drivers/net/sssnic/sssnic_ethdev.c
@@ -349,6 +349,8 @@  sssnic_ethdev_release(struct rte_eth_dev *ethdev)
 	sssnic_ethdev_rx_queue_all_release(ethdev);
 	sssnic_ethdev_fdir_shutdown(ethdev);
 	sssnic_ethdev_mac_addrs_clean(ethdev);
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		sssnic_vf_port_unregister(hw);
 	sssnic_hw_shutdown(hw);
 	rte_free(hw);
 }
@@ -957,6 +959,47 @@  static const struct eth_dev_ops sssnic_ethdev_ops = {
 	.flow_ops_get = sssnic_ethdev_flow_ops_get,
 };
 
+static const struct eth_dev_ops sssnic_vf_ethdev_ops = {
+	.dev_start = sssnic_ethdev_start,
+	.dev_stop = sssnic_ethdev_stop,
+	.dev_close = sssnic_ethdev_close,
+	.link_update = sssnic_ethdev_link_update,
+	.dev_configure = sssnic_ethdev_configure,
+	.dev_infos_get = sssnic_ethdev_infos_get,
+	.mtu_set = sssnic_ethdev_mtu_set,
+	.mac_addr_set = sssnic_ethdev_mac_addr_set,
+	.mac_addr_remove = sssnic_ethdev_mac_addr_remove,
+	.mac_addr_add = sssnic_ethdev_mac_addr_add,
+	.set_mc_addr_list = sssnic_ethdev_set_mc_addr_list,
+	.rx_queue_setup = sssnic_ethdev_rx_queue_setup,
+	.rx_queue_release = sssnic_ethdev_rx_queue_release,
+	.tx_queue_setup = sssnic_ethdev_tx_queue_setup,
+	.tx_queue_release = sssnic_ethdev_tx_queue_release,
+	.rx_queue_start = sssnic_ethdev_rx_queue_start,
+	.rx_queue_stop = sssnic_ethdev_rx_queue_stop,
+	.tx_queue_start = sssnic_ethdev_tx_queue_start,
+	.tx_queue_stop = sssnic_ethdev_tx_queue_stop,
+	.rx_queue_intr_enable = sssnic_ethdev_rx_queue_intr_enable,
+	.rx_queue_intr_disable = sssnic_ethdev_rx_queue_intr_disable,
+	.allmulticast_enable = sssnic_ethdev_allmulticast_enable,
+	.allmulticast_disable = sssnic_ethdev_allmulticast_disable,
+	.stats_get = sssnic_ethdev_stats_get,
+	.stats_reset = sssnic_ethdev_stats_reset,
+	.xstats_get_names = sssnic_ethdev_xstats_get_names,
+	.xstats_get = sssnic_ethdev_xstats_get,
+	.xstats_reset = sssnic_ethdev_xstats_reset,
+	.rss_hash_conf_get = sssnic_ethdev_rss_hash_config_get,
+	.rss_hash_update = sssnic_ethdev_rss_hash_update,
+	.reta_update = sssnic_ethdev_rss_reta_update,
+	.reta_query = sssnic_ethdev_rss_reta_query,
+	.rxq_info_get = sssnic_ethdev_rx_queue_info_get,
+	.txq_info_get = sssnic_ethdev_tx_queue_info_get,
+	.fw_version_get = sssnic_ethdev_fw_version_get,
+	.vlan_offload_set = sssnic_ethdev_vlan_offload_set,
+	.vlan_filter_set = sssnic_ethdev_vlan_filter_set,
+	.flow_ops_get = sssnic_ethdev_flow_ops_get,
+};
+
 static int
 sssnic_ethdev_init(struct rte_eth_dev *ethdev)
 {
@@ -989,6 +1032,14 @@  sssnic_ethdev_init(struct rte_eth_dev *ethdev)
 		return ret;
 	}
 
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF) {
+		ret = sssnic_vf_port_register(hw);
+		if (ret != 0) {
+			PMD_DRV_LOG(ERR, "Failed to register VF device");
+			goto vf_register_fail;
+		}
+	}
+
 	ret = sssnic_ethdev_mac_addrs_init(ethdev);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "Failed to initialize MAC addresses");
@@ -1004,7 +1055,10 @@  sssnic_ethdev_init(struct rte_eth_dev *ethdev)
 	netdev->max_num_rxq = SSSNIC_MAX_NUM_RXQ(hw);
 	netdev->max_num_txq = SSSNIC_MAX_NUM_TXQ(hw);
 
-	ethdev->dev_ops = &sssnic_ethdev_ops;
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		ethdev->dev_ops = &sssnic_vf_ethdev_ops;
+	else
+		ethdev->dev_ops = &sssnic_ethdev_ops;
 
 	sssnic_ethdev_link_update(ethdev, 0);
 	sssnic_ethdev_link_intr_enable(ethdev);
@@ -1014,6 +1068,9 @@  sssnic_ethdev_init(struct rte_eth_dev *ethdev)
 fdir_init_fail:
 	sssnic_ethdev_mac_addrs_clean(ethdev);
 mac_addrs_init_fail:
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		sssnic_vf_port_unregister(hw);
+vf_register_fail:
 	sssnic_hw_shutdown(0);
 	return ret;
 }
@@ -1059,6 +1116,7 @@  sssnic_pci_remove(struct rte_pci_device *pci_dev)
 
 static const struct rte_pci_id sssnic_pci_id_map[] = {
 	{ RTE_PCI_DEVICE(SSSNIC_PCI_VENDOR_ID, SSSNIC_DEVICE_ID_STD) },
+	{ RTE_PCI_DEVICE(SSSNIC_PCI_VENDOR_ID, SSSNIC_VF_DEVICE_ID) },
 	{ .vendor_id = 0 },
 };
 
diff --git a/drivers/net/sssnic/sssnic_ethdev_stats.c b/drivers/net/sssnic/sssnic_ethdev_stats.c
index dd91aef5f7..dc7d912dbf 100644
--- a/drivers/net/sssnic/sssnic_ethdev_stats.c
+++ b/drivers/net/sssnic/sssnic_ethdev_stats.c
@@ -244,9 +244,19 @@  sssnic_ethdev_stats_reset(struct rte_eth_dev *ethdev)
 static uint32_t
 sssnic_ethdev_xstats_num_calc(struct rte_eth_dev *ethdev)
 {
-	return SSSNIC_ETHDEV_NB_PORT_XSTATS + SSSNIC_ETHDEV_NB_MAC_XSTATS +
-	       (SSSNIC_ETHDEV_NB_TXQ_XSTATS * ethdev->data->nb_tx_queues) +
-	       (SSSNIC_ETHDEV_NB_RXQ_XSTATS * ethdev->data->nb_rx_queues);
+	struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);
+	uint32_t num;
+
+	num = SSSNIC_ETHDEV_NB_PORT_XSTATS;
+	num += SSSNIC_ETHDEV_NB_TXQ_XSTATS * ethdev->data->nb_tx_queues;
+	num += SSSNIC_ETHDEV_NB_RXQ_XSTATS * ethdev->data->nb_rx_queues;
+
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		return num;
+
+	num += SSSNIC_ETHDEV_NB_MAC_XSTATS;
+
+	return num;
 }
 
 int
@@ -255,6 +265,7 @@  sssnic_ethdev_xstats_get_names(struct rte_eth_dev *ethdev,
 	__rte_unused unsigned int limit)
 {
 	uint16_t i, qid, count = 0;
+	struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);
 
 	if (xstats_names == NULL)
 		return sssnic_ethdev_xstats_num_calc(ethdev);
@@ -283,6 +294,9 @@  sssnic_ethdev_xstats_get_names(struct rte_eth_dev *ethdev,
 		count++;
 	}
 
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		return count;
+
 	for (i = 0; i < SSSNIC_ETHDEV_NB_MAC_XSTATS; i++) {
 		snprintf(xstats_names[count].name, RTE_ETH_XSTATS_NAME_SIZE,
 			"mac_%s", mac_stats_strings[i].name);
@@ -348,6 +362,11 @@  sssnic_ethdev_xstats_get(struct rte_eth_dev *ethdev,
 		count++;
 	}
 
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF) {
+		ret = count;
+		goto out;
+	}
+
 	ret = sssnic_mac_stats_get(hw, &stats->mac);
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to get port %u mac stats",
@@ -372,6 +391,7 @@  int
 sssnic_ethdev_xstats_reset(struct rte_eth_dev *ethdev)
 {
 	int ret;
+	struct sssnic_hw *hw = SSSNIC_ETHDEV_TO_HW(ethdev);
 
 	ret = sssnic_ethdev_stats_reset(ethdev);
 	if (ret) {
@@ -380,6 +400,9 @@  sssnic_ethdev_xstats_reset(struct rte_eth_dev *ethdev)
 		return ret;
 	}
 
+	if (SSSNIC_FUNC_TYPE(hw) == SSSNIC_FUNC_TYPE_VF)
+		return 0;
+
 	ret = sssnic_mac_stats_clear(SSSNIC_ETHDEV_TO_HW(ethdev));
 	if (ret) {
 		PMD_DRV_LOG(ERR, "Failed to clear port %u MAC stats",