From: Ajit Khaparde Date: Mon, 26 Sep 2016 16:18:16 +0000 (-0500) Subject: net/bnxt: support NIC Partitioning X-Git-Tag: spdx-start~5765 X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=5cd0e2889c432b4dd2be65866f85a0306231496b;p=dpdk.git net/bnxt: support NIC Partitioning 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 Reviewed-by: Stephen Hurd Reviewed-by: David Christensen --- diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index df1f7718bf..c77ecefbe8 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 8f561a3fb7..eb086d5475 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 2ed4c2f1a3..3a6ff5c7e3 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 a508024f37..6519ef21a6 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 f2db3eaf06..5115937a8a 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