1a551c94aSIdo Barnea/*-
2a551c94aSIdo Barnea * Copyright (c) 2007-2013 Broadcom Corporation.
3a551c94aSIdo Barnea *
4a551c94aSIdo Barnea * Eric Davis        <edavis@broadcom.com>
5a551c94aSIdo Barnea * David Christensen <davidch@broadcom.com>
6a551c94aSIdo Barnea * Gary Zambrano     <zambrano@broadcom.com>
7a551c94aSIdo Barnea *
8a551c94aSIdo Barnea * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
9a551c94aSIdo Barnea * Copyright (c) 2015 QLogic Corporation.
10a551c94aSIdo Barnea * All rights reserved.
11a551c94aSIdo Barnea * www.qlogic.com
12a551c94aSIdo Barnea *
13a551c94aSIdo Barnea * See LICENSE.bnx2x_pmd for copyright and licensing details.
14a551c94aSIdo Barnea */
15a551c94aSIdo Barnea
16a551c94aSIdo Barnea#define BNX2X_DRIVER_VERSION "1.78.18"
17a551c94aSIdo Barnea
18a551c94aSIdo Barnea#include "bnx2x.h"
19a551c94aSIdo Barnea#include "bnx2x_vfpf.h"
20a551c94aSIdo Barnea#include "ecore_sp.h"
21a551c94aSIdo Barnea#include "ecore_init.h"
22a551c94aSIdo Barnea#include "ecore_init_ops.h"
23a551c94aSIdo Barnea
24a551c94aSIdo Barnea#include "rte_version.h"
25a551c94aSIdo Barnea
26a551c94aSIdo Barnea#include <sys/types.h>
27a551c94aSIdo Barnea#include <sys/stat.h>
28a551c94aSIdo Barnea#include <fcntl.h>
29a551c94aSIdo Barnea#include <zlib.h>
30a551c94aSIdo Barnea
31a551c94aSIdo Barnea#define BNX2X_PMD_VER_PREFIX "BNX2X PMD"
32a551c94aSIdo Barnea#define BNX2X_PMD_VERSION_MAJOR 1
33a551c94aSIdo Barnea#define BNX2X_PMD_VERSION_MINOR 0
3493f15e30SIdo Barnea#define BNX2X_PMD_VERSION_REVISION 5
35a551c94aSIdo Barnea#define BNX2X_PMD_VERSION_PATCH 1
36a551c94aSIdo Barnea
37a551c94aSIdo Barneastatic inline const char *
38a551c94aSIdo Barneabnx2x_pmd_version(void)
39a551c94aSIdo Barnea{
40a551c94aSIdo Barnea	static char version[32];
41a551c94aSIdo Barnea
42a551c94aSIdo Barnea	snprintf(version, sizeof(version), "%s %s_%d.%d.%d.%d",
43a551c94aSIdo Barnea			BNX2X_PMD_VER_PREFIX,
44a551c94aSIdo Barnea			BNX2X_DRIVER_VERSION,
45a551c94aSIdo Barnea			BNX2X_PMD_VERSION_MAJOR,
46a551c94aSIdo Barnea			BNX2X_PMD_VERSION_MINOR,
47a551c94aSIdo Barnea			BNX2X_PMD_VERSION_REVISION,
48a551c94aSIdo Barnea			BNX2X_PMD_VERSION_PATCH);
49a551c94aSIdo Barnea
50a551c94aSIdo Barnea	return version;
51a551c94aSIdo Barnea}
52a551c94aSIdo Barnea
53a551c94aSIdo Barneastatic z_stream zlib_stream;
54a551c94aSIdo Barnea
55a551c94aSIdo Barnea#define EVL_VLID_MASK 0x0FFF
56a551c94aSIdo Barnea
57a551c94aSIdo Barnea#define BNX2X_DEF_SB_ATT_IDX 0x0001
58a551c94aSIdo Barnea#define BNX2X_DEF_SB_IDX     0x0002
59a551c94aSIdo Barnea
60a551c94aSIdo Barnea/*
61a551c94aSIdo Barnea * FLR Support - bnx2x_pf_flr_clnup() is called during nic_load in the per
62a551c94aSIdo Barnea * function HW initialization.
63a551c94aSIdo Barnea */
64a551c94aSIdo Barnea#define FLR_WAIT_USEC     10000	/* 10 msecs */
65a551c94aSIdo Barnea#define FLR_WAIT_INTERVAL 50	/* usecs */
66a551c94aSIdo Barnea#define FLR_POLL_CNT      (FLR_WAIT_USEC / FLR_WAIT_INTERVAL)	/* 200 */
67a551c94aSIdo Barnea
68a551c94aSIdo Barneastruct pbf_pN_buf_regs {
69a551c94aSIdo Barnea	int pN;
70a551c94aSIdo Barnea	uint32_t init_crd;
71a551c94aSIdo Barnea	uint32_t crd;
72a551c94aSIdo Barnea	uint32_t crd_freed;
73a551c94aSIdo Barnea};
74a551c94aSIdo Barnea
75a551c94aSIdo Barneastruct pbf_pN_cmd_regs {
76a551c94aSIdo Barnea	int pN;
77a551c94aSIdo Barnea	uint32_t lines_occup;
78a551c94aSIdo Barnea	uint32_t lines_freed;
79a551c94aSIdo Barnea};
80a551c94aSIdo Barnea
81a551c94aSIdo Barnea/* resources needed for unloading a previously loaded device */
82a551c94aSIdo Barnea
83a551c94aSIdo Barnea#define BNX2X_PREV_WAIT_NEEDED 1
84a551c94aSIdo Barnearte_spinlock_t bnx2x_prev_mtx;
85a551c94aSIdo Barneastruct bnx2x_prev_list_node {
86a551c94aSIdo Barnea	LIST_ENTRY(bnx2x_prev_list_node) node;
87a551c94aSIdo Barnea	uint8_t bus;
88a551c94aSIdo Barnea	uint8_t slot;
89a551c94aSIdo Barnea	uint8_t path;
90a551c94aSIdo Barnea	uint8_t aer;
91a551c94aSIdo Barnea	uint8_t undi;
92a551c94aSIdo Barnea};
93a551c94aSIdo Barnea
94a551c94aSIdo Barneastatic LIST_HEAD(, bnx2x_prev_list_node) bnx2x_prev_list
95a551c94aSIdo Barnea	= LIST_HEAD_INITIALIZER(bnx2x_prev_list);
96a551c94aSIdo Barnea
97a551c94aSIdo Barneastatic int load_count[2][3] = { { 0 } };
98a551c94aSIdo Barnea	/* per-path: 0-common, 1-port0, 2-port1 */
99a551c94aSIdo Barnea
100a551c94aSIdo Barneastatic void bnx2x_cmng_fns_init(struct bnx2x_softc *sc, uint8_t read_cfg,
101a551c94aSIdo Barnea				uint8_t cmng_type);
102a551c94aSIdo Barneastatic int bnx2x_get_cmng_fns_mode(struct bnx2x_softc *sc);
103a551c94aSIdo Barneastatic void storm_memset_cmng(struct bnx2x_softc *sc, struct cmng_init *cmng,
104a551c94aSIdo Barnea			      uint8_t port);
105a551c94aSIdo Barneastatic void bnx2x_set_reset_global(struct bnx2x_softc *sc);
106a551c94aSIdo Barneastatic void bnx2x_set_reset_in_progress(struct bnx2x_softc *sc);
107a551c94aSIdo Barneastatic uint8_t bnx2x_reset_is_done(struct bnx2x_softc *sc, int engine);
108a551c94aSIdo Barneastatic uint8_t bnx2x_clear_pf_load(struct bnx2x_softc *sc);
109a551c94aSIdo Barneastatic uint8_t bnx2x_chk_parity_attn(struct bnx2x_softc *sc, uint8_t * global,
110a551c94aSIdo Barnea				     uint8_t print);
111a551c94aSIdo Barneastatic void bnx2x_int_disable(struct bnx2x_softc *sc);
112a551c94aSIdo Barneastatic int bnx2x_release_leader_lock(struct bnx2x_softc *sc);
113a551c94aSIdo Barneastatic void bnx2x_pf_disable(struct bnx2x_softc *sc);
114a551c94aSIdo Barneastatic void bnx2x_update_rx_prod(struct bnx2x_softc *sc,
115a551c94aSIdo Barnea				 struct bnx2x_fastpath *fp,
116a551c94aSIdo Barnea				 uint16_t rx_bd_prod, uint16_t rx_cq_prod);
117a551c94aSIdo Barneastatic void bnx2x_link_report(struct bnx2x_softc *sc);
118a551c94aSIdo Barneavoid bnx2x_link_status_update(struct bnx2x_softc *sc);
119a551c94aSIdo Barneastatic int bnx2x_alloc_mem(struct bnx2x_softc *sc);
120a551c94aSIdo Barneastatic void bnx2x_free_mem(struct bnx2x_softc *sc);
121a551c94aSIdo Barneastatic int bnx2x_alloc_fw_stats_mem(struct bnx2x_softc *sc);
122a551c94aSIdo Barneastatic void bnx2x_free_fw_stats_mem(struct bnx2x_softc *sc);
123a551c94aSIdo Barneastatic __attribute__ ((noinline))
124a551c94aSIdo Barneaint bnx2x_nic_load(struct bnx2x_softc *sc);
125a551c94aSIdo Barnea
126a551c94aSIdo Barneastatic int bnx2x_handle_sp_tq(struct bnx2x_softc *sc);
127a551c94aSIdo Barneastatic void bnx2x_handle_fp_tq(struct bnx2x_fastpath *fp, int scan_fp);
128a551c94aSIdo Barneastatic void bnx2x_periodic_stop(struct bnx2x_softc *sc);
129a551c94aSIdo Barneastatic void bnx2x_ack_sb(struct bnx2x_softc *sc, uint8_t igu_sb_id,
130a551c94aSIdo Barnea			 uint8_t storm, uint16_t index, uint8_t op,
131a551c94aSIdo Barnea			 uint8_t update);
132a551c94aSIdo Barnea
133a551c94aSIdo Barneaint bnx2x_test_bit(int nr, volatile unsigned long *addr)
134a551c94aSIdo Barnea{
135a551c94aSIdo Barnea	int res;
136a551c94aSIdo Barnea
137a551c94aSIdo Barnea	mb();
138a551c94aSIdo Barnea	res = ((*addr) & (1UL << nr)) != 0;
139a551c94aSIdo Barnea	mb();
140a551c94aSIdo Barnea	return res;
141a551c94aSIdo Barnea}
142a551c94aSIdo Barnea
143a551c94aSIdo Barneavoid bnx2x_set_bit(unsigned int nr, volatile unsigned long *addr)
144a551c94aSIdo Barnea{
145a551c94aSIdo Barnea	__sync_fetch_and_or(addr, (1UL << nr));
146a551c94aSIdo Barnea}
147a551c94aSIdo Barnea
148a551c94aSIdo Barneavoid bnx2x_clear_bit(int nr, volatile unsigned long *addr)
149a551c94aSIdo Barnea{
150a551c94aSIdo Barnea	__sync_fetch_and_and(addr, ~(1UL << nr));
151a551c94aSIdo Barnea}
152a551c94aSIdo Barnea
153a551c94aSIdo Barneaint bnx2x_test_and_clear_bit(int nr, volatile unsigned long *addr)
154a551c94aSIdo Barnea{
155a551c94aSIdo Barnea	unsigned long mask = (1UL << nr);
156a551c94aSIdo Barnea	return __sync_fetch_and_and(addr, ~mask) & mask;
157a551c94aSIdo Barnea}
158a551c94aSIdo Barnea
159a551c94aSIdo Barneaint bnx2x_cmpxchg(volatile int *addr, int old, int new)
160a551c94aSIdo Barnea{
161a551c94aSIdo Barnea	return __sync_val_compare_and_swap(addr, old, new);
162a551c94aSIdo Barnea}
163a551c94aSIdo Barnea
164a551c94aSIdo Barneaint
165a551c94aSIdo Barneabnx2x_dma_alloc(struct bnx2x_softc *sc, size_t size, struct bnx2x_dma *dma,
166a551c94aSIdo Barnea	      const char *msg, uint32_t align)
167a551c94aSIdo Barnea{
168a551c94aSIdo Barnea	char mz_name[RTE_MEMZONE_NAMESIZE];
169a551c94aSIdo Barnea	const struct rte_memzone *z;
170a551c94aSIdo Barnea
171a551c94aSIdo Barnea	dma->sc = sc;
172a551c94aSIdo Barnea	if (IS_PF(sc))
173a551c94aSIdo Barnea		sprintf(mz_name, "bnx2x%d_%s_%" PRIx64, SC_ABS_FUNC(sc), msg,
174a551c94aSIdo Barnea			rte_get_timer_cycles());
175a551c94aSIdo Barnea	else
176a551c94aSIdo Barnea		sprintf(mz_name, "bnx2x%d_%s_%" PRIx64, sc->pcie_device, msg,
177a551c94aSIdo Barnea			rte_get_timer_cycles());
178a551c94aSIdo Barnea
179a551c94aSIdo Barnea	/* Caller must take care that strlen(mz_name) < RTE_MEMZONE_NAMESIZE */
180a551c94aSIdo Barnea	z = rte_memzone_reserve_aligned(mz_name, (uint64_t) (size),
1819ca4a157SIdo Barnea					SOCKET_ID_ANY,
182a551c94aSIdo Barnea					0, align);
183a551c94aSIdo Barnea	if (z == NULL) {
184a551c94aSIdo Barnea		PMD_DRV_LOG(ERR, "DMA alloc failed for %s", msg);
185a551c94aSIdo Barnea		return -ENOMEM;
186a551c94aSIdo Barnea	}
187a551c94aSIdo Barnea	dma->paddr = (uint64_t) z->phys_addr;
188a551c94aSIdo Barnea	dma->vaddr = z->addr;
189a551c94aSIdo Barnea
190a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG, "%s: virt=%p phys=%" PRIx64, msg, dma->vaddr, dma->paddr);
191a551c94aSIdo Barnea
192a551c94aSIdo Barnea	return 0;
193a551c94aSIdo Barnea}
194a551c94aSIdo Barnea
195a551c94aSIdo Barneastatic int bnx2x_acquire_hw_lock(struct bnx2x_softc *sc, uint32_t resource)
196a551c94aSIdo Barnea{
197a551c94aSIdo Barnea	uint32_t lock_status;
198a551c94aSIdo Barnea	uint32_t resource_bit = (1 << resource);
199a551c94aSIdo Barnea	int func = SC_FUNC(sc);
200a551c94aSIdo Barnea	uint32_t hw_lock_control_reg;
201a551c94aSIdo Barnea	int cnt;
202a551c94aSIdo Barnea
203a551c94aSIdo Barnea	PMD_INIT_FUNC_TRACE();
204a551c94aSIdo Barnea
205a551c94aSIdo Barnea	/* validate the resource is within range */
206a551c94aSIdo Barnea	if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
207a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE,
208a551c94aSIdo Barnea			    "resource 0x%x > HW_LOCK_MAX_RESOURCE_VALUE",
209a551c94aSIdo Barnea			    resource);
210a551c94aSIdo Barnea		return -1;
211a551c94aSIdo Barnea	}
212a551c94aSIdo Barnea
213a551c94aSIdo Barnea	if (func <= 5) {
214a551c94aSIdo Barnea		hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + (func * 8));
215a551c94aSIdo Barnea	} else {
216a551c94aSIdo Barnea		hw_lock_control_reg =
217a551c94aSIdo Barnea		    (MISC_REG_DRIVER_CONTROL_7 + ((func - 6) * 8));
218a551c94aSIdo Barnea	}
219a551c94aSIdo Barnea
220a551c94aSIdo Barnea	/* validate the resource is not already taken */
221a551c94aSIdo Barnea	lock_status = REG_RD(sc, hw_lock_control_reg);
222a551c94aSIdo Barnea	if (lock_status & resource_bit) {
223a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE,
224a551c94aSIdo Barnea			    "resource in use (status 0x%x bit 0x%x)",
225a551c94aSIdo Barnea			    lock_status, resource_bit);
226a551c94aSIdo Barnea		return -1;
227a551c94aSIdo Barnea	}
228a551c94aSIdo Barnea
229a551c94aSIdo Barnea	/* try every 5ms for 5 seconds */
230a551c94aSIdo Barnea	for (cnt = 0; cnt < 1000; cnt++) {
231a551c94aSIdo Barnea		REG_WR(sc, (hw_lock_control_reg + 4), resource_bit);
232a551c94aSIdo Barnea		lock_status = REG_RD(sc, hw_lock_control_reg);
233a551c94aSIdo Barnea		if (lock_status & resource_bit) {
234a551c94aSIdo Barnea			return 0;
235a551c94aSIdo Barnea		}
236a551c94aSIdo Barnea		DELAY(5000);
237a551c94aSIdo Barnea	}
238a551c94aSIdo Barnea
239a551c94aSIdo Barnea	PMD_DRV_LOG(NOTICE, "Resource lock timeout!");
240a551c94aSIdo Barnea	return -1;
241a551c94aSIdo Barnea}
242a551c94aSIdo Barnea
243a551c94aSIdo Barneastatic int bnx2x_release_hw_lock(struct bnx2x_softc *sc, uint32_t resource)
244a551c94aSIdo Barnea{
245a551c94aSIdo Barnea	uint32_t lock_status;
246a551c94aSIdo Barnea	uint32_t resource_bit = (1 << resource);
247a551c94aSIdo Barnea	int func = SC_FUNC(sc);
248a551c94aSIdo Barnea	uint32_t hw_lock_control_reg;
249a551c94aSIdo Barnea
250a551c94aSIdo Barnea	PMD_INIT_FUNC_TRACE();
251a551c94aSIdo Barnea
252a551c94aSIdo Barnea	/* validate the resource is within range */
253a551c94aSIdo Barnea	if (resource > HW_LOCK_MAX_RESOURCE_VALUE) {
254a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE,
255a551c94aSIdo Barnea			    "resource 0x%x > HW_LOCK_MAX_RESOURCE_VALUE",
256a551c94aSIdo Barnea			    resource);
257a551c94aSIdo Barnea		return -1;
258a551c94aSIdo Barnea	}
259a551c94aSIdo Barnea
260a551c94aSIdo Barnea	if (func <= 5) {
261a551c94aSIdo Barnea		hw_lock_control_reg = (MISC_REG_DRIVER_CONTROL_1 + (func * 8));
262a551c94aSIdo Barnea	} else {
263a551c94aSIdo Barnea		hw_lock_control_reg =
264a551c94aSIdo Barnea		    (MISC_REG_DRIVER_CONTROL_7 + ((func - 6) * 8));
265a551c94aSIdo Barnea	}
266a551c94aSIdo Barnea
267a551c94aSIdo Barnea	/* validate the resource is currently taken */
268a551c94aSIdo Barnea	lock_status = REG_RD(sc, hw_lock_control_reg);
269a551c94aSIdo Barnea	if (!(lock_status & resource_bit)) {
270a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE,
271a551c94aSIdo Barnea			    "resource not in use (status 0x%x bit 0x%x)",
272a551c94aSIdo Barnea			    lock_status, resource_bit);
273a551c94aSIdo Barnea		return -1;
274a551c94aSIdo Barnea	}
275a551c94aSIdo Barnea
276a551c94aSIdo Barnea	REG_WR(sc, hw_lock_control_reg, resource_bit);
277a551c94aSIdo Barnea	return 0;
278a551c94aSIdo Barnea}
279a551c94aSIdo Barnea
280a551c94aSIdo Barnea/* copy command into DMAE command memory and set DMAE command Go */
281a551c94aSIdo Barneavoid bnx2x_post_dmae(struct bnx2x_softc *sc, struct dmae_command *dmae, int idx)
282a551c94aSIdo Barnea{
283a551c94aSIdo Barnea	uint32_t cmd_offset;
284a551c94aSIdo Barnea	uint32_t i;
285a551c94aSIdo Barnea
286a551c94aSIdo Barnea	cmd_offset = (DMAE_REG_CMD_MEM + (sizeof(struct dmae_command) * idx));
287a551c94aSIdo Barnea	for (i = 0; i < ((sizeof(struct dmae_command) / 4)); i++) {
288a551c94aSIdo Barnea		REG_WR(sc, (cmd_offset + (i * 4)), *(((uint32_t *) dmae) + i));
289a551c94aSIdo Barnea	}
290a551c94aSIdo Barnea
291a551c94aSIdo Barnea	REG_WR(sc, dmae_reg_go_c[idx], 1);
292a551c94aSIdo Barnea}
293a551c94aSIdo Barnea
294a551c94aSIdo Barneauint32_t bnx2x_dmae_opcode_add_comp(uint32_t opcode, uint8_t comp_type)
295a551c94aSIdo Barnea{
296a551c94aSIdo Barnea	return opcode | ((comp_type << DMAE_COMMAND_C_DST_SHIFT) |
297a551c94aSIdo Barnea			  DMAE_COMMAND_C_TYPE_ENABLE);
298a551c94aSIdo Barnea}
299a551c94aSIdo Barnea
300a551c94aSIdo Barneauint32_t bnx2x_dmae_opcode_clr_src_reset(uint32_t opcode)
301a551c94aSIdo Barnea{
302a551c94aSIdo Barnea	return opcode & ~DMAE_COMMAND_SRC_RESET;
303a551c94aSIdo Barnea}
304a551c94aSIdo Barnea
305a551c94aSIdo Barneauint32_t
306a551c94aSIdo Barneabnx2x_dmae_opcode(struct bnx2x_softc * sc, uint8_t src_type, uint8_t dst_type,
307a551c94aSIdo Barnea		uint8_t with_comp, uint8_t comp_type)
308a551c94aSIdo Barnea{
309a551c94aSIdo Barnea	uint32_t opcode = 0;
310a551c94aSIdo Barnea
311a551c94aSIdo Barnea	opcode |= ((src_type << DMAE_COMMAND_SRC_SHIFT) |
312a551c94aSIdo Barnea		   (dst_type << DMAE_COMMAND_DST_SHIFT));
313a551c94aSIdo Barnea
314a551c94aSIdo Barnea	opcode |= (DMAE_COMMAND_SRC_RESET | DMAE_COMMAND_DST_RESET);
315a551c94aSIdo Barnea
316a551c94aSIdo Barnea	opcode |= (SC_PORT(sc) ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0);
317a551c94aSIdo Barnea
318a551c94aSIdo Barnea	opcode |= ((SC_VN(sc) << DMAE_COMMAND_E1HVN_SHIFT) |
319a551c94aSIdo Barnea		   (SC_VN(sc) << DMAE_COMMAND_DST_VN_SHIFT));
320a551c94aSIdo Barnea
321a551c94aSIdo Barnea	opcode |= (DMAE_COM_SET_ERR << DMAE_COMMAND_ERR_POLICY_SHIFT);
322a551c94aSIdo Barnea
323a551c94aSIdo Barnea#ifdef __BIG_ENDIAN
324a551c94aSIdo Barnea	opcode |= DMAE_CMD_ENDIANITY_B_DW_SWAP;
325a551c94aSIdo Barnea#else
326a551c94aSIdo Barnea	opcode |= DMAE_CMD_ENDIANITY_DW_SWAP;
327a551c94aSIdo Barnea#endif
328a551c94aSIdo Barnea
329a551c94aSIdo Barnea	if (with_comp) {
330a551c94aSIdo Barnea		opcode = bnx2x_dmae_opcode_add_comp(opcode, comp_type);
331a551c94aSIdo Barnea	}
332a551c94aSIdo Barnea
333a551c94aSIdo Barnea	return opcode;
334a551c94aSIdo Barnea}
335a551c94aSIdo Barnea
336a551c94aSIdo Barneastatic void
337a551c94aSIdo Barneabnx2x_prep_dmae_with_comp(struct bnx2x_softc *sc, struct dmae_command *dmae,
338a551c94aSIdo Barnea			uint8_t src_type, uint8_t dst_type)
339a551c94aSIdo Barnea{
340a551c94aSIdo Barnea	memset(dmae, 0, sizeof(struct dmae_command));
341a551c94aSIdo Barnea
342a551c94aSIdo Barnea	/* set the opcode */
343a551c94aSIdo Barnea	dmae->opcode = bnx2x_dmae_opcode(sc, src_type, dst_type,
344a551c94aSIdo Barnea				       TRUE, DMAE_COMP_PCI);
345a551c94aSIdo Barnea
346a551c94aSIdo Barnea	/* fill in the completion parameters */
347a551c94aSIdo Barnea	dmae->comp_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, wb_comp));
348a551c94aSIdo Barnea	dmae->comp_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, wb_comp));
349a551c94aSIdo Barnea	dmae->comp_val = DMAE_COMP_VAL;
350a551c94aSIdo Barnea}
351a551c94aSIdo Barnea
352a551c94aSIdo Barnea/* issue a DMAE command over the init channel and wait for completion */
353a551c94aSIdo Barneastatic int
354a551c94aSIdo Barneabnx2x_issue_dmae_with_comp(struct bnx2x_softc *sc, struct dmae_command *dmae)
355a551c94aSIdo Barnea{
356a551c94aSIdo Barnea	uint32_t *wb_comp = BNX2X_SP(sc, wb_comp);
357a551c94aSIdo Barnea	int timeout = CHIP_REV_IS_SLOW(sc) ? 400000 : 4000;
358a551c94aSIdo Barnea
359a551c94aSIdo Barnea	/* reset completion */
360a551c94aSIdo Barnea	*wb_comp = 0;
361a551c94aSIdo Barnea
362a551c94aSIdo Barnea	/* post the command on the channel used for initializations */
363a551c94aSIdo Barnea	bnx2x_post_dmae(sc, dmae, INIT_DMAE_C(sc));
364a551c94aSIdo Barnea
365a551c94aSIdo Barnea	/* wait for completion */
366a551c94aSIdo Barnea	DELAY(500);
367a551c94aSIdo Barnea
368a551c94aSIdo Barnea	while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) {
369a551c94aSIdo Barnea		if (!timeout ||
370a551c94aSIdo Barnea		    (sc->recovery_state != BNX2X_RECOVERY_DONE &&
371a551c94aSIdo Barnea		     sc->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) {
372a551c94aSIdo Barnea			PMD_DRV_LOG(INFO, "DMAE timeout!");
373a551c94aSIdo Barnea			return DMAE_TIMEOUT;
374a551c94aSIdo Barnea		}
375a551c94aSIdo Barnea
376a551c94aSIdo Barnea		timeout--;
377a551c94aSIdo Barnea		DELAY(50);
378a551c94aSIdo Barnea	}
379a551c94aSIdo Barnea
380a551c94aSIdo Barnea	if (*wb_comp & DMAE_PCI_ERR_FLAG) {
381a551c94aSIdo Barnea		PMD_DRV_LOG(INFO, "DMAE PCI error!");
382a551c94aSIdo Barnea		return DMAE_PCI_ERROR;
383a551c94aSIdo Barnea	}
384a551c94aSIdo Barnea
385a551c94aSIdo Barnea	return 0;
386a551c94aSIdo Barnea}
387a551c94aSIdo Barnea
388a551c94aSIdo Barneavoid bnx2x_read_dmae(struct bnx2x_softc *sc, uint32_t src_addr, uint32_t len32)
389a551c94aSIdo Barnea{
390a551c94aSIdo Barnea	struct dmae_command dmae;
391a551c94aSIdo Barnea	uint32_t *data;
392a551c94aSIdo Barnea	uint32_t i;
393a551c94aSIdo Barnea	int rc;
394a551c94aSIdo Barnea
395a551c94aSIdo Barnea	if (!sc->dmae_ready) {
396a551c94aSIdo Barnea		data = BNX2X_SP(sc, wb_data[0]);
397a551c94aSIdo Barnea
398a551c94aSIdo Barnea		for (i = 0; i < len32; i++) {
399a551c94aSIdo Barnea			data[i] = REG_RD(sc, (src_addr + (i * 4)));
400a551c94aSIdo Barnea		}
401a551c94aSIdo Barnea
402a551c94aSIdo Barnea		return;
403a551c94aSIdo Barnea	}
404a551c94aSIdo Barnea
405a551c94aSIdo Barnea	/* set opcode and fixed command fields */
406a551c94aSIdo Barnea	bnx2x_prep_dmae_with_comp(sc, &dmae, DMAE_SRC_GRC, DMAE_DST_PCI);
407a551c94aSIdo Barnea
408a551c94aSIdo Barnea	/* fill in addresses and len */
409a551c94aSIdo Barnea	dmae.src_addr_lo = (src_addr >> 2);	/* GRC addr has dword resolution */
410a551c94aSIdo Barnea	dmae.src_addr_hi = 0;
411a551c94aSIdo Barnea	dmae.dst_addr_lo = U64_LO(BNX2X_SP_MAPPING(sc, wb_data));
412a551c94aSIdo Barnea	dmae.dst_addr_hi = U64_HI(BNX2X_SP_MAPPING(sc, wb_data));
413a551c94aSIdo Barnea	dmae.len = len32;
414a551c94aSIdo Barnea
415a551c94aSIdo Barnea	/* issue the command and wait for completion */
416a551c94aSIdo Barnea	if ((rc = bnx2x_issue_dmae_with_comp(sc, &dmae)) != 0) {
417a551c94aSIdo Barnea		rte_panic("DMAE failed (%d)", rc);
418a551c94aSIdo Barnea	};
419a551c94aSIdo Barnea}
420a551c94aSIdo Barnea
421a551c94aSIdo Barneavoid
422a551c94aSIdo Barneabnx2x_write_dmae(struct bnx2x_softc *sc, phys_addr_t dma_addr, uint32_t dst_addr,
423a551c94aSIdo Barnea	       uint32_t len32)
424a551c94aSIdo Barnea{
425a551c94aSIdo Barnea	struct dmae_command dmae;
426a551c94aSIdo Barnea	int rc;
427a551c94aSIdo Barnea
428a551c94aSIdo Barnea	if (!sc->dmae_ready) {
429a551c94aSIdo Barnea		ecore_init_str_wr(sc, dst_addr, BNX2X_SP(sc, wb_data[0]), len32);
430a551c94aSIdo Barnea		return;
431a551c94aSIdo Barnea	}
432a551c94aSIdo Barnea
433a551c94aSIdo Barnea	/* set opcode and fixed command fields */
434a551c94aSIdo Barnea	bnx2x_prep_dmae_with_comp(sc, &dmae, DMAE_SRC_PCI, DMAE_DST_GRC);
435a551c94aSIdo Barnea
436a551c94aSIdo Barnea	/* fill in addresses and len */
437a551c94aSIdo Barnea	dmae.src_addr_lo = U64_LO(dma_addr);
438a551c94aSIdo Barnea	dmae.src_addr_hi = U64_HI(dma_addr);
439a551c94aSIdo Barnea	dmae.dst_addr_lo = (dst_addr >> 2);	/* GRC addr has dword resolution */
440a551c94aSIdo Barnea	dmae.dst_addr_hi = 0;
441a551c94aSIdo Barnea	dmae.len = len32;
442a551c94aSIdo Barnea
443a551c94aSIdo Barnea	/* issue the command and wait for completion */
444a551c94aSIdo Barnea	if ((rc = bnx2x_issue_dmae_with_comp(sc, &dmae)) != 0) {
445a551c94aSIdo Barnea		rte_panic("DMAE failed (%d)", rc);
446a551c94aSIdo Barnea	}
447a551c94aSIdo Barnea}
448a551c94aSIdo Barnea
449a551c94aSIdo Barneastatic void
450a551c94aSIdo Barneabnx2x_write_dmae_phys_len(struct bnx2x_softc *sc, phys_addr_t phys_addr,
451a551c94aSIdo Barnea			uint32_t addr, uint32_t len)
452a551c94aSIdo Barnea{
453a551c94aSIdo Barnea	uint32_t dmae_wr_max = DMAE_LEN32_WR_MAX(sc);
454a551c94aSIdo Barnea	uint32_t offset = 0;
455a551c94aSIdo Barnea
456a551c94aSIdo Barnea	while (len > dmae_wr_max) {
457a551c94aSIdo Barnea		bnx2x_write_dmae(sc, (phys_addr + offset),	/* src DMA address */
458a551c94aSIdo Barnea			       (addr + offset),	/* dst GRC address */
459a551c94aSIdo Barnea			       dmae_wr_max);
460a551c94aSIdo Barnea		offset += (dmae_wr_max * 4);
461a551c94aSIdo Barnea		len -= dmae_wr_max;
462a551c94aSIdo Barnea	}
463a551c94aSIdo Barnea
464a551c94aSIdo Barnea	bnx2x_write_dmae(sc, (phys_addr + offset),	/* src DMA address */
465a551c94aSIdo Barnea		       (addr + offset),	/* dst GRC address */
466a551c94aSIdo Barnea		       len);
467a551c94aSIdo Barnea}
468a551c94aSIdo Barnea
469a551c94aSIdo Barneavoid
470a551c94aSIdo Barneabnx2x_set_ctx_validation(struct bnx2x_softc *sc, struct eth_context *cxt,
471a551c94aSIdo Barnea		       uint32_t cid)
472a551c94aSIdo Barnea{
473a551c94aSIdo Barnea	/* ustorm cxt validation */
474a551c94aSIdo Barnea	cxt->ustorm_ag_context.cdu_usage =
475a551c94aSIdo Barnea	    CDU_RSRVD_VALUE_TYPE_A(HW_CID(sc, cid),
476a551c94aSIdo Barnea				   CDU_REGION_NUMBER_UCM_AG,
477a551c94aSIdo Barnea				   ETH_CONNECTION_TYPE);
478a551c94aSIdo Barnea	/* xcontext validation */
479a551c94aSIdo Barnea	cxt->xstorm_ag_context.cdu_reserved =
480a551c94aSIdo Barnea	    CDU_RSRVD_VALUE_TYPE_A(HW_CID(sc, cid),
481a551c94aSIdo Barnea				   CDU_REGION_NUMBER_XCM_AG,
482a551c94aSIdo Barnea				   ETH_CONNECTION_TYPE);
483a551c94aSIdo Barnea}
484a551c94aSIdo Barnea
485a551c94aSIdo Barneastatic void
486a551c94aSIdo Barneabnx2x_storm_memset_hc_timeout(struct bnx2x_softc *sc, uint8_t fw_sb_id,
487a551c94aSIdo Barnea			    uint8_t sb_index, uint8_t ticks)
488a551c94aSIdo Barnea{
489a551c94aSIdo Barnea	uint32_t addr =
490a551c94aSIdo Barnea	    (BAR_CSTRORM_INTMEM +
491a551c94aSIdo Barnea	     CSTORM_STATUS_BLOCK_DATA_TIMEOUT_OFFSET(fw_sb_id, sb_index));
492a551c94aSIdo Barnea
493a551c94aSIdo Barnea	REG_WR8(sc, addr, ticks);
494a551c94aSIdo Barnea}
495a551c94aSIdo Barnea
496a551c94aSIdo Barneastatic void
497a551c94aSIdo Barneabnx2x_storm_memset_hc_disable(struct bnx2x_softc *sc, uint16_t fw_sb_id,
498a551c94aSIdo Barnea			    uint8_t sb_index, uint8_t disable)
499a551c94aSIdo Barnea{
500a551c94aSIdo Barnea	uint32_t enable_flag =
501a551c94aSIdo Barnea	    (disable) ? 0 : (1 << HC_INDEX_DATA_HC_ENABLED_SHIFT);
502a551c94aSIdo Barnea	uint32_t addr =
503a551c94aSIdo Barnea	    (BAR_CSTRORM_INTMEM +
504a551c94aSIdo Barnea	     CSTORM_STATUS_BLOCK_DATA_FLAGS_OFFSET(fw_sb_id, sb_index));
505a551c94aSIdo Barnea	uint8_t flags;
506a551c94aSIdo Barnea
507a551c94aSIdo Barnea	/* clear and set */
508a551c94aSIdo Barnea	flags = REG_RD8(sc, addr);
509a551c94aSIdo Barnea	flags &= ~HC_INDEX_DATA_HC_ENABLED;
510a551c94aSIdo Barnea	flags |= enable_flag;
511a551c94aSIdo Barnea	REG_WR8(sc, addr, flags);
512a551c94aSIdo Barnea}
513a551c94aSIdo Barnea
514a551c94aSIdo Barneavoid
515a551c94aSIdo Barneabnx2x_update_coalesce_sb_index(struct bnx2x_softc *sc, uint8_t fw_sb_id,
516a551c94aSIdo Barnea			     uint8_t sb_index, uint8_t disable, uint16_t usec)
517a551c94aSIdo Barnea{
518a551c94aSIdo Barnea	uint8_t ticks = (usec / 4);
519a551c94aSIdo Barnea
520a551c94aSIdo Barnea	bnx2x_storm_memset_hc_timeout(sc, fw_sb_id, sb_index, ticks);
521a551c94aSIdo Barnea
522a551c94aSIdo Barnea	disable = (disable) ? 1 : ((usec) ? 0 : 1);
523a551c94aSIdo Barnea	bnx2x_storm_memset_hc_disable(sc, fw_sb_id, sb_index, disable);
524a551c94aSIdo Barnea}
525a551c94aSIdo Barnea
526a551c94aSIdo Barneauint32_t elink_cb_reg_read(struct bnx2x_softc *sc, uint32_t reg_addr)
527a551c94aSIdo Barnea{
528a551c94aSIdo Barnea	return REG_RD(sc, reg_addr);
529a551c94aSIdo Barnea}
530a551c94aSIdo Barnea
531a551c94aSIdo Barneavoid elink_cb_reg_write(struct bnx2x_softc *sc, uint32_t reg_addr, uint32_t val)
532a551c94aSIdo Barnea{
533a551c94aSIdo Barnea	REG_WR(sc, reg_addr, val);
534a551c94aSIdo Barnea}
535a551c94aSIdo Barnea
536a551c94aSIdo Barneavoid
537a551c94aSIdo Barneaelink_cb_event_log(__rte_unused struct bnx2x_softc *sc,
538a551c94aSIdo Barnea		   __rte_unused const elink_log_id_t elink_log_id, ...)
539a551c94aSIdo Barnea{
540a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG, "ELINK EVENT LOG (%d)", elink_log_id);
541a551c94aSIdo Barnea}
542a551c94aSIdo Barnea
543a551c94aSIdo Barneastatic int bnx2x_set_spio(struct bnx2x_softc *sc, int spio, uint32_t mode)
544a551c94aSIdo Barnea{
545a551c94aSIdo Barnea	uint32_t spio_reg;
546a551c94aSIdo Barnea
547a551c94aSIdo Barnea	/* Only 2 SPIOs are configurable */
548a551c94aSIdo Barnea	if ((spio != MISC_SPIO_SPIO4) && (spio != MISC_SPIO_SPIO5)) {
549a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "Invalid SPIO 0x%x", spio);
550a551c94aSIdo Barnea		return -1;
551a551c94aSIdo Barnea	}
552a551c94aSIdo Barnea
553a551c94aSIdo Barnea	bnx2x_acquire_hw_lock(sc, HW_LOCK_RESOURCE_SPIO);
554a551c94aSIdo Barnea
555a551c94aSIdo Barnea	/* read SPIO and mask except the float bits */
556a551c94aSIdo Barnea	spio_reg = (REG_RD(sc, MISC_REG_SPIO) & MISC_SPIO_FLOAT);
557a551c94aSIdo Barnea
558a551c94aSIdo Barnea	switch (mode) {
559a551c94aSIdo Barnea	case MISC_SPIO_OUTPUT_LOW:
560a551c94aSIdo Barnea		/* clear FLOAT and set CLR */
561a551c94aSIdo Barnea		spio_reg &= ~(spio << MISC_SPIO_FLOAT_POS);
562a551c94aSIdo Barnea		spio_reg |= (spio << MISC_SPIO_CLR_POS);
563a551c94aSIdo Barnea		break;
564a551c94aSIdo Barnea
565a551c94aSIdo Barnea	case MISC_SPIO_OUTPUT_HIGH:
566a551c94aSIdo Barnea		/* clear FLOAT and set SET */
567a551c94aSIdo Barnea		spio_reg &= ~(spio << MISC_SPIO_FLOAT_POS);
568a551c94aSIdo Barnea		spio_reg |= (spio << MISC_SPIO_SET_POS);
569a551c94aSIdo Barnea		break;
570a551c94aSIdo Barnea
571a551c94aSIdo Barnea	case MISC_SPIO_INPUT_HI_Z:
572a551c94aSIdo Barnea		/* set FLOAT */
573a551c94aSIdo Barnea		spio_reg |= (spio << MISC_SPIO_FLOAT_POS);
574a551c94aSIdo Barnea		break;
575a551c94aSIdo Barnea
576a551c94aSIdo Barnea	default:
577a551c94aSIdo Barnea		break;
578a551c94aSIdo Barnea	}
579a551c94aSIdo Barnea
580a551c94aSIdo Barnea	REG_WR(sc, MISC_REG_SPIO, spio_reg);
581a551c94aSIdo Barnea	bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_SPIO);
582a551c94aSIdo Barnea
583a551c94aSIdo Barnea	return 0;
584a551c94aSIdo Barnea}
585a551c94aSIdo Barnea
586a551c94aSIdo Barneastatic int bnx2x_gpio_read(struct bnx2x_softc *sc, int gpio_num, uint8_t port)
587a551c94aSIdo Barnea{
588a551c94aSIdo Barnea	/* The GPIO should be swapped if swap register is set and active */
589a551c94aSIdo Barnea	int gpio_port = ((REG_RD(sc, NIG_REG_PORT_SWAP) &&
590a551c94aSIdo Barnea			  REG_RD(sc, NIG_REG_STRAP_OVERRIDE)) ^ port);
591a551c94aSIdo Barnea	int gpio_shift = gpio_num;
592a551c94aSIdo Barnea	if (gpio_port)
593a551c94aSIdo Barnea		gpio_shift += MISC_REGISTERS_GPIO_PORT_SHIFT;
594a551c94aSIdo Barnea
595a551c94aSIdo Barnea	uint32_t gpio_mask = (1 << gpio_shift);
596a551c94aSIdo Barnea	uint32_t gpio_reg;
597a551c94aSIdo Barnea
598a551c94aSIdo Barnea	if (gpio_num > MISC_REGISTERS_GPIO_3) {
599a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "Invalid GPIO %d", gpio_num);
600a551c94aSIdo Barnea		return -1;
601a551c94aSIdo Barnea	}
602a551c94aSIdo Barnea
603a551c94aSIdo Barnea	/* read GPIO value */
604a551c94aSIdo Barnea	gpio_reg = REG_RD(sc, MISC_REG_GPIO);
605a551c94aSIdo Barnea
606a551c94aSIdo Barnea	/* get the requested pin value */
607a551c94aSIdo Barnea	return ((gpio_reg & gpio_mask) == gpio_mask) ? 1 : 0;
608a551c94aSIdo Barnea}
609a551c94aSIdo Barnea
610a551c94aSIdo Barneastatic int
611a551c94aSIdo Barneabnx2x_gpio_write(struct bnx2x_softc *sc, int gpio_num, uint32_t mode, uint8_t port)
612a551c94aSIdo Barnea{
613a551c94aSIdo Barnea	/* The GPIO should be swapped if swap register is set and active */
614a551c94aSIdo Barnea	int gpio_port = ((REG_RD(sc, NIG_REG_PORT_SWAP) &&
615a551c94aSIdo Barnea			  REG_RD(sc, NIG_REG_STRAP_OVERRIDE)) ^ port);
616a551c94aSIdo Barnea	int gpio_shift = gpio_num;
617a551c94aSIdo Barnea	if (gpio_port)
618a551c94aSIdo Barnea		gpio_shift += MISC_REGISTERS_GPIO_PORT_SHIFT;
619a551c94aSIdo Barnea
620a551c94aSIdo Barnea	uint32_t gpio_mask = (1 << gpio_shift);
621a551c94aSIdo Barnea	uint32_t gpio_reg;
622a551c94aSIdo Barnea
623a551c94aSIdo Barnea	if (gpio_num > MISC_REGISTERS_GPIO_3) {
624a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "Invalid GPIO %d", gpio_num);
625a551c94aSIdo Barnea		return -1;
626a551c94aSIdo Barnea	}
627a551c94aSIdo Barnea
628a551c94aSIdo Barnea	bnx2x_acquire_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
629a551c94aSIdo Barnea
630a551c94aSIdo Barnea	/* read GPIO and mask except the float bits */
631a551c94aSIdo Barnea	gpio_reg = (REG_RD(sc, MISC_REG_GPIO) & MISC_REGISTERS_GPIO_FLOAT);
632a551c94aSIdo Barnea
633a551c94aSIdo Barnea	switch (mode) {
634a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_OUTPUT_LOW:
635a551c94aSIdo Barnea		/* clear FLOAT and set CLR */
636a551c94aSIdo Barnea		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
637a551c94aSIdo Barnea		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_CLR_POS);
638a551c94aSIdo Barnea		break;
639a551c94aSIdo Barnea
640a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
641a551c94aSIdo Barnea		/* clear FLOAT and set SET */
642a551c94aSIdo Barnea		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
643a551c94aSIdo Barnea		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_SET_POS);
644a551c94aSIdo Barnea		break;
645a551c94aSIdo Barnea
646a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_INPUT_HI_Z:
647a551c94aSIdo Barnea		/* set FLOAT */
648a551c94aSIdo Barnea		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_FLOAT_POS);
649a551c94aSIdo Barnea		break;
650a551c94aSIdo Barnea
651a551c94aSIdo Barnea	default:
652a551c94aSIdo Barnea		break;
653a551c94aSIdo Barnea	}
654a551c94aSIdo Barnea
655a551c94aSIdo Barnea	REG_WR(sc, MISC_REG_GPIO, gpio_reg);
656a551c94aSIdo Barnea	bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
657a551c94aSIdo Barnea
658a551c94aSIdo Barnea	return 0;
659a551c94aSIdo Barnea}
660a551c94aSIdo Barnea
661a551c94aSIdo Barneastatic int
662a551c94aSIdo Barneabnx2x_gpio_mult_write(struct bnx2x_softc *sc, uint8_t pins, uint32_t mode)
663a551c94aSIdo Barnea{
664a551c94aSIdo Barnea	uint32_t gpio_reg;
665a551c94aSIdo Barnea
666a551c94aSIdo Barnea	/* any port swapping should be handled by caller */
667a551c94aSIdo Barnea
668a551c94aSIdo Barnea	bnx2x_acquire_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
669a551c94aSIdo Barnea
670a551c94aSIdo Barnea	/* read GPIO and mask except the float bits */
671a551c94aSIdo Barnea	gpio_reg = REG_RD(sc, MISC_REG_GPIO);
672a551c94aSIdo Barnea	gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_FLOAT_POS);
673a551c94aSIdo Barnea	gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_CLR_POS);
674a551c94aSIdo Barnea	gpio_reg &= ~(pins << MISC_REGISTERS_GPIO_SET_POS);
675a551c94aSIdo Barnea
676a551c94aSIdo Barnea	switch (mode) {
677a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_OUTPUT_LOW:
678a551c94aSIdo Barnea		/* set CLR */
679a551c94aSIdo Barnea		gpio_reg |= (pins << MISC_REGISTERS_GPIO_CLR_POS);
680a551c94aSIdo Barnea		break;
681a551c94aSIdo Barnea
682a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_OUTPUT_HIGH:
683a551c94aSIdo Barnea		/* set SET */
684a551c94aSIdo Barnea		gpio_reg |= (pins << MISC_REGISTERS_GPIO_SET_POS);
685a551c94aSIdo Barnea		break;
686a551c94aSIdo Barnea
687a551c94aSIdo Barnea	case MISC_REGISTERS_GPIO_INPUT_HI_Z:
688a551c94aSIdo Barnea		/* set FLOAT */
689a551c94aSIdo Barnea		gpio_reg |= (pins << MISC_REGISTERS_GPIO_FLOAT_POS);
690a551c94aSIdo Barnea		break;
691a551c94aSIdo Barnea
692a551c94aSIdo Barnea	default:
693a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "Invalid GPIO mode assignment %d", mode);
694a551c94aSIdo Barnea		bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
695a551c94aSIdo Barnea		return -1;
696a551c94aSIdo Barnea	}
697a551c94aSIdo Barnea
698a551c94aSIdo Barnea	REG_WR(sc, MISC_REG_GPIO, gpio_reg);
699a551c94aSIdo Barnea	bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
700a551c94aSIdo Barnea
701a551c94aSIdo Barnea	return 0;
702a551c94aSIdo Barnea}
703a551c94aSIdo Barnea
704a551c94aSIdo Barneastatic int
705a551c94aSIdo Barneabnx2x_gpio_int_write(struct bnx2x_softc *sc, int gpio_num, uint32_t mode,
706a551c94aSIdo Barnea		   uint8_t port)
707a551c94aSIdo Barnea{
708a551c94aSIdo Barnea	/* The GPIO should be swapped if swap register is set and active */
709a551c94aSIdo Barnea	int gpio_port = ((REG_RD(sc, NIG_REG_PORT_SWAP) &&
710a551c94aSIdo Barnea			  REG_RD(sc, NIG_REG_STRAP_OVERRIDE)) ^ port);
711a551c94aSIdo Barnea	int gpio_shift = gpio_num;
712a551c94aSIdo Barnea	if (gpio_port)
713a551c94aSIdo Barnea		gpio_shift += MISC_REGISTERS_GPIO_PORT_SHIFT;
714a551c94aSIdo Barnea
715a551c94aSIdo Barnea	uint32_t gpio_mask = (1 << gpio_shift);
716a551c94aSIdo Barnea	uint32_t gpio_reg;
717a551c94aSIdo Barnea
718a551c94aSIdo Barnea	if (gpio_num > MISC_REGISTERS_GPIO_3) {
719a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "Invalid GPIO %d", gpio_num);
720a551c94aSIdo Barnea		return -1;
721a551c94aSIdo Barnea	}
722a551c94aSIdo Barnea
723a551c94aSIdo Barnea	bnx2x_acquire_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
724a551c94aSIdo Barnea
725a551c94aSIdo Barnea	/* read GPIO int */
726a551c94aSIdo Barnea	gpio_reg = REG_RD(sc, MISC_REG_GPIO_INT);
727a551c94aSIdo Barnea
728a551c94aSIdo Barnea	switch (mode) {
730a551c94aSIdo Barnea		/* clear SET and set CLR */
731a551c94aSIdo Barnea		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
732a551c94aSIdo Barnea		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
733a551c94aSIdo Barnea		break;
734a551c94aSIdo Barnea
736a551c94aSIdo Barnea		/* clear CLR and set SET */
737a551c94aSIdo Barnea		gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS);
738a551c94aSIdo Barnea		gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS);
739a551c94aSIdo Barnea		break;
740a551c94aSIdo Barnea
741a551c94aSIdo Barnea	default:
742a551c94aSIdo Barnea		break;
743a551c94aSIdo Barnea	}
744a551c94aSIdo Barnea
745a551c94aSIdo Barnea	REG_WR(sc, MISC_REG_GPIO_INT, gpio_reg);
746a551c94aSIdo Barnea	bnx2x_release_hw_lock(sc, HW_LOCK_RESOURCE_GPIO);
747a551c94aSIdo Barnea
748a551c94aSIdo Barnea	return 0;
749a551c94aSIdo Barnea}
750a551c94aSIdo Barnea
751a551c94aSIdo Barneauint32_t
752a551c94aSIdo Barneaelink_cb_gpio_read(struct bnx2x_softc * sc, uint16_t gpio_num, uint8_t port)
753a551c94aSIdo Barnea{
754a551c94aSIdo Barnea	return bnx2x_gpio_read(sc, gpio_num, port);
755a551c94aSIdo Barnea}
756a551c94aSIdo Barnea
757a551c94aSIdo Barneauint8_t elink_cb_gpio_write(struct bnx2x_softc * sc, uint16_t gpio_num, uint8_t mode,	/* 0=low 1=high */
758a551c94aSIdo Barnea			    uint8_t port)
759a551c94aSIdo Barnea{
760a551c94aSIdo Barnea	return bnx2x_gpio_write(sc, gpio_num, mode, port);
761a551c94aSIdo Barnea}
762a551c94aSIdo Barnea
763a551c94aSIdo Barneauint8_t
764a551c94aSIdo Barneaelink_cb_gpio_mult_write(struct bnx2x_softc * sc, uint8_t pins,
765a551c94aSIdo Barnea			 uint8_t mode /* 0=low 1=high */ )
766a551c94aSIdo Barnea{
767a551c94aSIdo Barnea	return bnx2x_gpio_mult_write(sc, pins, mode);
768a551c94aSIdo Barnea}
769a551c94aSIdo Barnea
770a551c94aSIdo Barneauint8_t elink_cb_gpio_int_write(struct bnx2x_softc * sc, uint16_t gpio_num, uint8_t mode,	/* 0=low 1=high */
771a551c94aSIdo Barnea				uint8_t port)
772a551c94aSIdo Barnea{
773a551c94aSIdo Barnea	return bnx2x_gpio_int_write(sc, gpio_num, mode, port);
774a551c94aSIdo Barnea}
775a551c94aSIdo Barnea
776a551c94aSIdo Barneavoid elink_cb_notify_link_changed(struct bnx2x_softc *sc)
777a551c94aSIdo Barnea{
778a551c94aSIdo Barnea	REG_WR(sc, (MISC_REG_AEU_GENERAL_ATTN_12 +
779a551c94aSIdo Barnea		    (SC_FUNC(sc) * sizeof(uint32_t))), 1);
780a551c94aSIdo Barnea}
781a551c94aSIdo Barnea
782a551c94aSIdo Barnea/* send the MCP a request, block until there is a reply */
783a551c94aSIdo Barneauint32_t
784a551c94aSIdo Barneaelink_cb_fw_command(struct bnx2x_softc *sc, uint32_t command, uint32_t param)
785a551c94aSIdo Barnea{
786a551c94aSIdo Barnea	int mb_idx = SC_FW_MB_IDX(sc);
787a551c94aSIdo Barnea	uint32_t seq;
788a551c94aSIdo Barnea	uint32_t rc = 0;
789a551c94aSIdo Barnea	uint32_t cnt = 1;
790a551c94aSIdo Barnea	uint8_t delay = CHIP_REV_IS_SLOW(sc) ? 100 : 10;
791a551c94aSIdo Barnea
792a551c94aSIdo Barnea	seq = ++sc->fw_seq;
793a551c94aSIdo Barnea	SHMEM_WR(sc, func_mb[mb_idx].drv_mb_param, param);
794a551c94aSIdo Barnea	SHMEM_WR(sc, func_mb[mb_idx].drv_mb_header, (command | seq));
795a551c94aSIdo Barnea
796a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG,
797a551c94aSIdo Barnea		    "wrote command 0x%08x to FW MB param 0x%08x",
798a551c94aSIdo Barnea		    (command | seq), param);
799a551c94aSIdo Barnea
800a551c94aSIdo Barnea	/* Let the FW do it's magic. GIve it up to 5 seconds... */
801a551c94aSIdo Barnea	do {
802a551c94aSIdo Barnea		DELAY(delay * 1000);
803a551c94aSIdo Barnea		rc = SHMEM_RD(sc, func_mb[mb_idx].fw_mb_header);
804a551c94aSIdo Barnea	} while ((seq != (rc & FW_MSG_SEQ_NUMBER_MASK)) && (cnt++ < 500));
805a551c94aSIdo Barnea
806a551c94aSIdo Barnea	/* is this a reply to our command? */
807a551c94aSIdo Barnea	if (seq == (rc & FW_MSG_SEQ_NUMBER_MASK)) {
808a551c94aSIdo Barnea		rc &= FW_MSG_CODE_MASK;
809a551c94aSIdo Barnea	} else {
810a551c94aSIdo Barnea		/* Ruh-roh! */
811a551c94aSIdo Barnea		PMD_DRV_LOG(NOTICE, "FW failed to respond!");
812a551c94aSIdo Barnea		rc = 0;
813a551c94aSIdo Barnea	}
814a551c94aSIdo Barnea
815a551c94aSIdo Barnea	return rc;
816a551c94aSIdo Barnea}
817a551c94aSIdo Barnea
818a551c94aSIdo Barneastatic uint32_t
819a551c94aSIdo Barneabnx2x_fw_command(struct bnx2x_softc *sc, uint32_t command, uint32_t param)
820a551c94aSIdo Barnea{
821a551c94aSIdo Barnea	return elink_cb_fw_command(sc, command, param);
822a551c94aSIdo Barnea}
823a551c94aSIdo Barnea
824a551c94aSIdo Barneastatic void
825a551c94aSIdo Barnea__storm_memset_dma_mapping(struct bnx2x_softc *sc, uint32_t addr,
826a551c94aSIdo Barnea			   phys_addr_t mapping)
827a551c94aSIdo Barnea{
828a551c94aSIdo Barnea	REG_WR(sc, addr, U64_LO(mapping));
829a551c94aSIdo Barnea	REG_WR(sc, (addr + 4), U64_HI(mapping));
830a551c94aSIdo Barnea}
831a551c94aSIdo Barnea
832a551c94aSIdo Barneastatic void
833a551c94aSIdo Barneastorm_memset_spq_addr(struct bnx2x_softc *sc, phys_addr_t mapping,
834a551c94aSIdo Barnea		      uint16_t abs_fid)
835a551c94aSIdo Barnea{
836a551c94aSIdo Barnea	uint32_t addr = (XSEM_REG_FAST_MEMORY +
837a551c94aSIdo Barnea			 XSTORM_SPQ_PAGE_BASE_OFFSET(abs_fid));
838a551c94aSIdo Barnea	__storm_memset_dma_mapping(sc, addr, mapping);
839a551c94aSIdo Barnea}
840a551c94aSIdo Barnea
841a551c94aSIdo Barneastatic void
842a551c94aSIdo Barneastorm_memset_vf_to_pf(struct bnx2x_softc *sc, uint16_t abs_fid, uint16_t pf_id)
843a551c94aSIdo Barnea{
844a551c94aSIdo Barnea	REG_WR8(sc, (BAR_XSTRORM_INTMEM + XSTORM_VF_TO_PF_OFFSET(abs_fid)),
845a551c94aSIdo Barnea		pf_id);
846a551c94aSIdo Barnea	REG_WR8(sc, (BAR_CSTRORM_INTMEM + CSTORM_VF_TO_PF_OFFSET(abs_fid)),
847a551c94aSIdo Barnea		pf_id);
848a551c94aSIdo Barnea	REG_WR8(sc, (BAR_TSTRORM_INTMEM + TSTORM_VF_TO_PF_OFFSET(abs_fid)),
849a551c94aSIdo Barnea		pf_id);
850a551c94aSIdo Barnea	REG_WR8(sc, (BAR_USTRORM_INTMEM + USTORM_VF_TO_PF_OFFSET(abs_fid)),
851a551c94aSIdo Barnea		pf_id);
852a551c94aSIdo Barnea}
853a551c94aSIdo Barnea
854a551c94aSIdo Barneastatic void
855a551c94aSIdo Barneastorm_memset_func_en(struct bnx2x_softc *sc, uint16_t abs_fid, uint8_t enable)
856a551c94aSIdo Barnea{
857a551c94aSIdo Barnea	REG_WR8(sc, (BAR_XSTRORM_INTMEM + XSTORM_FUNC_EN_OFFSET(abs_fid)),
858a551c94aSIdo Barnea		enable);
859a551c94aSIdo Barnea	REG_WR8(sc, (BAR_CSTRORM_INTMEM + CSTORM_FUNC_EN_OFFSET(abs_fid)),
860a551c94aSIdo Barnea		enable);
861a551c94aSIdo Barnea	REG_WR8(sc, (BAR_TSTRORM_INTMEM + TSTORM_FUNC_EN_OFFSET(abs_fid)),
862a551c94aSIdo Barnea		enable);
863a551c94aSIdo Barnea	REG_WR8(sc, (BAR_USTRORM_INTMEM + USTORM_FUNC_EN_OFFSET(abs_fid)),
864a551c94aSIdo Barnea		enable);
865a551c94aSIdo Barnea}
866a551c94aSIdo Barnea
867a551c94aSIdo Barneastatic void
868a551c94aSIdo Barneastorm_memset_eq_data(struct bnx2x_softc *sc, struct event_ring_data *eq_data,
869a551c94aSIdo Barnea		     uint16_t pfid)
870a551c94aSIdo Barnea{
871a551c94aSIdo Barnea	uint32_t addr;
872a551c94aSIdo Barnea	size_t size;
873a551c94aSIdo Barnea
874a551c94aSIdo Barnea	addr = (BAR_CSTRORM_INTMEM + CSTORM_EVENT_RING_DATA_OFFSET(pfid));
875a551c94aSIdo Barnea	size = sizeof(struct event_ring_data);
876a551c94aSIdo Barnea	ecore_storm_memset_struct(sc, addr, size, (uint32_t *) eq_data);
877a551c94aSIdo Barnea}
878a551c94aSIdo Barnea
879a551c94aSIdo Barneastatic void
880a551c94aSIdo Barneastorm_memset_eq_prod(struct bnx2x_softc *sc, uint16_t eq_prod, uint16_t pfid)
881a551c94aSIdo Barnea{
882a551c94aSIdo Barnea	uint32_t addr = (BAR_CSTRORM_INTMEM +
883a551c94aSIdo Barnea			 CSTORM_EVENT_RING_PROD_OFFSET(pfid));
884a551c94aSIdo Barnea	REG_WR16(sc, addr, eq_prod);
885a551c94aSIdo Barnea}
886a551c94aSIdo Barnea
887a551c94aSIdo Barnea/*
888a551c94aSIdo Barnea * Post a slowpath command.
889a551c94aSIdo Barnea *
890a551c94aSIdo Barnea * A slowpath command is used to propogate a configuration change through
891a551c94aSIdo Barnea * the controller in a controlled manner, allowing each STORM processor and
892a551c94aSIdo Barnea * other H/W blocks to phase in the change.  The commands sent on the
893a551c94aSIdo Barnea * slowpath are referred to as ramrods.  Depending on the ramrod used the
894a551c94aSIdo Barnea * completion of the ramrod will occur in different ways.  Here's a
895a551c94aSIdo Barnea * breakdown of ramrods and how they complete:
896a551c94aSIdo Barnea *
897a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_PORT_SETUP
898a551c94aSIdo Barnea *   Used to setup the leading connection on a port.  Completes on the
899a551c94aSIdo Barnea *   Receive Completion Queue (RCQ) of that port (typically fp[0]).
900a551c94aSIdo Barnea *
902a551c94aSIdo Barnea *   Used to setup an additional connection on a port.  Completes on the
903a551c94aSIdo Barnea *   RCQ of the multi-queue/RSS connection being initialized.
904a551c94aSIdo Barnea *
905a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_STAT_QUERY
906a551c94aSIdo Barnea *   Used to force the storm processors to update the statistics database
907a551c94aSIdo Barnea *   in host memory.  This ramrod is send on the leading connection CID and
908a551c94aSIdo Barnea *   completes as an index increment of the CSTORM on the default status
909a551c94aSIdo Barnea *   block.
910a551c94aSIdo Barnea *
911a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_UPDATE
912a551c94aSIdo Barnea *   Used to update the state of the leading connection, usually to udpate
913a551c94aSIdo Barnea *   the RSS indirection table.  Completes on the RCQ of the leading
914a551c94aSIdo Barnea *   connection. (Not currently used under FreeBSD until OS support becomes
915a551c94aSIdo Barnea *   available.)
916a551c94aSIdo Barnea *
917a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_HALT
918a551c94aSIdo Barnea *   Used when tearing down a connection prior to driver unload.  Completes
919a551c94aSIdo Barnea *   on the RCQ of the multi-queue/RSS connection being torn down.  Don't
920a551c94aSIdo Barnea *   use this on the leading connection.
921a551c94aSIdo Barnea *
922a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_SET_MAC
923a551c94aSIdo Barnea *   Sets the Unicast/Broadcast/Multicast used by the port.  Completes on
924a551c94aSIdo Barnea *   the RCQ of the leading connection.
925a551c94aSIdo Barnea *
926a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_CFC_DEL
927a551c94aSIdo Barnea *   Used when tearing down a conneciton prior to driver unload.  Completes
928a551c94aSIdo Barnea *   on the RCQ of the leading connection (since the current connection
929a551c94aSIdo Barnea *   has been completely removed from controller memory).
930a551c94aSIdo Barnea *
931a551c94aSIdo Barnea * RAMROD_CMD_ID_ETH_PORT_DEL
932a551c94aSIdo Barnea *   Used to tear down the leading connection prior to driver unload,
933a551c94aSIdo Barnea *   typically fp[0].  Completes as an index increment of the CSTORM on the
934a551c94aSIdo Barnea *   default status block.
935a551c94aSIdo Barnea *
937a551c94aSIdo Barnea *   Used for connection offload.  Completes on the RCQ of the multi-queue
938a551c94aSIdo Barnea *   RSS connection that is being offloaded.  (Not currently used under
939a551c94aSIdo Barnea *   FreeBSD.)
940a551c94aSIdo Barnea *
941a551c94aSIdo Barnea * There can only be one command pending per function.
942a551c94aSIdo Barnea *
943a551c94aSIdo Barnea * Returns:
944a551c94aSIdo Barnea *   0 = Success, !0 = Failure.
945a551c94aSIdo Barnea */
946a551c94aSIdo Barnea
947a551c94aSIdo Barnea/* must be called under the spq lock */
948a551c94aSIdo Barneastatic inline struct eth_spe *bnx2x_sp_get_next(struct bnx2x_softc *sc)
949a551c94aSIdo Barnea{
950a551c94aSIdo Barnea	struct eth_spe *next_spe = sc->spq_prod_bd;
951a551c94aSIdo Barnea
952a551c94aSIdo Barnea	if (sc->spq_prod_bd == sc->spq_last_bd) {
953a551c94aSIdo Barnea		/* wrap back to the first eth_spq */
954a551c94aSIdo Barnea		sc->spq_prod_bd = sc->spq;
955a551c94aSIdo Barnea		sc->spq_prod_idx = 0;
956a551c94aSIdo Barnea	} else {
957a551c94aSIdo Barnea		sc->spq_prod_bd++;
958a551c94aSIdo Barnea		sc->spq_prod_idx++;
959a551c94aSIdo Barnea	}
960a551c94aSIdo Barnea
961a551c94aSIdo Barnea	return next_spe;
962a551c94aSIdo Barnea}
963a551c94aSIdo Barnea
964a551c94aSIdo Barnea/* must be called under the spq lock */
965a551c94aSIdo Barneastatic void bnx2x_sp_prod_update(struct bnx2x_softc *sc)
966a551c94aSIdo Barnea{
967a551c94aSIdo Barnea	int func = SC_FUNC(sc);
968a551c94aSIdo Barnea
969a551c94aSIdo Barnea	/*
970a551c94aSIdo Barnea	 * Make sure that BD data is updated before writing the producer.
971a551c94aSIdo Barnea	 * BD data is written to the memory, the producer is read from the
972a551c94aSIdo Barnea	 * memory, thus we need a full memory barrier to ensure the ordering.
973a551c94aSIdo Barnea	 */
974a551c94aSIdo Barnea	mb();
975a551c94aSIdo Barnea
976a551c94aSIdo Barnea	REG_WR16(sc, (BAR_XSTRORM_INTMEM + XSTORM_SPQ_PROD_OFFSET(func)),
977a551c94aSIdo Barnea		 sc->spq_prod_idx);
978a551c94aSIdo Barnea
979a551c94aSIdo Barnea	mb();
980a551c94aSIdo Barnea}
981a551c94aSIdo Barnea
982a551c94aSIdo Barnea/**
983a551c94aSIdo Barnea * bnx2x_is_contextless_ramrod - check if the current command ends on EQ
984a551c94aSIdo Barnea *
985a551c94aSIdo Barnea * @cmd:      command to check
986a551c94aSIdo Barnea * @cmd_type: command type
987a551c94aSIdo Barnea */
988a551c94aSIdo Barneastatic int bnx2x_is_contextless_ramrod(int cmd, int cmd_type)
989a551c94aSIdo Barnea{
990a551c94aSIdo Barnea	if ((cmd_type == NONE_CONNECTION_TYPE) ||
991a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_FORWARD_SETUP) ||
992a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES) ||
993a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_FILTER_RULES) ||
994a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_MULTICAST_RULES) ||
995a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_SET_MAC) ||
996a551c94aSIdo Barnea	    (cmd == RAMROD_CMD_ID_ETH_RSS_UPDATE)) {
997a551c94aSIdo Barnea		return TRUE;
998a551c94aSIdo Barnea	} else {
999a551c94aSIdo Barnea		return FALSE;
1000a551c94aSIdo Barnea	}
1001a551c94aSIdo Barnea}
1002a551c94aSIdo Barnea
1003a551c94aSIdo Barnea/**
1004a551c94aSIdo Barnea * bnx2x_sp_post - place a single command on an SP ring
1005a551c94aSIdo Barnea *
1006a551c94aSIdo Barnea * @sc:         driver handle
1007a551c94aSIdo Barnea * @command:    command to place (e.g. SETUP, FILTER_RULES, etc.)
1008a551c94aSIdo Barnea * @cid:        SW CID the command is related to
1009a551c94aSIdo Barnea * @data_hi:    command private data address (high 32 bits)
1010a551c94aSIdo Barnea * @data_lo:    command private data address (low 32 bits)
1011a551c94aSIdo Barnea * @cmd_type:   command type (e.g. NONE, ETH)
1012a551c94aSIdo Barnea *
1013a551c94aSIdo Barnea * SP data is handled as if it's always an address pair, thus data fields are
1014a551c94aSIdo Barnea * not swapped to little endian in upper functions. Instead this function swaps
1015a551c94aSIdo Barnea * data as if it's two uint32 fields.
1016a551c94aSIdo Barnea */
1017a551c94aSIdo Barneaint
1018a551c94aSIdo Barneabnx2x_sp_post(struct bnx2x_softc *sc, int command, int cid, uint32_t data_hi,
1019a551c94aSIdo Barnea	    uint32_t data_lo, int cmd_type)
1020a551c94aSIdo Barnea{
1021a551c94aSIdo Barnea	struct eth_spe *spe;
1022a551c94aSIdo Barnea	uint16_t type;
1023a551c94aSIdo Barnea	int common;
1024a551c94aSIdo Barnea
1025a551c94aSIdo Barnea	common = bnx2x_is_contextless_ramrod(command, cmd_type);
1026a551c94aSIdo Barnea
1027a551c94aSIdo Barnea	if (common) {
1028a551c94aSIdo Barnea		if (!atomic_load_acq_long(&sc->eq_spq_left)) {
1029a551c94aSIdo Barnea			PMD_DRV_LOG(INFO, "EQ ring is full!");
1030a551c94aSIdo Barnea			return -1;
1031a551c94aSIdo Barnea		}
1032a551c94aSIdo Barnea	} else {
1033a551c94aSIdo Barnea		if (!atomic_load_acq_long(&sc->cq_spq_left)) {
1034a551c94aSIdo Barnea			PMD_DRV_LOG(INFO, "SPQ ring is full!");
1035a551c94aSIdo Barnea			return -1;
1036a551c94aSIdo Barnea		}
1037a551c94aSIdo Barnea	}
1038a551c94aSIdo Barnea
1039a551c94aSIdo Barnea	spe = bnx2x_sp_get_next(sc);
1040a551c94aSIdo Barnea
1041a551c94aSIdo Barnea	/* CID needs port number to be encoded int it */
1042a551c94aSIdo Barnea	spe->hdr.conn_and_cmd_data =
1043a551c94aSIdo Barnea	    htole32((command << SPE_HDR_CMD_ID_SHIFT) | HW_CID(sc, cid));
1044a551c94aSIdo Barnea
1045a551c94aSIdo Barnea	type = (cmd_type << SPE_HDR_CONN_TYPE_SHIFT) & SPE_HDR_CONN_TYPE;
1046a551c94aSIdo Barnea
1047a551c94aSIdo Barnea	/* TBD: Check if it works for VFs */
1048a551c94aSIdo Barnea	type |= ((SC_FUNC(sc) << SPE_HDR_FUNCTION_ID_SHIFT) &
1049a551c94aSIdo Barnea		 SPE_HDR_FUNCTION_ID);
1050a551c94aSIdo Barnea
1051a551c94aSIdo Barnea	spe->hdr.type = htole16(type);
1052a551c94aSIdo Barnea
1053a551c94aSIdo Barnea	spe->data.update_data_addr.hi = htole32(data_hi);
1054a551c94aSIdo Barnea	spe->data.update_data_addr.lo = htole32(data_lo);
1055a551c94aSIdo Barnea
1056a551c94aSIdo Barnea	/*
1057a551c94aSIdo Barnea	 * It's ok if the actual decrement is issued towards the memory
1058a551c94aSIdo Barnea	 * somewhere between the lock and unlock. Thus no more explict
1059a551c94aSIdo Barnea	 * memory barrier is needed.
1060a551c94aSIdo Barnea	 */
1061a551c94aSIdo Barnea	if (common) {
1062a551c94aSIdo Barnea		atomic_subtract_acq_long(&sc->eq_spq_left, 1);
1063a551c94aSIdo Barnea	} else {
1064a551c94aSIdo Barnea		atomic_subtract_acq_long(&sc->cq_spq_left, 1);
1065a551c94aSIdo Barnea	}
1066a551c94aSIdo Barnea
1067a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG,
1068a551c94aSIdo Barnea		    "SPQE[%x] (%x:%x) (cmd, common?) (%d,%d) hw_cid %x"
1069a551c94aSIdo Barnea		    "data (%x:%x) type(0x%x) left (CQ, EQ) (%lx,%lx)",
1070a551c94aSIdo Barnea		    sc->spq_prod_idx,
1071a551c94aSIdo Barnea		    (uint32_t) U64_HI(sc->spq_dma.paddr),
1072a551c94aSIdo Barnea		    (uint32_t) (U64_LO(sc->spq_dma.paddr) +
1073a551c94aSIdo Barnea				(uint8_t *) sc->spq_prod_bd -
1074a551c94aSIdo Barnea				(uint8_t *) sc->spq), command, common,
1075a551c94aSIdo Barnea		    HW_CID(sc, cid), data_hi, data_lo, type,
1076a551c94aSIdo Barnea		    atomic_load_acq_long(&sc->cq_spq_left),
1077a551c94aSIdo Barnea		    atomic_load_acq_long(&sc->eq_spq_left));
1078a551c94aSIdo Barnea
1079a551c94aSIdo Barnea	bnx2x_sp_prod_update(sc);
1080a551c94aSIdo Barnea
1081a551c94aSIdo Barnea	return 0;
1082a551c94aSIdo Barnea}
1083a551c94aSIdo Barnea
1084a551c94aSIdo Barneastatic void bnx2x_drv_pulse(struct bnx2x_softc *sc)
1085a551c94aSIdo Barnea{
1086a551c94aSIdo Barnea	SHMEM_WR(sc, func_mb[SC_FW_MB_IDX(sc)].drv_pulse_mb,
1087a551c94aSIdo Barnea		 sc->fw_drv_pulse_wr_seq);
1088a551c94aSIdo Barnea}
1089a551c94aSIdo Barnea
1090a551c94aSIdo Barneastatic int bnx2x_tx_queue_has_work(const struct bnx2x_fastpath *fp)
1091a551c94aSIdo Barnea{
1092a551c94aSIdo Barnea	uint16_t hw_cons;
1093a551c94aSIdo Barnea	struct bnx2x_tx_queue *txq = fp->sc->tx_queues[fp->index];
1094a551c94aSIdo Barnea
1095a551c94aSIdo Barnea	if (unlikely(!txq)) {
1096a551c94aSIdo Barnea		PMD_TX_LOG(ERR, "ERROR: TX queue is NULL");
1097a551c94aSIdo Barnea		return 0;
1098a551c94aSIdo Barnea	}
1099a551c94aSIdo Barnea
1100a551c94aSIdo Barnea	mb();			/* status block fields can change */
1101a551c94aSIdo Barnea	hw_cons = le16toh(*fp->tx_cons_sb);
1102a551c94aSIdo Barnea	return hw_cons != txq->tx_pkt_head;
1103a551c94aSIdo Barnea}
1104a551c94aSIdo Barnea
1105a551c94aSIdo Barneastatic uint8_t bnx2x_has_tx_work(struct bnx2x_fastpath *fp)
1106a551c94aSIdo Barnea{
1107a551c94aSIdo Barnea	/* expand this for multi-cos if ever supported */
1108a551c94aSIdo Barnea	return bnx2x_tx_queue_has_work(fp);
1109a551c94aSIdo Barnea}
1110a551c94aSIdo Barnea
1111a551c94aSIdo Barneastatic int bnx2x_has_rx_work(struct bnx2x_fastpath *fp)
1112a551c94aSIdo Barnea{
1113a551c94aSIdo Barnea	uint16_t rx_cq_cons_sb;
1114a551c94aSIdo Barnea	struct bnx2x_rx_queue *rxq;
1115a551c94aSIdo Barnea	rxq = fp->sc->rx_queues[fp->index];
1116a551c94aSIdo Barnea	if (unlikely(!rxq)) {
1117a551c94aSIdo Barnea		PMD_RX_LOG(ERR, "ERROR: RX queue is NULL");
1118a551c94aSIdo Barnea		return 0;
1119a551c94aSIdo Barnea	}
1120a551c94aSIdo Barnea
1121a551c94aSIdo Barnea	mb();			/* status block fields can change */
1122a551c94aSIdo Barnea	rx_cq_cons_sb = le16toh(*fp->rx_cq_cons_sb);
1123a551c94aSIdo Barnea	if (unlikely((rx_cq_cons_sb & MAX_RCQ_ENTRIES(rxq)) ==
1124a551c94aSIdo Barnea		     MAX_RCQ_ENTRIES(rxq)))
1125a551c94aSIdo Barnea		rx_cq_cons_sb++;
1126a551c94aSIdo Barnea	return rxq->rx_cq_head != rx_cq_cons_sb;
1127a551c94aSIdo Barnea}
1128a551c94aSIdo Barnea
1129a551c94aSIdo Barneastatic void
1130a551c94aSIdo Barneabnx2x_sp_event(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp,
1131a551c94aSIdo Barnea	     union eth_rx_cqe *rr_cqe)
1132a551c94aSIdo Barnea{
1133a551c94aSIdo Barnea#ifdef RTE_LIBRTE_BNX2X_DEBUG
1134a551c94aSIdo Barnea	int cid = SW_CID(rr_cqe->ramrod_cqe.conn_and_cmd_data);
1135a551c94aSIdo Barnea#endif
1136a551c94aSIdo Barnea	int command = CQE_CMD(rr_cqe->ramrod_cqe.conn_and_cmd_data);
1137a551c94aSIdo Barnea	enum ecore_queue_cmd drv_cmd = ECORE_Q_CMD_MAX;
1138a551c94aSIdo Barnea	struct ecore_queue_sp_obj *q_obj = &BNX2X_SP_OBJ(sc, fp).q_obj;
1139a551c94aSIdo Barnea
1140a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG,
1141a551c94aSIdo Barnea		    "fp=%d cid=%d got ramrod #%d state is %x type is %d",
1142a551c94aSIdo Barnea		    fp->index, cid, command, sc->state,
1143a551c94aSIdo Barnea		    rr_cqe->ramrod_cqe.ramrod_type);
1144a551c94aSIdo Barnea
1145a551c94aSIdo Barnea	switch (command) {
1146a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_CLIENT_UPDATE):
1147a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got UPDATE ramrod. CID %d", cid);
1148a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_UPDATE;
1149a551c94aSIdo Barnea		break;
1150a551c94aSIdo Barnea
1151a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_CLIENT_SETUP):
1152a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got MULTI[%d] setup ramrod", cid);
1153a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_SETUP;
1154a551c94aSIdo Barnea		break;
1155a551c94aSIdo Barnea
1156a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_TX_QUEUE_SETUP):
1157a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got MULTI[%d] tx-only setup ramrod", cid);
1158a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_SETUP_TX_ONLY;
1159a551c94aSIdo Barnea		break;
1160a551c94aSIdo Barnea
1161a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_HALT):
1162a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got MULTI[%d] halt ramrod", cid);
1163a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_HALT;
1164a551c94aSIdo Barnea		break;
1165a551c94aSIdo Barnea
1166a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_TERMINATE):
1167a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got MULTI[%d] teminate ramrod", cid);
1168a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_TERMINATE;
1169a551c94aSIdo Barnea		break;
1170a551c94aSIdo Barnea
1171a551c94aSIdo Barnea	case (RAMROD_CMD_ID_ETH_EMPTY):
1172a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG, "got MULTI[%d] empty ramrod", cid);
1173a551c94aSIdo Barnea		drv_cmd = ECORE_Q_CMD_EMPTY;
1174a551c94aSIdo Barnea		break;
1175a551c94aSIdo Barnea
1176a551c94aSIdo Barnea	default:
1177a551c94aSIdo Barnea		PMD_DRV_LOG(DEBUG,
1178a551c94aSIdo Barnea			    "ERROR: unexpected MC reply (%d)"
1179a551c94aSIdo Barnea			    "on fp[%d]", command, fp->index);
1180a551c94aSIdo Barnea		return;
1181a551c94aSIdo Barnea	}
1182a551c94aSIdo Barnea
1183a551c94aSIdo Barnea	if ((drv_cmd != ECORE_Q_CMD_MAX) &&
1184a551c94aSIdo Barnea	    q_obj->complete_cmd(sc, q_obj, drv_cmd)) {
1185a551c94aSIdo Barnea		/*
1186a551c94aSIdo Barnea		 * q_obj->complete_cmd() failure means that this was
1187a551c94aSIdo Barnea		 * an unexpected completion.
1188a551c94aSIdo Barnea		 *
1189a551c94aSIdo Barnea		 * In this case we don't want to increase the sc->spq_left
1190a551c94aSIdo Barnea		 * because apparently we haven't sent this command the first
1191a551c94aSIdo Barnea		 * place.
1192a551c94aSIdo Barnea		 */
1193a551c94aSIdo Barnea		// rte_panic("Unexpected SP completion");
1194a551c94aSIdo Barnea		return;
1195a551c94aSIdo Barnea	}
1196a551c94aSIdo Barnea
1197a551c94aSIdo Barnea	atomic_add_acq_long(&sc->cq_spq_left, 1);
1198a551c94aSIdo Barnea
1199a551c94aSIdo Barnea	PMD_DRV_LOG(DEBUG, "sc->cq_spq_left 0x%lx",
1200a551c94aSIdo Barnea		    atomic_load_acq_long(&sc->cq_spq_left));
1201a551c94aSIdo Barnea}
1202a551c94aSIdo Barnea
1203a551c94aSIdo Barneastatic uint8_t bnx2x_rxeof(struct bnx2x_softc *sc, struct bnx2x_fastpath *fp)
1204a551c94aSIdo Barnea{
1205a551c94aSIdo Barnea	struct bnx2x_rx_queue *rxq;
1206a551c94aSIdo Barnea	uint16_t bd_cons, bd_prod, bd_prod_fw, comp_ring_cons;
1207a551c94aSIdo Barnea	uint16_t hw_cq_cons, sw_cq_cons, sw_cq_prod;
1208a551c94aSIdo Barnea
1209a551c94aSIdo Barnea	rxq = sc->rx_queues[fp->index];
1210a551c94aSIdo Barnea	if (!rxq) {
1211a551c94aSIdo Barnea		PMD_RX_LOG(ERR, "RX queue %d is NULL", fp->index);
1212a551c94aSIdo Barnea		return 0;
1213a551c94aSIdo Barnea	}
1214a551c94aSIdo Barnea
1215a551c94aSIdo Barnea	/* CQ "next element" is of the size of the regular element */
1216a551c94aSIdo Barnea	hw_cq_cons = le16toh(*fp->rx_cq_cons_sb);
1217a551c94aSIdo Barnea	if (unlikely((hw_cq_cons & USABLE_RCQ_ENTRIES_PER_PAGE) ==
1218a551c94aSIdo Barnea		     USABLE_RCQ_ENTRIES_PER_PAGE)) {
1219a551c94aSIdo Barnea		hw_cq_cons++;
1220a551c94aSIdo Barnea	}
1221a551c94aSIdo Barnea
1222a551c94aSIdo Barnea	bd_cons = rxq->rx_bd_head;
1223a551c94aSIdo Barnea	bd_prod = rxq->rx_bd_tail;
1224a551c94aSIdo Barnea	bd_prod_fw = bd_prod;
1225a551c94aSIdo Barnea	sw_cq_cons = rxq->rx_cq_head;
1226a551c94aSIdo Barnea	sw_cq_prod = rxq->rx_cq_tail;
1227a551c94aSIdo Barnea
1228a551c94aSIdo Barnea	/*
1229a551c94aSIdo Barnea	 * Memory barrier necessary as speculative reads of the rx
1230a551c94aSIdo Barnea	 * buffer can be ahead of the index in the status block
1231a551c94aSIdo Barnea	 */
1232a551c94aSIdo Barnea	rmb();
1233a551c94aSIdo Barnea
1234a551c94aSIdo Barnea	while (sw_cq_cons != hw_cq_cons) {
1235a551c94aSIdo Barnea		union eth_rx_cqe *cqe;
1236a551c94aSIdo Barnea		struct eth_fast_path_rx_cqe *cqe_fp;
1237a551c94aSIdo Barnea		uint8_t cqe_fp_flags;
1238a551c94aSIdo Barnea		enum eth_rx_cqe_type cqe_fp_type;
1239a551c94aSIdo Barnea
1240a551c94aSIdo Barnea		comp_ring_cons = RCQ_ENTRY(sw_cq_cons, rxq);
1241a551c94aSIdo Barnea		bd_prod = RX_BD(bd_prod, rxq);
1242a551c94aSIdo Barnea		bd_cons = RX_BD(bd_cons, rxq);
1243a551c94aSIdo Barnea
1244a551c94aSIdo Barnea		cqe = &rxq->cq_ring[comp_ring_cons];
1245a551c94aSIdo Barnea		cqe_fp = &cqe->fast_path_cqe;
1246a551c94aSIdo Barnea		cqe_fp_flags = cqe_fp->type_error_flags;
1247a551c94aSIdo Barnea		cqe_fp_type = cqe_fp_flags & ETH_FAST_PATH_RX_CQE_TYPE;
1248a551c94aSIdo Barnea
1249a551c94aSIdo Barnea		/* is this a slowpath msg? */
1250a551c94aSIdo Barnea		if (CQE_TYPE_SLOW(cqe_fp_type)) {
1251a551c94aSIdo Barnea			bnx2x_sp_event(sc, fp, cqe);
1252a551c94aSIdo Barnea			goto next_cqe;
1253a551c94aSIdo Barnea		}
1254a551c94aSIdo Barnea
1255a551c94aSIdo Barnea		/* is this an error packet? */
1256a551c94aSIdo Barnea		if (unlikely(cqe_fp_flags &
1257a551c94aSIdo Barnea			     ETH_FAST_PATH_RX_CQE_PHY_DECODE_ERR_FLG)) {
1258a551c94aSIdo Barnea			PMD_RX_LOG(DEBUG, "flags 0x%x rx packet %u",
1259a551c94aSIdo Barnea				   cqe_fp_flags, sw_cq_cons);
1260a551c94aSIdo Barnea			goto next_rx;
1261a551c94aSIdo Barnea		}
1262a551c94aSIdo Barnea
1263a551c94aSIdo Barnea		PMD_RX_LOG(DEBUG, "Dropping fastpath called from attn poller!");
1264a551c94aSIdo Barnea
1265a551c94aSIdo Barneanext_rx:
1266a551c94aSIdo Barnea		bd_cons = NEXT_RX_BD(bd_cons);
1267a551c94aSIdo Barnea		bd_prod = NEXT_RX_BD(bd_prod);
1268a551c94aSIdo Barnea		bd_prod_fw = NEXT_RX_BD(bd_prod_fw);
1269a551c94aSIdo Barnea
1270a551c94aSIdo Barneanext_cqe:
1271a551c94aSIdo Barnea		sw_cq_prod = NEXT_RCQ_IDX(sw_cq_prod);
1272a551c94aSIdo Barnea		sw_cq_cons = NEXT_RCQ_IDX(sw_cq_cons);
1273a551c94aSIdo Barnea
1274a551c94aSIdo Barnea	}			/* while work to do */
1275a551c94aSIdo Barnea
1276a551c94aSIdo Barnea	rxq->rx_bd_head = bd_cons;
1277a551c94aSIdo Barnea	rxq->rx_bd_tail = bd_prod_fw;
1278a551c94aSIdo Barnea	rxq->rx_cq_head = sw_cq_cons;
1279a551c94aSIdo Barnea	rxq->rx_cq_tail = sw_cq_prod;
1280a551c94aSIdo Barnea
1281a551c94aSIdo Barnea	/* Update producers */
1282a551c94aSIdo Barnea	bnx2x_update_rx_prod(sc, fp, bd_prod_fw, sw_cq_prod);
1283a551c94aSIdo Barnea
1284a551c94aSIdo Barnea	return sw_cq_cons != hw_cq_cons;
1285a551c94aSIdo Barnea}
1286a551c94aSIdo Barnea
1287a551c94aSIdo Barneastatic uint16_t
1288a551c94aSIdo Barneabnx2x_free_tx_pkt(__rte_unused struct bnx2x_fastpath *fp, struct bnx2x_tx_queue *txq,
1289a551c94aSIdo Barnea		uint16_t pkt_idx, uint16_t bd_idx)
1290a551c94aSIdo Barnea{
1291a551c94aSIdo Barnea	struct eth_tx_start_bd *tx_start_bd =
1292a551c94aSIdo Barnea	    &txq->tx_ring[TX_BD(bd_idx, txq)].start_bd;
1293a551c94aSIdo Barnea	uint16_t nbd = rte_le_to_cpu_16(tx_start_bd->nbd);
1294a551c94aSIdo Barnea	struct rte_mbuf *tx_mbuf = txq->sw_ring[TX_BD(pkt_idx, txq)];
1295a551c94aSIdo Barnea
1296a551c94aSIdo Barnea	if (likely(tx_mbuf != NULL)) {
1297a551c94aSIdo Barnea		rte_pktmbuf_free_seg(tx_mbuf);
1298a551c94aSIdo Barnea	} else {
1299a551c94aSIdo Barnea		PMD_RX_LOG(ERR, "fp[%02d] lost mbuf %lu",
1300a551c94aSIdo Barnea			   fp->index, (unsigned long)TX_BD(pkt_idx, txq));
1301a551c94aSIdo Barnea	}
1302a551c94aSIdo Barnea
1303a551c94aSIdo Barnea	txq->sw_ring[TX_BD(pkt_idx, txq)] = NULL;
1304a551c94aSIdo Barnea	txq->nb_tx_avail += nbd;
1305a551c94aSIdo Barnea
1306a551c94aSIdo Barnea	while (nbd--)
1307a551c94aSIdo Barnea		bd_idx = NEXT_TX_BD(bd_idx);
1308a551c94aSIdo Barnea
1309a551c94aSIdo Barnea	return bd_idx;
1310a551c94aSIdo Barnea}
1311a551c94aSIdo Barnea
1312a551c94aSIdo Barnea/* processes transmit completions */
1313a551c94aSIdo Barneauint8_t bnx2x_txeof(__rte_unused struct bnx2x_softc * sc, struct bnx2x_fastpath * fp)
1314a551c94aSIdo Barnea{
1315a551c94aSIdo Barnea	uint16_t bd_cons, hw_cons, sw_cons;
1316a551c94aSIdo Barnea	__rte_unused uint16_t tx_bd_avail;
1317a551c94aSIdo Barnea
1318a551c94aSIdo Barnea	struct bnx2x_tx_queue *txq = fp->sc->tx_queues[fp->index];
1319a551c94aSIdo Barnea
1320a551c94aSIdo Barnea	if (unlikely(!txq)) {
1321a551c94aSIdo Barnea		PMD_TX_LOG(ERR, "ERROR: TX queue is NULL");
1322a551c94aSIdo Barnea		return 0;
1323a551c94aSIdo Barnea	}
1324a551c94aSIdo Barnea
1325a551c94aSIdo Barnea	bd_cons = txq->tx_bd_head;
1326a551c94aSIdo Barnea	hw_cons = rte_le_to_cpu_16(*fp->tx_cons_sb);
1327a551c94aSIdo Barnea	sw_cons = txq->tx_pkt_head;
1328a551c94aSIdo Barnea
1329a551c94aSIdo Barnea	while (sw_cons != hw_cons) {
1330a551c94aSIdo Barnea		bd_cons = bnx2x_free_tx_pkt(fp, txq, sw_cons, bd_cons);
1331a551c94aSIdo Barnea		sw_cons++;
1332a551c94aSIdo Barnea	}
1333a551c94aSIdo Barnea
1334a551c94aSIdo Barnea	txq->tx_pkt_head = sw_cons;
1335a551c94aSIdo Barnea	txq->tx_bd_head = bd_cons;
1336a551c94aSIdo Barnea
1337a551c94aSIdo Barnea	tx_bd_avail = txq->nb_tx_avail;
1338a551c94aSIdo Barnea
1339a551c94aSIdo Barnea	PMD_TX_LOG(DEBUG, "fp[%02d] avail=%u cons_sb=%u, "
1340a551c94aSIdo Barnea		   "pkt_head=%u pkt_tail=%u bd_head=%u bd_tail=%u",
1341a551c94aSIdo Barnea		   fp->index, tx_bd_avail, hw_cons,
1342a551c94aSIdo Barnea		   txq->tx_pkt_head, txq->tx_pkt_tail,
1343a551c94aSIdo Barnea		   txq->tx_bd_head, txq->tx_bd_tail);
1344a551c94aSIdo Barnea	return TRUE;
1345a551c94aSIdo Barnea}
1346a551c94aSIdo Barnea
1347a551c94aSIdo Barneastatic void bnx2x_drain_tx_queues(struct bnx2x_softc *sc)
1348a551c94aSIdo Barnea{
1349a551c94aSIdo Barnea	struct bnx2x_fastpath *fp;
1350a551c94aSIdo Barnea	int i, count;
1351a551c94aSIdo Barnea
1352a551c94aSIdo Barnea	/* wait until all TX fastpath tasks have completed */
1353a551c94aSIdo Barnea	for (i = 0; i < sc->num_queues; i++) {
1354a551c94aSIdo Barnea		fp = &sc->fp[i];
1355a551c94aSIdo Barnea
1356a551c94aSIdo Barnea		count = 1000;
1357a551c94aSIdo Barnea
1358a551c94aSIdo Barnea		while (bnx2x_has_tx_work(fp)) {
1359a551c94aSIdo Barnea			bnx2x_txeof(sc, fp);
1360a551c94aSIdo Barnea
1361a551c94aSIdo Barnea			if (count == 0) {
1362a551c94aSIdo Barnea				PMD_TX_LOG(ERR,
1363a551c94aSIdo Barnea					   "Timeout waiting for fp[%d] "
1364a551c94aSIdo Barnea					   "transmits to complete!", i);
1365a551c94aSIdo Barnea				rte_panic("tx drain failure");
1366a551c94aSIdo Barnea				return;
1367a551c94aSIdo Barnea			}
1368a551c94aSIdo Barnea
1369a551c94aSIdo Barnea			count--;
1370a551c94aSIdo Barnea			DELAY(1000);
1371a551c94aSIdo Barnea			rmb();
1372a551c94aSIdo Barnea		}
1373a551c94aSIdo Barnea	}
1374a551c94aSIdo Barnea
1375a551c94aSIdo Barnea	return;
1376a551c94aSIdo Barnea}
1377a551c94aSIdo Barnea
1378a551c94aSIdo Barneastatic int
1379a551c94aSIdo Barneabnx2x_del_all_macs(struct bnx2x_softc *sc, struct ecore_vlan_mac_obj *mac_obj,
1380a551c94aSIdo Barnea		 int mac_type, uint8_t wait_for_comp)
1381a551c94aSIdo Barnea{
1382a551c94aSIdo Barnea	unsigned long ramrod_flags = 0, vlan_mac_flags = 0;
1383a551c94aSIdo Barnea	int rc;
1384a551c94aSIdo Barnea
1385a551c94aSIdo Barnea	/* wait for completion of requested */
1386a551c94aSIdo Barnea	if (wait_for_comp) {
1387a551c94aSIdo Barnea		bnx2x_set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
1388a551c94aSIdo Barnea	}
1389a551c94aSIdo Barnea
1390a551c94aSIdo Barnea	/* Set the mac type of addresses we want to clear */
1391a551c94aSIdo Barnea	bnx2x_set_bit(mac_type, &vlan_mac_flags);
1392a551c94aSIdo Barnea
1393a551c94aSIdo Barnea	rc = mac_obj->delete_all(sc, mac_obj, &vlan_mac_flags, &ramrod_flags);
1394a551c94aSIdo Barnea	if (rc < 0)
1395a551c94aSIdo Barnea		PMD_DRV_LOG(ERR, "Failed to delete MACs (%d)", rc);
1396a551c94aSIdo Barnea
1397a551c94aSIdo Barnea	return rc;
1398a551c94aSIdo Barnea}
1399a551c94aSIdo Barnea
14009ca4a157SIdo Barneastatic int
1401a551c94aSIdo Barneabnx2x_fill_accept_flags(struct bnx2x_softc *sc, uint32_t rx_mode,
14029ca4a157SIdo Barnea			unsigned long *rx_accept_flags,
14039ca4a157SIdo Barnea			unsigned long *tx_accept_flags)
1404a551c94aSIdo Barnea{
1405a551c94aSIdo Barnea	/* Clear the flags first */
1406a551c94aSIdo Barnea	*rx_accept_flags = 0;
1407a551c94aSIdo Barnea	*tx_accept_flags = 0;
1408a551c94aSIdo Barnea
1409a551c94aSIdo Barnea	switch (rx_mode) {
1410a551c94aSIdo Barnea	case BNX2X_RX_MODE_NONE:
1411a551c94aSIdo Barnea		/*
1412a551c94aSIdo Barnea		 * 'drop all' supersedes any accept flags that may have been
1413a551c94aSIdo Barnea		 * passed to the function.
1414a551c94aSIdo Barnea		 */
1415a551c94aSIdo Barnea		break;
1416a551c94aSIdo Barnea
1417a551c94aSIdo Barnea	case BNX2X_RX_MODE_NORMAL:
1418a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNICAST, rx_accept_flags);
1419a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_MULTICAST, rx_accept_flags);
1420a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, rx_accept_flags);
1421a551c94aSIdo Barnea
1422a551c94aSIdo Barnea		/* internal switching mode */
1423a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNICAST, tx_accept_flags);
1424a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_MULTICAST, tx_accept_flags);
1425a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, tx_accept_flags);
1426a551c94aSIdo Barnea
1427a551c94aSIdo Barnea		break;
1428a551c94aSIdo Barnea
1429a551c94aSIdo Barnea	case BNX2X_RX_MODE_ALLMULTI:
1430a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNICAST, rx_accept_flags);
1431a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ALL_MULTICAST, rx_accept_flags);
1432a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, rx_accept_flags);
1433a551c94aSIdo Barnea
1434a551c94aSIdo Barnea		/* internal switching mode */
1435a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNICAST, tx_accept_flags);
1436a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ALL_MULTICAST, tx_accept_flags);
1437a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, tx_accept_flags);
1438a551c94aSIdo Barnea
1439a551c94aSIdo Barnea		break;
1440a551c94aSIdo Barnea
14419ca4a157SIdo Barnea	case BNX2X_RX_MODE_ALLMULTI_PROMISC:
1442a551c94aSIdo Barnea	case BNX2X_RX_MODE_PROMISC:
1443a551c94aSIdo Barnea		/*
1444a551c94aSIdo Barnea		 * According to deffinition of SI mode, iface in promisc mode
1445a551c94aSIdo Barnea		 * should receive matched and unmatched (in resolution of port)
1446a551c94aSIdo Barnea		 * unicast packets.
1447a551c94aSIdo Barnea		 */
1448a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNMATCHED, rx_accept_flags);
1449a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_UNICAST, rx_accept_flags);
1450a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ALL_MULTICAST, rx_accept_flags);
1451a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, rx_accept_flags);
1452a551c94aSIdo Barnea
1453a551c94aSIdo Barnea		/* internal switching mode */
1454a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ALL_MULTICAST, tx_accept_flags);
1455a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_BROADCAST, tx_accept_flags);
1456a551c94aSIdo Barnea
1457a551c94aSIdo Barnea		if (IS_MF_SI(sc)) {
1458a551c94aSIdo Barnea			bnx2x_set_bit(ECORE_ACCEPT_ALL_UNICAST, tx_accept_flags);
1459a551c94aSIdo Barnea		} else {
1460a551c94aSIdo Barnea			bnx2x_set_bit(ECORE_ACCEPT_UNICAST, tx_accept_flags);
1461a551c94aSIdo Barnea		}
1462a551c94aSIdo Barnea
1463a551c94aSIdo Barnea		break;
1464a551c94aSIdo Barnea
1465a551c94aSIdo Barnea	default:
1466a551c94aSIdo Barnea		PMD_RX_LOG(ERR, "Unknown rx_mode (%d)", rx_mode);
1467a551c94aSIdo Barnea		return -1;
1468a551c94aSIdo Barnea	}
1469a551c94aSIdo Barnea
1470a551c94aSIdo Barnea	/* Set ACCEPT_ANY_VLAN as we do not enable filtering by VLAN */
1471a551c94aSIdo Barnea	if (rx_mode != BNX2X_RX_MODE_NONE) {
1472a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ANY_VLAN, rx_accept_flags);
1473a551c94aSIdo Barnea		bnx2x_set_bit(ECORE_ACCEPT_ANY_VLAN, tx_accept_flags);
1474a551c94aSIdo Barnea	}
1475a551c94aSIdo Barnea
1476a551c94aSIdo Barnea	return 0;
1477a551c94aSIdo Barnea}
1478a551c94aSIdo Barnea
1479a551c94aSIdo Barneastatic int
1480a551c94aSIdo Barneabnx2x_set_q_rx_mode(struct bnx2x_softc *sc, uint8