X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Fbnxt_hwrm.c;h=6d54b16568de003bdaa847ef360568b168e46467;hb=ec12dc5a554ab4f8dd8a90cab54426dfa685ba80;hp=fc89cc29a6a571b3b39290f315b6be31899a61a0;hpb=7ed45b1a7c0fdbf04bd02fd57c15b920185c0cc4;p=dpdk.git diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index fc89cc29a6..6d54b16568 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -64,6 +64,9 @@ static void bnxt_hwrm_set_pg_attr(struct bnxt_ring_mem_info *rmem, uint8_t *pg_attr, uint64_t *pg_dir) { + if (rmem->nr_pages == 0) + return; + if (rmem->nr_pages > 1) { *pg_attr = 1; *pg_dir = rte_cpu_to_le_64(rmem->pg_tbl_map); @@ -635,7 +638,7 @@ static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp) HWRM_CHECK_RESULT(); - if (!BNXT_CHIP_THOR(bp) && + if (!BNXT_CHIP_P5(bp) && !(resp->flags & HWRM_PORT_MAC_PTP_QCFG_OUTPUT_FLAGS_DIRECT_ACCESS)) return 0; @@ -646,7 +649,7 @@ static int bnxt_hwrm_ptp_qcfg(struct bnxt *bp) if (!ptp) return -ENOMEM; - if (!BNXT_CHIP_THOR(bp)) { + if (!BNXT_CHIP_P5(bp)) { ptp->rx_regs[BNXT_PTP_RX_TS_L] = rte_le_to_cpu_32(resp->rx_ts_reg_off_lower); ptp->rx_regs[BNXT_PTP_RX_TS_H] = @@ -718,6 +721,7 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) sizeof(bp->pf->vf_info[0]) * new_max_vfs, 0); if (bp->pf->vf_info == NULL) { PMD_DRV_LOG(ERR, "Alloc vf info fail\n"); + HWRM_UNLOCK(); return -ENOMEM; } bp->pf->max_vfs = new_max_vfs; @@ -765,7 +769,7 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->first_vf_id = rte_le_to_cpu_16(resp->first_vf_id); bp->max_rx_em_flows = rte_le_to_cpu_16(resp->max_rx_em_flows); bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs); - if (!BNXT_CHIP_THOR(bp)) + if (!BNXT_CHIP_P5(bp) && !bp->pdev->max_vfs) bp->max_l2_ctx += bp->max_rx_em_flows; /* TODO: For now, do not support VMDq/RFS on VFs. */ if (BNXT_PF(bp)) { @@ -803,6 +807,9 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_HOT_RESET_CAPABLE) bp->fw_cap |= BNXT_FW_CAP_HOT_RESET; + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_LINK_ADMIN_STATUS_SUPPORTED) + bp->fw_cap |= BNXT_FW_CAP_LINK_ADMIN; + HWRM_UNLOCK(); return rc; @@ -818,16 +825,15 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp) if (rc) return rc; + /* On older FW, + * bnxt_hwrm_func_resc_qcaps can fail and cause init failure. + * But the error can be ignored. Return success. + */ rc = bnxt_hwrm_func_resc_qcaps(bp); if (!rc) bp->flags |= BNXT_FLAG_NEW_RM; } - /* On older FW, - * bnxt_hwrm_func_resc_qcaps can fail and cause init failure. - * But the error can be ignored. Return success. - */ - return 0; } @@ -857,6 +863,9 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp) if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_OUTERMOST_RSS_CAP) bp->vnic_cap_flags |= BNXT_VNIC_CAP_OUTER_RSS; + if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RX_CMPL_V2_CAP) + bp->vnic_cap_flags |= BNXT_VNIC_CAP_RX_CMPL_V2; + bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported); HWRM_UNLOCK(); @@ -916,14 +925,6 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) memcpy(req.vf_req_fwd, bp->pf->vf_req_fwd, RTE_MIN(sizeof(req.vf_req_fwd), sizeof(bp->pf->vf_req_fwd))); - - /* - * PF can sniff HWRM API issued by VF. This can be set up by - * linux driver and inherited by the DPDK PF driver. Clear - * this HWRM sniffer list in FW because DPDK PF driver does - * not support this. - */ - flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE; } req.flags = rte_cpu_to_le_32(flags); @@ -944,7 +945,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) req.async_event_fwd[1] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_DBG_NOTIFICATION); - if (BNXT_VF_IS_TRUSTED(bp)) + if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) req.async_event_fwd[1] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_DEFAULT_VNIC_CHANGE); @@ -1052,21 +1053,19 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp) HWRM_CHECK_RESULT_SILENT(); - if (BNXT_VF(bp)) { - bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); - bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings); - bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings); - bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings); - bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps); - /* func_resource_qcaps does not return max_rx_em_flows. - * So use the value provided by func_qcaps. - */ - bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs); - if (!BNXT_CHIP_THOR(bp)) - bp->max_l2_ctx += bp->max_rx_em_flows; - bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics); - bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx); - } + bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); + bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings); + bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings); + bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings); + bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps); + /* func_resource_qcaps does not return max_rx_em_flows. + * So use the value provided by func_qcaps. + */ + bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs); + if (!BNXT_CHIP_P5(bp) && !bp->pdev->max_vfs) + bp->max_l2_ctx += bp->max_rx_em_flows; + bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics); + bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx); bp->max_nq_rings = rte_le_to_cpu_16(resp->max_msix); bp->vf_resv_strategy = rte_le_to_cpu_16(resp->vf_reservation_strategy); if (bp->vf_resv_strategy > @@ -1136,6 +1135,9 @@ int bnxt_hwrm_ver_get(struct bnxt *bp, uint32_t timeout) PMD_DRV_LOG(ERR, "Unsupported request length\n"); rc = -EINVAL; } + + bp->chip_num = rte_le_to_cpu_16(resp->chip_num); + bp->max_req_len = rte_le_to_cpu_16(resp->max_req_win_len); bp->hwrm_max_ext_req_len = rte_le_to_cpu_16(resp->max_ext_req_len); if (bp->hwrm_max_ext_req_len < HWRM_MAX_REQ_LEN) @@ -1280,9 +1282,10 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf) HWRM_PORT_PHY_CFG_IN_EN_FORCE_PAM4_LINK_SPEED; req.force_pam4_link_speed = rte_cpu_to_le_16(conf->link_speed); - } - req.force_link_speed = + } else { + req.force_link_speed = rte_cpu_to_le_16(conf->link_speed); + } } /* AutoNeg - Advertise speeds specified. */ if (conf->auto_link_speed_mask && @@ -1364,7 +1367,8 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, link_info->phy_ver[0] = resp->phy_maj; link_info->phy_ver[1] = resp->phy_min; link_info->phy_ver[2] = resp->phy_bld; - link_info->link_signal_mode = rte_le_to_cpu_16(resp->link_signal_mode); + link_info->link_signal_mode = + rte_le_to_cpu_16(resp->active_fec_signal_mode); link_info->force_pam4_link_speed = rte_le_to_cpu_16(resp->force_pam4_link_speed); link_info->support_pam4_speeds = @@ -1377,6 +1381,11 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, link_info->link_speed, link_info->auto_mode, link_info->auto_link_speed, link_info->auto_link_speed_mask, link_info->support_speeds, link_info->force_link_speed); + PMD_DRV_LOG(DEBUG, "Link Signal:%d,PAM::Auto:%x,Support:%x,Force:%x\n", + link_info->link_signal_mode, + link_info->auto_pam4_link_speeds, + link_info->support_pam4_speeds, + link_info->force_pam4_link_speed); return rc; } @@ -1557,7 +1566,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp, req.ring_type = ring_type; req.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id); req.stat_ctx_id = rte_cpu_to_le_32(stats_ctx_id); - if (BNXT_CHIP_THOR(bp)) { + if (BNXT_CHIP_P5(bp)) { mb_pool = bp->rx_queues[0]->mb_pool; rx_buf_size = rte_pktmbuf_data_room_size(mb_pool) - RTE_PKTMBUF_HEADROOM; @@ -1927,7 +1936,7 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) HWRM_PREP(&req, HWRM_VNIC_CFG, BNXT_USE_CHIMP_MB); - if (BNXT_CHIP_THOR(bp)) { + if (BNXT_CHIP_P5(bp)) { int dflt_rxq = vnic->start_grp_id; struct bnxt_rx_ring_info *rxr; struct bnxt_cp_ring_info *cpr; @@ -1958,6 +1967,11 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) rte_cpu_to_le_16(cpr->cp_ring_struct->fw_ring_id); enables = HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_RX_RING_ID | HWRM_VNIC_CFG_INPUT_ENABLES_DEFAULT_CMPL_RING_ID; + if (bp->vnic_cap_flags & BNXT_VNIC_CAP_RX_CMPL_V2) { + enables |= HWRM_VNIC_CFG_INPUT_ENABLES_RX_CSUM_V2_MODE; + req.rx_csum_v2_mode = + HWRM_VNIC_CFG_INPUT_RX_CSUM_V2_MODE_ALL_OK; + } goto config_mru; } @@ -2117,7 +2131,7 @@ int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic) { int rc = 0; - if (BNXT_CHIP_THOR(bp)) { + if (BNXT_CHIP_P5(bp)) { int j; for (j = 0; j < vnic->num_lb_ctxts; j++) { @@ -2164,7 +2178,7 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic) } static int -bnxt_hwrm_vnic_rss_cfg_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic) +bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) { int i; int rc = 0; @@ -2208,8 +2222,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp, if (!vnic->rss_table) return 0; - if (BNXT_CHIP_THOR(bp)) - return bnxt_hwrm_vnic_rss_cfg_thor(bp, vnic); + if (BNXT_CHIP_P5(bp)) + return bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic); HWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB); @@ -2274,7 +2288,7 @@ int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp, struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 }; struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr; - if (BNXT_CHIP_THOR(bp) && !bp->max_tpa_v2) { + if (BNXT_CHIP_P5(bp) && !bp->max_tpa_v2) { if (enable) PMD_DRV_LOG(ERR, "No HW support for LRO\n"); return -ENOTSUP; @@ -2566,7 +2580,7 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index) ring = rxr->ag_ring_struct; if (ring->fw_ring_id != INVALID_HW_RING_ID) { bnxt_hwrm_ring_free(bp, ring, - BNXT_CHIP_THOR(bp) ? + BNXT_CHIP_P5(bp) ? HWRM_RING_FREE_INPUT_RING_TYPE_RX_AGG : HWRM_RING_FREE_INPUT_RING_TYPE_RX); if (BNXT_HAS_RING_GRPS(bp)) @@ -2601,8 +2615,8 @@ bnxt_free_all_hwrm_rings(struct bnxt *bp) memset(txr->tx_buf_ring, 0, txr->tx_ring_struct->ring_size * sizeof(*txr->tx_buf_ring)); - txr->tx_prod = 0; - txr->tx_cons = 0; + txr->tx_raw_prod = 0; + txr->tx_raw_cons = 0; } if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) { bnxt_free_cp_ring(bp, cpr); @@ -2749,11 +2763,10 @@ bnxt_free_tunnel_ports(struct bnxt *bp) if (bp->vxlan_port_cnt) bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id, HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN); - bp->vxlan_port = 0; + if (bp->geneve_port_cnt) bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id, HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE); - bp->geneve_port = 0; } void bnxt_free_all_hwrm_resources(struct bnxt *bp) @@ -3069,7 +3082,7 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) goto port_phy_cfg; autoneg = bnxt_check_eth_link_autoneg(dev_conf->link_speeds); - if (BNXT_CHIP_THOR(bp) && + if (BNXT_CHIP_P5(bp) && dev_conf->link_speeds == ETH_LINK_SPEED_40G) { /* 40G is not supported as part of media auto detect. * The speed should be forced and autoneg disabled @@ -3079,6 +3092,12 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) autoneg = 0; } + /* No auto speeds and no auto_pam4_link. Disable autoneg */ + if (bp->link_info->auto_link_speed == 0 && + bp->link_info->link_signal_mode && + bp->link_info->auto_pam4_link_speeds == 0) + autoneg = 0; + speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds, bp->link_info->link_signal_mode); link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY; @@ -3088,7 +3107,7 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) * to 40G until link comes up at new speed. */ if (autoneg == 1 && - !(!BNXT_CHIP_THOR(bp) && + !(!BNXT_CHIP_P5(bp) && (bp->link_info->auto_link_speed || bp->link_info->force_link_speed))) { link_req.phy_flags |= @@ -3124,6 +3143,12 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up) link_req.link_speed = bp->link_info->force_link_speed; else link_req.link_speed = bp->link_info->auto_link_speed; + /* Auto PAM4 link speed is zero, but auto_link_speed is not + * zero. Use the auto_link_speed. + */ + if (bp->link_info->auto_link_speed != 0 && + bp->link_info->auto_pam4_link_speeds == 0) + link_req.link_speed = bp->link_info->auto_link_speed; } link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds); link_req.auto_pause = bp->link_info->auto_pause; @@ -3196,6 +3221,9 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) break; } + bp->legacy_db_size = + rte_le_to_cpu_16(resp->legacy_l2_db_size_kb) * 1024; + HWRM_UNLOCK(); return rc; @@ -3299,33 +3327,8 @@ int bnxt_hwrm_port_mac_qcfg(struct bnxt *bp) return 0; } -static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg, - struct hwrm_func_qcaps_output *qcaps) -{ - qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs; - memcpy(qcaps->mac_address, fcfg->dflt_mac_addr, - sizeof(qcaps->mac_address)); - qcaps->max_l2_ctxs = fcfg->num_l2_ctxs; - qcaps->max_rx_rings = fcfg->num_rx_rings; - qcaps->max_tx_rings = fcfg->num_tx_rings; - qcaps->max_cmpl_rings = fcfg->num_cmpl_rings; - qcaps->max_stat_ctx = fcfg->num_stat_ctxs; - qcaps->max_vfs = 0; - qcaps->first_vf_id = 0; - qcaps->max_vnics = fcfg->num_vnics; - qcaps->max_decap_records = 0; - qcaps->max_encap_records = 0; - qcaps->max_tx_wm_flows = 0; - qcaps->max_tx_em_flows = 0; - qcaps->max_rx_wm_flows = 0; - qcaps->max_rx_em_flows = 0; - qcaps->max_flow_id = 0; - qcaps->max_mcast_filters = fcfg->num_mcast_filters; - qcaps->max_sp_tx_rings = 0; - qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps; -} - -static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings) +static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, + struct bnxt_pf_resource_info *pf_resc) { struct hwrm_func_cfg_input req = {0}; struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr; @@ -3344,7 +3347,8 @@ static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings) if (BNXT_HAS_RING_GRPS(bp)) { enables |= HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS; - req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps); + req.num_hw_ring_grps = + rte_cpu_to_le_16(pf_resc->num_hw_ring_grps); } else if (BNXT_HAS_NQ(bp)) { enables |= HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MSIX; req.num_msix = rte_cpu_to_le_16(bp->max_nq_rings); @@ -3353,12 +3357,12 @@ static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings) req.flags = rte_cpu_to_le_32(bp->pf->func_cfg_flags); req.mtu = rte_cpu_to_le_16(BNXT_MAX_MTU); req.mru = rte_cpu_to_le_16(BNXT_VNIC_MRU(bp->eth_dev->data->mtu)); - req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx); - req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx); - req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings); - req.num_tx_rings = rte_cpu_to_le_16(tx_rings); - req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings); - req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx); + req.num_rsscos_ctxs = rte_cpu_to_le_16(pf_resc->num_rsscos_ctxs); + req.num_stat_ctxs = rte_cpu_to_le_16(pf_resc->num_stat_ctxs); + req.num_cmpl_rings = rte_cpu_to_le_16(pf_resc->num_cp_rings); + req.num_tx_rings = rte_cpu_to_le_16(pf_resc->num_tx_rings); + req.num_rx_rings = rte_cpu_to_le_16(pf_resc->num_rx_rings); + req.num_l2_ctxs = rte_cpu_to_le_16(pf_resc->num_l2_ctxs); req.num_vnics = rte_cpu_to_le_16(bp->max_vnics); req.fid = rte_cpu_to_le_16(0xffff); req.enables = rte_cpu_to_le_32(enables); @@ -3373,9 +3377,43 @@ static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings) return rc; } -static void populate_vf_func_cfg_req(struct bnxt *bp, - struct hwrm_func_cfg_input *req, - int num_vfs) +/* min values are the guaranteed resources and max values are subject + * to availability. The strategy for now is to keep both min & max + * values the same. + */ +static void +bnxt_fill_vf_func_cfg_req_new(struct bnxt *bp, + struct hwrm_func_vf_resource_cfg_input *req, + int num_vfs) +{ + req->max_rsscos_ctx = rte_cpu_to_le_16(bp->max_rsscos_ctx / + (num_vfs + 1)); + req->min_rsscos_ctx = req->max_rsscos_ctx; + req->max_stat_ctx = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1)); + req->min_stat_ctx = req->max_stat_ctx; + req->max_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings / + (num_vfs + 1)); + req->min_cmpl_rings = req->max_cmpl_rings; + req->max_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1)); + req->min_tx_rings = req->max_tx_rings; + req->max_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1)); + req->min_rx_rings = req->max_rx_rings; + req->max_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1)); + req->min_l2_ctxs = req->max_l2_ctxs; + /* TODO: For now, do not support VMDq/RFS on VFs. */ + req->max_vnics = rte_cpu_to_le_16(1); + req->min_vnics = req->max_vnics; + req->max_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps / + (num_vfs + 1)); + req->min_hw_ring_grps = req->max_hw_ring_grps; + req->flags = + rte_cpu_to_le_16(HWRM_FUNC_VF_RESOURCE_CFG_INPUT_FLAGS_MIN_GUARANTEED); +} + +static void +bnxt_fill_vf_func_cfg_req_old(struct bnxt *bp, + struct hwrm_func_cfg_input *req, + int num_vfs) { req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU | HWRM_FUNC_CFG_INPUT_ENABLES_MRU | @@ -3406,60 +3444,58 @@ static void populate_vf_func_cfg_req(struct bnxt *bp, (num_vfs + 1)); } -static void add_random_mac_if_needed(struct bnxt *bp, - struct hwrm_func_cfg_input *cfg_req, +/* Update the port wide resource values based on how many resources + * got allocated to the VF. + */ +static int bnxt_update_max_resources(struct bnxt *bp, int vf) { - struct rte_ether_addr mac; + struct hwrm_func_qcfg_input req = {0}; + struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; + int rc; - if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac)) - return; + /* Get the actual allocated values now */ + HWRM_PREP(&req, HWRM_FUNC_QCFG, BNXT_USE_CHIMP_MB); + req.fid = rte_cpu_to_le_16(bp->pf->vf_info[vf].fid); + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + HWRM_CHECK_RESULT(); - if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) { - cfg_req->enables |= - rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR); - rte_eth_random_addr(cfg_req->dflt_mac_addr); - bp->pf->vf_info[vf].random_mac = true; - } else { - memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, - RTE_ETHER_ADDR_LEN); - } + bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->alloc_rsscos_ctx); + bp->max_stat_ctx -= rte_le_to_cpu_16(resp->alloc_stat_ctx); + bp->max_cp_rings -= rte_le_to_cpu_16(resp->alloc_cmpl_rings); + bp->max_tx_rings -= rte_le_to_cpu_16(resp->alloc_tx_rings); + bp->max_rx_rings -= rte_le_to_cpu_16(resp->alloc_rx_rings); + bp->max_l2_ctx -= rte_le_to_cpu_16(resp->alloc_l2_ctx); + bp->max_ring_grps -= rte_le_to_cpu_16(resp->alloc_hw_ring_grps); + + HWRM_UNLOCK(); + + return 0; } -static int reserve_resources_from_vf(struct bnxt *bp, - struct hwrm_func_cfg_input *cfg_req, - int vf) +/* Update the PF resource values based on how many resources + * got allocated to it. + */ +static int bnxt_update_max_resources_pf_only(struct bnxt *bp) { - struct hwrm_func_qcaps_input req = {0}; - struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_qcfg_input req = {0}; + struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; int rc; /* Get the actual allocated values now */ - HWRM_PREP(&req, HWRM_FUNC_QCAPS, BNXT_USE_CHIMP_MB); - req.fid = rte_cpu_to_le_16(bp->pf->vf_info[vf].fid); + HWRM_PREP(&req, HWRM_FUNC_QCFG, BNXT_USE_CHIMP_MB); + req.fid = rte_cpu_to_le_16(0xffff); rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + HWRM_CHECK_RESULT(); - if (rc) { - PMD_DRV_LOG(ERR, "hwrm_func_qcaps failed rc:%d\n", rc); - copy_func_cfg_to_qcaps(cfg_req, resp); - } else if (resp->error_code) { - rc = rte_le_to_cpu_16(resp->error_code); - PMD_DRV_LOG(ERR, "hwrm_func_qcaps error %d\n", rc); - copy_func_cfg_to_qcaps(cfg_req, resp); - } - - bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx); - bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx); - bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings); - bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings); - bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings); - bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs); - /* - * TODO: While not supporting VMDq with VFs, max_vnics is always - * forced to 1 in this case - */ - //bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics); - bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps); + bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->alloc_rsscos_ctx); + bp->max_stat_ctx = rte_le_to_cpu_16(resp->alloc_stat_ctx); + bp->max_cp_rings = rte_le_to_cpu_16(resp->alloc_cmpl_rings); + bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings); + bp->max_rx_rings = rte_le_to_cpu_16(resp->alloc_rx_rings); + bp->max_l2_ctx = rte_le_to_cpu_16(resp->alloc_l2_ctx); + bp->max_ring_grps = rte_le_to_cpu_16(resp->alloc_hw_ring_grps); + bp->max_vnics = rte_le_to_cpu_16(resp->alloc_vnics); HWRM_UNLOCK(); @@ -3484,7 +3520,8 @@ int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf) return rc; } -static int update_pf_resource_max(struct bnxt *bp) +static int bnxt_query_pf_resources(struct bnxt *bp, + struct bnxt_pf_resource_info *pf_resc) { struct hwrm_func_qcfg_input req = {0}; struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr; @@ -3496,8 +3533,13 @@ static int update_pf_resource_max(struct bnxt *bp) rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); HWRM_CHECK_RESULT(); - /* Only TX ring value reflects actual allocation? TODO */ - bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings); + pf_resc->num_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings); + pf_resc->num_rsscos_ctxs = rte_le_to_cpu_16(resp->alloc_rsscos_ctx); + pf_resc->num_stat_ctxs = rte_le_to_cpu_16(resp->alloc_stat_ctx); + pf_resc->num_cp_rings = rte_le_to_cpu_16(resp->alloc_cmpl_rings); + pf_resc->num_rx_rings = rte_le_to_cpu_16(resp->alloc_rx_rings); + pf_resc->num_l2_ctxs = rte_le_to_cpu_16(resp->alloc_l2_ctx); + pf_resc->num_hw_ring_grps = rte_le_to_cpu_32(resp->alloc_hw_ring_grps); bp->pf->evb_mode = resp->evb_mode; HWRM_UNLOCK(); @@ -3505,37 +3547,43 @@ static int update_pf_resource_max(struct bnxt *bp) return rc; } -int bnxt_hwrm_allocate_pf_only(struct bnxt *bp) -{ - int rc; +static void +bnxt_calculate_pf_resources(struct bnxt *bp, + struct bnxt_pf_resource_info *pf_resc, + int num_vfs) +{ + if (!num_vfs) { + pf_resc->num_rsscos_ctxs = bp->max_rsscos_ctx; + pf_resc->num_stat_ctxs = bp->max_stat_ctx; + pf_resc->num_cp_rings = bp->max_cp_rings; + pf_resc->num_tx_rings = bp->max_tx_rings; + pf_resc->num_rx_rings = bp->max_rx_rings; + pf_resc->num_l2_ctxs = bp->max_l2_ctx; + pf_resc->num_hw_ring_grps = bp->max_ring_grps; - if (!BNXT_PF(bp)) { - PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n"); - return -EINVAL; + return; } - rc = bnxt_hwrm_func_qcaps(bp); - if (rc) - return rc; - - bp->pf->func_cfg_flags &= - ~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE | - HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE); - bp->pf->func_cfg_flags |= - HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE; - rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings); - rc = __bnxt_hwrm_func_qcaps(bp); - return rc; + pf_resc->num_rsscos_ctxs = bp->max_rsscos_ctx / (num_vfs + 1) + + bp->max_rsscos_ctx % (num_vfs + 1); + pf_resc->num_stat_ctxs = bp->max_stat_ctx / (num_vfs + 1) + + bp->max_stat_ctx % (num_vfs + 1); + pf_resc->num_cp_rings = bp->max_cp_rings / (num_vfs + 1) + + bp->max_cp_rings % (num_vfs + 1); + pf_resc->num_tx_rings = bp->max_tx_rings / (num_vfs + 1) + + bp->max_tx_rings % (num_vfs + 1); + pf_resc->num_rx_rings = bp->max_rx_rings / (num_vfs + 1) + + bp->max_rx_rings % (num_vfs + 1); + pf_resc->num_l2_ctxs = bp->max_l2_ctx / (num_vfs + 1) + + bp->max_l2_ctx % (num_vfs + 1); + pf_resc->num_hw_ring_grps = bp->max_ring_grps / (num_vfs + 1) + + bp->max_ring_grps % (num_vfs + 1); } -int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs) +int bnxt_hwrm_allocate_pf_only(struct bnxt *bp) { - struct hwrm_func_cfg_input req = {0}; - struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr; - int i; - size_t sz; - int rc = 0; - size_t req_buf_sz; + struct bnxt_pf_resource_info pf_resc = { 0 }; + int rc; if (!BNXT_PF(bp)) { PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n"); @@ -3543,57 +3591,108 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs) } rc = bnxt_hwrm_func_qcaps(bp); - if (rc) return rc; - bp->pf->active_vfs = num_vfs; + bnxt_calculate_pf_resources(bp, &pf_resc, 0); - /* - * First, configure the PF to only use one TX ring. This ensures that - * there are enough rings for all VFs. - * - * If we don't do this, when we call func_alloc() later, we will lock - * extra rings to the PF that won't be available during func_cfg() of - * the VFs. - * - * This has been fixed with firmware versions above 20.6.54 - */ bp->pf->func_cfg_flags &= ~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE | HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE); bp->pf->func_cfg_flags |= - HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE; - rc = bnxt_hwrm_pf_func_cfg(bp, 1); + HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE; + + rc = bnxt_hwrm_pf_func_cfg(bp, &pf_resc); if (rc) return rc; - /* - * Now, create and register a buffer to hold forwarded VF requests - */ + rc = bnxt_update_max_resources_pf_only(bp); + + return rc; +} + +static int +bnxt_configure_vf_req_buf(struct bnxt *bp, int num_vfs) +{ + size_t req_buf_sz, sz; + int i, rc; + req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN; bp->pf->vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz, page_roundup(num_vfs * HWRM_MAX_REQ_LEN)); if (bp->pf->vf_req_buf == NULL) { - rc = -ENOMEM; - goto error_free; + return -ENOMEM; } + for (sz = 0; sz < req_buf_sz; sz += getpagesize()) rte_mem_lock_page(((char *)bp->pf->vf_req_buf) + sz); + for (i = 0; i < num_vfs; i++) bp->pf->vf_info[i].req_buf = ((char *)bp->pf->vf_req_buf) + - (i * HWRM_MAX_REQ_LEN); + (i * HWRM_MAX_REQ_LEN); - rc = bnxt_hwrm_func_buf_rgtr(bp); + rc = bnxt_hwrm_func_buf_rgtr(bp, num_vfs); if (rc) - goto error_free; + rte_free(bp->pf->vf_req_buf); - populate_vf_func_cfg_req(bp, &req, num_vfs); + return rc; +} + +static int +bnxt_process_vf_resc_config_new(struct bnxt *bp, int num_vfs) +{ + struct hwrm_func_vf_resource_cfg_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_vf_resource_cfg_input req = {0}; + int i, rc = 0; + bnxt_fill_vf_func_cfg_req_new(bp, &req, num_vfs); bp->pf->active_vfs = 0; for (i = 0; i < num_vfs; i++) { - add_random_mac_if_needed(bp, &req, i); + HWRM_PREP(&req, HWRM_FUNC_VF_RESOURCE_CFG, BNXT_USE_CHIMP_MB); + req.vf_id = rte_cpu_to_le_16(bp->pf->vf_info[i].fid); + rc = bnxt_hwrm_send_message(bp, + &req, + sizeof(req), + BNXT_USE_CHIMP_MB); + if (rc || resp->error_code) { + PMD_DRV_LOG(ERR, + "Failed to initialize VF %d\n", i); + PMD_DRV_LOG(ERR, + "Not all VFs available. (%d, %d)\n", + rc, resp->error_code); + HWRM_UNLOCK(); + /* If the first VF configuration itself fails, + * unregister the vf_fwd_request buffer. + */ + if (i == 0) + bnxt_hwrm_func_buf_unrgtr(bp); + break; + } + HWRM_UNLOCK(); + + /* Update the max resource values based on the resource values + * allocated to the VF. + */ + bnxt_update_max_resources(bp, i); + bp->pf->active_vfs++; + bnxt_hwrm_func_clr_stats(bp, bp->pf->vf_info[i].fid); + } + + return 0; +} + +static int +bnxt_process_vf_resc_config_old(struct bnxt *bp, int num_vfs) +{ + struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_cfg_input req = {0}; + int i, rc; + + bnxt_fill_vf_func_cfg_req_old(bp, &req, num_vfs); + + bp->pf->active_vfs = 0; + for (i = 0; i < num_vfs; i++) { HWRM_PREP(&req, HWRM_FUNC_CFG, BNXT_USE_CHIMP_MB); req.flags = rte_cpu_to_le_32(bp->pf->vf_info[i].func_cfg_flags); req.fid = rte_cpu_to_le_16(bp->pf->vf_info[i].fid); @@ -3608,40 +3707,107 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs) if (rc || resp->error_code) { PMD_DRV_LOG(ERR, - "Failed to initizlie VF %d\n", i); + "Failed to initialize VF %d\n", i); PMD_DRV_LOG(ERR, "Not all VFs available. (%d, %d)\n", rc, resp->error_code); HWRM_UNLOCK(); + + /* If the first VF configuration itself fails, + * unregister the vf_fwd_request buffer. + */ + if (i == 0) + bnxt_hwrm_func_buf_unrgtr(bp); break; } HWRM_UNLOCK(); - reserve_resources_from_vf(bp, &req, i); + /* Update the max resource values based on the resource values + * allocated to the VF. + */ + bnxt_update_max_resources(bp, i); bp->pf->active_vfs++; bnxt_hwrm_func_clr_stats(bp, bp->pf->vf_info[i].fid); } + return 0; +} + +static void +bnxt_configure_vf_resources(struct bnxt *bp, int num_vfs) +{ + if (bp->flags & BNXT_FLAG_NEW_RM) + bnxt_process_vf_resc_config_new(bp, num_vfs); + else + bnxt_process_vf_resc_config_old(bp, num_vfs); +} + +static void +bnxt_update_pf_resources(struct bnxt *bp, + struct bnxt_pf_resource_info *pf_resc) +{ + bp->max_rsscos_ctx = pf_resc->num_rsscos_ctxs; + bp->max_stat_ctx = pf_resc->num_stat_ctxs; + bp->max_cp_rings = pf_resc->num_cp_rings; + bp->max_tx_rings = pf_resc->num_tx_rings; + bp->max_rx_rings = pf_resc->num_rx_rings; + bp->max_ring_grps = pf_resc->num_hw_ring_grps; +} + +static int32_t +bnxt_configure_pf_resources(struct bnxt *bp, + struct bnxt_pf_resource_info *pf_resc) +{ /* - * Now configure the PF to use "the rest" of the resources - * We're using STD_TX_RING_MODE here though which will limit the TX - * rings. This will allow QoS to function properly. Not setting this + * We're using STD_TX_RING_MODE here which will limit the TX + * rings. This will allow QoS to function properly. Not setting this * will cause PF rings to break bandwidth settings. */ - rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings); + bp->pf->func_cfg_flags &= + ~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE | + HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE); + bp->pf->func_cfg_flags |= + HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE; + return bnxt_hwrm_pf_func_cfg(bp, pf_resc); +} + +int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs) +{ + struct bnxt_pf_resource_info pf_resc = { 0 }; + int rc; + + if (!BNXT_PF(bp)) { + PMD_DRV_LOG(ERR, "Attempt to allocate VFs on a VF!\n"); + return -EINVAL; + } + + rc = bnxt_hwrm_func_qcaps(bp); if (rc) - goto error_free; + return rc; + + bnxt_calculate_pf_resources(bp, &pf_resc, num_vfs); - rc = update_pf_resource_max(bp); + rc = bnxt_configure_pf_resources(bp, &pf_resc); if (rc) - goto error_free; + return rc; - return rc; + rc = bnxt_query_pf_resources(bp, &pf_resc); + if (rc) + return rc; -error_free: - bnxt_hwrm_func_buf_unrgtr(bp); - return rc; + /* + * Now, create and register a buffer to hold forwarded VF requests + */ + rc = bnxt_configure_vf_req_buf(bp, num_vfs); + if (rc) + return rc; + + bnxt_configure_vf_resources(bp, num_vfs); + + bnxt_update_pf_resources(bp, &pf_resc); + + return 0; } int bnxt_hwrm_pf_evb_mode(struct bnxt *bp) @@ -3712,6 +3878,18 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port, HWRM_CHECK_RESULT(); HWRM_UNLOCK(); + if (tunnel_type == + HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN) { + bp->vxlan_port = 0; + bp->vxlan_port_cnt = 0; + } + + if (tunnel_type == + HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE) { + bp->geneve_port = 0; + bp->geneve_port_cnt = 0; + } + return rc; } @@ -3746,23 +3924,24 @@ int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic) return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL); } -int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp) +int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp, int num_vfs) { - int rc = 0; - struct hwrm_func_buf_rgtr_input req = {.req_type = 0 }; struct hwrm_func_buf_rgtr_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_buf_rgtr_input req = {.req_type = 0 }; + int rc; HWRM_PREP(&req, HWRM_FUNC_BUF_RGTR, BNXT_USE_CHIMP_MB); req.req_buf_num_pages = rte_cpu_to_le_16(1); - req.req_buf_page_size = rte_cpu_to_le_16( - page_getenum(bp->pf->active_vfs * HWRM_MAX_REQ_LEN)); + req.req_buf_page_size = + rte_cpu_to_le_16(page_getenum(num_vfs * HWRM_MAX_REQ_LEN)); req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN); req.req_buf_page_addr0 = rte_cpu_to_le_64(rte_malloc_virt2iova(bp->pf->vf_req_buf)); if (req.req_buf_page_addr0 == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, "unable to map buffer address to physical memory\n"); + HWRM_UNLOCK(); return -ENOMEM; } @@ -4011,8 +4190,8 @@ int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx, stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes); stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes); stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes); - stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts); - stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts); + stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_discard_pkts); + stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_error_pkts); } else { stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts); stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts); @@ -4193,6 +4372,7 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data) return -ENOMEM; dma_handle = rte_malloc_virt2iova(buf); if (dma_handle == RTE_BAD_IOVA) { + rte_free(buf); PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; @@ -4227,6 +4407,7 @@ int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index, dma_handle = rte_malloc_virt2iova(buf); if (dma_handle == RTE_BAD_IOVA) { + rte_free(buf); PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; @@ -4280,6 +4461,7 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type, dma_handle = rte_malloc_virt2iova(buf); if (dma_handle == RTE_BAD_IOVA) { + rte_free(buf); PMD_DRV_LOG(ERR, "unable to map response address to physical memory\n"); return -ENOMEM; @@ -4689,7 +4871,7 @@ int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp, } static int -bnxt_vnic_rss_configure_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic) +bnxt_vnic_rss_configure_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic) { struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr; uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state; @@ -4713,7 +4895,7 @@ bnxt_vnic_rss_configure_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic) req.ring_grp_tbl_addr = rte_cpu_to_le_64(vnic->rss_table_dma_addr + - i * BNXT_RSS_ENTRIES_PER_CTX_THOR * + i * BNXT_RSS_ENTRIES_PER_CTX_P5 * 2 * sizeof(*ring_tbl)); req.hash_key_tbl_addr = rte_cpu_to_le_64(vnic->rss_hash_key_dma_addr); @@ -4765,37 +4947,35 @@ int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic) { unsigned int rss_idx, fw_idx, i; - if (!(vnic->rss_table && vnic->hash_type)) + if (vnic->fw_vnic_id == INVALID_HW_RING_ID) return 0; - if (BNXT_CHIP_THOR(bp)) - return bnxt_vnic_rss_configure_thor(bp, vnic); - - if (vnic->fw_vnic_id == INVALID_HW_RING_ID) + if (!(vnic->rss_table && vnic->hash_type)) return 0; - if (vnic->rss_table && vnic->hash_type) { - /* - * Fill the RSS hash & redirection table with - * ring group ids for all VNICs - */ - for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE; - rss_idx++, fw_idx++) { - for (i = 0; i < bp->rx_cp_nr_rings; i++) { - fw_idx %= bp->rx_cp_nr_rings; - if (vnic->fw_grp_ids[fw_idx] != - INVALID_HW_RING_ID) - break; - fw_idx++; - } - if (i == bp->rx_cp_nr_rings) - return 0; - vnic->rss_table[rss_idx] = vnic->fw_grp_ids[fw_idx]; + if (BNXT_CHIP_P5(bp)) + return bnxt_vnic_rss_configure_p5(bp, vnic); + + /* + * Fill the RSS hash & redirection table with + * ring group ids for all VNICs + */ + for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE; + rss_idx++, fw_idx++) { + for (i = 0; i < bp->rx_cp_nr_rings; i++) { + fw_idx %= bp->rx_cp_nr_rings; + if (vnic->fw_grp_ids[fw_idx] != INVALID_HW_RING_ID) + break; + fw_idx++; } - return bnxt_hwrm_vnic_rss_cfg(bp, vnic); + + if (i == bp->rx_cp_nr_rings) + return 0; + + vnic->rss_table[rss_idx] = vnic->fw_grp_ids[fw_idx]; } - return 0; + return bnxt_hwrm_vnic_rss_cfg(bp, vnic); } static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, @@ -4828,7 +5008,7 @@ static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal, req->flags = rte_cpu_to_le_16(flags); } -static int bnxt_hwrm_set_coal_params_thor(struct bnxt *bp, +static int bnxt_hwrm_set_coal_params_p5(struct bnxt *bp, struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *agg_req) { struct hwrm_ring_aggint_qcaps_input req = {0}; @@ -4865,8 +5045,8 @@ int bnxt_hwrm_set_ring_coal(struct bnxt *bp, int rc; /* Set ring coalesce parameters only for 100G NICs */ - if (BNXT_CHIP_THOR(bp)) { - if (bnxt_hwrm_set_coal_params_thor(bp, &req)) + if (BNXT_CHIP_P5(bp)) { + if (bnxt_hwrm_set_coal_params_p5(bp, &req)) return -1; } else if (bnxt_stratus_device(bp)) { bnxt_hwrm_set_coal_params(coal, &req); @@ -4895,7 +5075,7 @@ int bnxt_hwrm_func_backing_store_qcaps(struct bnxt *bp) int total_alloc_len; int rc, i, tqm_rings; - if (!BNXT_CHIP_THOR(bp) || + if (!BNXT_CHIP_P5(bp) || bp->hwrm_spec_code < HWRM_VERSION_1_9_2 || BNXT_VF(bp) || bp->ctx) @@ -5562,55 +5742,6 @@ int bnxt_hwrm_cfa_counter_qstats(struct bnxt *bp, return 0; } -int bnxt_hwrm_cfa_vfr_alloc(struct bnxt *bp, uint16_t vf_idx) -{ - struct hwrm_cfa_vfr_alloc_output *resp = bp->hwrm_cmd_resp_addr; - struct hwrm_cfa_vfr_alloc_input req = {0}; - int rc; - - if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) { - PMD_DRV_LOG(DEBUG, - "Not a PF or trusted VF. Command not supported\n"); - return 0; - } - - HWRM_PREP(&req, HWRM_CFA_VFR_ALLOC, BNXT_USE_CHIMP_MB); - req.vf_id = rte_cpu_to_le_16(vf_idx); - snprintf(req.vfr_name, sizeof(req.vfr_name), "%svfr%d", - bp->eth_dev->data->name, vf_idx); - - rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); - HWRM_CHECK_RESULT(); - - HWRM_UNLOCK(); - PMD_DRV_LOG(DEBUG, "VFR %d allocated\n", vf_idx); - return rc; -} - -int bnxt_hwrm_cfa_vfr_free(struct bnxt *bp, uint16_t vf_idx) -{ - struct hwrm_cfa_vfr_free_output *resp = bp->hwrm_cmd_resp_addr; - struct hwrm_cfa_vfr_free_input req = {0}; - int rc; - - if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) { - PMD_DRV_LOG(DEBUG, - "Not a PF or trusted VF. Command not supported\n"); - return 0; - } - - HWRM_PREP(&req, HWRM_CFA_VFR_FREE, BNXT_USE_CHIMP_MB); - req.vf_id = rte_cpu_to_le_16(vf_idx); - snprintf(req.vfr_name, sizeof(req.vfr_name), "%svfr%d", - bp->eth_dev->data->name, vf_idx); - - rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); - HWRM_CHECK_RESULT(); - HWRM_UNLOCK(); - PMD_DRV_LOG(DEBUG, "VFR %d freed\n", vf_idx); - return rc; -} - int bnxt_hwrm_first_vf_id_query(struct bnxt *bp, uint16_t fid, uint16_t *first_vf_id) { @@ -5651,8 +5782,9 @@ int bnxt_hwrm_cfa_pair_alloc(struct bnxt *bp, struct bnxt_representor *rep_bp) snprintf(req.pair_name, sizeof(req.pair_name), "%svfr%d", bp->eth_dev->data->name, rep_bp->vf_id); - req.pf_b_id = rte_cpu_to_le_32(rep_bp->rep_based_pf); - req.vf_b_id = rte_cpu_to_le_16(rep_bp->vf_id); + req.pf_b_id = rep_bp->parent_pf_idx; + req.vf_b_id = BNXT_REP_PF(rep_bp) ? rte_cpu_to_le_16(((uint16_t)-1)) : + rte_cpu_to_le_16(rep_bp->vf_id); req.vf_a_id = rte_cpu_to_le_16(bp->fw_fid); req.host_b_id = 1; /* TBD - Confirm if this is OK */ @@ -5694,10 +5826,10 @@ int bnxt_hwrm_cfa_pair_free(struct bnxt *bp, struct bnxt_representor *rep_bp) HWRM_PREP(&req, HWRM_CFA_PAIR_FREE, BNXT_USE_CHIMP_MB); snprintf(req.pair_name, sizeof(req.pair_name), "%svfr%d", bp->eth_dev->data->name, rep_bp->vf_id); - req.pf_b_id = rte_cpu_to_le_32(rep_bp->rep_based_pf); - req.vf_id = rte_cpu_to_le_16(rep_bp->vf_id); + req.pf_b_id = rep_bp->parent_pf_idx; req.pair_mode = HWRM_CFA_PAIR_FREE_INPUT_PAIR_MODE_REP2FN_TRUFLOW; - + req.vf_id = BNXT_REP_PF(rep_bp) ? rte_cpu_to_le_16(((uint16_t)-1)) : + rte_cpu_to_le_16(rep_bp->vf_id); rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); HWRM_CHECK_RESULT(); HWRM_UNLOCK(); @@ -5705,3 +5837,35 @@ int bnxt_hwrm_cfa_pair_free(struct bnxt *bp, struct bnxt_representor *rep_bp) rep_bp->vf_id); return rc; } + +int bnxt_hwrm_cfa_adv_flow_mgmt_qcaps(struct bnxt *bp) +{ + struct hwrm_cfa_adv_flow_mgnt_qcaps_output *resp = + bp->hwrm_cmd_resp_addr; + struct hwrm_cfa_adv_flow_mgnt_qcaps_input req = {0}; + uint32_t flags = 0; + int rc = 0; + + if (!(bp->fw_cap & BNXT_FW_CAP_ADV_FLOW_MGMT)) + return 0; + + if (!(BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))) { + PMD_DRV_LOG(DEBUG, + "Not a PF or trusted VF. Command not supported\n"); + return 0; + } + + HWRM_PREP(&req, HWRM_CFA_ADV_FLOW_MGNT_QCAPS, BNXT_USE_CHIMP_MB); + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + + HWRM_CHECK_RESULT(); + flags = rte_le_to_cpu_32(resp->flags); + HWRM_UNLOCK(); + + if (flags & HWRM_CFA_ADV_FLOW_MGNT_QCAPS_RFS_RING_TBL_IDX_V2_SUPPORTED) + bp->flags |= BNXT_FLAG_FLOW_CFA_RFS_RING_TBL_IDX_V2; + else + bp->flags |= BNXT_FLAG_RFS_NEEDS_VNIC; + + return rc; +}