X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcxgbe%2Fcxgbe_main.c;h=620f60b4d6342e40d6aa5dc40079ceec7ecaa062;hb=c3318f529c28e8320ac43f86f214f93e2190445d;hp=21ad380ae82b4273230a6a38b71fc9267c789b22;hpb=8d3c12e193685fa58865f6893ca2729c6bfdd7b6;p=dpdk.git diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c index 21ad380ae8..620f60b4d6 100644 --- a/drivers/net/cxgbe/cxgbe_main.c +++ b/drivers/net/cxgbe/cxgbe_main.c @@ -33,10 +33,13 @@ #include #include -#include "common.h" -#include "t4_regs.h" -#include "t4_msg.h" +#include "base/common.h" +#include "base/t4_regs.h" +#include "base/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. @@ -86,10 +89,22 @@ static int fwevtq_handler(struct sge_rspq *q, const __be64 *rsp, const struct cpl_fw6_msg *msg = (const void *)rsp; t4_handle_fw_rpl(q->adapter, msg->data); + } else if (opcode == CPL_ABORT_RPL_RSS) { + const struct cpl_abort_rpl_rss *p = (const void *)rsp; + + hash_del_filter_rpl(q->adapter, p); } else if (opcode == CPL_SET_TCB_RPL) { const struct cpl_set_tcb_rpl *p = (const void *)rsp; filter_rpl(q->adapter, p); + } else if (opcode == CPL_ACT_OPEN_RPL) { + 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); @@ -101,12 +116,13 @@ out: /** * Setup sge control queues to pass control information. */ -int setup_sge_ctrl_txq(struct adapter *adapter) +int cxgbe_setup_sge_ctrl_txq(struct adapter *adapter) { struct sge *s = &adapter->sge; 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]; @@ -120,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; } } @@ -142,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; @@ -166,12 +185,12 @@ 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; } -int setup_sge_fwevtq(struct adapter *adapter) +int cxgbe_setup_sge_fwevtq(struct adapter *adapter) { struct sge *s = &adapter->sge; int err = 0; @@ -262,6 +281,102 @@ int cxgb4_set_rspq_intr_params(struct sge_rspq *q, unsigned int us, return 0; } +/** + * Allocate an active-open TID and set it to the supplied value. + */ +int cxgbe_alloc_atid(struct tid_info *t, void *data) +{ + int atid = -1; + + t4_os_lock(&t->atid_lock); + if (t->afree) { + union aopen_entry *p = t->afree; + + atid = p - t->atid_tab; + t->afree = p->next; + p->data = data; + t->atids_in_use++; + } + t4_os_unlock(&t->atid_lock); + return atid; +} + +/** + * Release an active-open TID. + */ +void cxgbe_free_atid(struct tid_info *t, unsigned int atid) +{ + union aopen_entry *p = &t->atid_tab[atid]; + + t4_os_lock(&t->atid_lock); + p->next = t->afree; + t->afree = p; + t->atids_in_use--; + t4_os_unlock(&t->atid_lock); +} + +/** + * Populate a TID_RELEASE WR. Caller must properly size the skb. + */ +static void mk_tid_release(struct rte_mbuf *mbuf, unsigned int tid) +{ + struct cpl_tid_release *req; + + req = rte_pktmbuf_mtod(mbuf, struct cpl_tid_release *); + INIT_TP_WR_MIT_CPL(req, CPL_TID_RELEASE, tid); +} + +/** + * Release a TID and inform HW. If we are unable to allocate the release + * message we defer to a work queue. + */ +void cxgbe_remove_tid(struct tid_info *t, unsigned int chan, unsigned int tid, + unsigned short family) +{ + struct rte_mbuf *mbuf; + struct adapter *adap = container_of(t, struct adapter, tids); + + WARN_ON(tid >= t->ntids); + + if (t->tid_tab[tid]) { + t->tid_tab[tid] = NULL; + rte_atomic32_dec(&t->conns_in_use); + if (t->hash_base && tid >= t->hash_base) { + if (family == FILTER_TYPE_IPV4) + rte_atomic32_dec(&t->hash_tids_in_use); + } else { + if (family == FILTER_TYPE_IPV4) + rte_atomic32_dec(&t->tids_in_use); + } + } + + mbuf = rte_pktmbuf_alloc((&adap->sge.ctrlq[chan])->mb_pool); + if (mbuf) { + mbuf->data_len = sizeof(struct cpl_tid_release); + mbuf->pkt_len = mbuf->data_len; + mk_tid_release(mbuf, tid); + t4_mgmt_tx(&adap->sge.ctrlq[chan], mbuf); + } +} + +/** + * Insert a TID. + */ +void cxgbe_insert_tid(struct tid_info *t, void *data, unsigned int tid, + unsigned short family) +{ + t->tid_tab[tid] = data; + if (t->hash_base && tid >= t->hash_base) { + if (family == FILTER_TYPE_IPV4) + rte_atomic32_inc(&t->hash_tids_in_use); + } else { + if (family == FILTER_TYPE_IPV4) + rte_atomic32_inc(&t->tids_in_use); + } + + rte_atomic32_inc(&t->conns_in_use); +} + /** * Free TID tables. */ @@ -287,24 +402,43 @@ static int tid_init(struct tid_info *t) { size_t size; unsigned int ftid_bmap_size; + unsigned int natids = t->natids; unsigned int max_ftids = t->nftids; ftid_bmap_size = rte_bitmap_get_memory_footprint(t->nftids); size = t->ntids * sizeof(*t->tid_tab) + - max_ftids * sizeof(*t->ftid_tab); + max_ftids * sizeof(*t->ftid_tab) + + natids * sizeof(*t->atid_tab); t->tid_tab = t4_os_alloc(size); if (!t->tid_tab) return -ENOMEM; - t->ftid_tab = (struct filter_entry *)&t->tid_tab[t->ntids]; + t->atid_tab = (union aopen_entry *)&t->tid_tab[t->ntids]; + t->ftid_tab = (struct filter_entry *)&t->atid_tab[t->natids]; t->ftid_bmap_array = t4_os_alloc(ftid_bmap_size); if (!t->ftid_bmap_array) { tid_free(t); return -ENOMEM; } + t4_os_lock_init(&t->atid_lock); t4_os_lock_init(&t->ftid_lock); + + t->afree = NULL; + t->atids_in_use = 0; + rte_atomic32_init(&t->tids_in_use); + rte_atomic32_set(&t->tids_in_use, 0); + rte_atomic32_init(&t->conns_in_use); + rte_atomic32_set(&t->conns_in_use, 0); + + /* Setup the free list for atid_tab and clear the stid bitmap. */ + if (natids) { + while (--natids) + t->atid_tab[natids - 1].next = &t->atid_tab[natids]; + t->afree = t->atid_tab; + } + t->ftid_bmap = rte_bitmap_init(t->nftids, t->ftid_bmap_array, ftid_bmap_size); if (!t->ftid_bmap) { @@ -331,7 +465,7 @@ static inline bool is_x_10g_port(const struct link_config *lc) return high_speeds != 0; } -inline void init_rspq(struct adapter *adap, struct sge_rspq *q, +static inline void init_rspq(struct adapter *adap, struct sge_rspq *q, unsigned int us, unsigned int cnt, unsigned int size, unsigned int iqe_size) { @@ -341,9 +475,9 @@ inline void init_rspq(struct adapter *adap, struct sge_rspq *q, q->size = size; } -int cfg_queue_count(struct rte_eth_dev *eth_dev) +int cxgbe_cfg_queue_count(struct rte_eth_dev *eth_dev) { - struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private); + struct port_info *pi = eth_dev->data->dev_private; struct adapter *adap = pi->adapter; struct sge *s = &adap->sge; unsigned int max_queues = s->max_ethqsets / adap->params.nports; @@ -368,10 +502,9 @@ int cfg_queue_count(struct rte_eth_dev *eth_dev) return 0; } -void cfg_queues(struct rte_eth_dev *eth_dev) +void cxgbe_cfg_queues(struct rte_eth_dev *eth_dev) { - struct rte_config *config = rte_eal_get_configuration(); - struct port_info *pi = (struct port_info *)(eth_dev->data->dev_private); + struct port_info *pi = eth_dev->data->dev_private; struct adapter *adap = pi->adapter; struct sge *s = &adap->sge; unsigned int i, nb_ports = 0, qidx = 0; @@ -389,12 +522,12 @@ 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; - if (q_per_port > config->lcore_count) - q_per_port = config->lcore_count; + if (q_per_port > rte_lcore_count()) + q_per_port = rte_lcore_count(); for_each_port(adap, i) { struct port_info *pi = adap2pinfo(adap, i); @@ -413,8 +546,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]; @@ -464,7 +595,7 @@ static void setup_memwin(struct adapter *adap) MEMWIN_NIC)); } -int init_rss(struct adapter *adap) +int cxgbe_init_rss(struct adapter *adap) { unsigned int i; @@ -491,7 +622,7 @@ int init_rss(struct adapter *adap) /** * Dump basic information about the adapter. */ -void print_adapter_info(struct adapter *adap) +void cxgbe_print_adapter_info(struct adapter *adap) { /** * Hardware/Firmware/etc. Version/Revision IDs. @@ -499,7 +630,7 @@ void print_adapter_info(struct adapter *adap) t4_dump_version_info(adap); } -void print_port_info(struct adapter *adap) +void cxgbe_print_port_info(struct adapter *adap) { int i; char buf[80]; @@ -646,6 +777,40 @@ static void configure_pcie_ext_tag(struct adapter *adapter) } } +/* Figure out how many Queue Sets we can support */ +void cxgbe_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 @@ -784,8 +949,7 @@ static int adap_init0_config(struct adapter *adapter, int reset) * This will allow the firmware to optimize aspects of the hardware * configuration which will result in improved performance. */ - caps_cmd.niccaps &= cpu_to_be16(~(FW_CAPS_CONFIG_NIC_HASHFILTER | - FW_CAPS_CONFIG_NIC_ETHOFLD)); + caps_cmd.niccaps &= cpu_to_be16(~FW_CAPS_CONFIG_NIC_ETHOFLD); caps_cmd.toecaps = 0; caps_cmd.iscsicaps = 0; caps_cmd.rdmacaps = 0; @@ -928,6 +1092,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); @@ -969,13 +1144,25 @@ 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); + 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->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); ret = t4_query_params(adap, adap->mbox, adap->pf, 0, 2, params, val); if (ret < 0) goto bye; - adap->tids.ftid_base = val[0]; - adap->tids.nftids = val[1] - val[0] + 1; + adap->clipt_start = val[0]; + adap->clipt_end = val[1]; /* * Get device capabilities so we can determine what resources we need @@ -990,6 +1177,22 @@ static int adap_init0(struct adapter *adap) if (ret < 0) goto bye; + if ((caps_cmd.niccaps & cpu_to_be16(FW_CAPS_CONFIG_NIC_HASHFILTER)) && + is_t6(adap->params.chip)) { + if (init_hash_filter(adap) < 0) + 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, @@ -997,6 +1200,7 @@ static int adap_init0(struct adapter *adap) if (ret < 0) goto bye; adap->tids.ntids = val[0]; + adap->tids.natids = min(adap->tids.ntids / 2, MAX_ATIDS); /* If we're running on newer firmware, let it know that we're * prepared to deal with encapsulated CPL messages. Older @@ -1063,6 +1267,7 @@ static int adap_init0(struct adapter *adap) t4_init_tp_params(adap); configure_pcie_ext_tag(adap); configure_vlan_types(adap); + cxgbe_configure_max_ethqsets(adap); adap->params.drv_memwin = MEMWIN_NIC; adap->flags |= FW_OK; @@ -1116,7 +1321,7 @@ void t4_os_portmod_changed(const struct adapter *adap, int port_id) pi->port_id, pi->mod_type); } -inline bool force_linkup(struct adapter *adap) +bool cxgbe_force_linkup(struct adapter *adap) { struct rte_pci_device *pdev = adap->pdev; @@ -1134,26 +1339,28 @@ inline bool force_linkup(struct adapter *adap) * * Performs the MAC and PHY actions needed to enable a port. */ -int link_start(struct port_info *pi) +int cxgbe_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); + (RTE_ETHER_HDR_LEN + RTE_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; @@ -1174,7 +1381,7 @@ int link_start(struct port_info *pi) true, true, false); } - if (ret == 0 && force_linkup(adapter)) + if (ret == 0 && cxgbe_force_linkup(adapter)) pi->eth_dev->data->dev_link.link_status = ETH_LINK_UP; return ret; } @@ -1203,7 +1410,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) @@ -1213,14 +1420,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]; @@ -1280,7 +1489,7 @@ int cxgbe_write_rss(const struct port_info *pi, const u16 *queues) * We always configure the RSS mapping for all ports since the mapping * table has plenty of entries. */ -int setup_rss(struct port_info *pi) +int cxgbe_setup_rss(struct port_info *pi) { int j, err; struct adapter *adapter = pi->adapter; @@ -1434,6 +1643,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 @@ -1459,17 +1692,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); } /* @@ -1481,9 +1704,12 @@ void cxgbe_close(struct adapter *adapter) int i; if (adapter->flags & FULL_INIT_DONE) { + 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); - tid_free(&adapter->tids); t4_sge_tx_monitor_stop(adapter); t4_free_sge_resources(adapter); for_each_port(adapter, i) { @@ -1491,12 +1717,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; } @@ -1603,7 +1824,7 @@ int cxgbe_probe(struct adapter *adapter) goto out_free; allocate_mac: - pi = (struct port_info *)eth_dev->data->dev_private; + pi = eth_dev->data->dev_private; adapter->port[i] = pi; pi->eth_dev = eth_dev; pi->adapter = adapter; @@ -1619,7 +1840,7 @@ allocate_mac: rte_eth_copy_pci_info(pi->eth_dev, adapter->pdev); pi->eth_dev->data->mac_addrs = rte_zmalloc(name, - ETHER_ADDR_LEN, 0); + RTE_ETHER_ADDR_LEN, 0); if (!pi->eth_dev->data->mac_addrs) { dev_err(adapter, "%s: Mem allocation failed for storing mac addr, aborting\n", __func__); @@ -1642,10 +1863,25 @@ allocate_mac: } } - cfg_queues(adapter->eth_dev); + cxgbe_cfg_queues(adapter->eth_dev); + + cxgbe_print_adapter_info(adapter); + cxgbe_print_port_info(adapter); + + adapter->clipt = t4_init_clip_tbl(adapter->clipt_start, + adapter->clipt_end); + if (!adapter->clipt) { + /* We tolerate a lack of clip_table, giving up some + * functionality + */ + dev_warn(adapter, "could not allocate CLIP. Continuing\n"); + } - print_adapter_info(adapter); - print_port_info(adapter); + 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 */ @@ -1653,7 +1889,26 @@ allocate_mac: "filter support disabled. Continuing\n"); } - err = init_rss(adapter); + 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; + + hash_reg = A_LE_DB_TID_HASHBASE; + hash_base = t4_read_reg(adapter, hash_reg); + adapter->tids.hash_base = hash_base / 4; + } + } else { + /* Disable hash filtering support */ + dev_warn(adapter, + "Maskless filter support disabled. Continuing\n"); + } + + err = cxgbe_init_rss(adapter); if (err) goto out_free; @@ -1665,14 +1920,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)