From patchwork Fri Jun 29 19:23:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rahul Lakkireddy X-Patchwork-Id: 42000 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 415661BACD; Fri, 29 Jun 2018 21:25:34 +0200 (CEST) Received: from stargate.chelsio.com (stargate.chelsio.com [12.32.117.8]) by dpdk.org (Postfix) with ESMTP id 23E171BAB6 for ; Fri, 29 Jun 2018 21:25:31 +0200 (CEST) Received: from localhost (scalar.blr.asicdesigners.com [10.193.185.94]) by stargate.chelsio.com (8.13.8/8.13.8) with ESMTP id w5TJPQmM028999; Fri, 29 Jun 2018 12:25:27 -0700 From: Rahul Lakkireddy To: dev@dpdk.org Cc: surendra@chelsio.com, shaguna@chelsio.com, indranil@chelsio.com, nirranjan@chelsio.com Date: Sat, 30 Jun 2018 00:53:53 +0530 Message-Id: <968f776ccb53269cb825f847b017bfcc83b5a840.1530300158.git.rahul.lakkireddy@chelsio.com> X-Mailer: git-send-email 2.5.3 In-Reply-To: References: In-Reply-To: References: Subject: [dpdk-dev] [PATCH 3/5] net/cxgbe: query firmware for max queues available X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Query firmware for max Tx and Rx queues that can be allocated. Move the code to determine max queues to common place for both PF and VF. Signed-off-by: Rahul Lakkireddy --- drivers/net/cxgbe/base/common.h | 10 +++++++ drivers/net/cxgbe/base/t4_hw.c | 40 ++++++++++++++++++++++++++ drivers/net/cxgbe/base/t4fw_interface.h | 6 ++++ drivers/net/cxgbe/cxgbe.h | 1 + drivers/net/cxgbe/cxgbe_main.c | 50 +++++++++++++++++++++++++++++++-- drivers/net/cxgbe/cxgbevf_main.c | 20 ++----------- 6 files changed, 106 insertions(+), 21 deletions(-) diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h index e524f7931..9c4a33771 100644 --- a/drivers/net/cxgbe/base/common.h +++ b/drivers/net/cxgbe/base/common.h @@ -207,6 +207,14 @@ struct rss_params { } u; }; +/* + * Maximum resources provisioned for a PCI PF. + */ +struct pf_resources { + unsigned int neq; /* N egress Qs */ + unsigned int niqflint; /* N ingress Qs/w free list(s) & intr */ +}; + /* * Maximum resources provisioned for a PCI VF. */ @@ -230,6 +238,7 @@ struct adapter_params { struct pci_params pci; struct devlog_params devlog; struct rss_params rss; + struct pf_resources pfres; struct vf_resources vfres; enum pcie_memwin drv_memwin; @@ -456,6 +465,7 @@ void t4_write_indirect(struct adapter *adap, unsigned int addr_reg, unsigned int nregs, unsigned int start_idx); int t4_get_vpd_params(struct adapter *adapter, struct vpd_params *p); +int t4_get_pfres(struct adapter *adapter); int t4_read_flash(struct adapter *adapter, unsigned int addr, unsigned int nwords, u32 *data, int byte_oriented); int t4_flash_cfg_addr(struct adapter *adapter); diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c index 66d080476..698781509 100644 --- a/drivers/net/cxgbe/base/t4_hw.c +++ b/drivers/net/cxgbe/base/t4_hw.c @@ -2480,6 +2480,46 @@ int t4_get_core_clock(struct adapter *adapter, struct vpd_params *p) return 0; } +/** + * t4_get_pfres - retrieve VF resource limits + * @adapter: the adapter + * + * Retrieves configured resource limits and capabilities for a physical + * function. The results are stored in @adapter->pfres. + */ +int t4_get_pfres(struct adapter *adapter) +{ + struct pf_resources *pfres = &adapter->params.pfres; + struct fw_pfvf_cmd cmd, rpl; + u32 word; + int v; + + /* + * Execute PFVF Read command to get VF resource limits; bail out early + * with error on command failure. + */ + memset(&cmd, 0, sizeof(cmd)); + cmd.op_to_vfn = cpu_to_be32(V_FW_CMD_OP(FW_PFVF_CMD) | + F_FW_CMD_REQUEST | + F_FW_CMD_READ | + V_FW_PFVF_CMD_PFN(adapter->pf) | + V_FW_PFVF_CMD_VFN(0)); + cmd.retval_len16 = cpu_to_be32(FW_LEN16(cmd)); + v = t4_wr_mbox(adapter, adapter->mbox, &cmd, sizeof(cmd), &rpl); + if (v != FW_SUCCESS) + return v; + + /* + * Extract PF resource limits and return success. + */ + word = be32_to_cpu(rpl.niqflint_niq); + pfres->niqflint = G_FW_PFVF_CMD_NIQFLINT(word); + + word = be32_to_cpu(rpl.type_to_neq); + pfres->neq = G_FW_PFVF_CMD_NEQ(word); + return 0; +} + /* serial flash and firmware constants and flash config file constants */ enum { SF_ATTEMPTS = 10, /* max retries for SF operations */ diff --git a/drivers/net/cxgbe/base/t4fw_interface.h b/drivers/net/cxgbe/base/t4fw_interface.h index 842aa1263..9dc6d8123 100644 --- a/drivers/net/cxgbe/base/t4fw_interface.h +++ b/drivers/net/cxgbe/base/t4fw_interface.h @@ -729,6 +729,12 @@ struct fw_pfvf_cmd { __be32 r4; }; +#define S_FW_PFVF_CMD_PFN 8 +#define V_FW_PFVF_CMD_PFN(x) ((x) << S_FW_PFVF_CMD_PFN) + +#define S_FW_PFVF_CMD_VFN 0 +#define V_FW_PFVF_CMD_VFN(x) ((x) << S_FW_PFVF_CMD_VFN) + #define S_FW_PFVF_CMD_NIQFLINT 20 #define M_FW_PFVF_CMD_NIQFLINT 0xfff #define G_FW_PFVF_CMD_NIQFLINT(x) \ diff --git a/drivers/net/cxgbe/cxgbe.h b/drivers/net/cxgbe/cxgbe.h index 70f974f5a..5e6f5c98d 100644 --- a/drivers/net/cxgbe/cxgbe.h +++ b/drivers/net/cxgbe/cxgbe.h @@ -63,5 +63,6 @@ void cxgbe_enable_rx_queues(struct port_info *pi); void print_port_info(struct adapter *adap); void print_adapter_info(struct adapter *adap); int cxgbe_get_devargs(struct rte_devargs *devargs, const char *key); +void configure_max_ethqsets(struct adapter *adapter); #endif /* _CXGBE_H_ */ diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c index 1d77d4621..334c3678f 100644 --- a/drivers/net/cxgbe/cxgbe_main.c +++ b/drivers/net/cxgbe/cxgbe_main.c @@ -389,7 +389,7 @@ void cfg_queues(struct rte_eth_dev *eth_dev) * We default up to # of cores queues per 1G/10G port. */ if (nb_ports) - q_per_port = (MAX_ETH_QSETS - + q_per_port = (s->max_ethqsets - (adap->params.nports - nb_ports)) / nb_ports; @@ -413,8 +413,6 @@ void cfg_queues(struct rte_eth_dev *eth_dev) qidx += pi->n_rx_qsets; } - s->max_ethqsets = qidx; - for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) { struct sge_eth_rxq *r = &s->ethrxq[i]; @@ -646,6 +644,40 @@ static void configure_pcie_ext_tag(struct adapter *adapter) } } +/* Figure out how many Queue Sets we can support */ +void configure_max_ethqsets(struct adapter *adapter) +{ + unsigned int ethqsets; + + /* + * We need to reserve an Ingress Queue for the Asynchronous Firmware + * Event Queue. + * + * For each Queue Set, we'll need the ability to allocate two Egress + * Contexts -- one for the Ingress Queue Free List and one for the TX + * Ethernet Queue. + */ + if (is_pf4(adapter)) { + struct pf_resources *pfres = &adapter->params.pfres; + + ethqsets = pfres->niqflint - 1; + if (pfres->neq < ethqsets * 2) + ethqsets = pfres->neq / 2; + } else { + struct vf_resources *vfres = &adapter->params.vfres; + + ethqsets = vfres->niqflint - 1; + if (vfres->nethctrl != ethqsets) + ethqsets = min(vfres->nethctrl, ethqsets); + if (vfres->neq < ethqsets * 2) + ethqsets = vfres->neq / 2; + } + + if (ethqsets > MAX_ETH_QSETS) + ethqsets = MAX_ETH_QSETS; + adapter->sge.max_ethqsets = ethqsets; +} + /* * Tweak configuration based on system architecture, etc. Most of these have * defaults assigned to them by Firmware Configuration Files (if we're using @@ -928,6 +960,17 @@ static int adap_init0(struct adapter *adap) goto bye; } + /* Now that we've successfully configured and initialized the adapter + * (or found it already initialized), we can ask the Firmware what + * resources it has provisioned for us. + */ + ret = t4_get_pfres(adap); + if (ret) { + dev_err(adap->pdev_dev, + "Unable to retrieve resource provisioning info\n"); + goto bye; + } + /* Find out what ports are available to us. */ v = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_PORTVEC); @@ -1063,6 +1106,7 @@ static int adap_init0(struct adapter *adap) t4_init_tp_params(adap); configure_pcie_ext_tag(adap); configure_vlan_types(adap); + configure_max_ethqsets(adap); adap->params.drv_memwin = MEMWIN_NIC; adap->flags |= FW_OK; diff --git a/drivers/net/cxgbe/cxgbevf_main.c b/drivers/net/cxgbe/cxgbevf_main.c index 5b3fb5399..4214d0312 100644 --- a/drivers/net/cxgbe/cxgbevf_main.c +++ b/drivers/net/cxgbe/cxgbevf_main.c @@ -20,7 +20,7 @@ static void size_nports_qsets(struct adapter *adapter) { struct vf_resources *vfres = &adapter->params.vfres; - unsigned int ethqsets, pmask_nports; + unsigned int pmask_nports; /* * The number of "ports" which we support is equal to the number of @@ -49,23 +49,7 @@ static void size_nports_qsets(struct adapter *adapter) adapter->params.nports = pmask_nports; } - /* - * We need to reserve an Ingress Queue for the Asynchronous Firmware - * Event Queue. - * - * For each Queue Set, we'll need the ability to allocate two Egress - * Contexts -- one for the Ingress Queue Free List and one for the TX - * Ethernet Queue. - */ - ethqsets = vfres->niqflint - 1; - if (vfres->nethctrl != ethqsets) - ethqsets = min(vfres->nethctrl, ethqsets); - if (vfres->neq < ethqsets * 2) - ethqsets = vfres->neq / 2; - if (ethqsets > MAX_ETH_QSETS) - ethqsets = MAX_ETH_QSETS; - adapter->sge.max_ethqsets = ethqsets; - + configure_max_ethqsets(adapter); if (adapter->sge.max_ethqsets < adapter->params.nports) { dev_warn(adapter->pdev_dev, "only using %d of %d available" " virtual interfaces (too few Queue Sets)\n",