From: Rahul Lakkireddy Date: Fri, 29 Jun 2018 19:23:53 +0000 (+0530) Subject: net/cxgbe: query firmware for max queues available X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=87a3ae3e1ec7b050aee5e203a98e259aa02f56ee;p=dpdk.git net/cxgbe: query firmware for max queues available 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 --- diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h index ea3e112b98..157201da27 100644 --- a/drivers/net/cxgbe/base/common.h +++ b/drivers/net/cxgbe/base/common.h @@ -210,6 +210,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. */ @@ -233,6 +241,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; @@ -466,6 +475,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 0893b7ba06..628b280ef4 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 7b2f2d37f0..a17ebea2ee 100644 --- a/drivers/net/cxgbe/base/t4fw_interface.h +++ b/drivers/net/cxgbe/base/t4fw_interface.h @@ -744,6 +744,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 70f974f5a3..5e6f5c98d7 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 c3f0053420..c3938e8db2 100644 --- a/drivers/net/cxgbe/cxgbe_main.c +++ b/drivers/net/cxgbe/cxgbe_main.c @@ -513,7 +513,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; @@ -537,8 +537,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]; @@ -770,6 +768,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 @@ -1051,6 +1083,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); @@ -1201,6 +1244,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 5b3fb5399b..4214d03128 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",