X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fcxgbe_main.c;h=0368db509171376a33e1b7dcdb45a7a313ee914a;hb=4dc73ff7042a27602a738be4450a8bae39388c4f;hp=08b2a42d11ee59ba04dd07a1bf5f32bbaa64a49c;hpb=41dc98b0827a486b929bbea3dff18771d8bf3414;p=dpdk.git diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c index 08b2a42d11..0368db5091 100644 --- a/drivers/net/cxgbe/cxgbe_main.c +++ b/drivers/net/cxgbe/cxgbe_main.c @@ -38,6 +38,8 @@ #include "t4_msg.h" #include "cxgbe.h" #include "clip_tbl.h" +#include "l2t.h" +#include "mps_tcam.h" /** * Allocate a chunk of memory. The allocated memory is cleared. @@ -99,6 +101,10 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, const struct cpl_act_open_rpl *p = (const void *)rsp; hash_filter_rpl(q->adapter, p); + } else if (opcode == CPL_L2T_WRITE_RPL) { + const struct cpl_l2t_write_rpl *p = (const void *)rsp; + + do_l2t_write_rpl(q->adapter, p); } else { dev_err(adapter, "unexpected CPL %#x on FW event queue\n", opcode); @@ -116,6 +122,7 @@ int setup_sge_ctrl_txq(struct adapter *adapter) int err = 0, i = 0; for_each_port(adapter, i) { + struct port_info *pi = adap2pinfo(adapter, i); char name[RTE_ETH_NAME_MAX_LEN]; struct sge_ctrl_txq *q = &s->ctrlq[i]; @@ -129,16 +136,19 @@ int setup_sge_ctrl_txq(struct adapter *adapter) err); goto out; } - snprintf(name, sizeof(name), "cxgbe_ctrl_pool_%d", i); + snprintf(name, sizeof(name), "%s_ctrl_pool_%d", + pi->eth_dev->device->driver->name, + pi->eth_dev->data->port_id); q->mb_pool = rte_pktmbuf_pool_create(name, s->ctrlq[i].q.size, RTE_CACHE_LINE_SIZE, RTE_MBUF_PRIV_ALIGN, RTE_MBUF_DEFAULT_BUF_SIZE, SOCKET_ID_ANY); if (!q->mb_pool) { - dev_err(adapter, "Can't create ctrl pool for port: %d", - i); - err = -ENOMEM; + err = -rte_errno; + dev_err(adapter, + "Can't create ctrl pool for port %d. Err: %d\n", + pi->eth_dev->data->port_id, err); goto out; } } @@ -151,18 +161,18 @@ out: /** * cxgbe_poll_for_completion: Poll rxq for completion * @q: rxq to poll - * @us: microseconds to delay + * @ms: milliseconds to delay * @cnt: number of times to poll * @c: completion to check for 'done' status * * Polls the rxq for reples until completion is done or the count * expires. */ -int cxgbe_poll_for_completion(struct sge_rspq *q, unsigned int us, +int cxgbe_poll_for_completion(struct sge_rspq *q, unsigned int ms, unsigned int cnt, struct t4_completion *c) { unsigned int i; - unsigned int work_done, budget = 4; + unsigned int work_done, budget = 32; if (!c) return -EINVAL; @@ -175,7 +185,7 @@ int cxgbe_poll_for_completion(struct sge_rspq *q, unsigned int us, return 0; } t4_os_unlock(&c->lock); - udelay(us); + rte_delay_ms(ms); } return -ETIMEDOUT; } @@ -513,7 +523,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 +547,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 +778,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 +1093,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); @@ -1092,13 +1145,17 @@ static int adap_init0(struct adapter *adap) V_FW_PARAMS_PARAM_Y(0) | \ V_FW_PARAMS_PARAM_Z(0)) - params[0] = FW_PARAM_PFVF(FILTER_START); - params[1] = FW_PARAM_PFVF(FILTER_END); - ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2, params, val); + params[0] = FW_PARAM_PFVF(L2T_START); + params[1] = FW_PARAM_PFVF(L2T_END); + params[2] = FW_PARAM_PFVF(FILTER_START); + params[3] = FW_PARAM_PFVF(FILTER_END); + ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 4, params, val); if (ret < 0) goto bye; - adap->tids.ftid_base = val[0]; - adap->tids.nftids = val[1] - val[0] + 1; + adap->l2t_start = val[0]; + adap->l2t_end = val[1]; + adap->tids.ftid_base = val[2]; + adap->tids.nftids = val[3] - val[2] + 1; params[0] = FW_PARAM_PFVF(CLIP_START); params[1] = FW_PARAM_PFVF(CLIP_END); @@ -1127,6 +1184,16 @@ static int adap_init0(struct adapter *adap) goto bye; } + /* See if FW supports FW_FILTER2 work request */ + if (is_t4(adap->params.chip)) { + adap->params.filter2_wr_support = 0; + } else { + params[0] = FW_PARAM_DEV(FILTER2_WR); + ret = t4_query_params(adap, adap->mbox, adap->pf, 0, + 1, params, val); + adap->params.filter2_wr_support = (ret == 0 && val[0] != 0); + } + /* query tid-related parameters */ params[0] = FW_PARAM_DEV(NTID); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 1, @@ -1201,6 +1268,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; @@ -1275,23 +1343,25 @@ inline bool force_linkup(struct adapter *adap) int link_start(struct port_info *pi) { struct adapter *adapter = pi->adapter; - int ret; + u64 conf_offloads; unsigned int mtu; + int ret; mtu = pi->eth_dev->data->dev_conf.rxmode.max_rx_pkt_len - (ETHER_HDR_LEN + ETHER_CRC_LEN); + conf_offloads = pi->eth_dev->data->dev_conf.rxmode.offloads; + /* * We do not set address filters and promiscuity here, the stack does * that step explicitly. */ - ret = t4_set_rxmode(adapter, adapter->mbox, pi->viid, mtu, -1, -1, - -1, 1, true); + ret = t4_set_rxmode(adapter, adapter->mbox, pi->viid, mtu, -1, -1, -1, + !!(conf_offloads & DEV_RX_OFFLOAD_VLAN_STRIP), + true); if (ret == 0) { - ret = t4_change_mac(adapter, adapter->mbox, pi->viid, - pi->xact_addr_filt, - (u8 *)&pi->eth_dev->data->mac_addrs[0], - true, true); + ret = cxgbe_mpstcam_modify(pi, (int)pi->xact_addr_filt, + (u8 *)&pi->eth_dev->data->mac_addrs[0]); if (ret >= 0) { pi->xact_addr_filt = ret; ret = 0; @@ -1341,7 +1411,7 @@ int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf) if (rss_hf & ~CXGBE_RSS_HF_ALL) return -EINVAL; - if (rss_hf & ETH_RSS_IPV4) + if (rss_hf & CXGBE_RSS_HF_IPV4_MASK) flags |= F_FW_RSS_VI_CONFIG_CMD_IP4TWOTUPEN; if (rss_hf & ETH_RSS_NONFRAG_IPV4_TCP) @@ -1351,14 +1421,16 @@ int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf) flags |= F_FW_RSS_VI_CONFIG_CMD_IP4FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_UDPEN; - if (rss_hf & ETH_RSS_IPV6) + if (rss_hf & CXGBE_RSS_HF_IPV6_MASK) flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN; - if (rss_hf & ETH_RSS_NONFRAG_IPV6_TCP) - flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN; + if (rss_hf & CXGBE_RSS_HF_TCP_IPV6_MASK) + flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN | + F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN; - if (rss_hf & ETH_RSS_NONFRAG_IPV6_UDP) - flags |= F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN | + if (rss_hf & CXGBE_RSS_HF_UDP_IPV6_MASK) + flags |= F_FW_RSS_VI_CONFIG_CMD_IP6TWOTUPEN | + F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN | F_FW_RSS_VI_CONFIG_CMD_UDPEN; rxq = &adapter->sge.ethrxq[pi->first_qset]; @@ -1572,6 +1644,30 @@ void cxgbe_get_speed_caps(struct port_info *pi, u32 *speed_caps) *speed_caps |= ETH_LINK_SPEED_FIXED; } +/** + * cxgbe_set_link_status - Set device link up or down. + * @pi: Underlying port's info + * @status: 0 - down, 1 - up + * + * Set the device link up or down. + */ +int cxgbe_set_link_status(struct port_info *pi, bool status) +{ + struct adapter *adapter = pi->adapter; + int err = 0; + + err = t4_enable_vi(adapter, adapter->mbox, pi->viid, status, status); + if (err) { + dev_err(adapter, "%s: disable_vi failed: %d\n", __func__, err); + return err; + } + + if (!status) + t4_reset_link_config(adapter, pi->pidx); + + return 0; +} + /** * cxgb_up - enable the adapter * @adap: adapter being enabled @@ -1597,17 +1693,7 @@ int cxgbe_up(struct adapter *adap) */ int cxgbe_down(struct port_info *pi) { - struct adapter *adapter = pi->adapter; - int err = 0; - - err = t4_enable_vi(adapter, adapter->mbox, pi->viid, false, false); - if (err) { - dev_err(adapter, "%s: disable_vi failed: %d\n", __func__, err); - return err; - } - - t4_reset_link_config(adapter, pi->pidx); - return 0; + return cxgbe_set_link_status(pi, false); } /* @@ -1619,10 +1705,12 @@ void cxgbe_close(struct adapter *adapter) int i; if (adapter->flags & FULL_INIT_DONE) { - if (is_pf4(adapter)) - t4_intr_disable(adapter); tid_free(&adapter->tids); + t4_cleanup_mpstcam(adapter); t4_cleanup_clip_tbl(adapter); + t4_cleanup_l2t(adapter); + if (is_pf4(adapter)) + t4_intr_disable(adapter); t4_sge_tx_monitor_stop(adapter); t4_free_sge_resources(adapter); for_each_port(adapter, i) { @@ -1630,12 +1718,7 @@ void cxgbe_close(struct adapter *adapter) if (pi->viid != 0) t4_free_vi(adapter, adapter->mbox, adapter->pf, 0, pi->viid); - rte_free(pi->eth_dev->data->mac_addrs); - /* Skip first port since it'll be freed by DPDK stack */ - if (i) { - rte_free(pi->eth_dev->data->dev_private); - rte_eth_dev_release_port(pi->eth_dev); - } + rte_eth_dev_release_port(pi->eth_dev); } adapter->flags &= ~FULL_INIT_DONE; } @@ -1795,12 +1878,23 @@ allocate_mac: dev_warn(adapter, "could not allocate CLIP. Continuing\n"); } + adapter->l2t = t4_init_l2t(adapter->l2t_start, adapter->l2t_end); + if (!adapter->l2t) { + /* We tolerate a lack of L2T, giving up some functionality */ + dev_warn(adapter, "could not allocate L2T. Continuing\n"); + } + if (tid_init(&adapter->tids) < 0) { /* Disable filtering support */ dev_warn(adapter, "could not allocate TID table, " "filter support disabled. Continuing\n"); } + adapter->mpstcam = t4_init_mpstcam(adapter); + if (!adapter->mpstcam) + dev_warn(adapter, "could not allocate mps tcam table." + " Continuing\n"); + if (is_hashfilter(adapter)) { if (t4_read_reg(adapter, A_LE_DB_CONFIG) & F_HASHEN) { u32 hash_base, hash_reg; @@ -1827,14 +1921,7 @@ out_free: if (pi->viid != 0) t4_free_vi(adapter, adapter->mbox, adapter->pf, 0, pi->viid); - /* Skip first port since it'll be de-allocated by DPDK */ - if (i == 0) - continue; - if (pi->eth_dev) { - if (pi->eth_dev->data->dev_private) - rte_free(pi->eth_dev->data->dev_private); - rte_eth_dev_release_port(pi->eth_dev); - } + rte_eth_dev_release_port(pi->eth_dev); } if (adapter->flags & FW_OK)