[dpdk-dev] [v2 02/15] bnxt: Enable support for NPAR 1.0 feature

Ajit Khaparde ajit.khaparde at broadcom.com
Mon Sep 26 18:18:16 CEST 2016


Adding code to enable support for NIC Partitioning or NPAR 1.0
As a part of NPAR, we don't allow port settings like speed or flow
control to be changed.

Signed-off-by: Ajit Khaparde <ajit.khaparde at broadcom.com>
Reviewed-by: Stephen Hurd <stephen.hurd at broadcom.com>
Reviewed-by: David Christensen <david.christensen at broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   4 +
 drivers/net/bnxt/bnxt_ethdev.c         |  13 +-
 drivers/net/bnxt/bnxt_hwrm.c           |  38 ++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 211 +++++++++++++++++++++++++++++++++
 5 files changed, 259 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index df1f771..c77ecef 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -63,6 +63,7 @@ struct bnxt_vf_info {
 	uint16_t		max_rx_rings;
 	uint16_t		max_l2_ctx;
 	uint16_t		max_vnics;
+	uint16_t		vlan;
 	struct bnxt_pf_info	*pf;
 };
 
@@ -130,6 +131,8 @@ struct bnxt {
 #define BNXT_FLAG_VF		(1 << 1)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
+#define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
+#define BNXT_NPAR_PF(bp)	(BNXT_PF(bp) && BNXT_NPAR_ENABLED(bp))
 
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
@@ -171,6 +174,7 @@ struct bnxt {
 
 	struct bnxt_pf_info		pf;
 	struct bnxt_vf_info		vf;
+	uint8_t			port_partition_type;
 };
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index cea86cf..7431080 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -815,6 +815,9 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
 {
 	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
 
+	if (BNXT_NPAR_PF(bp))
+		return 0;
+
 	switch (fc_conf->mode) {
 	case RTE_FC_NONE:
 		bp->link_info.auto_pause = 0;
@@ -943,14 +946,6 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (version_printed++ == 0)
 		RTE_LOG(INFO, PMD, "%s", bnxt_version);
 
-	if (eth_dev->pci_dev->addr.function >= 2 &&
-			eth_dev->pci_dev->addr.function < 4) {
-		RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
-			eth_dev->pci_dev->addr.function);
-		rc = -ENOMEM;
-		goto error;
-	}
-
 	rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
 	bp = eth_dev->data->dev_private;
 
@@ -978,6 +973,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error_free;
 	bnxt_hwrm_queue_qportcfg(bp);
 
+	bnxt_hwrm_func_qcfg(bp);
+
 	/* Get the MAX capabilities for this function */
 	rc = bnxt_hwrm_func_qcaps(bp);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 2ed4c2f..3a6ff5c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1452,6 +1452,9 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 	struct bnxt_link_info link_req;
 	uint16_t speed;
 
+	if (BNXT_NPAR_PF(bp))
+		return 0;
+
 	rc = bnxt_valid_link_speed(dev_conf->link_speeds,
 			bp->eth_dev->data->port_id);
 	if (rc)
@@ -1488,3 +1491,38 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 error:
 	return rc;
 }
+
+/* JIRA 22088 */
+int bnxt_hwrm_func_qcfg(struct bnxt *bp)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (BNXT_VF(bp)) {
+		struct bnxt_vf_info *vf = &bp->vf;
+
+		/* Hard Coded.. 0xfff VLAN ID mask */
+		vf->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
+	}
+
+	switch (resp->port_partition_type) {
+	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
+	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5:
+	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0:
+		bp->port_partition_type = resp->port_partition_type;
+		break;
+	default:
+		bp->port_partition_type = 0;
+		break;
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index a508024..6519ef2 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -100,5 +100,6 @@ void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
 int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link);
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
+int bnxt_hwrm_func_qcfg(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index f2db3ea..5115937 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -85,6 +85,7 @@ struct ctx_hw_stats64 {
 #define HWRM_VER_GET			(UINT32_C(0x0))
 #define HWRM_FUNC_RESET			(UINT32_C(0x11))
 #define HWRM_FUNC_QCAPS			(UINT32_C(0x15))
+#define HWRM_FUNC_QCFG			(UINT32_C(0x16))
 #define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
@@ -5796,4 +5797,214 @@ struct hwrm_func_drv_unrgtr_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_func_qcfg */
+/*
+ * Description: This command returns the current configuration of a function.
+ * The input FID value is used to indicate what function is being queried. This
+ * allows a physical function driver to query virtual functions that are
+ * children of the physical function. The output FID value is needed to
+ * configure Rings and MSI-X vectors so their DMA operations appear correctly on
+ * the PCI bus.
+ */
+/* Input (24 bytes) */
+struct hwrm_func_qcfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+	/*
+	 * Function ID of the function that is being queried. 0xFF... (All Fs)
+	 * if the query is for the requesting function.
+	 */
+	uint16_t fid;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (72 bytes) */
+struct hwrm_func_qcfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+	/*
+	 * FID value. This value is used to identify operations on the PCI bus
+	 * as belonging to a particular PCI function.
+	 */
+	uint16_t fid;
+	/*
+	 * Port ID of port that this function is associated with. 0xFF... (All
+	 * Fs) if this function is not associated with any port.
+	 */
+	uint16_t port_id;
+	/*
+	 * This value is the current VLAN setting for this function. The value
+	 * of 0 for this field indicates no priority tagging or VLAN is used.
+	 * This VLAN is in 802.1Q tag format.
+	*/
+	uint16_t vlan;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+
+	/*
+	 * This value is current MAC address configured for this function. A
+	 * value of 00-00-00-00-00-00 indicates no MAC address is currently
+	 * configured.
+	 */
+	uint8_t mac_address[6];
+
+	/*
+	 * This value is current PCI ID of this function. If ARI is enabled,
+	 * then it is Bus Number (8b):Function Number(8b). Otherwise, it is Bus
+	 * Number (8b):Device Number (4b):Function Number(4b).
+	 */
+	uint16_t pci_id;
+	/* The number of RSS/COS contexts currently allocated to the function. */
+	uint16_t alloc_rsscos_ctx;
+	/*
+	 * The number of completion rings currently allocated to the function.
+	 * This does not include the rings allocated to any children functions
+	 * if any.
+	 */
+	uint16_t alloc_cmpl_rings;
+	/*
+	 * The number of transmit rings currently allocated to the function.
+	 * This does not include the rings allocated to any children functions
+	 * if any.
+	 */
+	uint16_t alloc_tx_rings;
+	/*
+	 * The number of receive rings currently allocated to the function. This
+	 * does not include the rings allocated to any children functions if
+	 * any.
+	 */
+	uint16_t alloc_rx_rings;
+	/* The allocated number of L2 contexts to the function. */
+	uint16_t alloc_l2_ctx;
+	/* The allocated number of vnics to the function. */
+	uint16_t alloc_vnics;
+	/*
+	 * The maximum transmission unit of the function. For rings allocated on
+	 * this function, this default value is used if ring MTU is not
+	 * specified.
+	 */
+	uint16_t mtu;
+	/*
+	 * The maximum receive unit of the function. For vnics allocated on this
+	 * function, this default value is used if vnic MRU is not specified.
+	 */
+	uint16_t mru;
+	/* The statistics context assigned to a function. */
+	uint16_t stat_ctx_id;
+	/*
+	 * The HWRM shall return Unknown value for this field when this command
+	 * is used to query VF's configuration.
+	 */
+	/* Single physical function */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_SPF \
+							(UINT32_C(0x0) << 0)
+	/* Multiple physical functions */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS \
+							(UINT32_C(0x1) << 0)
+	/* Network Partitioning 1.0 */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 \
+							(UINT32_C(0x2) << 0)
+	/* Network Partitioning 1.5 */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 \
+							(UINT32_C(0x3) << 0)
+	/* Network Partitioning 2.0 */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 \
+							(UINT32_C(0x4) << 0)
+	/* Unknown */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t port_partition_type;
+
+	uint8_t unused_2;
+	/* The default VNIC ID assigned to a function that is being queried. */
+	uint16_t dflt_vnic_id;
+
+	uint8_t unused_3;
+	uint8_t unused_4;
+	/*
+	 * Minimum BW allocated for this function in Mbps. The HWRM will
+	 * translate this value into byte counter and time interval used for the
+	 * scheduler inside the device. A value of 0 indicates the minimum
+	 * bandwidth is not configured.
+	 */
+	uint32_t min_bw;
+	/*
+	 * Maximum BW allocated for this function in Mbps. The HWRM will
+	 * translate this value into byte counter and time interval used for the
+	 * scheduler inside the device. A value of 0 indicates that the maximum
+	 * bandwidth is not configured.
+	 */
+	uint32_t max_bw;
+	/*
+	 * This value indicates the Edge virtual bridge mode for the domain that
+	 * this function belongs to.
+	 */
+	/* No Edge Virtual Bridging (EVB) */
+	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB	(UINT32_C(0x0) << 0)
+	/* Virtual Ethernet Bridge (VEB) */
+	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB	(UINT32_C(0x1) << 0)
+	/* Virtual Ethernet Port Aggregator (VEPA) */
+	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA	(UINT32_C(0x2) << 0)
+	uint8_t evb_mode;
+
+	uint8_t unused_5;
+	uint16_t unused_6;
+	/*
+	 * The number of allocated multicast filters for this function on the RX
+	 * side.
+	 */
+	uint32_t alloc_mcast_filters;
+	/* The number of allocated HW ring groups for this function. */
+	uint32_t alloc_hw_ring_grps;
+
+	uint8_t unused_7;
+	uint8_t unused_8;
+	uint8_t unused_9;
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
 #endif
-- 
2.4.3



More information about the dev mailing list