1fd710bb1SScott Branden /* SPDX-License-Identifier: BSD-3-Clause 2e6e8f03eSRandy Schacher * Copyright(c) 2014-2023 Broadcom 3f2a768d4SAjit Khaparde * All rights reserved. 4f2a768d4SAjit Khaparde */ 5f2a768d4SAjit Khaparde 62bb1d5dbSAjit Khaparde #include <rte_malloc.h> 7df6cd7c1SKalesh AP #include <rte_alarm.h> 81db68899SKalesh AP #include <rte_cycles.h> 92bb1d5dbSAjit Khaparde 10f2a768d4SAjit Khaparde #include "bnxt.h" 11f2a768d4SAjit Khaparde #include "bnxt_hwrm.h" 12f2a768d4SAjit Khaparde #include "bnxt_ring.h" 1357d5e5bcSAjit Khaparde #include "hsi_struct_def_dpdk.h" 14dd0191d5SShuanglin Wang #include "tfc_vf2pf_msg.h" 15f2a768d4SAjit Khaparde 161db68899SKalesh AP void bnxt_wait_for_device_shutdown(struct bnxt *bp) 171db68899SKalesh AP { 181db68899SKalesh AP uint32_t val, timeout; 191db68899SKalesh AP 201db68899SKalesh AP /* if HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD is set 211db68899SKalesh AP * in HWRM_FUNC_QCAPS command, wait for FW_STATUS to set 221db68899SKalesh AP * the SHUTDOWN bit in health register 231db68899SKalesh AP */ 241db68899SKalesh AP if (!(bp->recovery_info && 25839dee40SKalesh AP (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD))) 261db68899SKalesh AP return; 271db68899SKalesh AP 281db68899SKalesh AP /* Driver has to wait for fw_reset_max_msecs or shutdown bit which comes 291db68899SKalesh AP * first for FW to collect crash dump. 301db68899SKalesh AP */ 311db68899SKalesh AP timeout = bp->fw_reset_max_msecs; 321db68899SKalesh AP 331db68899SKalesh AP /* Driver has to poll for shutdown bit in fw_status register 341db68899SKalesh AP * 351db68899SKalesh AP * 1. in case of hot fw upgrade, this bit will be set after all 361db68899SKalesh AP * function drivers unregistered with fw. 371db68899SKalesh AP * 2. in case of fw initiated error recovery, this bit will be 381db68899SKalesh AP * set after fw has collected the core dump 391db68899SKalesh AP */ 401db68899SKalesh AP do { 411db68899SKalesh AP val = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); 421db68899SKalesh AP if (val & BNXT_FW_STATUS_SHUTDOWN) 431db68899SKalesh AP return; 441db68899SKalesh AP 451db68899SKalesh AP rte_delay_ms(100); 461db68899SKalesh AP timeout -= 100; 471db68899SKalesh AP } while (timeout); 481db68899SKalesh AP } 491db68899SKalesh AP 5095de0fafSSomnath Kotur static void bnxt_handle_event_error_report(struct bnxt *bp, 5195de0fafSSomnath Kotur uint32_t data1, 5295de0fafSSomnath Kotur uint32_t data2) 5395de0fafSSomnath Kotur { 5495de0fafSSomnath Kotur switch (BNXT_EVENT_ERROR_REPORT_TYPE(data1)) { 5595de0fafSSomnath Kotur case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_PAUSE_STORM: 56e99981afSDavid Marchand PMD_DRV_LOG_LINE(WARNING, "Port:%d Pause Storm detected!", 5795de0fafSSomnath Kotur bp->eth_dev->data->port_id); 5895de0fafSSomnath Kotur break; 59c934cb1dSKalesh AP case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DUAL_DATA_RATE_NOT_SUPPORTED: 60e99981afSDavid Marchand PMD_DRV_LOG_LINE(WARNING, "Port:%d Speed change not supported with dual rate transceivers on this board", 61c934cb1dSKalesh AP bp->eth_dev->data->port_id); 62c934cb1dSKalesh AP break; 6395de0fafSSomnath Kotur default: 64e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "FW reported unknown error type data1 %d" 65e99981afSDavid Marchand " data2: %d", data1, data2); 6695de0fafSSomnath Kotur break; 6795de0fafSSomnath Kotur } 6895de0fafSSomnath Kotur } 6995de0fafSSomnath Kotur 706c63f349SKalesh AP void bnxt_handle_vf_cfg_change(void *arg) 716c63f349SKalesh AP { 726c63f349SKalesh AP struct bnxt *bp = arg; 736c63f349SKalesh AP struct rte_eth_dev *eth_dev = bp->eth_dev; 746c63f349SKalesh AP int rc; 756c63f349SKalesh AP 766c63f349SKalesh AP /* Free and recreate filters with default VLAN */ 776c63f349SKalesh AP if (eth_dev->data->dev_started) { 786c63f349SKalesh AP rc = bnxt_dev_stop_op(eth_dev); 796c63f349SKalesh AP if (rc != 0) { 80e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, "Failed to stop Port:%u", eth_dev->data->port_id); 816c63f349SKalesh AP return; 826c63f349SKalesh AP } 836c63f349SKalesh AP 846c63f349SKalesh AP rc = bnxt_dev_start_op(eth_dev); 856c63f349SKalesh AP if (rc != 0) 86e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, "Failed to start Port:%u", eth_dev->data->port_id); 876c63f349SKalesh AP } 886c63f349SKalesh AP } 896c63f349SKalesh AP 908ef4bc87SJay Ding static void 918ef4bc87SJay Ding bnxt_process_vf_flr(struct bnxt *bp, uint32_t data1) 928ef4bc87SJay Ding { 938ef4bc87SJay Ding uint16_t pfid, vfid; 94dd0191d5SShuanglin Wang int rc; 958ef4bc87SJay Ding 968ef4bc87SJay Ding if (!BNXT_TRUFLOW_EN(bp)) 978ef4bc87SJay Ding return; 988ef4bc87SJay Ding 998ef4bc87SJay Ding pfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_MASK) >> 1008ef4bc87SJay Ding HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_SFT; 1018ef4bc87SJay Ding vfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_MASK) >> 1028ef4bc87SJay Ding HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_SFT; 1038ef4bc87SJay Ding 104e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "VF FLR async event received pfid: %u, vfid: %u", 1058ef4bc87SJay Ding pfid, vfid); 106dd0191d5SShuanglin Wang 107dd0191d5SShuanglin Wang rc = tfc_tbl_scope_func_reset(&bp->tfcp, vfid); 108dd0191d5SShuanglin Wang if (rc != 0) 109dd0191d5SShuanglin Wang PMD_DRV_LOG_LINE(ERR, "Failed to reset vf"); 1108ef4bc87SJay Ding } 1118ef4bc87SJay Ding 112f2a768d4SAjit Khaparde /* 113f2a768d4SAjit Khaparde * Async event handling 114f2a768d4SAjit Khaparde */ 1157bc8e9a2SAjit Khaparde void bnxt_handle_async_event(struct bnxt *bp, 116f2a768d4SAjit Khaparde struct cmpl_base *cmp) 117f2a768d4SAjit Khaparde { 118f2a768d4SAjit Khaparde struct hwrm_async_event_cmpl *async_cmp = 119f2a768d4SAjit Khaparde (struct hwrm_async_event_cmpl *)cmp; 1207bc8e9a2SAjit Khaparde uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id); 121a7dda7e0SKalesh AP uint16_t port_id = bp->eth_dev->data->port_id; 1226391aeb8SKalesh AP struct bnxt_error_recovery_info *info; 1232e88b083SKalesh AP uint32_t event_data; 1241125b16bSSomnath Kotur uint32_t data1, data2; 125a5d81111SKalesh AP uint32_t status; 1261125b16bSSomnath Kotur 1271125b16bSSomnath Kotur data1 = rte_le_to_cpu_32(async_cmp->event_data1); 1281125b16bSSomnath Kotur data2 = rte_le_to_cpu_32(async_cmp->event_data2); 129f2a768d4SAjit Khaparde 1307bc8e9a2SAjit Khaparde switch (event_id) { 1317bc8e9a2SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE: 1327bc8e9a2SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE: 1337bc8e9a2SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE: 134704d430cSAjit Khaparde /* FALLTHROUGH */ 135af57c49cSKalesh AP bnxt_link_update_op(bp->eth_dev, 0); 1368117f5f6SWeifeng Li rte_eth_dev_callback_process(bp->eth_dev, 1378117f5f6SWeifeng Li RTE_ETH_EVENT_INTR_LSC, NULL); 138f2a768d4SAjit Khaparde break; 13912213821SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD: 140e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "Async event: PF driver unloaded"); 14112213821SAjit Khaparde break; 14212213821SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE: 143e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "Port %u: VF config change async event", port_id); 144e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "event: data1 %#x data2 %#x", data1, data2); 145905cd45cSSomnath Kotur bnxt_hwrm_func_qcfg(bp, NULL); 1466c63f349SKalesh AP if (BNXT_VF(bp)) 1476c63f349SKalesh AP rte_eal_alarm_set(1, bnxt_handle_vf_cfg_change, (void *)bp); 14812213821SAjit Khaparde break; 14912213821SAjit Khaparde case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED: 150e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "Port conn async event"); 15112213821SAjit Khaparde break; 152df6cd7c1SKalesh AP case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: 15333ac72d7SRahul Gupta /* 15433ac72d7SRahul Gupta * Avoid any rx/tx packet processing during firmware reset 15533ac72d7SRahul Gupta * operation. 15633ac72d7SRahul Gupta */ 157e21aca08SSomnath Kotur bnxt_stop_rxtx(bp->eth_dev); 15833ac72d7SRahul Gupta 159c696cc65SKalesh AP /* Ignore reset notify async events when stopping the port */ 160c696cc65SKalesh AP if (!bp->eth_dev->data->dev_started) { 161c696cc65SKalesh AP bp->flags |= BNXT_FLAG_FATAL_ERROR; 162c696cc65SKalesh AP return; 163c696cc65SKalesh AP } 164c696cc65SKalesh AP 165e11052f3SKalesh AP rte_eth_dev_callback_process(bp->eth_dev, 166e11052f3SKalesh AP RTE_ETH_EVENT_ERR_RECOVERING, 167e11052f3SKalesh AP NULL); 168e11052f3SKalesh AP 1696f5f3b99SSomnath Kotur pthread_mutex_lock(&bp->err_recovery_lock); 1701125b16bSSomnath Kotur event_data = data1; 171df6cd7c1SKalesh AP /* timestamp_lo/hi values are in units of 100ms */ 172df6cd7c1SKalesh AP bp->fw_reset_max_msecs = async_cmp->timestamp_hi ? 173df6cd7c1SKalesh AP rte_le_to_cpu_16(async_cmp->timestamp_hi) * 100 : 174df6cd7c1SKalesh AP BNXT_MAX_FW_RESET_TIMEOUT; 175df6cd7c1SKalesh AP bp->fw_reset_min_msecs = async_cmp->timestamp_lo ? 176df6cd7c1SKalesh AP async_cmp->timestamp_lo * 100 : 177df6cd7c1SKalesh AP BNXT_MIN_FW_READY_TIMEOUT; 1782e88b083SKalesh AP if ((event_data & EVENT_DATA1_REASON_CODE_MASK) == 1792e88b083SKalesh AP EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL) { 180e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, 181e99981afSDavid Marchand "Port %u: Firmware fatal reset event received", 182a7dda7e0SKalesh AP port_id); 1832e88b083SKalesh AP bp->flags |= BNXT_FLAG_FATAL_ERROR; 1842e88b083SKalesh AP } else { 185e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, 186e99981afSDavid Marchand "Port %u: Firmware non-fatal reset event received", 187a7dda7e0SKalesh AP port_id); 1882e88b083SKalesh AP } 189df6cd7c1SKalesh AP 190df6cd7c1SKalesh AP bp->flags |= BNXT_FLAG_FW_RESET; 1916f5f3b99SSomnath Kotur pthread_mutex_unlock(&bp->err_recovery_lock); 192df6cd7c1SKalesh AP rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, 193df6cd7c1SKalesh AP (void *)bp); 194df6cd7c1SKalesh AP break; 1956391aeb8SKalesh AP case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY: 1966391aeb8SKalesh AP info = bp->recovery_info; 1976391aeb8SKalesh AP 1986391aeb8SKalesh AP if (!info) 1996391aeb8SKalesh AP return; 2006391aeb8SKalesh AP 2011125b16bSSomnath Kotur event_data = data1 & EVENT_DATA1_FLAGS_MASK; 2026391aeb8SKalesh AP 203a5d81111SKalesh AP if (event_data & EVENT_DATA1_FLAGS_RECOVERY_ENABLED) { 2046391aeb8SKalesh AP info->flags |= BNXT_FLAG_RECOVERY_ENABLED; 205a5d81111SKalesh AP } else { 2066391aeb8SKalesh AP info->flags &= ~BNXT_FLAG_RECOVERY_ENABLED; 207e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "Driver recovery watchdog is disabled"); 208a5d81111SKalesh AP return; 209a5d81111SKalesh AP } 2106391aeb8SKalesh AP 211a5d81111SKalesh AP if (event_data & EVENT_DATA1_FLAGS_MASTER_FUNC) 212a5d81111SKalesh AP info->flags |= BNXT_FLAG_PRIMARY_FUNC; 213a5d81111SKalesh AP else 214a5d81111SKalesh AP info->flags &= ~BNXT_FLAG_PRIMARY_FUNC; 215a5d81111SKalesh AP 216a5d81111SKalesh AP status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); 217e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, 218e99981afSDavid Marchand "Port: %u Driver recovery watchdog, role: %s, FW status: 0x%x (%s)", 219a5d81111SKalesh AP port_id, bnxt_is_primary_func(bp) ? "primary" : "backup", status, 220a5d81111SKalesh AP (status == BNXT_FW_STATUS_HEALTHY) ? "healthy" : "unhealthy"); 2219d0cbaecSKalesh AP 2229d0cbaecSKalesh AP if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED) 2239d0cbaecSKalesh AP return; 2249d0cbaecSKalesh AP 2259d0cbaecSKalesh AP info->last_heart_beat = 2269d0cbaecSKalesh AP bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG); 2279d0cbaecSKalesh AP info->last_reset_counter = 2289d0cbaecSKalesh AP bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG); 2299d0cbaecSKalesh AP 2309d0cbaecSKalesh AP bnxt_schedule_fw_health_check(bp); 2316391aeb8SKalesh AP break; 23275a675d6SKalesh AP case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEBUG_NOTIFICATION: 233e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, "Port: %u DNC event: data1 %#x data2 %#x", 2341125b16bSSomnath Kotur port_id, data1, data2); 23575a675d6SKalesh AP break; 236705e0f32SKalesh AP case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST: 237e99981afSDavid Marchand PMD_DRV_LOG_LINE(INFO, 238e99981afSDavid Marchand "Port %u: Received fw echo request: data1 %#x data2 %#x", 2391125b16bSSomnath Kotur port_id, data1, data2); 240705e0f32SKalesh AP if (bp->recovery_info) 2411125b16bSSomnath Kotur bnxt_hwrm_fw_echo_reply(bp, data1, data2); 242705e0f32SKalesh AP break; 24395de0fafSSomnath Kotur case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT: 24495de0fafSSomnath Kotur bnxt_handle_event_error_report(bp, data1, data2); 24595de0fafSSomnath Kotur break; 2468ef4bc87SJay Ding case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR: 2478ef4bc87SJay Ding bnxt_process_vf_flr(bp, data1); 2488ef4bc87SJay Ding break; 249*643e7ee3SManish Kurup case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RSS_CHANGE: 250*643e7ee3SManish Kurup /* RSS change notification, re-read QCAPS */ 251*643e7ee3SManish Kurup PMD_DRV_LOG_LINE(INFO, "Async event: RSS change event [%#x, %#x]", 252*643e7ee3SManish Kurup data1, data2); 253*643e7ee3SManish Kurup bnxt_hwrm_vnic_qcaps(bp); 254*643e7ee3SManish Kurup break; 255f2a768d4SAjit Khaparde default: 256e99981afSDavid Marchand PMD_DRV_LOG_LINE(DEBUG, "handle_async_event id = 0x%x", event_id); 257f2a768d4SAjit Khaparde break; 258f2a768d4SAjit Khaparde } 259f2a768d4SAjit Khaparde } 260f2a768d4SAjit Khaparde 261f2a768d4SAjit Khaparde void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl) 262f2a768d4SAjit Khaparde { 2634535cad3SAjit Khaparde struct hwrm_exec_fwd_resp_input *fwreq; 264f2a768d4SAjit Khaparde struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl; 265f2a768d4SAjit Khaparde struct input *fwd_cmd; 2664535cad3SAjit Khaparde uint16_t fw_vf_id; 2674535cad3SAjit Khaparde uint16_t vf_id; 2684535cad3SAjit Khaparde uint16_t req_len; 2694535cad3SAjit Khaparde int rc; 2704535cad3SAjit Khaparde 271e8fe0e06SAjit Khaparde if (bp->pf->active_vfs <= 0) { 272e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, "Forwarded VF with no active VFs"); 2734535cad3SAjit Khaparde return; 2744535cad3SAjit Khaparde } 275f2a768d4SAjit Khaparde 276f2a768d4SAjit Khaparde /* Qualify the fwd request */ 2774535cad3SAjit Khaparde fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id); 278e8fe0e06SAjit Khaparde vf_id = fw_vf_id - bp->pf->first_vf_id; 2794535cad3SAjit Khaparde 2804535cad3SAjit Khaparde req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) & 2814535cad3SAjit Khaparde HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >> 2824535cad3SAjit Khaparde HWRM_FWD_REQ_CMPL_REQ_LEN_SFT; 2834535cad3SAjit Khaparde if (req_len > sizeof(fwreq->encap_request)) 2844535cad3SAjit Khaparde req_len = sizeof(fwreq->encap_request); 285f2a768d4SAjit Khaparde 286f2a768d4SAjit Khaparde /* Locate VF's forwarded command */ 287e8fe0e06SAjit Khaparde fwd_cmd = (struct input *)bp->pf->vf_info[vf_id].req_buf; 288f2a768d4SAjit Khaparde 289e8fe0e06SAjit Khaparde if (fw_vf_id < bp->pf->first_vf_id || 290e8fe0e06SAjit Khaparde fw_vf_id >= bp->pf->first_vf_id + bp->pf->active_vfs) { 291e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, 292e99981afSDavid Marchand "FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)", 293e8fe0e06SAjit Khaparde fw_vf_id, bp->pf->first_vf_id, 294e8fe0e06SAjit Khaparde (bp->pf->first_vf_id) + bp->pf->active_vfs - 1, 295e8fe0e06SAjit Khaparde bp->pf->first_vf_id, bp->pf->active_vfs); 296f2a768d4SAjit Khaparde goto reject; 297f2a768d4SAjit Khaparde } 298f2a768d4SAjit Khaparde 299ef10add3SVenkat Duvvuru if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd)) { 3004535cad3SAjit Khaparde /* 3014535cad3SAjit Khaparde * In older firmware versions, the MAC had to be all zeros for 3024535cad3SAjit Khaparde * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all 3034535cad3SAjit Khaparde * zeros if it's being configured and has been ok'd by caller. 3044535cad3SAjit Khaparde */ 3054535cad3SAjit Khaparde if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) { 3064535cad3SAjit Khaparde struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd; 3074535cad3SAjit Khaparde 3084535cad3SAjit Khaparde if (vfc->enables & 3094535cad3SAjit Khaparde HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) { 3104535cad3SAjit Khaparde bnxt_hwrm_func_vf_mac(bp, vf_id, 3114535cad3SAjit Khaparde (const uint8_t *)"\x00\x00\x00\x00\x00"); 3124535cad3SAjit Khaparde } 3134535cad3SAjit Khaparde } 314ef10add3SVenkat Duvvuru 3154535cad3SAjit Khaparde if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) { 3164535cad3SAjit Khaparde struct hwrm_cfa_l2_set_rx_mask_input *srm = 3174535cad3SAjit Khaparde (void *)fwd_cmd; 3184535cad3SAjit Khaparde 3194535cad3SAjit Khaparde srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0); 3204535cad3SAjit Khaparde srm->num_vlan_tags = rte_cpu_to_le_32(0); 3214535cad3SAjit Khaparde srm->mask &= ~rte_cpu_to_le_32( 3224535cad3SAjit Khaparde HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY | 3234535cad3SAjit Khaparde HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN | 3244535cad3SAjit Khaparde HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN); 3254535cad3SAjit Khaparde } 326ef10add3SVenkat Duvvuru 327dd0191d5SShuanglin Wang if (fwd_cmd->req_type == HWRM_OEM_CMD) { 328dd0191d5SShuanglin Wang struct hwrm_oem_cmd_input *oem_cmd = (void *)fwd_cmd; 329dd0191d5SShuanglin Wang struct hwrm_oem_cmd_output oem_out = { 0 }; 330dd0191d5SShuanglin Wang 331dd0191d5SShuanglin Wang if (oem_cmd->oem_id == 0x14e4 && 332dd0191d5SShuanglin Wang oem_cmd->naming_authority 333dd0191d5SShuanglin Wang == HWRM_OEM_CMD_INPUT_NAMING_AUTHORITY_PCI_SIG && 334dd0191d5SShuanglin Wang oem_cmd->message_family 335dd0191d5SShuanglin Wang == HWRM_OEM_CMD_INPUT_MESSAGE_FAMILY_TRUFLOW) { 336dd0191d5SShuanglin Wang uint32_t resp[18] = { 0 }; 337dd0191d5SShuanglin Wang uint16_t oem_data_len = sizeof(oem_out.oem_data); 338dd0191d5SShuanglin Wang uint16_t resp_len = oem_data_len; 339dd0191d5SShuanglin Wang 340dd0191d5SShuanglin Wang rc = tfc_oem_cmd_process(&bp->tfcp, 341dd0191d5SShuanglin Wang oem_cmd->oem_data, 342dd0191d5SShuanglin Wang resp, 343dd0191d5SShuanglin Wang &resp_len); 344dd0191d5SShuanglin Wang if (rc) { 345dd0191d5SShuanglin Wang PMD_DRV_LOG_LINE(ERR, 346dd0191d5SShuanglin Wang "OEM cmd process error id 0x%x, name 0x%x, family 0x%x", 347dd0191d5SShuanglin Wang oem_cmd->oem_id, 348dd0191d5SShuanglin Wang oem_cmd->naming_authority, 349dd0191d5SShuanglin Wang oem_cmd->message_family); 350dd0191d5SShuanglin Wang goto reject; 351dd0191d5SShuanglin Wang } 352dd0191d5SShuanglin Wang 353dd0191d5SShuanglin Wang oem_out.error_code = 0; 354dd0191d5SShuanglin Wang oem_out.req_type = oem_cmd->req_type; 355dd0191d5SShuanglin Wang oem_out.seq_id = oem_cmd->seq_id; 356dd0191d5SShuanglin Wang oem_out.resp_len = rte_cpu_to_le_16(sizeof(oem_out)); 357dd0191d5SShuanglin Wang oem_out.oem_id = oem_cmd->oem_id; 358dd0191d5SShuanglin Wang oem_out.naming_authority = oem_cmd->naming_authority; 359dd0191d5SShuanglin Wang oem_out.message_family = oem_cmd->message_family; 360dd0191d5SShuanglin Wang memcpy(oem_out.oem_data, resp, resp_len); 361dd0191d5SShuanglin Wang oem_out.valid = 1; 362dd0191d5SShuanglin Wang 363dd0191d5SShuanglin Wang rc = bnxt_hwrm_fwd_resp(bp, fw_vf_id, &oem_out, oem_out.resp_len, 364dd0191d5SShuanglin Wang oem_cmd->resp_addr, oem_cmd->cmpl_ring); 365dd0191d5SShuanglin Wang if (rc) { 366dd0191d5SShuanglin Wang PMD_DRV_LOG_LINE(ERR, 367dd0191d5SShuanglin Wang "Failed to send HWRM_FWD_RESP VF 0x%x, type", 368dd0191d5SShuanglin Wang fw_vf_id - bp->pf->first_vf_id); 369dd0191d5SShuanglin Wang } 370dd0191d5SShuanglin Wang } else { 371dd0191d5SShuanglin Wang PMD_DRV_LOG_LINE(ERR, 372dd0191d5SShuanglin Wang "Unsupported OEM cmd id 0x%x, name 0x%x, family 0x%x", 373dd0191d5SShuanglin Wang oem_cmd->oem_id, oem_cmd->naming_authority, 374dd0191d5SShuanglin Wang oem_cmd->message_family); 375dd0191d5SShuanglin Wang goto reject; 376dd0191d5SShuanglin Wang } 377dd0191d5SShuanglin Wang 378dd0191d5SShuanglin Wang return; 379dd0191d5SShuanglin Wang } 380dd0191d5SShuanglin Wang 381f2a768d4SAjit Khaparde /* Forward */ 3824535cad3SAjit Khaparde rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len); 3834535cad3SAjit Khaparde if (rc) { 384e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, 385e99981afSDavid Marchand "Failed to send FWD req VF 0x%x, type 0x%x.", 386e8fe0e06SAjit Khaparde fw_vf_id - bp->pf->first_vf_id, 3874535cad3SAjit Khaparde rte_le_to_cpu_16(fwd_cmd->req_type)); 3884535cad3SAjit Khaparde } 389f2a768d4SAjit Khaparde return; 3904535cad3SAjit Khaparde } 391f2a768d4SAjit Khaparde 392f2a768d4SAjit Khaparde reject: 3934535cad3SAjit Khaparde rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len); 3944535cad3SAjit Khaparde if (rc) { 395e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, 396e99981afSDavid Marchand "Failed to send REJECT req VF 0x%x, type 0x%x.", 397e8fe0e06SAjit Khaparde fw_vf_id - bp->pf->first_vf_id, 3984535cad3SAjit Khaparde rte_le_to_cpu_16(fwd_cmd->req_type)); 3994535cad3SAjit Khaparde } 4004535cad3SAjit Khaparde 4014535cad3SAjit Khaparde return; 402f2a768d4SAjit Khaparde } 403f2a768d4SAjit Khaparde 4042b947bd2SAjit Khaparde int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp) 4054535cad3SAjit Khaparde { 4062b947bd2SAjit Khaparde bool evt = 0; 4074535cad3SAjit Khaparde 4082b947bd2SAjit Khaparde if (bp == NULL || cmp == NULL) { 409e99981afSDavid Marchand PMD_DRV_LOG_LINE(ERR, "invalid NULL argument"); 4102b947bd2SAjit Khaparde return evt; 4114535cad3SAjit Khaparde } 4124535cad3SAjit Khaparde 4131bf01f51SKalesh AP if (unlikely(is_bnxt_in_error(bp))) 4141bf01f51SKalesh AP return 0; 4151bf01f51SKalesh AP 4162b947bd2SAjit Khaparde switch (CMP_TYPE(cmp)) { 4172b947bd2SAjit Khaparde case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: 4182b947bd2SAjit Khaparde /* Handle any async event */ 4192b947bd2SAjit Khaparde bnxt_handle_async_event(bp, cmp); 4202b947bd2SAjit Khaparde evt = 1; 4212b947bd2SAjit Khaparde break; 422ef10add3SVenkat Duvvuru case CMPL_BASE_TYPE_HWRM_FWD_REQ: 4232b947bd2SAjit Khaparde /* Handle HWRM forwarded responses */ 4242b947bd2SAjit Khaparde bnxt_handle_fwd_req(bp, cmp); 4252b947bd2SAjit Khaparde evt = 1; 4262b947bd2SAjit Khaparde break; 4272b947bd2SAjit Khaparde default: 4282b947bd2SAjit Khaparde /* Ignore any other events */ 429e99981afSDavid Marchand PMD_DRV_LOG_LINE(DEBUG, "Ignoring %02x completion", CMP_TYPE(cmp)); 4302b947bd2SAjit Khaparde break; 431f2a768d4SAjit Khaparde } 432f2a768d4SAjit Khaparde 4332b947bd2SAjit Khaparde return evt; 434f2a768d4SAjit Khaparde } 4356391aeb8SKalesh AP 436a5d81111SKalesh AP bool bnxt_is_primary_func(struct bnxt *bp) 4376391aeb8SKalesh AP { 438a5d81111SKalesh AP if (bp->recovery_info->flags & BNXT_FLAG_PRIMARY_FUNC) 4396391aeb8SKalesh AP return true; 4406391aeb8SKalesh AP 4416391aeb8SKalesh AP return false; 4426391aeb8SKalesh AP } 4436391aeb8SKalesh AP 4446391aeb8SKalesh AP bool bnxt_is_recovery_enabled(struct bnxt *bp) 4456391aeb8SKalesh AP { 4466391aeb8SKalesh AP struct bnxt_error_recovery_info *info; 4476391aeb8SKalesh AP 4486391aeb8SKalesh AP info = bp->recovery_info; 4496391aeb8SKalesh AP if (info && (info->flags & BNXT_FLAG_RECOVERY_ENABLED)) 4506391aeb8SKalesh AP return true; 4516391aeb8SKalesh AP 4526391aeb8SKalesh AP return false; 4536391aeb8SKalesh AP } 45433ac72d7SRahul Gupta 455e21aca08SSomnath Kotur void bnxt_stop_rxtx(struct rte_eth_dev *eth_dev) 45633ac72d7SRahul Gupta { 457a41f593fSFerruh Yigit eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy; 458a41f593fSFerruh Yigit eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy; 459720b55adSSomnath Kotur 460e21aca08SSomnath Kotur rte_eth_fp_ops[eth_dev->data->port_id].rx_pkt_burst = 461e21aca08SSomnath Kotur eth_dev->rx_pkt_burst; 462e21aca08SSomnath Kotur rte_eth_fp_ops[eth_dev->data->port_id].tx_pkt_burst = 463e21aca08SSomnath Kotur eth_dev->tx_pkt_burst; 464720b55adSSomnath Kotur rte_mb(); 465720b55adSSomnath Kotur 466720b55adSSomnath Kotur /* Allow time for threads to exit the real burst functions. */ 467720b55adSSomnath Kotur rte_delay_ms(100); 46833ac72d7SRahul Gupta } 469