X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fbnxt%2Fbnxt_hwrm.c;h=8178213e5af752476f4dda6e1a1d25de7efb68fe;hb=f0f6b5e6cf94e75cd419bb1bc37463bbc7884110;hp=daed4ee76fda58486d3cf08f2f3c06df05f32f65;hpb=938a87db43242a204772307a2d7e66950c661b1e;p=dpdk.git diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index daed4ee76f..8178213e5a 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -363,10 +363,11 @@ int bnxt_hwrm_cfa_vlan_antispoof_cfg(struct bnxt *bp, uint16_t fid, } int bnxt_hwrm_clear_l2_filter(struct bnxt *bp, - struct bnxt_filter_info *filter) + struct bnxt_filter_info *filter) { int rc = 0; struct bnxt_filter_info *l2_filter = filter; + struct bnxt_vnic_info *vnic = NULL; struct hwrm_cfa_l2_filter_free_input req = {.req_type = 0 }; struct hwrm_cfa_l2_filter_free_output *resp = bp->hwrm_cmd_resp_addr; @@ -379,6 +380,9 @@ int bnxt_hwrm_clear_l2_filter(struct bnxt *bp, PMD_DRV_LOG(DEBUG, "filter: %p l2_filter: %p ref_cnt: %d\n", filter, l2_filter, l2_filter->l2_ref_cnt); + if (l2_filter->l2_ref_cnt == 0) + return 0; + if (l2_filter->l2_ref_cnt > 0) l2_filter->l2_ref_cnt--; @@ -395,6 +399,14 @@ int bnxt_hwrm_clear_l2_filter(struct bnxt *bp, HWRM_UNLOCK(); filter->fw_l2_filter_id = UINT64_MAX; + if (l2_filter->l2_ref_cnt == 0) { + vnic = l2_filter->vnic; + if (vnic) { + STAILQ_REMOVE(&vnic->filter, l2_filter, + bnxt_filter_info, next); + bnxt_free_filter(bp, l2_filter); + } + } return 0; } @@ -661,16 +673,15 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->flags |= BNXT_FLAG_EXT_STATS_SUPPORTED; if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE) { - bp->flags |= BNXT_FLAG_FW_CAP_ERROR_RECOVERY; + bp->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY; PMD_DRV_LOG(DEBUG, "Adapter Error recovery SUPPORTED\n"); - } else { - bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY; } if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD) - bp->flags |= BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD; - else - bp->flags &= ~BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD; + bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD; + + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_HOT_RESET_CAPABLE) + bp->fw_cap |= BNXT_FW_CAP_HOT_RESET; HWRM_UNLOCK(); @@ -692,7 +703,12 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->flags |= BNXT_FLAG_NEW_RM; } - return rc; + /* On older FW, + * bnxt_hwrm_func_resc_qcaps can fail and cause init failure. + * But the error can be ignored. Return success. + */ + + return 0; } /* VNIC cap covers capability of all VNICs. So no need to pass vnic_id */ @@ -751,8 +767,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) if (bp->flags & BNXT_FLAG_REGISTERED) return 0; - flags = HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_HOT_RESET_SUPPORT; - if (bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY) + if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET) + flags = HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_HOT_RESET_SUPPORT; + if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ERROR_RECOVERY_SUPPORT; /* PFs and trusted VFs should indicate the support of the @@ -792,7 +809,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE | ASYNC_CMPL_EVENT_ID_LINK_SPEED_CHANGE | ASYNC_CMPL_EVENT_ID_RESET_NOTIFY); - if (bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY) + if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) req.async_event_fwd[0] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_ERROR_RECOVERY); req.async_event_fwd[1] |= @@ -805,7 +822,7 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) flags = rte_le_to_cpu_32(resp->flags); if (flags & HWRM_FUNC_DRV_RGTR_OUTPUT_FLAGS_IF_CHANGE_SUPPORTED) - bp->flags |= BNXT_FLAG_FW_CAP_IF_CHANGE; + bp->fw_cap |= BNXT_FW_CAP_IF_CHANGE; HWRM_UNLOCK(); @@ -901,7 +918,7 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp) rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); - HWRM_CHECK_RESULT(); + HWRM_CHECK_RESULT_SILENT(); if (BNXT_VF(bp)) { bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx); @@ -1205,6 +1222,35 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp, return rc; } +static bool bnxt_find_lossy_profile(struct bnxt *bp) +{ + int i = 0; + + for (i = BNXT_COS_QUEUE_COUNT - 1; i >= 0; i--) { + if (bp->tx_cos_queue[i].profile == + HWRM_QUEUE_SERVICE_PROFILE_LOSSY) { + bp->tx_cosq_id[0] = bp->tx_cos_queue[i].id; + return true; + } + } + return false; +} + +static void bnxt_find_first_valid_profile(struct bnxt *bp) +{ + int i = 0; + + for (i = BNXT_COS_QUEUE_COUNT - 1; i >= 0; i--) { + if (bp->tx_cos_queue[i].profile != + HWRM_QUEUE_SERVICE_PROFILE_UNKNOWN && + bp->tx_cos_queue[i].id != + HWRM_QUEUE_SERVICE_PROFILE_UNKNOWN) { + bp->tx_cosq_id[0] = bp->tx_cos_queue[i].id; + break; + } + } +} + int bnxt_hwrm_queue_qportcfg(struct bnxt *bp) { int rc = 0; @@ -1217,8 +1263,9 @@ get_rx_info: HWRM_PREP(req, QUEUE_QPORTCFG, BNXT_USE_CHIMP_MB); req.flags = rte_cpu_to_le_32(dir); - /* HWRM Version >= 1.9.1 */ - if (bp->hwrm_spec_code >= HWRM_VERSION_1_9_1) + /* HWRM Version >= 1.9.1 only if COS Classification is not required. */ + if (bp->hwrm_spec_code >= HWRM_VERSION_1_9_1 && + !(bp->vnic_cap_flags & BNXT_VNIC_CAP_COS_CLASSIFY)) req.drv_qmap_cap = HWRM_QUEUE_QPORTCFG_INPUT_DRV_QMAP_CAP_ENABLED; rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); @@ -1263,14 +1310,13 @@ get_rx_info: bp->tx_cos_queue[i].id; } } else { - for (i = BNXT_COS_QUEUE_COUNT - 1; i >= 0; i--) { - if (bp->tx_cos_queue[i].profile == - HWRM_QUEUE_SERVICE_PROFILE_LOSSY) { - bp->tx_cosq_id[0] = - bp->tx_cos_queue[i].id; - break; - } - } + /* When CoS classification is disabled, for normal NIC + * operations, ideally we should look to use LOSSY. + * If not found, fallback to the first valid profile + */ + if (!bnxt_find_lossy_profile(bp)) + bnxt_find_first_valid_profile(bp); + } } @@ -1695,10 +1741,29 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic) HWRM_PREP(req, VNIC_CFG, BNXT_USE_CHIMP_MB); if (BNXT_CHIP_THOR(bp)) { - struct bnxt_rx_queue *rxq = - bp->eth_dev->data->rx_queues[vnic->start_grp_id]; - struct bnxt_rx_ring_info *rxr = rxq->rx_ring; - struct bnxt_cp_ring_info *cpr = rxq->cp_ring; + int dflt_rxq = vnic->start_grp_id; + struct bnxt_rx_ring_info *rxr; + struct bnxt_cp_ring_info *cpr; + struct bnxt_rx_queue *rxq; + int i; + + /* + * The first active receive ring is used as the VNIC + * default receive ring. If there are no active receive + * rings (all corresponding receive queues are stopped), + * the first receive ring is used. + */ + for (i = vnic->start_grp_id; i < vnic->end_grp_id; i++) { + rxq = bp->eth_dev->data->rx_queues[i]; + if (rxq->rx_started) { + dflt_rxq = i; + break; + } + } + + rxq = bp->eth_dev->data->rx_queues[dflt_rxq]; + rxr = rxq->rx_ring; + cpr = rxq->cp_ring; req.default_rx_ring_id = rte_cpu_to_le_16(rxr->rx_ring_struct->fw_ring_id); @@ -2430,8 +2495,7 @@ int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic) rc = bnxt_hwrm_clear_em_filter(bp, filter); else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) rc = bnxt_hwrm_clear_ntuple_filter(bp, filter); - else - rc = bnxt_hwrm_clear_l2_filter(bp, filter); + rc = bnxt_hwrm_clear_l2_filter(bp, filter); STAILQ_REMOVE(&vnic->filter, filter, bnxt_filter_info, next); bnxt_free_filter(bp, filter); } @@ -2453,8 +2517,7 @@ bnxt_clear_hwrm_vnic_flows(struct bnxt *bp, struct bnxt_vnic_info *vnic) rc = bnxt_hwrm_clear_em_filter(bp, filter); else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) rc = bnxt_hwrm_clear_ntuple_filter(bp, filter); - else - rc = bnxt_hwrm_clear_l2_filter(bp, filter); + rc = bnxt_hwrm_clear_l2_filter(bp, filter); STAILQ_REMOVE(&vnic->flow_list, flow, rte_flow, next); rte_free(flow); @@ -2953,8 +3016,7 @@ 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(RTE_MIN(bp->eth_dev->data->mtu, - BNXT_MAX_MTU)); //FW adds hdr sizes + 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); @@ -4168,7 +4230,6 @@ int bnxt_hwrm_clear_em_filter(struct bnxt *bp, struct bnxt_filter_info *filter) if (filter->fw_em_filter_id == UINT64_MAX) return 0; - PMD_DRV_LOG(ERR, "Clear EM filter\n"); HWRM_PREP(req, CFA_EM_FLOW_FREE, BNXT_USE_KONG(bp)); req.em_filter_id = rte_cpu_to_le_64(filter->fw_em_filter_id); @@ -4336,8 +4397,10 @@ bnxt_vnic_rss_configure_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic) } /* Return if no rings are active. */ - if (cnt == max_rings) + if (cnt == max_rings) { + HWRM_UNLOCK(); return 0; + } /* Add rx/cp ring pair to RSS table. */ rxr = rxqs[k]->rx_ring; @@ -4818,7 +4881,7 @@ int bnxt_hwrm_if_change(struct bnxt *bp, bool up) uint32_t flags; int rc; - if (!(bp->flags & BNXT_FLAG_FW_CAP_IF_CHANGE)) + if (!(bp->fw_cap & BNXT_FW_CAP_IF_CHANGE)) return 0; /* Do not issue FUNC_DRV_IF_CHANGE during reset recovery. @@ -4861,7 +4924,7 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) int rc; /* Older FW does not have error recovery support */ - if (!(bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY)) + if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)) return 0; if (!info) {