}
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;
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--;
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;
}
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();
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 */
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
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] |=
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();
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);
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;
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);
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);
+
}
}
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);
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);
}
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);
int rc = 0;
STAILQ_FOREACH(filter, &vnic->filter, next) {
- if (filter->filter_type == HWRM_CFA_EM_FILTER) {
+ if (filter->filter_type == HWRM_CFA_EM_FILTER)
rc = bnxt_hwrm_set_em_filter(bp, filter->dst_id,
filter);
- } else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER) {
+ else if (filter->filter_type == HWRM_CFA_NTUPLE_FILTER)
rc = bnxt_hwrm_set_ntuple_filter(bp, filter->dst_id,
filter);
- } else {
+ else
rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id,
filter);
- if (!rc)
- filter->dflt = 1;
- }
if (rc)
break;
}
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);
}
/* 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;
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.
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) {