Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2014-2023 Broadcom
3 : : * All rights reserved.
4 : : */
5 : :
6 : : #include <rte_malloc.h>
7 : : #include <rte_alarm.h>
8 : : #include <rte_cycles.h>
9 : :
10 : : #include "bnxt.h"
11 : : #include "bnxt_hwrm.h"
12 : : #include "bnxt_ring.h"
13 : : #include "hsi_struct_def_dpdk.h"
14 : : #include "tfc_vf2pf_msg.h"
15 : :
16 : 0 : void bnxt_process_async_msg(struct bnxt *bp, struct tx_cmpl *cmpl)
17 : : {
18 : 0 : uint16_t type = cmpl->flags_type & TX_CMPL_TYPE_MASK;
19 : :
20 [ # # # ]: 0 : switch (type) {
21 : : case HWRM_CMPL_TYPE_HWRM_DONE:
22 : : break;
23 : 0 : case HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT:
24 : 0 : bnxt_handle_async_event(bp, (struct cmpl_base *)cmpl);
25 : 0 : break;
26 : 0 : default:
27 : 0 : PMD_DRV_LOG_LINE(ERR, "Port: %d Unhandled async message %x",
28 : : bp->eth_dev->data->port_id, type);
29 : 0 : break;
30 : : }
31 : 0 : }
32 : :
33 : 0 : void bnxt_process_nq(struct bnxt *bp, struct bnxt_cp_ring_info *nqr,
34 : : struct bnxt_cp_ring_info *rx_cpr)
35 : : {
36 : 0 : struct nqe_cn *nqcmps = (struct nqe_cn *)nqr->cp_desc_ring;
37 : 0 : uint32_t ring_mask = nqr->cp_ring_struct->ring_mask;
38 : 0 : uint32_t raw_cons = nqr->cp_raw_cons;
39 : : uint16_t nq_type, nqe_cnt = 0;
40 : 0 : bool v_bit = nqr->valid;
41 : 0 : uint32_t cons = RING_CMPL(ring_mask, raw_cons);
42 : :
43 : : while (1) {
44 [ # # ]: 0 : if (!CMPL_VALID(&nqcmps[cons], v_bit)) {
45 [ # # ]: 0 : if (nqe_cnt) {
46 : 0 : nqr->cp_raw_cons = raw_cons;
47 : 0 : nqr->valid = v_bit;
48 : : }
49 : 0 : return;
50 : : }
51 : :
52 : 0 : nq_type = NQ_CN_TYPE_MASK & nqcmps[cons].type;
53 : :
54 [ # # ]: 0 : if (CMP_TYPE((struct cmpl_base *)&nqcmps[cons]) != NQ_CN_TYPE_CQ_NOTIFICATION)
55 : 0 : bnxt_process_async_msg(bp, (struct tx_cmpl *)&nqcmps[cons]);
56 : : else
57 : 0 : rx_cpr->toggle = NQE_CN_TOGGLE((uint64_t)nqcmps[cons].type);
58 : :
59 [ # # ]: 0 : NEXT_CMPL(nqr, cons, v_bit, 1);
60 : 0 : raw_cons++;
61 [ # # ]: 0 : if (nq_type)
62 : 0 : nqe_cnt++;
63 : : }
64 : : }
65 : :
66 : : /* Arms/disarms the given NQ for Thor/Thor2, with P5+ represening the ASIC family */
67 : 0 : void bnxt_arm_nq_p5p(struct bnxt_cp_ring_info *nqr, bool enable_irq)
68 : : {
69 : 0 : uint32_t raw_cons = nqr->cp_raw_cons;
70 : : uint64_t db_msg = 0;
71 : : uint32_t toggle = 0;
72 : :
73 [ # # ]: 0 : if (enable_irq == 1)
74 : 0 : toggle = nqr->toggle;
75 : :
76 : 0 : db_msg = nqr->cp_db.db_key64 | (raw_cons & nqr->cp_db.db_ring_mask)
77 [ # # ]: 0 : | DB_EPOCH(&nqr->cp_db, raw_cons) | DB_TOGGLE(toggle);
78 : :
79 [ # # ]: 0 : if (enable_irq)
80 : 0 : db_msg |= DBR_TYPE_NQ_ARM;
81 : : else
82 : 0 : db_msg |= DBR_TYPE_NQ_MASK;
83 : :
84 : 0 : rte_compiler_barrier();
85 : 0 : rte_write64(db_msg, nqr->cp_db.doorbell);
86 : 0 : rte_compiler_barrier();
87 : 0 : }
88 : :
89 : : /* Arms/disarms the given CQ for Thor/Thor2, with P5+ represening the ASIC family */
90 : 0 : void bnxt_arm_rx_cq_p5p(struct bnxt_cp_ring_info *cpr, bool enable_irq)
91 : : {
92 : 0 : uint32_t raw_cons = cpr->cp_raw_cons;
93 : : uint64_t db_msg = 0;
94 : : uint32_t toggle = 0;
95 : :
96 [ # # ]: 0 : if (raw_cons == UINT32_MAX)
97 : : raw_cons = 0;
98 : :
99 [ # # ]: 0 : if (enable_irq == 1)
100 : 0 : toggle = cpr->toggle;
101 : :
102 : 0 : db_msg = cpr->cp_db.db_key64 | (raw_cons & cpr->cp_db.db_ring_mask)
103 [ # # ]: 0 : | DB_EPOCH(&cpr->cp_db, raw_cons) | DB_TOGGLE(toggle);
104 : :
105 [ # # ]: 0 : if (enable_irq)
106 : 0 : db_msg |= DBR_TYPE_CQ_ARMALL;
107 : : else
108 : 0 : db_msg |= DBR_TYPE_CQ;
109 : :
110 : 0 : rte_compiler_barrier();
111 : 0 : rte_write64(db_msg, cpr->cp_db.doorbell);
112 : 0 : rte_compiler_barrier();
113 : 0 : }
114 : :
115 : :
116 : 0 : void bnxt_wait_for_device_shutdown(struct bnxt *bp)
117 : : {
118 : : uint32_t val, timeout;
119 : :
120 : : /* if HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD is set
121 : : * in HWRM_FUNC_QCAPS command, wait for FW_STATUS to set
122 : : * the SHUTDOWN bit in health register
123 : : */
124 [ # # ]: 0 : if (!(bp->recovery_info &&
125 [ # # ]: 0 : (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD)))
126 : : return;
127 : :
128 : : /* Driver has to wait for fw_reset_max_msecs or shutdown bit which comes
129 : : * first for FW to collect crash dump.
130 : : */
131 : 0 : timeout = bp->fw_reset_max_msecs;
132 : :
133 : : /* Driver has to poll for shutdown bit in fw_status register
134 : : *
135 : : * 1. in case of hot fw upgrade, this bit will be set after all
136 : : * function drivers unregistered with fw.
137 : : * 2. in case of fw initiated error recovery, this bit will be
138 : : * set after fw has collected the core dump
139 : : */
140 : : do {
141 : 0 : val = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG);
142 [ # # ]: 0 : if (val & BNXT_FW_STATUS_SHUTDOWN)
143 : : return;
144 : :
145 : : rte_delay_ms(100);
146 : 0 : timeout -= 100;
147 [ # # ]: 0 : } while (timeout);
148 : : }
149 : :
150 : 0 : static void bnxt_handle_event_error_report(struct bnxt *bp,
151 : : uint32_t data1,
152 : : uint32_t data2)
153 : : {
154 [ # # # ]: 0 : switch (BNXT_EVENT_ERROR_REPORT_TYPE(data1)) {
155 : 0 : case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_PAUSE_STORM:
156 : 0 : PMD_DRV_LOG_LINE(WARNING, "Port:%d Pause Storm detected!",
157 : : bp->eth_dev->data->port_id);
158 : 0 : break;
159 : 0 : case HWRM_ASYNC_EVENT_CMPL_ERROR_REPORT_BASE_EVENT_DATA1_ERROR_TYPE_DUAL_DATA_RATE_NOT_SUPPORTED:
160 : 0 : PMD_DRV_LOG_LINE(WARNING, "Port:%d Speed change not supported with dual rate transceivers on this board",
161 : : bp->eth_dev->data->port_id);
162 : 0 : break;
163 : 0 : default:
164 : 0 : PMD_DRV_LOG_LINE(INFO, "FW reported unknown error type data1 %d"
165 : : " data2: %d", data1, data2);
166 : 0 : break;
167 : : }
168 : 0 : }
169 : :
170 : 0 : void bnxt_handle_vf_cfg_change(void *arg)
171 : : {
172 : : struct bnxt *bp = arg;
173 : 0 : struct rte_eth_dev *eth_dev = bp->eth_dev;
174 : : int rc;
175 : :
176 : : /* Free and recreate filters with default VLAN */
177 [ # # ]: 0 : if (eth_dev->data->dev_started) {
178 : 0 : rc = bnxt_dev_stop_op(eth_dev);
179 [ # # ]: 0 : if (rc != 0) {
180 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to stop Port:%u", eth_dev->data->port_id);
181 : 0 : return;
182 : : }
183 : :
184 : 0 : rc = bnxt_dev_start_op(eth_dev);
185 [ # # ]: 0 : if (rc != 0)
186 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to start Port:%u", eth_dev->data->port_id);
187 : : }
188 : : }
189 : :
190 : : static void
191 : 0 : bnxt_process_vf_flr(struct bnxt *bp, uint32_t data1)
192 : : {
193 : : uint16_t pfid, vfid;
194 : : int rc;
195 : :
196 [ # # # # ]: 0 : if (!BNXT_TRUFLOW_EN(bp))
197 : : return;
198 : :
199 : 0 : pfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_MASK) >>
200 : : HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_SFT;
201 : : vfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_MASK) >>
202 : : HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_SFT;
203 : :
204 : 0 : PMD_DRV_LOG_LINE(INFO, "VF FLR async event received pfid: %u, vfid: %u",
205 : : pfid, vfid);
206 : :
207 : 0 : rc = tfc_tbl_scope_func_reset(&bp->tfcp, vfid);
208 [ # # ]: 0 : if (rc != 0)
209 : 0 : PMD_DRV_LOG_LINE(ERR, "Failed to reset vf");
210 : : }
211 : :
212 : : /*
213 : : * Async event handling
214 : : */
215 : 0 : void bnxt_handle_async_event(struct bnxt *bp,
216 : : struct cmpl_base *cmp)
217 : : {
218 : : struct hwrm_async_event_cmpl *async_cmp =
219 : : (struct hwrm_async_event_cmpl *)cmp;
220 : 0 : uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id);
221 : 0 : uint16_t port_id = bp->eth_dev->data->port_id;
222 : : struct bnxt_error_recovery_info *info;
223 : : uint32_t event_data;
224 : : uint32_t data1, data2;
225 : : uint32_t status;
226 : :
227 : 0 : data1 = rte_le_to_cpu_32(async_cmp->event_data1);
228 : 0 : data2 = rte_le_to_cpu_32(async_cmp->event_data2);
229 : :
230 [ # # # # : 0 : switch (event_id) {
# # # # #
# # # ]
231 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE:
232 : : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE:
233 : : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE:
234 : : /* FALLTHROUGH */
235 : 0 : bnxt_link_update_op(bp->eth_dev, 0);
236 : 0 : rte_eth_dev_callback_process(bp->eth_dev,
237 : : RTE_ETH_EVENT_INTR_LSC, NULL);
238 : 0 : break;
239 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD:
240 : 0 : PMD_DRV_LOG_LINE(INFO, "Async event: PF driver unloaded");
241 : 0 : break;
242 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE:
243 : 0 : PMD_DRV_LOG_LINE(INFO, "Port %u: VF config change async event", port_id);
244 : 0 : PMD_DRV_LOG_LINE(INFO, "event: data1 %#x data2 %#x", data1, data2);
245 : 0 : bnxt_hwrm_func_qcfg(bp, NULL);
246 [ # # ]: 0 : if (BNXT_VF(bp))
247 : 0 : rte_eal_alarm_set(1, bnxt_handle_vf_cfg_change, (void *)bp);
248 : : break;
249 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED:
250 : 0 : PMD_DRV_LOG_LINE(INFO, "Port conn async event");
251 : 0 : break;
252 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY:
253 : : /*
254 : : * Avoid any rx/tx packet processing during firmware reset
255 : : * operation.
256 : : */
257 : 0 : bnxt_stop_rxtx(bp->eth_dev);
258 : :
259 : : /* Ignore reset notify async events when stopping the port */
260 [ # # ]: 0 : if (!bp->eth_dev->data->dev_started) {
261 : 0 : bp->flags |= BNXT_FLAG_FATAL_ERROR;
262 : 0 : return;
263 : : }
264 : :
265 : 0 : rte_eth_dev_callback_process(bp->eth_dev,
266 : : RTE_ETH_EVENT_ERR_RECOVERING,
267 : : NULL);
268 : :
269 : 0 : pthread_mutex_lock(&bp->err_recovery_lock);
270 : : event_data = data1;
271 : : /* timestamp_lo/hi values are in units of 100ms */
272 [ # # ]: 0 : bp->fw_reset_max_msecs = async_cmp->timestamp_hi ?
273 : : rte_le_to_cpu_16(async_cmp->timestamp_hi) * 100 :
274 : : BNXT_MAX_FW_RESET_TIMEOUT;
275 [ # # ]: 0 : bp->fw_reset_min_msecs = async_cmp->timestamp_lo ?
276 : : async_cmp->timestamp_lo * 100 :
277 : : BNXT_MIN_FW_READY_TIMEOUT;
278 [ # # ]: 0 : if ((event_data & EVENT_DATA1_REASON_CODE_MASK) ==
279 : : EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL) {
280 : 0 : PMD_DRV_LOG_LINE(INFO,
281 : : "Port %u: Firmware fatal reset event received",
282 : : port_id);
283 : 0 : bp->flags |= BNXT_FLAG_FATAL_ERROR;
284 : : } else {
285 : 0 : PMD_DRV_LOG_LINE(INFO,
286 : : "Port %u: Firmware non-fatal reset event received",
287 : : port_id);
288 : : }
289 : :
290 : 0 : bp->flags |= BNXT_FLAG_FW_RESET;
291 : 0 : pthread_mutex_unlock(&bp->err_recovery_lock);
292 : 0 : rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume,
293 : : (void *)bp);
294 : 0 : break;
295 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY:
296 : 0 : info = bp->recovery_info;
297 : :
298 [ # # ]: 0 : if (!info)
299 : : return;
300 : :
301 : : event_data = data1 & EVENT_DATA1_FLAGS_MASK;
302 : :
303 [ # # ]: 0 : if (event_data & EVENT_DATA1_FLAGS_RECOVERY_ENABLED) {
304 : 0 : info->flags |= BNXT_FLAG_RECOVERY_ENABLED;
305 : : } else {
306 : 0 : info->flags &= ~BNXT_FLAG_RECOVERY_ENABLED;
307 : 0 : PMD_DRV_LOG_LINE(INFO, "Driver recovery watchdog is disabled");
308 : 0 : return;
309 : : }
310 : :
311 [ # # ]: 0 : if (event_data & EVENT_DATA1_FLAGS_MASTER_FUNC)
312 : 0 : info->flags |= BNXT_FLAG_PRIMARY_FUNC;
313 : : else
314 : 0 : info->flags &= ~BNXT_FLAG_PRIMARY_FUNC;
315 : :
316 : 0 : status = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG);
317 [ # # # # ]: 0 : PMD_DRV_LOG_LINE(INFO,
318 : : "Port: %u Driver recovery watchdog, role: %s, FW status: 0x%x (%s)",
319 : : port_id, bnxt_is_primary_func(bp) ? "primary" : "backup", status,
320 : : (status == BNXT_FW_STATUS_HEALTHY) ? "healthy" : "unhealthy");
321 : :
322 [ # # ]: 0 : if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED)
323 : : return;
324 : :
325 : 0 : info->last_heart_beat =
326 : 0 : bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG);
327 : 0 : info->last_reset_counter =
328 : 0 : bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG);
329 : :
330 : 0 : bnxt_schedule_fw_health_check(bp);
331 : 0 : break;
332 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DEBUG_NOTIFICATION:
333 : 0 : PMD_DRV_LOG_LINE(INFO, "Port: %u DNC event: data1 %#x data2 %#x",
334 : : port_id, data1, data2);
335 : 0 : break;
336 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST:
337 : 0 : PMD_DRV_LOG_LINE(INFO,
338 : : "Port %u: Received fw echo request: data1 %#x data2 %#x",
339 : : port_id, data1, data2);
340 [ # # ]: 0 : if (bp->recovery_info)
341 : 0 : bnxt_hwrm_fw_echo_reply(bp, data1, data2);
342 : : break;
343 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT:
344 : 0 : bnxt_handle_event_error_report(bp, data1, data2);
345 : 0 : break;
346 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR:
347 : 0 : bnxt_process_vf_flr(bp, data1);
348 : 0 : break;
349 : 0 : case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RSS_CHANGE:
350 : : /* RSS change notification, re-read QCAPS */
351 : 0 : PMD_DRV_LOG_LINE(INFO, "Async event: RSS change event [%#x, %#x]",
352 : : data1, data2);
353 : 0 : bnxt_hwrm_vnic_qcaps(bp);
354 : 0 : break;
355 : 0 : default:
356 : 0 : PMD_DRV_LOG_LINE(DEBUG, "handle_async_event id = 0x%x", event_id);
357 : 0 : break;
358 : : }
359 : : }
360 : :
361 : 0 : void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
362 : : {
363 : : struct hwrm_exec_fwd_resp_input *fwreq;
364 : : struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
365 : : struct input *fwd_cmd;
366 : : uint16_t fw_vf_id;
367 : : uint16_t vf_id;
368 : : uint16_t req_len;
369 : : int rc;
370 : :
371 [ # # ]: 0 : if (bp->pf->active_vfs <= 0) {
372 : 0 : PMD_DRV_LOG_LINE(ERR, "Forwarded VF with no active VFs");
373 : 0 : return;
374 : : }
375 : :
376 : : /* Qualify the fwd request */
377 : 0 : fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
378 : 0 : vf_id = fw_vf_id - bp->pf->first_vf_id;
379 : :
380 : 0 : req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
381 : : HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
382 : : HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
383 : : if (req_len > sizeof(fwreq->encap_request))
384 : : req_len = sizeof(fwreq->encap_request);
385 : :
386 : : /* Locate VF's forwarded command */
387 : 0 : fwd_cmd = (struct input *)bp->pf->vf_info[vf_id].req_buf;
388 : :
389 [ # # ]: 0 : if (fw_vf_id < bp->pf->first_vf_id ||
390 [ # # ]: 0 : fw_vf_id >= bp->pf->first_vf_id + bp->pf->active_vfs) {
391 : 0 : PMD_DRV_LOG_LINE(ERR,
392 : : "FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)",
393 : : fw_vf_id, bp->pf->first_vf_id,
394 : : (bp->pf->first_vf_id) + bp->pf->active_vfs - 1,
395 : : bp->pf->first_vf_id, bp->pf->active_vfs);
396 : 0 : goto reject;
397 : : }
398 : :
399 [ # # ]: 0 : if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd)) {
400 : : /*
401 : : * In older firmware versions, the MAC had to be all zeros for
402 : : * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
403 : : * zeros if it's being configured and has been ok'd by caller.
404 : : */
405 [ # # ]: 0 : if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
406 : : struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
407 : :
408 [ # # ]: 0 : if (vfc->enables &
409 : : HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
410 : 0 : bnxt_hwrm_func_vf_mac(bp, vf_id,
411 : : (const uint8_t *)"\x00\x00\x00\x00\x00");
412 : : }
413 : : }
414 : :
415 [ # # ]: 0 : if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
416 : : struct hwrm_cfa_l2_set_rx_mask_input *srm =
417 : : (void *)fwd_cmd;
418 : :
419 : 0 : srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
420 : 0 : srm->num_vlan_tags = rte_cpu_to_le_32(0);
421 : 0 : srm->mask &= ~rte_cpu_to_le_32(
422 : : HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
423 : : HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
424 : : HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
425 : : }
426 : :
427 [ # # ]: 0 : if (fwd_cmd->req_type == HWRM_OEM_CMD) {
428 : : struct hwrm_oem_cmd_input *oem_cmd = (void *)fwd_cmd;
429 : 0 : struct hwrm_oem_cmd_output oem_out = { 0 };
430 : :
431 [ # # ]: 0 : if (oem_cmd->oem_id == 0x14e4 &&
432 [ # # ]: 0 : oem_cmd->naming_authority
433 : 0 : == HWRM_OEM_CMD_INPUT_NAMING_AUTHORITY_PCI_SIG &&
434 [ # # ]: 0 : oem_cmd->message_family
435 : : == HWRM_OEM_CMD_INPUT_MESSAGE_FAMILY_TRUFLOW) {
436 : 0 : uint32_t resp[18] = { 0 };
437 : : uint16_t oem_data_len = sizeof(oem_out.oem_data);
438 : 0 : uint16_t resp_len = oem_data_len;
439 : :
440 : 0 : rc = tfc_oem_cmd_process(&bp->tfcp,
441 : 0 : oem_cmd->oem_data,
442 : : resp,
443 : : &resp_len);
444 [ # # ]: 0 : if (rc) {
445 : 0 : PMD_DRV_LOG_LINE(ERR,
446 : : "OEM cmd process error id 0x%x, name 0x%x, family 0x%x",
447 : : oem_cmd->oem_id,
448 : : oem_cmd->naming_authority,
449 : : oem_cmd->message_family);
450 : 0 : goto reject;
451 : : }
452 : :
453 : 0 : oem_out.error_code = 0;
454 : 0 : oem_out.req_type = oem_cmd->req_type;
455 : 0 : oem_out.seq_id = oem_cmd->seq_id;
456 : 0 : oem_out.resp_len = rte_cpu_to_le_16(sizeof(oem_out));
457 : 0 : oem_out.oem_id = oem_cmd->oem_id;
458 : 0 : oem_out.naming_authority = oem_cmd->naming_authority;
459 : 0 : oem_out.message_family = oem_cmd->message_family;
460 : 0 : memcpy(oem_out.oem_data, resp, resp_len);
461 : 0 : oem_out.valid = 1;
462 : :
463 : 0 : rc = bnxt_hwrm_fwd_resp(bp, fw_vf_id, &oem_out, oem_out.resp_len,
464 : 0 : oem_cmd->resp_addr, oem_cmd->cmpl_ring);
465 [ # # ]: 0 : if (rc) {
466 : 0 : PMD_DRV_LOG_LINE(ERR,
467 : : "Failed to send HWRM_FWD_RESP VF 0x%x, type",
468 : : fw_vf_id - bp->pf->first_vf_id);
469 : : }
470 : : } else {
471 : 0 : PMD_DRV_LOG_LINE(ERR,
472 : : "Unsupported OEM cmd id 0x%x, name 0x%x, family 0x%x",
473 : : oem_cmd->oem_id, oem_cmd->naming_authority,
474 : : oem_cmd->message_family);
475 : 0 : goto reject;
476 : : }
477 : :
478 : 0 : return;
479 : : }
480 : :
481 : : /* Forward */
482 : 0 : rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
483 [ # # ]: 0 : if (rc) {
484 : 0 : PMD_DRV_LOG_LINE(ERR,
485 : : "Failed to send FWD req VF 0x%x, type 0x%x.",
486 : : fw_vf_id - bp->pf->first_vf_id,
487 : : rte_le_to_cpu_16(fwd_cmd->req_type));
488 : : }
489 : 0 : return;
490 : : }
491 : :
492 : 0 : reject:
493 : 0 : rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
494 [ # # ]: 0 : if (rc) {
495 : 0 : PMD_DRV_LOG_LINE(ERR,
496 : : "Failed to send REJECT req VF 0x%x, type 0x%x.",
497 : : fw_vf_id - bp->pf->first_vf_id,
498 : : rte_le_to_cpu_16(fwd_cmd->req_type));
499 : : }
500 : :
501 : : return;
502 : : }
503 : :
504 : 0 : int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp)
505 : : {
506 : : bool evt = 0;
507 : :
508 [ # # ]: 0 : if (bp == NULL || cmp == NULL) {
509 : 0 : PMD_DRV_LOG_LINE(ERR, "invalid NULL argument");
510 : 0 : return evt;
511 : : }
512 : :
513 [ # # ]: 0 : if (unlikely(is_bnxt_in_error(bp)))
514 : : return 0;
515 : :
516 [ # # # ]: 0 : switch (CMP_TYPE(cmp)) {
517 : 0 : case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
518 : : /* Handle any async event */
519 : 0 : bnxt_handle_async_event(bp, cmp);
520 : : evt = 1;
521 : 0 : break;
522 : 0 : case CMPL_BASE_TYPE_HWRM_FWD_REQ:
523 : : /* Handle HWRM forwarded responses */
524 : 0 : bnxt_handle_fwd_req(bp, cmp);
525 : : evt = 1;
526 : 0 : break;
527 : 0 : default:
528 : : /* Ignore any other events */
529 : 0 : PMD_DRV_LOG_LINE(DEBUG, "Ignoring %02x completion", CMP_TYPE(cmp));
530 : 0 : break;
531 : : }
532 : :
533 : 0 : return evt;
534 : : }
535 : :
536 : 0 : bool bnxt_is_primary_func(struct bnxt *bp)
537 : : {
538 [ # # ]: 0 : if (bp->recovery_info->flags & BNXT_FLAG_PRIMARY_FUNC)
539 : 0 : return true;
540 : :
541 : : return false;
542 : : }
543 : :
544 : 0 : bool bnxt_is_recovery_enabled(struct bnxt *bp)
545 : : {
546 : : struct bnxt_error_recovery_info *info;
547 : :
548 : 0 : info = bp->recovery_info;
549 [ # # # # ]: 0 : if (info && (info->flags & BNXT_FLAG_RECOVERY_ENABLED))
550 : 0 : return true;
551 : :
552 : : return false;
553 : : }
554 : :
555 : 0 : void bnxt_stop_rxtx(struct rte_eth_dev *eth_dev)
556 : : {
557 : 0 : eth_dev->rx_pkt_burst = rte_eth_pkt_burst_dummy;
558 : 0 : eth_dev->tx_pkt_burst = rte_eth_pkt_burst_dummy;
559 : :
560 : 0 : rte_eth_fp_ops[eth_dev->data->port_id].rx_pkt_burst =
561 : : eth_dev->rx_pkt_burst;
562 : 0 : rte_eth_fp_ops[eth_dev->data->port_id].tx_pkt_burst =
563 : : eth_dev->tx_pkt_burst;
564 : : rte_mb();
565 : :
566 : : /* Allow time for threads to exit the real burst functions. */
567 : : rte_delay_ms(100);
568 : 0 : }
|