xref: /dpdk/drivers/net/bnxt/bnxt_cpr.c (revision ef9e424aa72477cc5fd35efeb31c923a67383241)
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