xref: /dpdk/drivers/net/qede/base/ecore_int.c (revision bdab5309193d8e1ed1a60b604677c86c322364e0)
13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause
29adde217SRasesh Mody  * Copyright (c) 2016 - 2018 Cavium Inc.
3ec94dbc5SRasesh Mody  * All rights reserved.
49adde217SRasesh Mody  * www.cavium.com
5ec94dbc5SRasesh Mody  */
6ec94dbc5SRasesh Mody 
70fa4f3eeSAndy Green #include <rte_string_fns.h>
80fa4f3eeSAndy Green 
9ec94dbc5SRasesh Mody #include "bcm_osal.h"
10ec94dbc5SRasesh Mody #include "ecore.h"
11ec94dbc5SRasesh Mody #include "ecore_spq.h"
12ec94dbc5SRasesh Mody #include "ecore_gtt_reg_addr.h"
13ec94dbc5SRasesh Mody #include "ecore_init_ops.h"
14ec94dbc5SRasesh Mody #include "ecore_rt_defs.h"
15ec94dbc5SRasesh Mody #include "ecore_int.h"
16ec94dbc5SRasesh Mody #include "reg_addr.h"
17ec94dbc5SRasesh Mody #include "ecore_hw.h"
1886a2265eSRasesh Mody #include "ecore_sriov.h"
1986a2265eSRasesh Mody #include "ecore_vf.h"
20ec94dbc5SRasesh Mody #include "ecore_hw_defs.h"
21ec94dbc5SRasesh Mody #include "ecore_hsi_common.h"
22ec94dbc5SRasesh Mody #include "ecore_mcp.h"
23ec94dbc5SRasesh Mody 
24ec94dbc5SRasesh Mody struct ecore_pi_info {
25ec94dbc5SRasesh Mody 	ecore_int_comp_cb_t comp_cb;
26ec94dbc5SRasesh Mody 	void *cookie;		/* Will be sent to the compl cb function */
27ec94dbc5SRasesh Mody };
28ec94dbc5SRasesh Mody 
29ec94dbc5SRasesh Mody struct ecore_sb_sp_info {
30ec94dbc5SRasesh Mody 	struct ecore_sb_info sb_info;
313b307c55SRasesh Mody 
323b307c55SRasesh Mody 	/* Per protocol index data */
3352fa735cSRasesh Mody 	struct ecore_pi_info pi_info_arr[MAX_PIS_PER_SB];
343b307c55SRasesh Mody 	osal_size_t pi_info_arr_size;
35ec94dbc5SRasesh Mody };
36ec94dbc5SRasesh Mody 
37ec94dbc5SRasesh Mody enum ecore_attention_type {
38ec94dbc5SRasesh Mody 	ECORE_ATTN_TYPE_ATTN,
39ec94dbc5SRasesh Mody 	ECORE_ATTN_TYPE_PARITY,
40ec94dbc5SRasesh Mody };
41ec94dbc5SRasesh Mody 
42ec94dbc5SRasesh Mody #define SB_ATTN_ALIGNED_SIZE(p_hwfn) \
43ec94dbc5SRasesh Mody 	ALIGNED_TYPE_SIZE(struct atten_status_block, p_hwfn)
44ec94dbc5SRasesh Mody 
45ec94dbc5SRasesh Mody struct aeu_invert_reg_bit {
46ec94dbc5SRasesh Mody 	char bit_name[30];
47ec94dbc5SRasesh Mody 
48ec94dbc5SRasesh Mody #define ATTENTION_PARITY		(1 << 0)
49ec94dbc5SRasesh Mody 
50ec94dbc5SRasesh Mody #define ATTENTION_LENGTH_MASK		(0x00000ff0)
51ec94dbc5SRasesh Mody #define ATTENTION_LENGTH_SHIFT		(4)
52ec94dbc5SRasesh Mody #define ATTENTION_LENGTH(flags)		(((flags) & ATTENTION_LENGTH_MASK) >> \
53ec94dbc5SRasesh Mody 					 ATTENTION_LENGTH_SHIFT)
54ec94dbc5SRasesh Mody #define ATTENTION_SINGLE		(1 << ATTENTION_LENGTH_SHIFT)
55ec94dbc5SRasesh Mody #define ATTENTION_PAR			(ATTENTION_SINGLE | ATTENTION_PARITY)
56ec94dbc5SRasesh Mody #define ATTENTION_PAR_INT		((2 << ATTENTION_LENGTH_SHIFT) | \
57ec94dbc5SRasesh Mody 					 ATTENTION_PARITY)
58ec94dbc5SRasesh Mody 
59ec94dbc5SRasesh Mody /* Multiple bits start with this offset */
60ec94dbc5SRasesh Mody #define ATTENTION_OFFSET_MASK		(0x000ff000)
61ec94dbc5SRasesh Mody #define ATTENTION_OFFSET_SHIFT		(12)
62ec94dbc5SRasesh Mody 
633b307c55SRasesh Mody #define ATTENTION_BB_MASK		(0xf)
64121f1cbdSRasesh Mody #define ATTENTION_BB_SHIFT		(20)
65121f1cbdSRasesh Mody #define ATTENTION_BB(value)		((value) << ATTENTION_BB_SHIFT)
663b307c55SRasesh Mody #define ATTENTION_BB_DIFFERENT		(1 << 24)
67121f1cbdSRasesh Mody 
68ec94dbc5SRasesh Mody #define	ATTENTION_CLEAR_ENABLE		(1 << 28)
69ec94dbc5SRasesh Mody 	unsigned int flags;
70ec94dbc5SRasesh Mody 
71ec94dbc5SRasesh Mody 	/* Callback to call if attention will be triggered */
72ec94dbc5SRasesh Mody 	enum _ecore_status_t (*cb)(struct ecore_hwfn *p_hwfn);
73ec94dbc5SRasesh Mody 
74ec94dbc5SRasesh Mody 	enum block_id block_index;
75ec94dbc5SRasesh Mody };
76ec94dbc5SRasesh Mody 
77ec94dbc5SRasesh Mody struct aeu_invert_reg {
78ec94dbc5SRasesh Mody 	struct aeu_invert_reg_bit bits[32];
79ec94dbc5SRasesh Mody };
80ec94dbc5SRasesh Mody 
81e6051bd6SRasesh Mody #define MAX_ATTN_GRPS		(8)
82ec94dbc5SRasesh Mody #define NUM_ATTN_REGS		(9)
83ec94dbc5SRasesh Mody 
ecore_mcp_attn_cb(struct ecore_hwfn * p_hwfn)84e6051bd6SRasesh Mody static enum _ecore_status_t ecore_mcp_attn_cb(struct ecore_hwfn *p_hwfn)
85e6051bd6SRasesh Mody {
86e6051bd6SRasesh Mody 	u32 tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, MCP_REG_CPU_STATE);
87e6051bd6SRasesh Mody 
88e6051bd6SRasesh Mody 	DP_INFO(p_hwfn->p_dev, "MCP_REG_CPU_STATE: %08x - Masking...\n", tmp);
89e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, MCP_REG_CPU_EVENT_MASK, 0xffffffff);
90e6051bd6SRasesh Mody 
91e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
92e6051bd6SRasesh Mody }
93e6051bd6SRasesh Mody 
94e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_PF_MASK		(0x3c000)
95e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_PF_SHIFT	(14)
96e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_VF_MASK		(0x03fc0)
97e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_VF_SHIFT	(6)
98e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_VALID_MASK	(0x00020)
99e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_VALID_SHIFT	(5)
100e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_CLIENT_MASK	(0x0001e)
101e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_CLIENT_SHIFT	(1)
102e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_DISABLED_WRITE_MASK	(0x1)
103e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTNETION_DISABLED_WRITE_SHIFT	(0)
104e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_VF_DISABLED		(0x1)
105e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS		(0x1)
106e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_WR_MASK		(0x1)
107e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_WR_SHIFT	(0)
108e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_CLIENT_MASK	(0x1e)
109e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_CLIENT_SHIFT	(1)
110e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_VALID_MASK	(0x20)
111e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_VALID_SHIFT	(5)
112e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_ID_MASK	(0x3fc0)
113e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_ID_SHIFT	(6)
114e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_PF_ID_MASK	(0x3c000)
115e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_PF_ID_SHIFT	(14)
116e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_BYTE_EN_MASK	(0x3fc0000)
117e6051bd6SRasesh Mody #define ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_BYTE_EN_SHIFT	(18)
ecore_pswhst_attn_cb(struct ecore_hwfn * p_hwfn)118e6051bd6SRasesh Mody static enum _ecore_status_t ecore_pswhst_attn_cb(struct ecore_hwfn *p_hwfn)
119e6051bd6SRasesh Mody {
120e6051bd6SRasesh Mody 	u32 tmp =
121e6051bd6SRasesh Mody 	    ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
122e6051bd6SRasesh Mody 		     PSWHST_REG_VF_DISABLED_ERROR_VALID);
123e6051bd6SRasesh Mody 
124e6051bd6SRasesh Mody 	/* Disabled VF access */
125e6051bd6SRasesh Mody 	if (tmp & ECORE_PSWHST_ATTENTION_VF_DISABLED) {
126e6051bd6SRasesh Mody 		u32 addr, data;
127e6051bd6SRasesh Mody 
128e6051bd6SRasesh Mody 		addr = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
129e6051bd6SRasesh Mody 				PSWHST_REG_VF_DISABLED_ERROR_ADDRESS);
130e6051bd6SRasesh Mody 		data = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
131e6051bd6SRasesh Mody 				PSWHST_REG_VF_DISABLED_ERROR_DATA);
132e6051bd6SRasesh Mody 		DP_INFO(p_hwfn->p_dev,
133e6051bd6SRasesh Mody 			"PF[0x%02x] VF [0x%02x] [Valid 0x%02x] Client [0x%02x]"
134e6051bd6SRasesh Mody 			" Write [0x%02x] Addr [0x%08x]\n",
135e6051bd6SRasesh Mody 			(u8)((data & ECORE_PSWHST_ATTENTION_DISABLED_PF_MASK)
136e6051bd6SRasesh Mody 			     >> ECORE_PSWHST_ATTENTION_DISABLED_PF_SHIFT),
137e6051bd6SRasesh Mody 			(u8)((data & ECORE_PSWHST_ATTENTION_DISABLED_VF_MASK)
138e6051bd6SRasesh Mody 			     >> ECORE_PSWHST_ATTENTION_DISABLED_VF_SHIFT),
139e6051bd6SRasesh Mody 			(u8)((data &
140e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTENTION_DISABLED_VALID_MASK) >>
141e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTENTION_DISABLED_VALID_SHIFT),
142e6051bd6SRasesh Mody 			(u8)((data &
143e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTENTION_DISABLED_CLIENT_MASK) >>
144e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTENTION_DISABLED_CLIENT_SHIFT),
145e6051bd6SRasesh Mody 			(u8)((data &
146e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTENTION_DISABLED_WRITE_MASK) >>
147e6051bd6SRasesh Mody 			      ECORE_PSWHST_ATTNETION_DISABLED_WRITE_SHIFT),
148e6051bd6SRasesh Mody 			addr);
149e6051bd6SRasesh Mody 	}
150e6051bd6SRasesh Mody 
151e6051bd6SRasesh Mody 	tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
152e6051bd6SRasesh Mody 		       PSWHST_REG_INCORRECT_ACCESS_VALID);
153e6051bd6SRasesh Mody 	if (tmp & ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS) {
154e6051bd6SRasesh Mody 		u32 addr, data, length;
155e6051bd6SRasesh Mody 
156e6051bd6SRasesh Mody 		addr = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
157e6051bd6SRasesh Mody 				PSWHST_REG_INCORRECT_ACCESS_ADDRESS);
158e6051bd6SRasesh Mody 		data = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
159e6051bd6SRasesh Mody 				PSWHST_REG_INCORRECT_ACCESS_DATA);
160e6051bd6SRasesh Mody 		length = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
161e6051bd6SRasesh Mody 				  PSWHST_REG_INCORRECT_ACCESS_LENGTH);
162e6051bd6SRasesh Mody 
163e6051bd6SRasesh Mody 		DP_INFO(p_hwfn->p_dev,
164e6051bd6SRasesh Mody 			"Incorrect access to %08x of length %08x - PF [%02x]"
165e6051bd6SRasesh Mody 			" VF [%04x] [valid %02x] client [%02x] write [%02x]"
166e6051bd6SRasesh Mody 			" Byte-Enable [%04x] [%08x]\n",
167e6051bd6SRasesh Mody 			addr, length,
168e6051bd6SRasesh Mody 			(u8)((data &
169e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_PF_ID_MASK) >>
170e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_PF_ID_SHIFT),
171e6051bd6SRasesh Mody 			(u8)((data &
172e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_ID_MASK) >>
173e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_ID_SHIFT),
174e6051bd6SRasesh Mody 			(u8)((data &
175e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_VALID_MASK) >>
176e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_VF_VALID_SHIFT),
177e6051bd6SRasesh Mody 			(u8)((data &
178e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_CLIENT_MASK) >>
179e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_CLIENT_SHIFT),
180e6051bd6SRasesh Mody 			(u8)((data &
181e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_WR_MASK) >>
182e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_WR_SHIFT),
183e6051bd6SRasesh Mody 			(u8)((data &
184e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_BYTE_EN_MASK) >>
185e6051bd6SRasesh Mody 		      ECORE_PSWHST_ATTENTION_INCORRECT_ACCESS_BYTE_EN_SHIFT),
186e6051bd6SRasesh Mody 			data);
187e6051bd6SRasesh Mody 	}
188e6051bd6SRasesh Mody 
189e6051bd6SRasesh Mody 	/* TODO - We know 'some' of these are legal due to virtualization,
190e6051bd6SRasesh Mody 	 * but is it true for all of them?
191e6051bd6SRasesh Mody 	 */
192e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
193e6051bd6SRasesh Mody }
194e6051bd6SRasesh Mody 
19558bb1ee4SRasesh Mody /* Register GRC_REG_TIMEOUT_ATTN_ACCESS_VALID */
19658bb1ee4SRasesh Mody #define ECORE_GRC_ATTENTION_VALID_BIT_MASK      (0x1)
19758bb1ee4SRasesh Mody #define ECORE_GRC_ATTENTION_VALID_BIT_SHIFT     (0)
19858bb1ee4SRasesh Mody 
199e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_ADDRESS_MASK	(0x7fffff << 0)
200e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_RDWR_BIT		(1 << 23)
201e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_MASTER_MASK		(0xf << 24)
202e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_MASTER_SHIFT	(24)
203e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_PF_MASK		(0xf)
204e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_VF_MASK		(0xff << 4)
205e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_VF_SHIFT		(4)
206e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_PRIV_MASK		(0x3 << 14)
207e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_PRIV_SHIFT		(14)
208e6051bd6SRasesh Mody #define ECORE_GRC_ATTENTION_PRIV_VF		(0)
grc_timeout_attn_master_to_str(u8 master)209e6051bd6SRasesh Mody static const char *grc_timeout_attn_master_to_str(u8 master)
210e6051bd6SRasesh Mody {
211e6051bd6SRasesh Mody 	switch (master) {
212e6051bd6SRasesh Mody 	case 1:
213e6051bd6SRasesh Mody 		return "PXP";
214e6051bd6SRasesh Mody 	case 2:
215e6051bd6SRasesh Mody 		return "MCP";
216e6051bd6SRasesh Mody 	case 3:
217e6051bd6SRasesh Mody 		return "MSDM";
218e6051bd6SRasesh Mody 	case 4:
219e6051bd6SRasesh Mody 		return "PSDM";
220e6051bd6SRasesh Mody 	case 5:
221e6051bd6SRasesh Mody 		return "YSDM";
222e6051bd6SRasesh Mody 	case 6:
223e6051bd6SRasesh Mody 		return "USDM";
224e6051bd6SRasesh Mody 	case 7:
225e6051bd6SRasesh Mody 		return "TSDM";
226e6051bd6SRasesh Mody 	case 8:
227e6051bd6SRasesh Mody 		return "XSDM";
228e6051bd6SRasesh Mody 	case 9:
229e6051bd6SRasesh Mody 		return "DBU";
230e6051bd6SRasesh Mody 	case 10:
231e6051bd6SRasesh Mody 		return "DMAE";
232e6051bd6SRasesh Mody 	default:
233e6051bd6SRasesh Mody 		return "Unknown";
234e6051bd6SRasesh Mody 	}
235e6051bd6SRasesh Mody }
236e6051bd6SRasesh Mody 
ecore_grc_attn_cb(struct ecore_hwfn * p_hwfn)237e6051bd6SRasesh Mody static enum _ecore_status_t ecore_grc_attn_cb(struct ecore_hwfn *p_hwfn)
238e6051bd6SRasesh Mody {
239538bcb37SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
240e6051bd6SRasesh Mody 	u32 tmp, tmp2;
241e6051bd6SRasesh Mody 
242e6051bd6SRasesh Mody 	/* We've already cleared the timeout interrupt register, so we learn
24358bb1ee4SRasesh Mody 	 * of interrupts via the validity register. If it is not a timeout do
24458bb1ee4SRasesh Mody 	 * nothing. It is too late at this stage to differentiate spurious
24558bb1ee4SRasesh Mody 	 * interrupt from fatal grc attention.
246e6051bd6SRasesh Mody 	 */
247e6051bd6SRasesh Mody 	tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
248e6051bd6SRasesh Mody 		       GRC_REG_TIMEOUT_ATTN_ACCESS_VALID);
24958bb1ee4SRasesh Mody 	if (!(GET_FIELD(tmp, ECORE_GRC_ATTENTION_VALID_BIT)))
250e6051bd6SRasesh Mody 		goto out;
251e6051bd6SRasesh Mody 
252e6051bd6SRasesh Mody 	/* Read the GRC timeout information */
253e6051bd6SRasesh Mody 	tmp = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
254e6051bd6SRasesh Mody 		       GRC_REG_TIMEOUT_ATTN_ACCESS_DATA_0);
255e6051bd6SRasesh Mody 	tmp2 = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
256e6051bd6SRasesh Mody 			GRC_REG_TIMEOUT_ATTN_ACCESS_DATA_1);
257e6051bd6SRasesh Mody 
258739a5b2fSRasesh Mody 	DP_NOTICE(p_hwfn->p_dev, false,
259739a5b2fSRasesh Mody 		  "GRC timeout [%08x:%08x] - %s Address [%08x] [Master %s] [PF: %02x %s %02x]\n",
260e6051bd6SRasesh Mody 		  tmp2, tmp,
261739a5b2fSRasesh Mody 		  (tmp & ECORE_GRC_ATTENTION_RDWR_BIT) ? "Write to"
262739a5b2fSRasesh Mody 						       : "Read from",
263e6051bd6SRasesh Mody 		  (tmp & ECORE_GRC_ATTENTION_ADDRESS_MASK) << 2,
264739a5b2fSRasesh Mody 		  grc_timeout_attn_master_to_str(
265739a5b2fSRasesh Mody 			(tmp & ECORE_GRC_ATTENTION_MASTER_MASK) >>
266e6051bd6SRasesh Mody 			 ECORE_GRC_ATTENTION_MASTER_SHIFT),
267e6051bd6SRasesh Mody 		  (tmp2 & ECORE_GRC_ATTENTION_PF_MASK),
268e6051bd6SRasesh Mody 		  (((tmp2 & ECORE_GRC_ATTENTION_PRIV_MASK) >>
269e6051bd6SRasesh Mody 		  ECORE_GRC_ATTENTION_PRIV_SHIFT) ==
270e6051bd6SRasesh Mody 		  ECORE_GRC_ATTENTION_PRIV_VF) ? "VF" : "(Irrelevant:)",
271e6051bd6SRasesh Mody 		  (tmp2 & ECORE_GRC_ATTENTION_VF_MASK) >>
272e6051bd6SRasesh Mody 		  ECORE_GRC_ATTENTION_VF_SHIFT);
273e6051bd6SRasesh Mody 
274538bcb37SRasesh Mody 	/* Clean the validity bit */
275e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt,
276e6051bd6SRasesh Mody 		 GRC_REG_TIMEOUT_ATTN_ACCESS_VALID, 0);
277538bcb37SRasesh Mody out:
278538bcb37SRasesh Mody 	return rc;
279e6051bd6SRasesh Mody }
280e6051bd6SRasesh Mody 
281e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_VALID (1 << 29)
282e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_RD_VALID (1 << 26)
283e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS_PFID_MASK (0xf << 20)
284e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS_PFID_SHIFT (20)
285e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS_VF_VALID (1 << 19)
286e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS_VFID_MASK (0xff << 24)
287e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS_VFID_SHIFT (24)
288e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS2_WAS_ERR (1 << 21)
289e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS2_BME	(1 << 22)
290e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_DETAILS2_FID_EN (1 << 23)
291e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_ICPL_VALID (1 << 23)
292e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_ZLR_VALID (1 << 25)
293e6051bd6SRasesh Mody #define ECORE_PGLUE_ATTENTION_ILT_VALID (1 << 23)
29460c78a5eSRasesh Mody 
ecore_pglueb_rbc_attn_handler(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,bool is_hw_init)29560c78a5eSRasesh Mody enum _ecore_status_t ecore_pglueb_rbc_attn_handler(struct ecore_hwfn *p_hwfn,
29652c5f7b5SRasesh Mody 						   struct ecore_ptt *p_ptt,
29752c5f7b5SRasesh Mody 						   bool is_hw_init)
298e6051bd6SRasesh Mody {
299c018d2b4SRasesh Mody 	u32 tmp;
30052c5f7b5SRasesh Mody 	char str[512] = {0};
301e6051bd6SRasesh Mody 
30260c78a5eSRasesh Mody 	tmp = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS2);
303e6051bd6SRasesh Mody 	if (tmp & ECORE_PGLUE_ATTENTION_VALID) {
304e6051bd6SRasesh Mody 		u32 addr_lo, addr_hi, details;
305e6051bd6SRasesh Mody 
30660c78a5eSRasesh Mody 		addr_lo = ecore_rd(p_hwfn, p_ptt,
307e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_WR_ADD_31_0);
30860c78a5eSRasesh Mody 		addr_hi = ecore_rd(p_hwfn, p_ptt,
309e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_WR_ADD_63_32);
31060c78a5eSRasesh Mody 		details = ecore_rd(p_hwfn, p_ptt,
311e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_WR_DETAILS);
31252c5f7b5SRasesh Mody 		OSAL_SNPRINTF(str, 512,
31360c78a5eSRasesh Mody 			 "Illegal write by chip to [%08x:%08x] blocked. Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x] Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
314e6051bd6SRasesh Mody 			  addr_hi, addr_lo, details,
315e6051bd6SRasesh Mody 			  (u8)((details &
316e6051bd6SRasesh Mody 				ECORE_PGLUE_ATTENTION_DETAILS_PFID_MASK) >>
317e6051bd6SRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_PFID_SHIFT),
318e6051bd6SRasesh Mody 			  (u8)((details &
319e6051bd6SRasesh Mody 				ECORE_PGLUE_ATTENTION_DETAILS_VFID_MASK) >>
320e6051bd6SRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_VFID_SHIFT),
32160c78a5eSRasesh Mody 			  (u8)((details &
32260c78a5eSRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0),
32360c78a5eSRasesh Mody 			  tmp,
32460c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_WAS_ERR) ?
32560c78a5eSRasesh Mody 				1 : 0),
32660c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_BME) ?
32760c78a5eSRasesh Mody 				1 : 0),
32860c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_FID_EN) ?
32960c78a5eSRasesh Mody 				1 : 0));
33052c5f7b5SRasesh Mody 		if (is_hw_init)
33152c5f7b5SRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "%s", str);
33252c5f7b5SRasesh Mody 		else
33352c5f7b5SRasesh Mody 			DP_NOTICE(p_hwfn, false, "%s", str);
334e6051bd6SRasesh Mody 	}
335e6051bd6SRasesh Mody 
33660c78a5eSRasesh Mody 	tmp = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_RD_DETAILS2);
337e6051bd6SRasesh Mody 	if (tmp & ECORE_PGLUE_ATTENTION_RD_VALID) {
338e6051bd6SRasesh Mody 		u32 addr_lo, addr_hi, details;
339e6051bd6SRasesh Mody 
34060c78a5eSRasesh Mody 		addr_lo = ecore_rd(p_hwfn, p_ptt,
341e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_RD_ADD_31_0);
34260c78a5eSRasesh Mody 		addr_hi = ecore_rd(p_hwfn, p_ptt,
343e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_RD_ADD_63_32);
34460c78a5eSRasesh Mody 		details = ecore_rd(p_hwfn, p_ptt,
345e6051bd6SRasesh Mody 				   PGLUE_B_REG_TX_ERR_RD_DETAILS);
346e6051bd6SRasesh Mody 
34760c78a5eSRasesh Mody 		DP_NOTICE(p_hwfn, false,
34860c78a5eSRasesh Mody 			  "Illegal read by chip from [%08x:%08x] blocked. Details: %08x [PFID %02x, VFID %02x, VF_VALID %02x] Details2 %08x [Was_error %02x BME deassert %02x FID_enable deassert %02x]\n",
349e6051bd6SRasesh Mody 			  addr_hi, addr_lo, details,
350e6051bd6SRasesh Mody 			  (u8)((details &
351e6051bd6SRasesh Mody 				ECORE_PGLUE_ATTENTION_DETAILS_PFID_MASK) >>
352e6051bd6SRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_PFID_SHIFT),
353e6051bd6SRasesh Mody 			  (u8)((details &
354e6051bd6SRasesh Mody 				ECORE_PGLUE_ATTENTION_DETAILS_VFID_MASK) >>
355e6051bd6SRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_VFID_SHIFT),
35660c78a5eSRasesh Mody 			  (u8)((details &
35760c78a5eSRasesh Mody 			       ECORE_PGLUE_ATTENTION_DETAILS_VF_VALID) ? 1 : 0),
35860c78a5eSRasesh Mody 			  tmp,
35960c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_WAS_ERR) ?
36060c78a5eSRasesh Mody 				1 : 0),
36160c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_BME) ?
36260c78a5eSRasesh Mody 				1 : 0),
36360c78a5eSRasesh Mody 			  (u8)((tmp & ECORE_PGLUE_ATTENTION_DETAILS2_FID_EN) ?
36460c78a5eSRasesh Mody 				1 : 0));
365e6051bd6SRasesh Mody 	}
366e6051bd6SRasesh Mody 
36760c78a5eSRasesh Mody 	tmp = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_TX_ERR_WR_DETAILS_ICPL);
368e6051bd6SRasesh Mody 	if (tmp & ECORE_PGLUE_ATTENTION_ICPL_VALID)
369*bdab5309SLuca Boccassi 		DP_NOTICE(p_hwfn, false, "ICPL error - %08x\n", tmp);
370e6051bd6SRasesh Mody 
37160c78a5eSRasesh Mody 	tmp = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_MASTER_ZLR_ERR_DETAILS);
372e6051bd6SRasesh Mody 	if (tmp & ECORE_PGLUE_ATTENTION_ZLR_VALID) {
373e6051bd6SRasesh Mody 		u32 addr_hi, addr_lo;
374e6051bd6SRasesh Mody 
37560c78a5eSRasesh Mody 		addr_lo = ecore_rd(p_hwfn, p_ptt,
376e6051bd6SRasesh Mody 				   PGLUE_B_REG_MASTER_ZLR_ERR_ADD_31_0);
37760c78a5eSRasesh Mody 		addr_hi = ecore_rd(p_hwfn, p_ptt,
378e6051bd6SRasesh Mody 				   PGLUE_B_REG_MASTER_ZLR_ERR_ADD_63_32);
379e6051bd6SRasesh Mody 
38060c78a5eSRasesh Mody 		DP_NOTICE(p_hwfn, false,
381*bdab5309SLuca Boccassi 			  "ICPL error - %08x [Address %08x:%08x]\n",
382e6051bd6SRasesh Mody 			  tmp, addr_hi, addr_lo);
383e6051bd6SRasesh Mody 	}
384e6051bd6SRasesh Mody 
38560c78a5eSRasesh Mody 	tmp = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_VF_ILT_ERR_DETAILS2);
386e6051bd6SRasesh Mody 	if (tmp & ECORE_PGLUE_ATTENTION_ILT_VALID) {
387e6051bd6SRasesh Mody 		u32 addr_hi, addr_lo, details;
388e6051bd6SRasesh Mody 
38960c78a5eSRasesh Mody 		addr_lo = ecore_rd(p_hwfn, p_ptt,
390e6051bd6SRasesh Mody 				   PGLUE_B_REG_VF_ILT_ERR_ADD_31_0);
39160c78a5eSRasesh Mody 		addr_hi = ecore_rd(p_hwfn, p_ptt,
392e6051bd6SRasesh Mody 				   PGLUE_B_REG_VF_ILT_ERR_ADD_63_32);
39360c78a5eSRasesh Mody 		details = ecore_rd(p_hwfn, p_ptt,
394e6051bd6SRasesh Mody 				   PGLUE_B_REG_VF_ILT_ERR_DETAILS);
395e6051bd6SRasesh Mody 
39660c78a5eSRasesh Mody 		DP_NOTICE(p_hwfn, false,
39760c78a5eSRasesh Mody 			  "ILT error - Details %08x Details2 %08x [Address %08x:%08x]\n",
398e6051bd6SRasesh Mody 			  details, tmp, addr_hi, addr_lo);
399e6051bd6SRasesh Mody 	}
400e6051bd6SRasesh Mody 
401e6051bd6SRasesh Mody 	/* Clear the indications */
40260c78a5eSRasesh Mody 	ecore_wr(p_hwfn, p_ptt, PGLUE_B_REG_LATCHED_ERRORS_CLR, (1 << 2));
403e6051bd6SRasesh Mody 
404e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
405e6051bd6SRasesh Mody }
406e6051bd6SRasesh Mody 
ecore_pglueb_rbc_attn_cb(struct ecore_hwfn * p_hwfn)40760c78a5eSRasesh Mody static enum _ecore_status_t ecore_pglueb_rbc_attn_cb(struct ecore_hwfn *p_hwfn)
40860c78a5eSRasesh Mody {
40952c5f7b5SRasesh Mody 	return ecore_pglueb_rbc_attn_handler(p_hwfn, p_hwfn->p_dpc_ptt, false);
41060c78a5eSRasesh Mody }
41160c78a5eSRasesh Mody 
ecore_fw_assertion(struct ecore_hwfn * p_hwfn)412e6051bd6SRasesh Mody static enum _ecore_status_t ecore_fw_assertion(struct ecore_hwfn *p_hwfn)
413e6051bd6SRasesh Mody {
414e6051bd6SRasesh Mody 	DP_NOTICE(p_hwfn, false, "FW assertion!\n");
415e6051bd6SRasesh Mody 
416e6051bd6SRasesh Mody 	ecore_hw_err_notify(p_hwfn, ECORE_HW_ERR_FW_ASSERT);
417e6051bd6SRasesh Mody 
418e6051bd6SRasesh Mody 	return ECORE_INVAL;
419e6051bd6SRasesh Mody }
420e6051bd6SRasesh Mody 
421e6051bd6SRasesh Mody static enum _ecore_status_t
ecore_general_attention_35(struct ecore_hwfn * p_hwfn)422e6051bd6SRasesh Mody ecore_general_attention_35(struct ecore_hwfn *p_hwfn)
423e6051bd6SRasesh Mody {
424e6051bd6SRasesh Mody 	DP_INFO(p_hwfn, "General attention 35!\n");
425e6051bd6SRasesh Mody 
426e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
427e6051bd6SRasesh Mody }
428e6051bd6SRasesh Mody 
429e6051bd6SRasesh Mody #define ECORE_DORQ_ATTENTION_REASON_MASK	(0xfffff)
430e6051bd6SRasesh Mody #define ECORE_DORQ_ATTENTION_OPAQUE_MASK	(0xffff)
431e916697fSRasesh Mody #define ECORE_DORQ_ATTENTION_OPAQUE_SHIFT	(0x0)
432e916697fSRasesh Mody #define ECORE_DORQ_ATTENTION_SIZE_MASK		(0x7f)
433e6051bd6SRasesh Mody #define ECORE_DORQ_ATTENTION_SIZE_SHIFT		(16)
434e6051bd6SRasesh Mody 
43515dfc1ecSRasesh Mody #define ECORE_DB_REC_COUNT			1000
436e916697fSRasesh Mody #define ECORE_DB_REC_INTERVAL			100
437e916697fSRasesh Mody 
ecore_db_rec_flush_queue(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)438f32557f9SRasesh Mody static enum _ecore_status_t ecore_db_rec_flush_queue(struct ecore_hwfn *p_hwfn,
439e916697fSRasesh Mody 						     struct ecore_ptt *p_ptt)
440e916697fSRasesh Mody {
44115dfc1ecSRasesh Mody 	u32 count = ECORE_DB_REC_COUNT;
442e916697fSRasesh Mody 	u32 usage = 1;
443e916697fSRasesh Mody 
444e916697fSRasesh Mody 	/* wait for usage to zero or count to run out. This is necessary since
445e916697fSRasesh Mody 	 * EDPM doorbell transactions can take multiple 64b cycles, and as such
446e916697fSRasesh Mody 	 * can "split" over the pci. Possibly, the doorbell drop can happen with
447e916697fSRasesh Mody 	 * half an EDPM in the queue and other half dropped. Another EDPM
448e916697fSRasesh Mody 	 * doorbell to the same address (from doorbell recovery mechanism or
449e916697fSRasesh Mody 	 * from the doorbelling entity) could have first half dropped and second
450e916697fSRasesh Mody 	 * half interperted as continuation of the first. To prevent such
451e916697fSRasesh Mody 	 * malformed doorbells from reaching the device, flush the queue before
452e916697fSRasesh Mody 	 * releaseing the overflow sticky indication.
453e916697fSRasesh Mody 	 */
454e916697fSRasesh Mody 	while (count-- && usage) {
455e916697fSRasesh Mody 		usage = ecore_rd(p_hwfn, p_ptt, DORQ_REG_PF_USAGE_CNT);
456e916697fSRasesh Mody 		OSAL_UDELAY(ECORE_DB_REC_INTERVAL);
457e916697fSRasesh Mody 	}
458e916697fSRasesh Mody 
459e916697fSRasesh Mody 	/* should have been depleted by now */
460e916697fSRasesh Mody 	if (usage) {
461e916697fSRasesh Mody 		DP_NOTICE(p_hwfn->p_dev, false,
462e916697fSRasesh Mody 			  "DB recovery: doorbell usage failed to zero after %d usec. usage was %x\n",
463e916697fSRasesh Mody 			  ECORE_DB_REC_INTERVAL * ECORE_DB_REC_COUNT, usage);
464e916697fSRasesh Mody 		return ECORE_TIMEOUT;
465e916697fSRasesh Mody 	}
466e916697fSRasesh Mody 
467f32557f9SRasesh Mody 	return ECORE_SUCCESS;
468f32557f9SRasesh Mody }
469f32557f9SRasesh Mody 
ecore_db_rec_handler(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)47015dfc1ecSRasesh Mody enum _ecore_status_t ecore_db_rec_handler(struct ecore_hwfn *p_hwfn,
471f32557f9SRasesh Mody 					  struct ecore_ptt *p_ptt)
472f32557f9SRasesh Mody {
47315dfc1ecSRasesh Mody 	u32 overflow;
474f32557f9SRasesh Mody 	enum _ecore_status_t rc;
475f32557f9SRasesh Mody 
47615dfc1ecSRasesh Mody 	overflow = ecore_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY);
47715dfc1ecSRasesh Mody 	DP_NOTICE(p_hwfn, false, "PF Overflow sticky 0x%x\n", overflow);
47815dfc1ecSRasesh Mody 	if (!overflow) {
47915dfc1ecSRasesh Mody 		ecore_db_recovery_execute(p_hwfn, DB_REC_ONCE);
48015dfc1ecSRasesh Mody 		return ECORE_SUCCESS;
48115dfc1ecSRasesh Mody 	}
48215dfc1ecSRasesh Mody 
483f32557f9SRasesh Mody 	if (ecore_edpm_enabled(p_hwfn)) {
484f32557f9SRasesh Mody 		rc = ecore_db_rec_flush_queue(p_hwfn, p_ptt);
485f32557f9SRasesh Mody 		if (rc != ECORE_SUCCESS)
486f32557f9SRasesh Mody 			return rc;
487f32557f9SRasesh Mody 	}
488f32557f9SRasesh Mody 
489e916697fSRasesh Mody 	/* flush any pedning (e)dpm as they may never arrive */
490e916697fSRasesh Mody 	ecore_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1);
491e916697fSRasesh Mody 
492e916697fSRasesh Mody 	/* release overflow sticky indication (stop silently dropping
493e916697fSRasesh Mody 	 * everything)
494e916697fSRasesh Mody 	 */
495e916697fSRasesh Mody 	ecore_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);
496e916697fSRasesh Mody 
497e916697fSRasesh Mody 	/* repeat all last doorbells (doorbell drop recovery) */
498e916697fSRasesh Mody 	ecore_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL);
499e916697fSRasesh Mody 
500e916697fSRasesh Mody 	return ECORE_SUCCESS;
501e916697fSRasesh Mody }
502e916697fSRasesh Mody 
ecore_dorq_attn_cb(struct ecore_hwfn * p_hwfn)503e6051bd6SRasesh Mody static enum _ecore_status_t ecore_dorq_attn_cb(struct ecore_hwfn *p_hwfn)
504e6051bd6SRasesh Mody {
50515dfc1ecSRasesh Mody 	u32 int_sts, first_drop_reason, details, address, all_drops_reason;
506e916697fSRasesh Mody 	struct ecore_ptt *p_ptt = p_hwfn->p_dpc_ptt;
507e916697fSRasesh Mody 	enum _ecore_status_t rc;
508e6051bd6SRasesh Mody 
509e916697fSRasesh Mody 	int_sts = ecore_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);
510e916697fSRasesh Mody 	DP_NOTICE(p_hwfn->p_dev, false, "DORQ attention. int_sts was %x\n",
511e916697fSRasesh Mody 		  int_sts);
512e916697fSRasesh Mody 
513e916697fSRasesh Mody 	/* int_sts may be zero since all PFs were interrupted for doorbell
514e916697fSRasesh Mody 	 * overflow but another one already handled it. Can abort here. If
515e916697fSRasesh Mody 	 * This PF also requires overflow recovery we will be interrupted again
516e916697fSRasesh Mody 	 */
517e916697fSRasesh Mody 	if (!int_sts)
518e916697fSRasesh Mody 		return ECORE_SUCCESS;
519e916697fSRasesh Mody 
520e916697fSRasesh Mody 	/* check if db_drop or overflow happened */
521e916697fSRasesh Mody 	if (int_sts & (DORQ_REG_INT_STS_DB_DROP |
522e916697fSRasesh Mody 		       DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) {
523e916697fSRasesh Mody 		/* obtain data about db drop/overflow */
524e916697fSRasesh Mody 		first_drop_reason = ecore_rd(p_hwfn, p_ptt,
525e916697fSRasesh Mody 				  DORQ_REG_DB_DROP_REASON) &
526e6051bd6SRasesh Mody 				  ECORE_DORQ_ATTENTION_REASON_MASK;
527e916697fSRasesh Mody 		details = ecore_rd(p_hwfn, p_ptt,
528e6051bd6SRasesh Mody 				   DORQ_REG_DB_DROP_DETAILS);
529e916697fSRasesh Mody 		address = ecore_rd(p_hwfn, p_ptt,
530e916697fSRasesh Mody 				   DORQ_REG_DB_DROP_DETAILS_ADDRESS);
531e916697fSRasesh Mody 		all_drops_reason = ecore_rd(p_hwfn, p_ptt,
532e916697fSRasesh Mody 					    DORQ_REG_DB_DROP_DETAILS_REASON);
533e6051bd6SRasesh Mody 
534e916697fSRasesh Mody 		/* log info */
535e916697fSRasesh Mody 		DP_NOTICE(p_hwfn->p_dev, false,
536e916697fSRasesh Mody 			  "Doorbell drop occurred\n"
537e916697fSRasesh Mody 			  "Address\t\t0x%08x\t(second BAR address)\n"
538e916697fSRasesh Mody 			  "FID\t\t0x%04x\t\t(Opaque FID)\n"
539e916697fSRasesh Mody 			  "Size\t\t0x%04x\t\t(in bytes)\n"
540e916697fSRasesh Mody 			  "1st drop reason\t0x%08x\t(details on first drop since last handling)\n"
54115dfc1ecSRasesh Mody 			  "Sticky reasons\t0x%08x\t(all drop reasons since last handling)\n",
542e916697fSRasesh Mody 			  address,
543e916697fSRasesh Mody 			  GET_FIELD(details, ECORE_DORQ_ATTENTION_OPAQUE),
544e916697fSRasesh Mody 			  GET_FIELD(details, ECORE_DORQ_ATTENTION_SIZE) * 4,
54515dfc1ecSRasesh Mody 			  first_drop_reason, all_drops_reason);
546e916697fSRasesh Mody 
54715dfc1ecSRasesh Mody 		rc = ecore_db_rec_handler(p_hwfn, p_ptt);
54815dfc1ecSRasesh Mody 		OSAL_DB_REC_OCCURRED(p_hwfn);
549e916697fSRasesh Mody 		if (rc != ECORE_SUCCESS)
550e916697fSRasesh Mody 			return rc;
551e6051bd6SRasesh Mody 
552e916697fSRasesh Mody 		/* clear the doorbell drop details and prepare for next drop */
553e916697fSRasesh Mody 		ecore_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0);
554e916697fSRasesh Mody 
555e916697fSRasesh Mody 		/* mark interrupt as handeld (note: even if drop was due to a
556e916697fSRasesh Mody 		 * different reason than overflow we mark as handled)
557e916697fSRasesh Mody 		 */
558e916697fSRasesh Mody 		ecore_wr(p_hwfn, p_ptt, DORQ_REG_INT_STS_WR,
559e916697fSRasesh Mody 			 DORQ_REG_INT_STS_DB_DROP |
560e916697fSRasesh Mody 			 DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR);
561e916697fSRasesh Mody 
562e916697fSRasesh Mody 		/* if there are no indications otherthan drop indications,
563e916697fSRasesh Mody 		 * success
564e916697fSRasesh Mody 		 */
565e916697fSRasesh Mody 		if ((int_sts & ~(DORQ_REG_INT_STS_DB_DROP |
566e916697fSRasesh Mody 				 DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR |
567e916697fSRasesh Mody 				 DORQ_REG_INT_STS_DORQ_FIFO_AFULL)) == 0)
568e916697fSRasesh Mody 			return ECORE_SUCCESS;
569e916697fSRasesh Mody 	}
570e916697fSRasesh Mody 
571e916697fSRasesh Mody 	/* some other indication was present - non recoverable */
572e916697fSRasesh Mody 	DP_INFO(p_hwfn, "DORQ fatal attention\n");
573e916697fSRasesh Mody 
574e6051bd6SRasesh Mody 	return ECORE_INVAL;
575e6051bd6SRasesh Mody }
576e6051bd6SRasesh Mody 
ecore_tm_attn_cb(struct ecore_hwfn * p_hwfn)577e6051bd6SRasesh Mody static enum _ecore_status_t ecore_tm_attn_cb(struct ecore_hwfn *p_hwfn)
578e6051bd6SRasesh Mody {
579e6051bd6SRasesh Mody #ifndef ASIC_ONLY
580e6051bd6SRasesh Mody 	if (CHIP_REV_IS_EMUL_B0(p_hwfn->p_dev)) {
581e6051bd6SRasesh Mody 		u32 val = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
582e6051bd6SRasesh Mody 				   TM_REG_INT_STS_1);
583e6051bd6SRasesh Mody 
584e6051bd6SRasesh Mody 		if (val & ~(TM_REG_INT_STS_1_PEND_TASK_SCAN |
585e6051bd6SRasesh Mody 			    TM_REG_INT_STS_1_PEND_CONN_SCAN))
586e6051bd6SRasesh Mody 			return ECORE_INVAL;
587e6051bd6SRasesh Mody 
588e6051bd6SRasesh Mody 		if (val & (TM_REG_INT_STS_1_PEND_TASK_SCAN |
589e6051bd6SRasesh Mody 			   TM_REG_INT_STS_1_PEND_CONN_SCAN))
590e6051bd6SRasesh Mody 			DP_INFO(p_hwfn,
591e6051bd6SRasesh Mody 				"TM attention on emulation - most likely"
592e6051bd6SRasesh Mody 				" results of clock-ratios\n");
593e6051bd6SRasesh Mody 		val = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, TM_REG_INT_MASK_1);
594e6051bd6SRasesh Mody 		val |= TM_REG_INT_MASK_1_PEND_CONN_SCAN |
595e6051bd6SRasesh Mody 		    TM_REG_INT_MASK_1_PEND_TASK_SCAN;
596e6051bd6SRasesh Mody 		ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, TM_REG_INT_MASK_1, val);
597e6051bd6SRasesh Mody 
598e6051bd6SRasesh Mody 		return ECORE_SUCCESS;
599e6051bd6SRasesh Mody 	}
600e6051bd6SRasesh Mody #endif
601e6051bd6SRasesh Mody 
602e6051bd6SRasesh Mody 	return ECORE_INVAL;
603e6051bd6SRasesh Mody }
604e6051bd6SRasesh Mody 
605121f1cbdSRasesh Mody /* Instead of major changes to the data-structure, we have a some 'special'
606121f1cbdSRasesh Mody  * identifiers for sources that changed meaning between adapters.
607121f1cbdSRasesh Mody  */
608121f1cbdSRasesh Mody enum aeu_invert_reg_special_type {
609121f1cbdSRasesh Mody 	AEU_INVERT_REG_SPECIAL_CNIG_0,
610121f1cbdSRasesh Mody 	AEU_INVERT_REG_SPECIAL_CNIG_1,
611121f1cbdSRasesh Mody 	AEU_INVERT_REG_SPECIAL_CNIG_2,
612121f1cbdSRasesh Mody 	AEU_INVERT_REG_SPECIAL_CNIG_3,
6133b307c55SRasesh Mody 	AEU_INVERT_REG_SPECIAL_MCP_UMP_TX,
6143b307c55SRasesh Mody 	AEU_INVERT_REG_SPECIAL_MCP_SCPAD,
615121f1cbdSRasesh Mody 	AEU_INVERT_REG_SPECIAL_MAX,
616121f1cbdSRasesh Mody };
617121f1cbdSRasesh Mody 
618121f1cbdSRasesh Mody static struct aeu_invert_reg_bit
619121f1cbdSRasesh Mody aeu_descs_special[AEU_INVERT_REG_SPECIAL_MAX] = {
620121f1cbdSRasesh Mody 	{"CNIG port 0", ATTENTION_SINGLE, OSAL_NULL, BLOCK_CNIG},
621121f1cbdSRasesh Mody 	{"CNIG port 1", ATTENTION_SINGLE, OSAL_NULL, BLOCK_CNIG},
622121f1cbdSRasesh Mody 	{"CNIG port 2", ATTENTION_SINGLE, OSAL_NULL, BLOCK_CNIG},
623121f1cbdSRasesh Mody 	{"CNIG port 3", ATTENTION_SINGLE, OSAL_NULL, BLOCK_CNIG},
6243b307c55SRasesh Mody 	{"MCP Latched ump_tx", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
6253b307c55SRasesh Mody 	{"MCP Latched scratchpad", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
626121f1cbdSRasesh Mody };
627121f1cbdSRasesh Mody 
628e6051bd6SRasesh Mody /* Notice aeu_invert_reg must be defined in the same order of bits as HW; */
629e6051bd6SRasesh Mody static struct aeu_invert_reg aeu_descs[NUM_ATTN_REGS] = {
630e6051bd6SRasesh Mody 	{
631e6051bd6SRasesh Mody 	 {			/* After Invert 1 */
632e6051bd6SRasesh Mody 	  {"GPIO0 function%d", (32 << ATTENTION_LENGTH_SHIFT), OSAL_NULL,
633e6051bd6SRasesh Mody 	   MAX_BLOCK_ID},
634e6051bd6SRasesh Mody 	  }
635e6051bd6SRasesh Mody 	 },
636e6051bd6SRasesh Mody 
637e6051bd6SRasesh Mody 	{
638e6051bd6SRasesh Mody 	 {			/* After Invert 2 */
639e6051bd6SRasesh Mody 	  {"PGLUE config_space", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
640e6051bd6SRasesh Mody 	  {"PGLUE misc_flr", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
64160c78a5eSRasesh Mody 	  {"PGLUE B RBC", ATTENTION_PAR_INT, ecore_pglueb_rbc_attn_cb,
642e6051bd6SRasesh Mody 	   BLOCK_PGLUE_B},
643e6051bd6SRasesh Mody 	  {"PGLUE misc_mctp", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
644e6051bd6SRasesh Mody 	  {"Flash event", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
645e6051bd6SRasesh Mody 	  {"SMB event", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
646e6051bd6SRasesh Mody 	  {"Main Power", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
647e6051bd6SRasesh Mody 	  {"SW timers #%d",
648e6051bd6SRasesh Mody 	   (8 << ATTENTION_LENGTH_SHIFT) | (1 << ATTENTION_OFFSET_SHIFT),
649e6051bd6SRasesh Mody 	   OSAL_NULL, MAX_BLOCK_ID},
650e6051bd6SRasesh Mody 	  {"PCIE glue/PXP VPD %d", (16 << ATTENTION_LENGTH_SHIFT), OSAL_NULL,
651e6051bd6SRasesh Mody 	   BLOCK_PGLCS},
652e6051bd6SRasesh Mody 	  }
653e6051bd6SRasesh Mody 	 },
654e6051bd6SRasesh Mody 
655e6051bd6SRasesh Mody 	{
656e6051bd6SRasesh Mody 	 {			/* After Invert 3 */
657e6051bd6SRasesh Mody 	  {"General Attention %d", (32 << ATTENTION_LENGTH_SHIFT), OSAL_NULL,
658e6051bd6SRasesh Mody 	   MAX_BLOCK_ID},
659e6051bd6SRasesh Mody 	  }
660e6051bd6SRasesh Mody 	 },
661e6051bd6SRasesh Mody 
662e6051bd6SRasesh Mody 	{
663e6051bd6SRasesh Mody 	 {			/* After Invert 4 */
664e6051bd6SRasesh Mody 	  {"General Attention 32", ATTENTION_SINGLE | ATTENTION_CLEAR_ENABLE,
665e6051bd6SRasesh Mody 	   ecore_fw_assertion, MAX_BLOCK_ID},
666e6051bd6SRasesh Mody 	  {"General Attention %d",
667e6051bd6SRasesh Mody 	   (2 << ATTENTION_LENGTH_SHIFT) | (33 << ATTENTION_OFFSET_SHIFT),
668e6051bd6SRasesh Mody 	   OSAL_NULL, MAX_BLOCK_ID},
669e6051bd6SRasesh Mody 	  {"General Attention 35", ATTENTION_SINGLE | ATTENTION_CLEAR_ENABLE,
670e6051bd6SRasesh Mody 	   ecore_general_attention_35, MAX_BLOCK_ID},
671121f1cbdSRasesh Mody 	  {"NWS Parity", ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
672121f1cbdSRasesh Mody 			 ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_0),
673121f1cbdSRasesh Mody 			 OSAL_NULL, BLOCK_NWS},
674121f1cbdSRasesh Mody 	  {"NWS Interrupt", ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
675121f1cbdSRasesh Mody 			    ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_1),
676121f1cbdSRasesh Mody 			    OSAL_NULL, BLOCK_NWS},
677121f1cbdSRasesh Mody 	  {"NWM Parity", ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
678121f1cbdSRasesh Mody 			 ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_2),
679121f1cbdSRasesh Mody 			 OSAL_NULL, BLOCK_NWM},
680121f1cbdSRasesh Mody 	  {"NWM Interrupt", ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
681121f1cbdSRasesh Mody 			    ATTENTION_BB(AEU_INVERT_REG_SPECIAL_CNIG_3),
682121f1cbdSRasesh Mody 			    OSAL_NULL, BLOCK_NWM},
683e6051bd6SRasesh Mody 	  {"MCP CPU", ATTENTION_SINGLE, ecore_mcp_attn_cb, MAX_BLOCK_ID},
684e6051bd6SRasesh Mody 	  {"MCP Watchdog timer", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
685e6051bd6SRasesh Mody 	  {"MCP M2P", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
686e6051bd6SRasesh Mody 	  {"AVS stop status ready", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
687e6051bd6SRasesh Mody 	  {"MSTAT", ATTENTION_PAR_INT, OSAL_NULL, MAX_BLOCK_ID},
688e6051bd6SRasesh Mody 	  {"MSTAT per-path", ATTENTION_PAR_INT, OSAL_NULL, MAX_BLOCK_ID},
6893b307c55SRasesh Mody 			{"OPTE", ATTENTION_PAR, OSAL_NULL, BLOCK_OPTE},
6903b307c55SRasesh Mody 			{"MCP", ATTENTION_PAR, OSAL_NULL, BLOCK_MCP},
6913b307c55SRasesh Mody 			{"MS", ATTENTION_SINGLE, OSAL_NULL, BLOCK_MS},
6923b307c55SRasesh Mody 			{"UMAC", ATTENTION_SINGLE, OSAL_NULL, BLOCK_UMAC},
6933b307c55SRasesh Mody 			{"LED", ATTENTION_SINGLE, OSAL_NULL, BLOCK_LED},
6943b307c55SRasesh Mody 			{"BMBN", ATTENTION_SINGLE, OSAL_NULL, BLOCK_BMBN},
695c018d2b4SRasesh Mody 	  {"NIG", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_NIG},
696e6051bd6SRasesh Mody 	  {"BMB/OPTE/MCP", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_BMB},
6973b307c55SRasesh Mody 			{"BMB", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_BMB},
698e6051bd6SRasesh Mody 	  {"BTB", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_BTB},
699e6051bd6SRasesh Mody 	  {"BRB", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_BRB},
700e6051bd6SRasesh Mody 	  {"PRS", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PRS},
701e6051bd6SRasesh Mody 	  }
702e6051bd6SRasesh Mody 	 },
703e6051bd6SRasesh Mody 
704e6051bd6SRasesh Mody 	{
705e6051bd6SRasesh Mody 	 {			/* After Invert 5 */
706e6051bd6SRasesh Mody 	  {"SRC", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_SRC},
707e6051bd6SRasesh Mody 	  {"PB Client1", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PBF_PB1},
708e6051bd6SRasesh Mody 	  {"PB Client2", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PBF_PB2},
709e6051bd6SRasesh Mody 	  {"RPB", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_RPB},
710e6051bd6SRasesh Mody 	  {"PBF", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PBF},
711e6051bd6SRasesh Mody 	  {"QM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_QM},
712e6051bd6SRasesh Mody 	  {"TM", ATTENTION_PAR_INT, ecore_tm_attn_cb, BLOCK_TM},
713e6051bd6SRasesh Mody 	  {"MCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MCM},
714e6051bd6SRasesh Mody 	  {"MSDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MSDM},
715e6051bd6SRasesh Mody 	  {"MSEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MSEM},
716e6051bd6SRasesh Mody 	  {"PCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PCM},
717e6051bd6SRasesh Mody 	  {"PSDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSDM},
718e6051bd6SRasesh Mody 	  {"PSEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSEM},
719e6051bd6SRasesh Mody 	  {"TCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TCM},
720e6051bd6SRasesh Mody 	  {"TSDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TSDM},
721e6051bd6SRasesh Mody 	  {"TSEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TSEM},
722e6051bd6SRasesh Mody 	  }
723e6051bd6SRasesh Mody 	 },
724e6051bd6SRasesh Mody 
725e6051bd6SRasesh Mody 	{
726e6051bd6SRasesh Mody 	 {			/* After Invert 6 */
727e6051bd6SRasesh Mody 	  {"UCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_UCM},
728e6051bd6SRasesh Mody 	  {"USDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_USDM},
729e6051bd6SRasesh Mody 	  {"USEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_USEM},
730e6051bd6SRasesh Mody 	  {"XCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_XCM},
731e6051bd6SRasesh Mody 	  {"XSDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_XSDM},
732e6051bd6SRasesh Mody 	  {"XSEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_XSEM},
733e6051bd6SRasesh Mody 	  {"YCM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_YCM},
734e6051bd6SRasesh Mody 	  {"YSDM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_YSDM},
735e6051bd6SRasesh Mody 	  {"YSEM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_YSEM},
736e6051bd6SRasesh Mody 	  {"XYLD", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_XYLD},
737e6051bd6SRasesh Mody 	  {"TMLD", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TMLD},
738e6051bd6SRasesh Mody 	  {"MYLD", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MULD},
739e6051bd6SRasesh Mody 	  {"YULD", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_YULD},
740e6051bd6SRasesh Mody 	  {"DORQ", ATTENTION_PAR_INT, ecore_dorq_attn_cb, BLOCK_DORQ},
741e6051bd6SRasesh Mody 	  {"DBG", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_DBG},
742e6051bd6SRasesh Mody 	  {"IPC", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_IPC},
743e6051bd6SRasesh Mody 	  }
744e6051bd6SRasesh Mody 	 },
745e6051bd6SRasesh Mody 
746e6051bd6SRasesh Mody 	{
747e6051bd6SRasesh Mody 	 {			/* After Invert 7 */
748e6051bd6SRasesh Mody 	  {"CCFC", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_CCFC},
749e6051bd6SRasesh Mody 	  {"CDU", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_CDU},
750e6051bd6SRasesh Mody 	  {"DMAE", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_DMAE},
751e6051bd6SRasesh Mody 	  {"IGU", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_IGU},
752e6051bd6SRasesh Mody 	  {"ATC", ATTENTION_PAR_INT, OSAL_NULL, MAX_BLOCK_ID},
753e6051bd6SRasesh Mody 	  {"CAU", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_CAU},
754e6051bd6SRasesh Mody 	  {"PTU", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PTU},
755e6051bd6SRasesh Mody 	  {"PRM", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PRM},
756e6051bd6SRasesh Mody 	  {"TCFC", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TCFC},
757e6051bd6SRasesh Mody 	  {"RDIF", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_RDIF},
758e6051bd6SRasesh Mody 	  {"TDIF", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_TDIF},
759e6051bd6SRasesh Mody 	  {"RSS", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_RSS},
760e6051bd6SRasesh Mody 	  {"MISC", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MISC},
761e6051bd6SRasesh Mody 	  {"MISCS", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_MISCS},
762e6051bd6SRasesh Mody 	  {"PCIE", ATTENTION_PAR, OSAL_NULL, BLOCK_PCIE},
763e6051bd6SRasesh Mody 	  {"Vaux PCI core", ATTENTION_SINGLE, OSAL_NULL, BLOCK_PGLCS},
764e6051bd6SRasesh Mody 	  {"PSWRQ", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWRQ},
765e6051bd6SRasesh Mody 	  }
766e6051bd6SRasesh Mody 	 },
767e6051bd6SRasesh Mody 
768e6051bd6SRasesh Mody 	{
769e6051bd6SRasesh Mody 	 {			/* After Invert 8 */
770e6051bd6SRasesh Mody 	  {"PSWRQ (pci_clk)", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWRQ2},
771e6051bd6SRasesh Mody 	  {"PSWWR", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWWR},
772e6051bd6SRasesh Mody 	  {"PSWWR (pci_clk)", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWWR2},
773e6051bd6SRasesh Mody 	  {"PSWRD", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWRD},
774e6051bd6SRasesh Mody 	  {"PSWRD (pci_clk)", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWRD2},
775e6051bd6SRasesh Mody 	  {"PSWHST", ATTENTION_PAR_INT, ecore_pswhst_attn_cb, BLOCK_PSWHST},
776e6051bd6SRasesh Mody 	  {"PSWHST (pci_clk)", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_PSWHST2},
777e6051bd6SRasesh Mody 	  {"GRC", ATTENTION_PAR_INT, ecore_grc_attn_cb, BLOCK_GRC},
778e6051bd6SRasesh Mody 	  {"CPMU", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_CPMU},
779e6051bd6SRasesh Mody 	  {"NCSI", ATTENTION_PAR_INT, OSAL_NULL, BLOCK_NCSI},
780e6051bd6SRasesh Mody 	  {"MSEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
781e6051bd6SRasesh Mody 	  {"PSEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
782e6051bd6SRasesh Mody 	  {"TSEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
783e6051bd6SRasesh Mody 	  {"USEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
784e6051bd6SRasesh Mody 	  {"XSEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
785e6051bd6SRasesh Mody 	  {"YSEM PRAM", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
786e6051bd6SRasesh Mody 	  {"pxp_misc_mps", ATTENTION_PAR, OSAL_NULL, BLOCK_PGLCS},
787e6051bd6SRasesh Mody 	  {"PCIE glue/PXP Exp. ROM", ATTENTION_SINGLE, OSAL_NULL, BLOCK_PGLCS},
788e6051bd6SRasesh Mody 	  {"PERST_B assertion", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
789e6051bd6SRasesh Mody 	  {"PERST_B deassertion", ATTENTION_SINGLE, OSAL_NULL, MAX_BLOCK_ID},
790e6051bd6SRasesh Mody 	  {"Reserved %d", (2 << ATTENTION_LENGTH_SHIFT), OSAL_NULL,
791e6051bd6SRasesh Mody 	   MAX_BLOCK_ID},
792e6051bd6SRasesh Mody 	  }
793e6051bd6SRasesh Mody 	 },
794e6051bd6SRasesh Mody 
795e6051bd6SRasesh Mody 	{
796e6051bd6SRasesh Mody 	 {			/* After Invert 9 */
797e6051bd6SRasesh Mody 	  {"MCP Latched memory", ATTENTION_PAR, OSAL_NULL, MAX_BLOCK_ID},
798e6051bd6SRasesh Mody 	  {"MCP Latched scratchpad cache", ATTENTION_SINGLE, OSAL_NULL,
799e6051bd6SRasesh Mody 	   MAX_BLOCK_ID},
8003b307c55SRasesh Mody 	  {"AVS", ATTENTION_PAR | ATTENTION_BB_DIFFERENT |
8013b307c55SRasesh Mody 	   ATTENTION_BB(AEU_INVERT_REG_SPECIAL_MCP_UMP_TX), OSAL_NULL,
8023b307c55SRasesh Mody 	   BLOCK_AVS_WRAP},
8033b307c55SRasesh Mody 	  {"AVS", ATTENTION_SINGLE | ATTENTION_BB_DIFFERENT |
8043b307c55SRasesh Mody 	   ATTENTION_BB(AEU_INVERT_REG_SPECIAL_MCP_SCPAD), OSAL_NULL,
8053b307c55SRasesh Mody 	   BLOCK_AVS_WRAP},
8063b307c55SRasesh Mody 	  {"PCIe core", ATTENTION_SINGLE, OSAL_NULL, BLOCK_PGLCS},
8073b307c55SRasesh Mody 	  {"PCIe link up", ATTENTION_SINGLE, OSAL_NULL, BLOCK_PGLCS},
8083b307c55SRasesh Mody 	  {"PCIe hot reset", ATTENTION_SINGLE, OSAL_NULL, BLOCK_PGLCS},
8093b307c55SRasesh Mody 	  {"Reserved %d", (9 << ATTENTION_LENGTH_SHIFT), OSAL_NULL,
810e6051bd6SRasesh Mody 	    MAX_BLOCK_ID},
811e6051bd6SRasesh Mody 	  }
812e6051bd6SRasesh Mody 	 },
813e6051bd6SRasesh Mody 
814e6051bd6SRasesh Mody };
815e6051bd6SRasesh Mody 
816121f1cbdSRasesh Mody static struct aeu_invert_reg_bit *
ecore_int_aeu_translate(struct ecore_hwfn * p_hwfn,struct aeu_invert_reg_bit * p_bit)817121f1cbdSRasesh Mody ecore_int_aeu_translate(struct ecore_hwfn *p_hwfn,
818121f1cbdSRasesh Mody 			struct aeu_invert_reg_bit *p_bit)
819121f1cbdSRasesh Mody {
820121f1cbdSRasesh Mody 	if (!ECORE_IS_BB(p_hwfn->p_dev))
821121f1cbdSRasesh Mody 		return p_bit;
822121f1cbdSRasesh Mody 
823121f1cbdSRasesh Mody 	if (!(p_bit->flags & ATTENTION_BB_DIFFERENT))
824121f1cbdSRasesh Mody 		return p_bit;
825121f1cbdSRasesh Mody 
826121f1cbdSRasesh Mody 	return &aeu_descs_special[(p_bit->flags & ATTENTION_BB_MASK) >>
827121f1cbdSRasesh Mody 				  ATTENTION_BB_SHIFT];
828121f1cbdSRasesh Mody }
829121f1cbdSRasesh Mody 
ecore_int_is_parity_flag(struct ecore_hwfn * p_hwfn,struct aeu_invert_reg_bit * p_bit)830121f1cbdSRasesh Mody static bool ecore_int_is_parity_flag(struct ecore_hwfn *p_hwfn,
831121f1cbdSRasesh Mody 				     struct aeu_invert_reg_bit *p_bit)
832121f1cbdSRasesh Mody {
833121f1cbdSRasesh Mody 	return !!(ecore_int_aeu_translate(p_hwfn, p_bit)->flags &
834121f1cbdSRasesh Mody 		  ATTENTION_PARITY);
835121f1cbdSRasesh Mody }
836121f1cbdSRasesh Mody 
837ec94dbc5SRasesh Mody #define ATTN_STATE_BITS		(0xfff)
838ec94dbc5SRasesh Mody #define ATTN_BITS_MASKABLE	(0x3ff)
839ec94dbc5SRasesh Mody struct ecore_sb_attn_info {
840ec94dbc5SRasesh Mody 	/* Virtual & Physical address of the SB */
841ec94dbc5SRasesh Mody 	struct atten_status_block *sb_attn;
842ec94dbc5SRasesh Mody 	dma_addr_t sb_phys;
843ec94dbc5SRasesh Mody 
844ec94dbc5SRasesh Mody 	/* Last seen running index */
845ec94dbc5SRasesh Mody 	u16 index;
846ec94dbc5SRasesh Mody 
847ec94dbc5SRasesh Mody 	/* A mask of the AEU bits resulting in a parity error */
848ec94dbc5SRasesh Mody 	u32 parity_mask[NUM_ATTN_REGS];
849ec94dbc5SRasesh Mody 
850ec94dbc5SRasesh Mody 	/* A pointer to the attention description structure */
851ec94dbc5SRasesh Mody 	struct aeu_invert_reg *p_aeu_desc;
852ec94dbc5SRasesh Mody 
853ec94dbc5SRasesh Mody 	/* Previously asserted attentions, which are still unasserted */
854ec94dbc5SRasesh Mody 	u16 known_attn;
855ec94dbc5SRasesh Mody 
856ec94dbc5SRasesh Mody 	/* Cleanup address for the link's general hw attention */
857ec94dbc5SRasesh Mody 	u32 mfw_attn_addr;
858ec94dbc5SRasesh Mody };
859ec94dbc5SRasesh Mody 
ecore_attn_update_idx(struct ecore_hwfn * p_hwfn,struct ecore_sb_attn_info * p_sb_desc)860ec94dbc5SRasesh Mody static u16 ecore_attn_update_idx(struct ecore_hwfn *p_hwfn,
861ec94dbc5SRasesh Mody 				 struct ecore_sb_attn_info *p_sb_desc)
862ec94dbc5SRasesh Mody {
863ec94dbc5SRasesh Mody 	u16 rc = 0, index;
864ec94dbc5SRasesh Mody 
865ec94dbc5SRasesh Mody 	OSAL_MMIOWB(p_hwfn->p_dev);
866ec94dbc5SRasesh Mody 
867ec94dbc5SRasesh Mody 	index = OSAL_LE16_TO_CPU(p_sb_desc->sb_attn->sb_index);
868ec94dbc5SRasesh Mody 	if (p_sb_desc->index != index) {
869ec94dbc5SRasesh Mody 		p_sb_desc->index = index;
870ec94dbc5SRasesh Mody 		rc = ECORE_SB_ATT_IDX;
871ec94dbc5SRasesh Mody 	}
872ec94dbc5SRasesh Mody 
873ec94dbc5SRasesh Mody 	OSAL_MMIOWB(p_hwfn->p_dev);
874ec94dbc5SRasesh Mody 
875ec94dbc5SRasesh Mody 	return rc;
876ec94dbc5SRasesh Mody }
877ec94dbc5SRasesh Mody 
878e6051bd6SRasesh Mody /**
879e6051bd6SRasesh Mody  * @brief ecore_int_assertion - handles asserted attention bits
880e6051bd6SRasesh Mody  *
881e6051bd6SRasesh Mody  * @param p_hwfn
882e6051bd6SRasesh Mody  * @param asserted_bits newly asserted bits
883e6051bd6SRasesh Mody  * @return enum _ecore_status_t
884e6051bd6SRasesh Mody  */
ecore_int_assertion(struct ecore_hwfn * p_hwfn,u16 asserted_bits)885e6051bd6SRasesh Mody static enum _ecore_status_t ecore_int_assertion(struct ecore_hwfn *p_hwfn,
886e6051bd6SRasesh Mody 						u16 asserted_bits)
887e6051bd6SRasesh Mody {
888e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *sb_attn_sw = p_hwfn->p_sb_attn;
889e6051bd6SRasesh Mody 	u32 igu_mask;
890e6051bd6SRasesh Mody 
891e6051bd6SRasesh Mody 	/* Mask the source of the attention in the IGU */
892e6051bd6SRasesh Mody 	igu_mask = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
893e6051bd6SRasesh Mody 			    IGU_REG_ATTENTION_ENABLE);
894e6051bd6SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "IGU mask: 0x%08x --> 0x%08x\n",
895e6051bd6SRasesh Mody 		   igu_mask, igu_mask & ~(asserted_bits & ATTN_BITS_MASKABLE));
896e6051bd6SRasesh Mody 	igu_mask &= ~(asserted_bits & ATTN_BITS_MASKABLE);
897e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, IGU_REG_ATTENTION_ENABLE, igu_mask);
898e6051bd6SRasesh Mody 
899e6051bd6SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
900e6051bd6SRasesh Mody 		   "inner known ATTN state: 0x%04x --> 0x%04x\n",
901e6051bd6SRasesh Mody 		   sb_attn_sw->known_attn,
902e6051bd6SRasesh Mody 		   sb_attn_sw->known_attn | asserted_bits);
903e6051bd6SRasesh Mody 	sb_attn_sw->known_attn |= asserted_bits;
904e6051bd6SRasesh Mody 
905e6051bd6SRasesh Mody 	/* Handle MCP events */
906e6051bd6SRasesh Mody 	if (asserted_bits & 0x100) {
907e6051bd6SRasesh Mody 		ecore_mcp_handle_events(p_hwfn, p_hwfn->p_dpc_ptt);
908e6051bd6SRasesh Mody 		/* Clean the MCP attention */
909e6051bd6SRasesh Mody 		ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt,
910e6051bd6SRasesh Mody 			 sb_attn_sw->mfw_attn_addr, 0);
911e6051bd6SRasesh Mody 	}
912e6051bd6SRasesh Mody 
913e6051bd6SRasesh Mody 	/* FIXME - this will change once we'll have GOOD gtt definitions */
914e6051bd6SRasesh Mody 	DIRECT_REG_WR(p_hwfn,
915e6051bd6SRasesh Mody 		      (u8 OSAL_IOMEM *) p_hwfn->regview +
916e6051bd6SRasesh Mody 		      GTT_BAR0_MAP_REG_IGU_CMD +
917e6051bd6SRasesh Mody 		      ((IGU_CMD_ATTN_BIT_SET_UPPER -
918e6051bd6SRasesh Mody 			IGU_CMD_INT_ACK_BASE) << 3), (u32)asserted_bits);
919e6051bd6SRasesh Mody 
920e6051bd6SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "set cmd IGU: 0x%04x\n",
921e6051bd6SRasesh Mody 		   asserted_bits);
922e6051bd6SRasesh Mody 
923e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
924e6051bd6SRasesh Mody }
925e6051bd6SRasesh Mody 
ecore_int_attn_print(struct ecore_hwfn * p_hwfn,enum block_id id,enum dbg_attn_type type,bool b_clear)92622d07d93SRasesh Mody static void ecore_int_attn_print(struct ecore_hwfn *p_hwfn,
92722d07d93SRasesh Mody 				 enum block_id id, enum dbg_attn_type type,
92822d07d93SRasesh Mody 				 bool b_clear)
929e6051bd6SRasesh Mody {
93022d07d93SRasesh Mody 	/* @DPDK */
931218d5484SIgor Russkikh 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "[block_id %d type %d]\n", id, type);
932e6051bd6SRasesh Mody }
933e6051bd6SRasesh Mody 
934e6051bd6SRasesh Mody /**
935e6051bd6SRasesh Mody  * @brief ecore_int_deassertion_aeu_bit - handles the effects of a single
936e6051bd6SRasesh Mody  * cause of the attention
937e6051bd6SRasesh Mody  *
938e6051bd6SRasesh Mody  * @param p_hwfn
939e6051bd6SRasesh Mody  * @param p_aeu - descriptor of an AEU bit which caused the attention
940e6051bd6SRasesh Mody  * @param aeu_en_reg - register offset of the AEU enable reg. which configured
941e6051bd6SRasesh Mody  *  this bit to this group.
942e6051bd6SRasesh Mody  * @param bit_index - index of this bit in the aeu_en_reg
943e6051bd6SRasesh Mody  *
944e6051bd6SRasesh Mody  * @return enum _ecore_status_t
945e6051bd6SRasesh Mody  */
946e6051bd6SRasesh Mody static enum _ecore_status_t
ecore_int_deassertion_aeu_bit(struct ecore_hwfn * p_hwfn,struct aeu_invert_reg_bit * p_aeu,u32 aeu_en_reg,const char * p_bit_name,u32 bitmask)947e6051bd6SRasesh Mody ecore_int_deassertion_aeu_bit(struct ecore_hwfn *p_hwfn,
948e6051bd6SRasesh Mody 			      struct aeu_invert_reg_bit *p_aeu,
9498427c664SRasesh Mody 			      u32 aeu_en_reg,
9508427c664SRasesh Mody 			      const char *p_bit_name,
9518427c664SRasesh Mody 			      u32 bitmask)
952e6051bd6SRasesh Mody {
953e6051bd6SRasesh Mody 	enum _ecore_status_t rc = ECORE_INVAL;
95422d07d93SRasesh Mody 	bool b_fatal = false;
955e6051bd6SRasesh Mody 
956e6051bd6SRasesh Mody 	DP_INFO(p_hwfn, "Deasserted attention `%s'[%08x]\n",
9578427c664SRasesh Mody 		p_bit_name, bitmask);
958e6051bd6SRasesh Mody 
959e6051bd6SRasesh Mody 	/* Call callback before clearing the interrupt status */
960e6051bd6SRasesh Mody 	if (p_aeu->cb) {
961e6051bd6SRasesh Mody 		DP_INFO(p_hwfn, "`%s (attention)': Calling Callback function\n",
9628427c664SRasesh Mody 			p_bit_name);
963e6051bd6SRasesh Mody 		rc = p_aeu->cb(p_hwfn);
964e6051bd6SRasesh Mody 	}
965e6051bd6SRasesh Mody 
96622d07d93SRasesh Mody 	if (rc != ECORE_SUCCESS)
96722d07d93SRasesh Mody 		b_fatal = true;
96822d07d93SRasesh Mody 
969c018d2b4SRasesh Mody 	/* Print HW block interrupt registers */
97022d07d93SRasesh Mody 	if (p_aeu->block_index != MAX_BLOCK_ID) {
97122d07d93SRasesh Mody 		ecore_int_attn_print(p_hwfn, p_aeu->block_index,
97222d07d93SRasesh Mody 				     ATTN_TYPE_INTERRUPT, !b_fatal);
97322d07d93SRasesh Mody }
974e6051bd6SRasesh Mody 
97560c78a5eSRasesh Mody 	/* @DPDK */
976e6051bd6SRasesh Mody 	/* Reach assertion if attention is fatal */
97760c78a5eSRasesh Mody 	if (b_fatal || (strcmp(p_bit_name, "PGLUE B RBC") == 0)) {
9783b307c55SRasesh Mody #ifndef ASIC_ONLY
9793b307c55SRasesh Mody 		DP_NOTICE(p_hwfn, !CHIP_REV_IS_EMUL(p_hwfn->p_dev),
9803b307c55SRasesh Mody 			  "`%s': Fatal attention\n", p_bit_name);
9813b307c55SRasesh Mody #else
982e6051bd6SRasesh Mody 		DP_NOTICE(p_hwfn, true, "`%s': Fatal attention\n",
9838427c664SRasesh Mody 			  p_bit_name);
9843b307c55SRasesh Mody #endif
985e6051bd6SRasesh Mody 
986e6051bd6SRasesh Mody 		ecore_hw_err_notify(p_hwfn, ECORE_HW_ERR_HW_ATTN);
987e6051bd6SRasesh Mody 	}
988e6051bd6SRasesh Mody 
989e6051bd6SRasesh Mody 	/* Prevent this Attention from being asserted in the future */
99022d07d93SRasesh Mody 	if (p_aeu->flags & ATTENTION_CLEAR_ENABLE ||
9913b307c55SRasesh Mody #ifndef ASIC_ONLY
9923b307c55SRasesh Mody 	    CHIP_REV_IS_EMUL(p_hwfn->p_dev) ||
9933b307c55SRasesh Mody #endif
99422d07d93SRasesh Mody 	    p_hwfn->p_dev->attn_clr_en) {
995e6051bd6SRasesh Mody 		u32 val;
996e6051bd6SRasesh Mody 		u32 mask = ~bitmask;
997e6051bd6SRasesh Mody 		val = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
998e6051bd6SRasesh Mody 		ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, (val & mask));
999e1c9b999SHarish Patil 		DP_ERR(p_hwfn, "`%s' - Disabled future attentions\n",
10008427c664SRasesh Mody 			p_bit_name);
1001e6051bd6SRasesh Mody 	}
1002e6051bd6SRasesh Mody 
1003e6051bd6SRasesh Mody 	return rc;
1004e6051bd6SRasesh Mody }
1005e6051bd6SRasesh Mody 
1006e6051bd6SRasesh Mody /**
1007e6051bd6SRasesh Mody  * @brief ecore_int_deassertion_parity - handle a single parity AEU source
1008e6051bd6SRasesh Mody  *
1009e6051bd6SRasesh Mody  * @param p_hwfn
1010e4782d30SRasesh Mody  * @param p_aeu - descriptor of an AEU bit which caused the parity
1011e4782d30SRasesh Mody  * @param aeu_en_reg - address of the AEU enable register
1012e6051bd6SRasesh Mody  * @param bit_index
1013e6051bd6SRasesh Mody  */
ecore_int_deassertion_parity(struct ecore_hwfn * p_hwfn,struct aeu_invert_reg_bit * p_aeu,u32 aeu_en_reg,u8 bit_index)1014e6051bd6SRasesh Mody static void ecore_int_deassertion_parity(struct ecore_hwfn *p_hwfn,
1015e6051bd6SRasesh Mody 					 struct aeu_invert_reg_bit *p_aeu,
1016e4782d30SRasesh Mody 					 u32 aeu_en_reg, u8 bit_index)
1017e6051bd6SRasesh Mody {
1018e4782d30SRasesh Mody 	u32 block_id = p_aeu->block_index, mask, val;
1019e6051bd6SRasesh Mody 
1020e4782d30SRasesh Mody 	DP_NOTICE(p_hwfn->p_dev, false,
1021e4782d30SRasesh Mody 		  "%s parity attention is set [address 0x%08x, bit %d]\n",
1022e4782d30SRasesh Mody 		  p_aeu->bit_name, aeu_en_reg, bit_index);
1023e6051bd6SRasesh Mody 
1024e4782d30SRasesh Mody 	if (block_id != MAX_BLOCK_ID) {
1025e4782d30SRasesh Mody 		ecore_int_attn_print(p_hwfn, block_id, ATTN_TYPE_PARITY, false);
102622d07d93SRasesh Mody 
1027e6051bd6SRasesh Mody 		/* In A0, there's a single parity bit for several blocks */
1028e6051bd6SRasesh Mody 		if (block_id == BLOCK_BTB) {
102922d07d93SRasesh Mody 			ecore_int_attn_print(p_hwfn, BLOCK_OPTE,
103022d07d93SRasesh Mody 					     ATTN_TYPE_PARITY, false);
103122d07d93SRasesh Mody 			ecore_int_attn_print(p_hwfn, BLOCK_MCP,
103222d07d93SRasesh Mody 					     ATTN_TYPE_PARITY, false);
1033e6051bd6SRasesh Mody 		}
1034e6051bd6SRasesh Mody 	}
1035e6051bd6SRasesh Mody 
1036e4782d30SRasesh Mody 	/* Prevent this parity error from being re-asserted */
1037e4782d30SRasesh Mody 	mask = ~(0x1 << bit_index);
1038e4782d30SRasesh Mody 	val = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg);
1039e4782d30SRasesh Mody 	ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en_reg, val & mask);
1040e4782d30SRasesh Mody 	DP_INFO(p_hwfn, "`%s' - Disabled future parity errors\n",
1041e4782d30SRasesh Mody 		p_aeu->bit_name);
1042e4782d30SRasesh Mody }
1043e4782d30SRasesh Mody 
10443b307c55SRasesh Mody #define MISC_REG_AEU_AFTER_INVERT_IGU(n) \
10453b307c55SRasesh Mody 	(MISC_REG_AEU_AFTER_INVERT_1_IGU + (n) * 0x4)
10463b307c55SRasesh Mody 
10473b307c55SRasesh Mody #define MISC_REG_AEU_ENABLE_IGU_OUT(n, group) \
10483b307c55SRasesh Mody 	(MISC_REG_AEU_ENABLE1_IGU_OUT_0 + (n) * 0x4 + \
10493b307c55SRasesh Mody 	 (group) * 0x4 * NUM_ATTN_REGS)
10503b307c55SRasesh Mody 
1051e6051bd6SRasesh Mody /**
1052e6051bd6SRasesh Mody  * @brief - handles deassertion of previously asserted attentions.
1053e6051bd6SRasesh Mody  *
1054e6051bd6SRasesh Mody  * @param p_hwfn
1055e6051bd6SRasesh Mody  * @param deasserted_bits - newly deasserted bits
1056e6051bd6SRasesh Mody  * @return enum _ecore_status_t
1057e6051bd6SRasesh Mody  *
1058e6051bd6SRasesh Mody  */
ecore_int_deassertion(struct ecore_hwfn * p_hwfn,u16 deasserted_bits)1059e6051bd6SRasesh Mody static enum _ecore_status_t ecore_int_deassertion(struct ecore_hwfn *p_hwfn,
1060e6051bd6SRasesh Mody 						  u16 deasserted_bits)
1061e6051bd6SRasesh Mody {
1062e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *sb_attn_sw = p_hwfn->p_sb_attn;
1063e4782d30SRasesh Mody 	u32 aeu_inv_arr[NUM_ATTN_REGS], aeu_mask, aeu_en, en;
1064e6051bd6SRasesh Mody 	u8 i, j, k, bit_idx;
1065e6051bd6SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
1066e6051bd6SRasesh Mody 
1067e6051bd6SRasesh Mody 	/* Read the attention registers in the AEU */
1068e6051bd6SRasesh Mody 	for (i = 0; i < NUM_ATTN_REGS; i++) {
1069e6051bd6SRasesh Mody 		aeu_inv_arr[i] = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
10703b307c55SRasesh Mody 					  MISC_REG_AEU_AFTER_INVERT_IGU(i));
1071e6051bd6SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
1072e6051bd6SRasesh Mody 			   "Deasserted bits [%d]: %08x\n", i, aeu_inv_arr[i]);
1073e6051bd6SRasesh Mody 	}
1074e6051bd6SRasesh Mody 
1075e6051bd6SRasesh Mody 	/* Handle parity attentions first */
1076e6051bd6SRasesh Mody 	for (i = 0; i < NUM_ATTN_REGS; i++) {
1077e6051bd6SRasesh Mody 		struct aeu_invert_reg *p_aeu = &sb_attn_sw->p_aeu_desc[i];
1078e4782d30SRasesh Mody 		u32 parities;
1079e6051bd6SRasesh Mody 
10803b307c55SRasesh Mody 		aeu_en = MISC_REG_AEU_ENABLE_IGU_OUT(i, 0);
1081e4782d30SRasesh Mody 		en = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
1082e4782d30SRasesh Mody 		parities = sb_attn_sw->parity_mask[i] & aeu_inv_arr[i] & en;
1083e6051bd6SRasesh Mody 
1084e6051bd6SRasesh Mody 		/* Skip register in which no parity bit is currently set */
1085e6051bd6SRasesh Mody 		if (!parities)
1086e6051bd6SRasesh Mody 			continue;
1087e6051bd6SRasesh Mody 
1088e6051bd6SRasesh Mody 		for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
1089e6051bd6SRasesh Mody 			struct aeu_invert_reg_bit *p_bit = &p_aeu->bits[j];
1090e6051bd6SRasesh Mody 
1091121f1cbdSRasesh Mody 			if (ecore_int_is_parity_flag(p_hwfn, p_bit) &&
1092e4782d30SRasesh Mody 			    !!(parities & (1 << bit_idx)))
1093e6051bd6SRasesh Mody 				ecore_int_deassertion_parity(p_hwfn, p_bit,
1094e4782d30SRasesh Mody 							     aeu_en, bit_idx);
1095e6051bd6SRasesh Mody 
1096e6051bd6SRasesh Mody 			bit_idx += ATTENTION_LENGTH(p_bit->flags);
1097e6051bd6SRasesh Mody 		}
1098e6051bd6SRasesh Mody 	}
1099e6051bd6SRasesh Mody 
1100e6051bd6SRasesh Mody 	/* Find non-parity cause for attention and act */
1101e6051bd6SRasesh Mody 	for (k = 0; k < MAX_ATTN_GRPS; k++) {
1102e6051bd6SRasesh Mody 		struct aeu_invert_reg_bit *p_aeu;
1103e6051bd6SRasesh Mody 
1104e6051bd6SRasesh Mody 		/* Handle only groups whose attention is currently deasserted */
1105e6051bd6SRasesh Mody 		if (!(deasserted_bits & (1 << k)))
1106e6051bd6SRasesh Mody 			continue;
1107e6051bd6SRasesh Mody 
1108e6051bd6SRasesh Mody 		for (i = 0; i < NUM_ATTN_REGS; i++) {
1109e4782d30SRasesh Mody 			u32 bits;
1110e4782d30SRasesh Mody 
11113b307c55SRasesh Mody 			aeu_en = MISC_REG_AEU_ENABLE_IGU_OUT(i, k);
1112e4782d30SRasesh Mody 			en = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt, aeu_en);
1113e4782d30SRasesh Mody 			bits = aeu_inv_arr[i] & en;
1114e6051bd6SRasesh Mody 
1115e6051bd6SRasesh Mody 			/* Skip if no bit from this group is currently set */
1116e6051bd6SRasesh Mody 			if (!bits)
1117e6051bd6SRasesh Mody 				continue;
1118e6051bd6SRasesh Mody 
1119e6051bd6SRasesh Mody 			/* Find all set bits from current register which belong
1120e6051bd6SRasesh Mody 			 * to current group, making them responsible for the
1121e6051bd6SRasesh Mody 			 * previous assertion.
1122e6051bd6SRasesh Mody 			 */
1123e6051bd6SRasesh Mody 			for (j = 0, bit_idx = 0; bit_idx < 32; j++) {
11249455b556SRasesh Mody 				unsigned long int bitmask;
1125e6051bd6SRasesh Mody 				u8 bit, bit_len;
1126e6051bd6SRasesh Mody 
1127121f1cbdSRasesh Mody 				/* Need to account bits with changed meaning */
1128e6051bd6SRasesh Mody 				p_aeu = &sb_attn_sw->p_aeu_desc[i].bits[j];
1129e6051bd6SRasesh Mody 
1130e6051bd6SRasesh Mody 				bit = bit_idx;
1131e6051bd6SRasesh Mody 				bit_len = ATTENTION_LENGTH(p_aeu->flags);
1132121f1cbdSRasesh Mody 				if (ecore_int_is_parity_flag(p_hwfn, p_aeu)) {
1133e6051bd6SRasesh Mody 					/* Skip Parity */
1134e6051bd6SRasesh Mody 					bit++;
1135e6051bd6SRasesh Mody 					bit_len--;
1136e6051bd6SRasesh Mody 				}
1137e6051bd6SRasesh Mody 
1138cf584e02SRasesh Mody 				/* Find the bits relating to HW-block, then
1139cf584e02SRasesh Mody 				 * shift so they'll become LSB.
1140cf584e02SRasesh Mody 				 */
1141e6051bd6SRasesh Mody 				bitmask = bits & (((1 << bit_len) - 1) << bit);
1142cf584e02SRasesh Mody 				bitmask >>= bit;
1143cf584e02SRasesh Mody 
1144e6051bd6SRasesh Mody 				if (bitmask) {
11458427c664SRasesh Mody 					u32 flags = p_aeu->flags;
11468427c664SRasesh Mody 					char bit_name[30];
1147cf584e02SRasesh Mody 					u8 num;
11488427c664SRasesh Mody 
1149cf584e02SRasesh Mody 					num = (u8)OSAL_FIND_FIRST_BIT(&bitmask,
11508427c664SRasesh Mody 								bit_len);
11518427c664SRasesh Mody 
11528427c664SRasesh Mody 					/* Some bits represent more than a
11538427c664SRasesh Mody 					 * a single interrupt. Correctly print
11548427c664SRasesh Mody 					 * their name.
11558427c664SRasesh Mody 					 */
11568427c664SRasesh Mody 					if (ATTENTION_LENGTH(flags) > 2 ||
11578427c664SRasesh Mody 					    ((flags & ATTENTION_PAR_INT) &&
11588427c664SRasesh Mody 					    ATTENTION_LENGTH(flags) > 1))
11598427c664SRasesh Mody 						OSAL_SNPRINTF(bit_name, 30,
11608427c664SRasesh Mody 							      p_aeu->bit_name,
1161cf584e02SRasesh Mody 							      num);
11628427c664SRasesh Mody 					else
11630fa4f3eeSAndy Green 						strlcpy(bit_name,
11648427c664SRasesh Mody 							p_aeu->bit_name,
11650fa4f3eeSAndy Green 							sizeof(bit_name));
1166cf584e02SRasesh Mody 
1167cf584e02SRasesh Mody 					/* We now need to pass bitmask in its
1168cf584e02SRasesh Mody 					 * correct position.
1169cf584e02SRasesh Mody 					 */
1170cf584e02SRasesh Mody 					bitmask <<= bit;
1171cf584e02SRasesh Mody 
1172e6051bd6SRasesh Mody 					/* Handle source of the attention */
1173e6051bd6SRasesh Mody 					ecore_int_deassertion_aeu_bit(p_hwfn,
1174e6051bd6SRasesh Mody 								      p_aeu,
1175e6051bd6SRasesh Mody 								      aeu_en,
11768427c664SRasesh Mody 								      bit_name,
1177e6051bd6SRasesh Mody 								      bitmask);
1178e6051bd6SRasesh Mody 				}
1179e6051bd6SRasesh Mody 
1180e6051bd6SRasesh Mody 				bit_idx += ATTENTION_LENGTH(p_aeu->flags);
1181e6051bd6SRasesh Mody 			}
1182e6051bd6SRasesh Mody 		}
1183e6051bd6SRasesh Mody 	}
1184e6051bd6SRasesh Mody 
1185e6051bd6SRasesh Mody 	/* Clear IGU indication for the deasserted bits */
1186e6051bd6SRasesh Mody 	/* FIXME - this will change once we'll have GOOD gtt definitions */
1187e6051bd6SRasesh Mody 	DIRECT_REG_WR(p_hwfn,
1188e6051bd6SRasesh Mody 		      (u8 OSAL_IOMEM *) p_hwfn->regview +
1189e6051bd6SRasesh Mody 		      GTT_BAR0_MAP_REG_IGU_CMD +
1190e6051bd6SRasesh Mody 		      ((IGU_CMD_ATTN_BIT_CLR_UPPER -
1191e6051bd6SRasesh Mody 			IGU_CMD_INT_ACK_BASE) << 3), ~((u32)deasserted_bits));
1192e6051bd6SRasesh Mody 
1193e6051bd6SRasesh Mody 	/* Unmask deasserted attentions in IGU */
1194e6051bd6SRasesh Mody 	aeu_mask = ecore_rd(p_hwfn, p_hwfn->p_dpc_ptt,
1195e6051bd6SRasesh Mody 			    IGU_REG_ATTENTION_ENABLE);
1196e6051bd6SRasesh Mody 	aeu_mask |= (deasserted_bits & ATTN_BITS_MASKABLE);
1197e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_hwfn->p_dpc_ptt, IGU_REG_ATTENTION_ENABLE, aeu_mask);
1198e6051bd6SRasesh Mody 
1199e6051bd6SRasesh Mody 	/* Clear deassertion from inner state */
1200e6051bd6SRasesh Mody 	sb_attn_sw->known_attn &= ~deasserted_bits;
1201e6051bd6SRasesh Mody 
1202e6051bd6SRasesh Mody 	return rc;
1203e6051bd6SRasesh Mody }
1204e6051bd6SRasesh Mody 
ecore_int_attentions(struct ecore_hwfn * p_hwfn)1205e6051bd6SRasesh Mody static enum _ecore_status_t ecore_int_attentions(struct ecore_hwfn *p_hwfn)
1206e6051bd6SRasesh Mody {
1207e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *p_sb_attn_sw = p_hwfn->p_sb_attn;
1208e6051bd6SRasesh Mody 	struct atten_status_block *p_sb_attn = p_sb_attn_sw->sb_attn;
1209e6051bd6SRasesh Mody 	u16 index = 0, asserted_bits, deasserted_bits;
1210e6051bd6SRasesh Mody 	u32 attn_bits = 0, attn_acks = 0;
12119455b556SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
1212e6051bd6SRasesh Mody 
1213e6051bd6SRasesh Mody 	/* Read current attention bits/acks - safeguard against attentions
1214e6051bd6SRasesh Mody 	 * by guaranting work on a synchronized timeframe
1215e6051bd6SRasesh Mody 	 */
1216e6051bd6SRasesh Mody 	do {
1217e6051bd6SRasesh Mody 		index = OSAL_LE16_TO_CPU(p_sb_attn->sb_index);
1218e6051bd6SRasesh Mody 		attn_bits = OSAL_LE32_TO_CPU(p_sb_attn->atten_bits);
1219e6051bd6SRasesh Mody 		attn_acks = OSAL_LE32_TO_CPU(p_sb_attn->atten_ack);
1220e6051bd6SRasesh Mody 	} while (index != OSAL_LE16_TO_CPU(p_sb_attn->sb_index));
1221e6051bd6SRasesh Mody 	p_sb_attn->sb_index = index;
1222e6051bd6SRasesh Mody 
1223e6051bd6SRasesh Mody 	/* Attention / Deassertion are meaningful (and in correct state)
1224e6051bd6SRasesh Mody 	 * only when they differ and consistent with known state - deassertion
1225e6051bd6SRasesh Mody 	 * when previous attention & current ack, and assertion when current
1226e6051bd6SRasesh Mody 	 * attention with no previous attention
1227e6051bd6SRasesh Mody 	 */
1228e6051bd6SRasesh Mody 	asserted_bits = (attn_bits & ~attn_acks & ATTN_STATE_BITS) &
1229e6051bd6SRasesh Mody 	    ~p_sb_attn_sw->known_attn;
1230e6051bd6SRasesh Mody 	deasserted_bits = (~attn_bits & attn_acks & ATTN_STATE_BITS) &
1231e6051bd6SRasesh Mody 	    p_sb_attn_sw->known_attn;
1232e6051bd6SRasesh Mody 
1233e6051bd6SRasesh Mody 	if ((asserted_bits & ~0x100) || (deasserted_bits & ~0x100))
1234e6051bd6SRasesh Mody 		DP_INFO(p_hwfn,
1235e6051bd6SRasesh Mody 			"Attention: Index: 0x%04x, Bits: 0x%08x, Acks: 0x%08x, asserted: 0x%04x, De-asserted 0x%04x [Prev. known: 0x%04x]\n",
1236e6051bd6SRasesh Mody 			index, attn_bits, attn_acks, asserted_bits,
1237e6051bd6SRasesh Mody 			deasserted_bits, p_sb_attn_sw->known_attn);
1238e6051bd6SRasesh Mody 	else if (asserted_bits == 0x100)
1239e6051bd6SRasesh Mody 		DP_INFO(p_hwfn, "MFW indication via attention\n");
1240e6051bd6SRasesh Mody 	else
1241e6051bd6SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
1242e6051bd6SRasesh Mody 			   "MFW indication [deassertion]\n");
1243e6051bd6SRasesh Mody 
1244e6051bd6SRasesh Mody 	if (asserted_bits) {
1245e6051bd6SRasesh Mody 		rc = ecore_int_assertion(p_hwfn, asserted_bits);
1246e6051bd6SRasesh Mody 		if (rc)
1247e6051bd6SRasesh Mody 			return rc;
1248e6051bd6SRasesh Mody 	}
1249e6051bd6SRasesh Mody 
1250e6051bd6SRasesh Mody 	if (deasserted_bits)
1251e6051bd6SRasesh Mody 		rc = ecore_int_deassertion(p_hwfn, deasserted_bits);
1252e6051bd6SRasesh Mody 
1253e6051bd6SRasesh Mody 	return rc;
1254e6051bd6SRasesh Mody }
1255e6051bd6SRasesh Mody 
ecore_sb_ack_attn(struct ecore_hwfn * p_hwfn,void OSAL_IOMEM * igu_addr,u32 ack_cons)1256ec94dbc5SRasesh Mody static void ecore_sb_ack_attn(struct ecore_hwfn *p_hwfn,
1257ec94dbc5SRasesh Mody 			      void OSAL_IOMEM *igu_addr, u32 ack_cons)
1258ec94dbc5SRasesh Mody {
12599ed26bc7SRasesh Mody 	struct igu_prod_cons_update igu_ack;
1260ec94dbc5SRasesh Mody 
12619ed26bc7SRasesh Mody 	OSAL_MEMSET(&igu_ack, 0, sizeof(struct igu_prod_cons_update));
1262ec94dbc5SRasesh Mody 	igu_ack.sb_id_and_flags =
1263ec94dbc5SRasesh Mody 	    ((ack_cons << IGU_PROD_CONS_UPDATE_SB_INDEX_SHIFT) |
1264ec94dbc5SRasesh Mody 	     (1 << IGU_PROD_CONS_UPDATE_UPDATE_FLAG_SHIFT) |
1265ec94dbc5SRasesh Mody 	     (IGU_INT_NOP << IGU_PROD_CONS_UPDATE_ENABLE_INT_SHIFT) |
1266ec94dbc5SRasesh Mody 	     (IGU_SEG_ACCESS_ATTN <<
1267ec94dbc5SRasesh Mody 	      IGU_PROD_CONS_UPDATE_SEGMENT_ACCESS_SHIFT));
1268ec94dbc5SRasesh Mody 
1269ec94dbc5SRasesh Mody 	DIRECT_REG_WR(p_hwfn, igu_addr, igu_ack.sb_id_and_flags);
1270ec94dbc5SRasesh Mody 
1271ec94dbc5SRasesh Mody 	/* Both segments (interrupts & acks) are written to same place address;
1272ec94dbc5SRasesh Mody 	 * Need to guarantee all commands will be received (in-order) by HW.
1273ec94dbc5SRasesh Mody 	 */
1274ec94dbc5SRasesh Mody 	OSAL_MMIOWB(p_hwfn->p_dev);
1275ec94dbc5SRasesh Mody 	OSAL_BARRIER(p_hwfn->p_dev);
1276ec94dbc5SRasesh Mody }
1277ec94dbc5SRasesh Mody 
ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie)1278ec94dbc5SRasesh Mody void ecore_int_sp_dpc(osal_int_ptr_t hwfn_cookie)
1279ec94dbc5SRasesh Mody {
1280ec94dbc5SRasesh Mody 	struct ecore_hwfn *p_hwfn = (struct ecore_hwfn *)hwfn_cookie;
1281ec94dbc5SRasesh Mody 	struct ecore_pi_info *pi_info = OSAL_NULL;
1282ec94dbc5SRasesh Mody 	struct ecore_sb_attn_info *sb_attn;
1283ec94dbc5SRasesh Mody 	struct ecore_sb_info *sb_info;
1284ec94dbc5SRasesh Mody 	u16 rc = 0;
1285ec94dbc5SRasesh Mody 
128622d07d93SRasesh Mody 	if (!p_hwfn)
1287ec94dbc5SRasesh Mody 		return;
1288ec94dbc5SRasesh Mody 
1289ec94dbc5SRasesh Mody 	if (!p_hwfn->p_sp_sb) {
1290ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev, "DPC called - no p_sp_sb\n");
1291ec94dbc5SRasesh Mody 		return;
1292ec94dbc5SRasesh Mody 	}
1293ec94dbc5SRasesh Mody 
1294ec94dbc5SRasesh Mody 	sb_info = &p_hwfn->p_sp_sb->sb_info;
1295ec94dbc5SRasesh Mody 	if (!sb_info) {
1296ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev,
1297ec94dbc5SRasesh Mody 		       "Status block is NULL - cannot ack interrupts\n");
1298ec94dbc5SRasesh Mody 		return;
1299ec94dbc5SRasesh Mody 	}
1300ec94dbc5SRasesh Mody 
1301ec94dbc5SRasesh Mody 	if (!p_hwfn->p_sb_attn) {
1302ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev, "DPC called - no p_sb_attn");
1303ec94dbc5SRasesh Mody 		return;
1304ec94dbc5SRasesh Mody 	}
1305ec94dbc5SRasesh Mody 	sb_attn = p_hwfn->p_sb_attn;
1306ec94dbc5SRasesh Mody 
1307ec94dbc5SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR, "DPC Called! (hwfn %p %d)\n",
1308ec94dbc5SRasesh Mody 		   p_hwfn, p_hwfn->my_id);
1309ec94dbc5SRasesh Mody 
1310ec94dbc5SRasesh Mody 	/* Disable ack for def status block. Required both for msix +
1311ec94dbc5SRasesh Mody 	 * inta in non-mask mode, in inta does no harm.
1312ec94dbc5SRasesh Mody 	 */
1313ec94dbc5SRasesh Mody 	ecore_sb_ack(sb_info, IGU_INT_DISABLE, 0);
1314ec94dbc5SRasesh Mody 
1315ec94dbc5SRasesh Mody 	/* Gather Interrupts/Attentions information */
1316ec94dbc5SRasesh Mody 	if (!sb_info->sb_virt) {
1317ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev,
1318ec94dbc5SRasesh Mody 		       "Interrupt Status block is NULL -"
1319ec94dbc5SRasesh Mody 		       " cannot check for new interrupts!\n");
1320ec94dbc5SRasesh Mody 	} else {
1321ec94dbc5SRasesh Mody 		u32 tmp_index = sb_info->sb_ack;
1322ec94dbc5SRasesh Mody 		rc = ecore_sb_update_sb_idx(sb_info);
1323ec94dbc5SRasesh Mody 		DP_VERBOSE(p_hwfn->p_dev, ECORE_MSG_INTR,
1324ec94dbc5SRasesh Mody 			   "Interrupt indices: 0x%08x --> 0x%08x\n",
1325ec94dbc5SRasesh Mody 			   tmp_index, sb_info->sb_ack);
1326ec94dbc5SRasesh Mody 	}
1327ec94dbc5SRasesh Mody 
1328ec94dbc5SRasesh Mody 	if (!sb_attn || !sb_attn->sb_attn) {
1329ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev,
1330ec94dbc5SRasesh Mody 		       "Attentions Status block is NULL -"
1331ec94dbc5SRasesh Mody 		       " cannot check for new attentions!\n");
1332ec94dbc5SRasesh Mody 	} else {
1333ec94dbc5SRasesh Mody 		u16 tmp_index = sb_attn->index;
1334ec94dbc5SRasesh Mody 
1335ec94dbc5SRasesh Mody 		rc |= ecore_attn_update_idx(p_hwfn, sb_attn);
1336ec94dbc5SRasesh Mody 		DP_VERBOSE(p_hwfn->p_dev, ECORE_MSG_INTR,
1337ec94dbc5SRasesh Mody 			   "Attention indices: 0x%08x --> 0x%08x\n",
1338ec94dbc5SRasesh Mody 			   tmp_index, sb_attn->index);
1339ec94dbc5SRasesh Mody 	}
1340ec94dbc5SRasesh Mody 
1341ec94dbc5SRasesh Mody 	/* Check if we expect interrupts at this time. if not just ack them */
1342ec94dbc5SRasesh Mody 	if (!(rc & ECORE_SB_EVENT_MASK)) {
1343ec94dbc5SRasesh Mody 		ecore_sb_ack(sb_info, IGU_INT_ENABLE, 1);
1344ec94dbc5SRasesh Mody 		return;
1345ec94dbc5SRasesh Mody 	}
1346ec94dbc5SRasesh Mody 
1347ec94dbc5SRasesh Mody /* Check the validity of the DPC ptt. If not ack interrupts and fail */
13489455b556SRasesh Mody 
1349ec94dbc5SRasesh Mody 	if (!p_hwfn->p_dpc_ptt) {
1350ec94dbc5SRasesh Mody 		DP_NOTICE(p_hwfn->p_dev, true, "Failed to allocate PTT\n");
1351ec94dbc5SRasesh Mody 		ecore_sb_ack(sb_info, IGU_INT_ENABLE, 1);
1352ec94dbc5SRasesh Mody 		return;
1353ec94dbc5SRasesh Mody 	}
1354ec94dbc5SRasesh Mody 
1355e6051bd6SRasesh Mody 	if (rc & ECORE_SB_ATT_IDX)
1356e6051bd6SRasesh Mody 		ecore_int_attentions(p_hwfn);
1357e6051bd6SRasesh Mody 
1358ec94dbc5SRasesh Mody 	if (rc & ECORE_SB_IDX) {
13593b307c55SRasesh Mody 		osal_size_t pi;
1360ec94dbc5SRasesh Mody 
1361ec94dbc5SRasesh Mody 		/* Since we only looked at the SB index, it's possible more
1362ec94dbc5SRasesh Mody 		 * than a single protocol-index on the SB incremented.
1363ec94dbc5SRasesh Mody 		 * Iterate over all configured protocol indices and check
1364ec94dbc5SRasesh Mody 		 * whether something happened for each.
1365ec94dbc5SRasesh Mody 		 */
13663b307c55SRasesh Mody 		for (pi = 0; pi < p_hwfn->p_sp_sb->pi_info_arr_size; pi++) {
1367ec94dbc5SRasesh Mody 			pi_info = &p_hwfn->p_sp_sb->pi_info_arr[pi];
1368ec94dbc5SRasesh Mody 			if (pi_info->comp_cb != OSAL_NULL)
1369ec94dbc5SRasesh Mody 				pi_info->comp_cb(p_hwfn, pi_info->cookie);
1370ec94dbc5SRasesh Mody 		}
1371ec94dbc5SRasesh Mody 	}
1372ec94dbc5SRasesh Mody 
1373ec94dbc5SRasesh Mody 	if (sb_attn && (rc & ECORE_SB_ATT_IDX)) {
1374ec94dbc5SRasesh Mody 		/* This should be done before the interrupts are enabled,
1375ec94dbc5SRasesh Mody 		 * since otherwise a new attention will be generated.
1376ec94dbc5SRasesh Mody 		 */
1377ec94dbc5SRasesh Mody 		ecore_sb_ack_attn(p_hwfn, sb_info->igu_addr, sb_attn->index);
1378ec94dbc5SRasesh Mody 	}
1379ec94dbc5SRasesh Mody 
1380ec94dbc5SRasesh Mody 	ecore_sb_ack(sb_info, IGU_INT_ENABLE, 1);
1381ec94dbc5SRasesh Mody }
1382ec94dbc5SRasesh Mody 
ecore_int_sb_attn_free(struct ecore_hwfn * p_hwfn)1383ec94dbc5SRasesh Mody static void ecore_int_sb_attn_free(struct ecore_hwfn *p_hwfn)
1384ec94dbc5SRasesh Mody {
1385ec94dbc5SRasesh Mody 	struct ecore_sb_attn_info *p_sb = p_hwfn->p_sb_attn;
1386ec94dbc5SRasesh Mody 
1387ec94dbc5SRasesh Mody 	if (!p_sb)
1388ec94dbc5SRasesh Mody 		return;
1389ec94dbc5SRasesh Mody 
1390ec94dbc5SRasesh Mody 	if (p_sb->sb_attn) {
1391ec94dbc5SRasesh Mody 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, p_sb->sb_attn,
1392ec94dbc5SRasesh Mody 				       p_sb->sb_phys,
1393ec94dbc5SRasesh Mody 				       SB_ATTN_ALIGNED_SIZE(p_hwfn));
1394ec94dbc5SRasesh Mody 	}
1395ec94dbc5SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_sb);
1396ec94dbc5SRasesh Mody }
1397ec94dbc5SRasesh Mody 
ecore_int_sb_attn_setup(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)1398e6051bd6SRasesh Mody static void ecore_int_sb_attn_setup(struct ecore_hwfn *p_hwfn,
1399e6051bd6SRasesh Mody 				    struct ecore_ptt *p_ptt)
1400e6051bd6SRasesh Mody {
1401e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *sb_info = p_hwfn->p_sb_attn;
1402e6051bd6SRasesh Mody 
1403e6051bd6SRasesh Mody 	OSAL_MEMSET(sb_info->sb_attn, 0, sizeof(*sb_info->sb_attn));
1404e6051bd6SRasesh Mody 
1405e6051bd6SRasesh Mody 	sb_info->index = 0;
1406e6051bd6SRasesh Mody 	sb_info->known_attn = 0;
1407e6051bd6SRasesh Mody 
1408e6051bd6SRasesh Mody 	/* Configure Attention Status Block in IGU */
1409e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTN_MSG_ADDR_L,
1410e6051bd6SRasesh Mody 		 DMA_LO(p_hwfn->p_sb_attn->sb_phys));
1411e6051bd6SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTN_MSG_ADDR_H,
1412e6051bd6SRasesh Mody 		 DMA_HI(p_hwfn->p_sb_attn->sb_phys));
1413e6051bd6SRasesh Mody }
1414e6051bd6SRasesh Mody 
ecore_int_sb_attn_init(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,void * sb_virt_addr,dma_addr_t sb_phy_addr)1415e6051bd6SRasesh Mody static void ecore_int_sb_attn_init(struct ecore_hwfn *p_hwfn,
1416e6051bd6SRasesh Mody 				   struct ecore_ptt *p_ptt,
1417e6051bd6SRasesh Mody 				   void *sb_virt_addr, dma_addr_t sb_phy_addr)
1418e6051bd6SRasesh Mody {
1419e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *sb_info = p_hwfn->p_sb_attn;
1420e6051bd6SRasesh Mody 	int i, j, k;
1421e6051bd6SRasesh Mody 
1422e6051bd6SRasesh Mody 	sb_info->sb_attn = sb_virt_addr;
1423e6051bd6SRasesh Mody 	sb_info->sb_phys = sb_phy_addr;
1424e6051bd6SRasesh Mody 
1425e6051bd6SRasesh Mody 	/* Set the pointer to the AEU descriptors */
1426e6051bd6SRasesh Mody 	sb_info->p_aeu_desc = aeu_descs;
1427e6051bd6SRasesh Mody 
1428e6051bd6SRasesh Mody 	/* Calculate Parity Masks */
1429e6051bd6SRasesh Mody 	OSAL_MEMSET(sb_info->parity_mask, 0, sizeof(u32) * NUM_ATTN_REGS);
1430e6051bd6SRasesh Mody 	for (i = 0; i < NUM_ATTN_REGS; i++) {
1431e6051bd6SRasesh Mody 		/* j is array index, k is bit index */
1432e6051bd6SRasesh Mody 		for (j = 0, k = 0; k < 32; j++) {
1433121f1cbdSRasesh Mody 			struct aeu_invert_reg_bit *p_aeu;
1434e6051bd6SRasesh Mody 
1435121f1cbdSRasesh Mody 			p_aeu = &aeu_descs[i].bits[j];
1436121f1cbdSRasesh Mody 			if (ecore_int_is_parity_flag(p_hwfn, p_aeu))
1437e6051bd6SRasesh Mody 				sb_info->parity_mask[i] |= 1 << k;
1438e6051bd6SRasesh Mody 
1439121f1cbdSRasesh Mody 			k += ATTENTION_LENGTH(p_aeu->flags);
1440e6051bd6SRasesh Mody 		}
1441e6051bd6SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
1442e6051bd6SRasesh Mody 			   "Attn Mask [Reg %d]: 0x%08x\n",
1443e6051bd6SRasesh Mody 			   i, sb_info->parity_mask[i]);
1444e6051bd6SRasesh Mody 	}
1445e6051bd6SRasesh Mody 
1446e6051bd6SRasesh Mody 	/* Set the address of cleanup for the mcp attention */
1447e6051bd6SRasesh Mody 	sb_info->mfw_attn_addr = (p_hwfn->rel_pf_id << 3) +
1448e6051bd6SRasesh Mody 	    MISC_REG_AEU_GENERAL_ATTN_0;
1449e6051bd6SRasesh Mody 
1450e6051bd6SRasesh Mody 	ecore_int_sb_attn_setup(p_hwfn, p_ptt);
1451e6051bd6SRasesh Mody }
1452e6051bd6SRasesh Mody 
ecore_int_sb_attn_alloc(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)1453e6051bd6SRasesh Mody static enum _ecore_status_t ecore_int_sb_attn_alloc(struct ecore_hwfn *p_hwfn,
1454e6051bd6SRasesh Mody 						    struct ecore_ptt *p_ptt)
1455e6051bd6SRasesh Mody {
1456e6051bd6SRasesh Mody 	struct ecore_dev *p_dev = p_hwfn->p_dev;
1457e6051bd6SRasesh Mody 	struct ecore_sb_attn_info *p_sb;
1458e6051bd6SRasesh Mody 	dma_addr_t p_phys = 0;
1459e6051bd6SRasesh Mody 	void *p_virt;
1460e6051bd6SRasesh Mody 
1461e6051bd6SRasesh Mody 	/* SB struct */
146222d07d93SRasesh Mody 	p_sb = OSAL_ALLOC(p_dev, GFP_KERNEL, sizeof(*p_sb));
1463e6051bd6SRasesh Mody 	if (!p_sb) {
146498abf84eSRasesh Mody 		DP_NOTICE(p_dev, false, "Failed to allocate `struct ecore_sb_attn_info'\n");
1465e6051bd6SRasesh Mody 		return ECORE_NOMEM;
1466e6051bd6SRasesh Mody 	}
1467e6051bd6SRasesh Mody 
1468e6051bd6SRasesh Mody 	/* SB ring  */
1469e6051bd6SRasesh Mody 	p_virt = OSAL_DMA_ALLOC_COHERENT(p_dev, &p_phys,
1470e6051bd6SRasesh Mody 					 SB_ATTN_ALIGNED_SIZE(p_hwfn));
1471e6051bd6SRasesh Mody 	if (!p_virt) {
147298abf84eSRasesh Mody 		DP_NOTICE(p_dev, false, "Failed to allocate status block (attentions)\n");
1473e6051bd6SRasesh Mody 		OSAL_FREE(p_dev, p_sb);
1474e6051bd6SRasesh Mody 		return ECORE_NOMEM;
1475e6051bd6SRasesh Mody 	}
1476e6051bd6SRasesh Mody 
1477e6051bd6SRasesh Mody 	/* Attention setup */
1478e6051bd6SRasesh Mody 	p_hwfn->p_sb_attn = p_sb;
1479e6051bd6SRasesh Mody 	ecore_int_sb_attn_init(p_hwfn, p_ptt, p_virt, p_phys);
1480e6051bd6SRasesh Mody 
1481e6051bd6SRasesh Mody 	return ECORE_SUCCESS;
1482e6051bd6SRasesh Mody }
1483e6051bd6SRasesh Mody 
1484ec94dbc5SRasesh Mody /* coalescing timeout = timeset << (timer_res + 1) */
1485ec94dbc5SRasesh Mody #define ECORE_CAU_DEF_RX_USECS 24
1486ec94dbc5SRasesh Mody #define ECORE_CAU_DEF_TX_USECS 48
1487ec94dbc5SRasesh Mody 
ecore_init_cau_sb_entry(struct ecore_hwfn * p_hwfn,struct cau_sb_entry * p_sb_entry,u8 pf_id,u16 vf_number,u8 vf_valid)1488ec94dbc5SRasesh Mody void ecore_init_cau_sb_entry(struct ecore_hwfn *p_hwfn,
1489ec94dbc5SRasesh Mody 			     struct cau_sb_entry *p_sb_entry,
1490ec94dbc5SRasesh Mody 			     u8 pf_id, u16 vf_number, u8 vf_valid)
1491ec94dbc5SRasesh Mody {
1492ec94dbc5SRasesh Mody 	struct ecore_dev *p_dev = p_hwfn->p_dev;
1493ec94dbc5SRasesh Mody 	u32 cau_state;
149422d07d93SRasesh Mody 	u8 timer_res;
1495ec94dbc5SRasesh Mody 
1496ec94dbc5SRasesh Mody 	OSAL_MEMSET(p_sb_entry, 0, sizeof(*p_sb_entry));
1497ec94dbc5SRasesh Mody 
1498ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_PF_NUMBER, pf_id);
1499ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_NUMBER, vf_number);
1500ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_VF_VALID, vf_valid);
1501ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET0, 0x7F);
1502ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_SB_TIMESET1, 0x7F);
1503ec94dbc5SRasesh Mody 
1504ec94dbc5SRasesh Mody 	cau_state = CAU_HC_DISABLE_STATE;
1505ec94dbc5SRasesh Mody 
1506ec94dbc5SRasesh Mody 	if (p_dev->int_coalescing_mode == ECORE_COAL_MODE_ENABLE) {
1507ec94dbc5SRasesh Mody 		cau_state = CAU_HC_ENABLE_STATE;
150822d07d93SRasesh Mody 		if (!p_dev->rx_coalesce_usecs)
1509ec94dbc5SRasesh Mody 			p_dev->rx_coalesce_usecs = ECORE_CAU_DEF_RX_USECS;
151022d07d93SRasesh Mody 		if (!p_dev->tx_coalesce_usecs)
1511ec94dbc5SRasesh Mody 			p_dev->tx_coalesce_usecs = ECORE_CAU_DEF_TX_USECS;
1512ec94dbc5SRasesh Mody 	}
151322d07d93SRasesh Mody 
151422d07d93SRasesh Mody 	/* Coalesce = (timeset << timer-res), timeset is 7bit wide */
151522d07d93SRasesh Mody 	if (p_dev->rx_coalesce_usecs <= 0x7F)
151622d07d93SRasesh Mody 		timer_res = 0;
151722d07d93SRasesh Mody 	else if (p_dev->rx_coalesce_usecs <= 0xFF)
151822d07d93SRasesh Mody 		timer_res = 1;
151922d07d93SRasesh Mody 	else
152022d07d93SRasesh Mody 		timer_res = 2;
152122d07d93SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
152222d07d93SRasesh Mody 
152322d07d93SRasesh Mody 	if (p_dev->tx_coalesce_usecs <= 0x7F)
152422d07d93SRasesh Mody 		timer_res = 0;
152522d07d93SRasesh Mody 	else if (p_dev->tx_coalesce_usecs <= 0xFF)
152622d07d93SRasesh Mody 		timer_res = 1;
152722d07d93SRasesh Mody 	else
152822d07d93SRasesh Mody 		timer_res = 2;
152922d07d93SRasesh Mody 	SET_FIELD(p_sb_entry->params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
1530ec94dbc5SRasesh Mody 
1531ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE0, cau_state);
1532ec94dbc5SRasesh Mody 	SET_FIELD(p_sb_entry->data, CAU_SB_ENTRY_STATE1, cau_state);
1533ec94dbc5SRasesh Mody }
1534ec94dbc5SRasesh Mody 
_ecore_int_cau_conf_pi(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u16 igu_sb_id,u32 pi_index,enum ecore_coalescing_fsm coalescing_fsm,u8 timeset)15356e4fcea9SRasesh Mody static void _ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
15366e4fcea9SRasesh Mody 				   struct ecore_ptt *p_ptt,
15376e4fcea9SRasesh Mody 				   u16 igu_sb_id, u32 pi_index,
15386e4fcea9SRasesh Mody 				   enum ecore_coalescing_fsm coalescing_fsm,
15396e4fcea9SRasesh Mody 				   u8 timeset)
15406e4fcea9SRasesh Mody {
15416e4fcea9SRasesh Mody 	struct cau_pi_entry pi_entry;
15426e4fcea9SRasesh Mody 	u32 sb_offset, pi_offset;
15436e4fcea9SRasesh Mody 
15446e4fcea9SRasesh Mody 	if (IS_VF(p_hwfn->p_dev))
15456e4fcea9SRasesh Mody 		return;/* @@@TBD MichalK- VF CAU... */
15466e4fcea9SRasesh Mody 
15473b307c55SRasesh Mody 	sb_offset = igu_sb_id * PIS_PER_SB;
15486e4fcea9SRasesh Mody 	OSAL_MEMSET(&pi_entry, 0, sizeof(struct cau_pi_entry));
15496e4fcea9SRasesh Mody 
15506e4fcea9SRasesh Mody 	SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_PI_TIMESET, timeset);
15516e4fcea9SRasesh Mody 	if (coalescing_fsm == ECORE_COAL_RX_STATE_MACHINE)
15526e4fcea9SRasesh Mody 		SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 0);
15536e4fcea9SRasesh Mody 	else
15546e4fcea9SRasesh Mody 		SET_FIELD(pi_entry.prod, CAU_PI_ENTRY_FSM_SEL, 1);
15556e4fcea9SRasesh Mody 
15566e4fcea9SRasesh Mody 	pi_offset = sb_offset + pi_index;
15576e4fcea9SRasesh Mody 	if (p_hwfn->hw_init_done) {
15586e4fcea9SRasesh Mody 		ecore_wr(p_hwfn, p_ptt,
15596e4fcea9SRasesh Mody 			 CAU_REG_PI_MEMORY + pi_offset * sizeof(u32),
15606e4fcea9SRasesh Mody 			 *((u32 *)&(pi_entry)));
15616e4fcea9SRasesh Mody 	} else {
15626e4fcea9SRasesh Mody 		STORE_RT_REG(p_hwfn,
15636e4fcea9SRasesh Mody 			     CAU_REG_PI_MEMORY_RT_OFFSET + pi_offset,
15646e4fcea9SRasesh Mody 			     *((u32 *)&(pi_entry)));
15656e4fcea9SRasesh Mody 	}
15666e4fcea9SRasesh Mody }
15676e4fcea9SRasesh Mody 
ecore_int_cau_conf_pi(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_sb_info * p_sb,u32 pi_index,enum ecore_coalescing_fsm coalescing_fsm,u8 timeset)15686e4fcea9SRasesh Mody void ecore_int_cau_conf_pi(struct ecore_hwfn *p_hwfn,
15696e4fcea9SRasesh Mody 			   struct ecore_ptt *p_ptt,
15706e4fcea9SRasesh Mody 			   struct ecore_sb_info *p_sb, u32 pi_index,
15716e4fcea9SRasesh Mody 			   enum ecore_coalescing_fsm coalescing_fsm,
15726e4fcea9SRasesh Mody 			   u8 timeset)
15736e4fcea9SRasesh Mody {
15746e4fcea9SRasesh Mody 	_ecore_int_cau_conf_pi(p_hwfn, p_ptt, p_sb->igu_sb_id,
15756e4fcea9SRasesh Mody 			       pi_index, coalescing_fsm, timeset);
15766e4fcea9SRasesh Mody }
15776e4fcea9SRasesh Mody 
ecore_int_cau_conf_sb(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,dma_addr_t sb_phys,u16 igu_sb_id,u16 vf_number,u8 vf_valid)1578ec94dbc5SRasesh Mody void ecore_int_cau_conf_sb(struct ecore_hwfn *p_hwfn,
1579ec94dbc5SRasesh Mody 			   struct ecore_ptt *p_ptt,
1580ec94dbc5SRasesh Mody 			   dma_addr_t sb_phys, u16 igu_sb_id,
1581ec94dbc5SRasesh Mody 			   u16 vf_number, u8 vf_valid)
1582ec94dbc5SRasesh Mody {
1583ec94dbc5SRasesh Mody 	struct cau_sb_entry sb_entry;
1584ec94dbc5SRasesh Mody 
1585ec94dbc5SRasesh Mody 	ecore_init_cau_sb_entry(p_hwfn, &sb_entry, p_hwfn->rel_pf_id,
1586ec94dbc5SRasesh Mody 				vf_number, vf_valid);
1587ec94dbc5SRasesh Mody 
1588ec94dbc5SRasesh Mody 	if (p_hwfn->hw_init_done) {
1589ec94dbc5SRasesh Mody 		/* Wide-bus, initialize via DMAE */
1590ec94dbc5SRasesh Mody 		u64 phys_addr = (u64)sb_phys;
1591ec94dbc5SRasesh Mody 
1592ec94dbc5SRasesh Mody 		ecore_dmae_host2grc(p_hwfn, p_ptt,
1593ec94dbc5SRasesh Mody 				    (u64)(osal_uintptr_t)&phys_addr,
1594ec94dbc5SRasesh Mody 				    CAU_REG_SB_ADDR_MEMORY +
15953eed444aSRasesh Mody 				    igu_sb_id * sizeof(u64), 2,
15963eed444aSRasesh Mody 				    OSAL_NULL /* default parameters */);
1597ec94dbc5SRasesh Mody 		ecore_dmae_host2grc(p_hwfn, p_ptt,
1598ec94dbc5SRasesh Mody 				    (u64)(osal_uintptr_t)&sb_entry,
1599ec94dbc5SRasesh Mody 				    CAU_REG_SB_VAR_MEMORY +
16003eed444aSRasesh Mody 				    igu_sb_id * sizeof(u64), 2,
16013eed444aSRasesh Mody 				    OSAL_NULL /* default parameters */);
1602ec94dbc5SRasesh Mody 	} else {
1603ec94dbc5SRasesh Mody 		/* Initialize Status Block Address */
1604ec94dbc5SRasesh Mody 		STORE_RT_REG_AGG(p_hwfn,
1605ec94dbc5SRasesh Mody 				 CAU_REG_SB_ADDR_MEMORY_RT_OFFSET +
1606ec94dbc5SRasesh Mody 				 igu_sb_id * 2, sb_phys);
1607ec94dbc5SRasesh Mody 
1608ec94dbc5SRasesh Mody 		STORE_RT_REG_AGG(p_hwfn,
1609ec94dbc5SRasesh Mody 				 CAU_REG_SB_VAR_MEMORY_RT_OFFSET +
1610ec94dbc5SRasesh Mody 				 igu_sb_id * 2, sb_entry);
1611ec94dbc5SRasesh Mody 	}
1612ec94dbc5SRasesh Mody 
1613ec94dbc5SRasesh Mody 	/* Configure pi coalescing if set */
1614ec94dbc5SRasesh Mody 	if (p_hwfn->p_dev->int_coalescing_mode == ECORE_COAL_MODE_ENABLE) {
161522d07d93SRasesh Mody 		/* eth will open queues for all tcs, so configure all of them
161622d07d93SRasesh Mody 		 * properly, rather than just the active ones
161722d07d93SRasesh Mody 		 */
161822d07d93SRasesh Mody 		u8 num_tc = p_hwfn->hw_info.num_hw_tc;
161922d07d93SRasesh Mody 
162022d07d93SRasesh Mody 		u8 timeset, timer_res;
1621ec94dbc5SRasesh Mody 		u8 i;
1622ec94dbc5SRasesh Mody 
162322d07d93SRasesh Mody 		/* timeset = (coalesce >> timer-res), timeset is 7bit wide */
162422d07d93SRasesh Mody 		if (p_hwfn->p_dev->rx_coalesce_usecs <= 0x7F)
162522d07d93SRasesh Mody 			timer_res = 0;
162622d07d93SRasesh Mody 		else if (p_hwfn->p_dev->rx_coalesce_usecs <= 0xFF)
162722d07d93SRasesh Mody 			timer_res = 1;
162822d07d93SRasesh Mody 		else
162922d07d93SRasesh Mody 			timer_res = 2;
163022d07d93SRasesh Mody 		timeset = (u8)(p_hwfn->p_dev->rx_coalesce_usecs >> timer_res);
16316e4fcea9SRasesh Mody 		_ecore_int_cau_conf_pi(p_hwfn, p_ptt, igu_sb_id, RX_PI,
16326e4fcea9SRasesh Mody 				       ECORE_COAL_RX_STATE_MACHINE,
16336e4fcea9SRasesh Mody 				       timeset);
1634ec94dbc5SRasesh Mody 
163522d07d93SRasesh Mody 		if (p_hwfn->p_dev->tx_coalesce_usecs <= 0x7F)
163622d07d93SRasesh Mody 			timer_res = 0;
163722d07d93SRasesh Mody 		else if (p_hwfn->p_dev->tx_coalesce_usecs <= 0xFF)
163822d07d93SRasesh Mody 			timer_res = 1;
163922d07d93SRasesh Mody 		else
164022d07d93SRasesh Mody 			timer_res = 2;
164122d07d93SRasesh Mody 		timeset = (u8)(p_hwfn->p_dev->tx_coalesce_usecs >> timer_res);
1642ec94dbc5SRasesh Mody 		for (i = 0; i < num_tc; i++) {
16436e4fcea9SRasesh Mody 			_ecore_int_cau_conf_pi(p_hwfn, p_ptt,
1644ec94dbc5SRasesh Mody 					       igu_sb_id, TX_PI(i),
1645ec94dbc5SRasesh Mody 					       ECORE_COAL_TX_STATE_MACHINE,
1646ec94dbc5SRasesh Mody 					       timeset);
1647ec94dbc5SRasesh Mody 		}
1648ec94dbc5SRasesh Mody 	}
1649ec94dbc5SRasesh Mody }
1650ec94dbc5SRasesh Mody 
ecore_int_sb_setup(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_sb_info * sb_info)1651ec94dbc5SRasesh Mody void ecore_int_sb_setup(struct ecore_hwfn *p_hwfn,
1652ec94dbc5SRasesh Mody 			struct ecore_ptt *p_ptt, struct ecore_sb_info *sb_info)
1653ec94dbc5SRasesh Mody {
1654ec94dbc5SRasesh Mody 	/* zero status block and ack counter */
1655ec94dbc5SRasesh Mody 	sb_info->sb_ack = 0;
16563b307c55SRasesh Mody 	OSAL_MEMSET(sb_info->sb_virt, 0, sb_info->sb_size);
1657ec94dbc5SRasesh Mody 
165886a2265eSRasesh Mody 	if (IS_PF(p_hwfn->p_dev))
1659ec94dbc5SRasesh Mody 		ecore_int_cau_conf_sb(p_hwfn, p_ptt, sb_info->sb_phys,
1660ec94dbc5SRasesh Mody 				      sb_info->igu_sb_id, 0, 0);
1661ec94dbc5SRasesh Mody }
1662ec94dbc5SRasesh Mody 
16636e4fcea9SRasesh Mody struct ecore_igu_block *
ecore_get_igu_free_sb(struct ecore_hwfn * p_hwfn,bool b_is_pf)16646e4fcea9SRasesh Mody ecore_get_igu_free_sb(struct ecore_hwfn *p_hwfn, bool b_is_pf)
16656e4fcea9SRasesh Mody {
16666e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
16676e4fcea9SRasesh Mody 	u16 igu_id;
16686e4fcea9SRasesh Mody 
16696e4fcea9SRasesh Mody 	for (igu_id = 0; igu_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
16706e4fcea9SRasesh Mody 	     igu_id++) {
16716e4fcea9SRasesh Mody 		p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_id];
16726e4fcea9SRasesh Mody 
16736e4fcea9SRasesh Mody 		if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
16746e4fcea9SRasesh Mody 		    !(p_block->status & ECORE_IGU_STATUS_FREE))
16756e4fcea9SRasesh Mody 			continue;
16766e4fcea9SRasesh Mody 
16776e4fcea9SRasesh Mody 		if (!!(p_block->status & ECORE_IGU_STATUS_PF) ==
16786e4fcea9SRasesh Mody 		    b_is_pf)
16796e4fcea9SRasesh Mody 			return p_block;
16806e4fcea9SRasesh Mody 	}
16816e4fcea9SRasesh Mody 
16826e4fcea9SRasesh Mody 	return OSAL_NULL;
16836e4fcea9SRasesh Mody }
16846e4fcea9SRasesh Mody 
ecore_get_pf_igu_sb_id(struct ecore_hwfn * p_hwfn,u16 vector_id)16856e4fcea9SRasesh Mody static u16 ecore_get_pf_igu_sb_id(struct ecore_hwfn *p_hwfn,
16866e4fcea9SRasesh Mody 				  u16 vector_id)
16876e4fcea9SRasesh Mody {
16886e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
16896e4fcea9SRasesh Mody 	u16 igu_id;
16906e4fcea9SRasesh Mody 
16916e4fcea9SRasesh Mody 	for (igu_id = 0; igu_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
16926e4fcea9SRasesh Mody 	     igu_id++) {
16936e4fcea9SRasesh Mody 		p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_id];
16946e4fcea9SRasesh Mody 
16956e4fcea9SRasesh Mody 		if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
16966e4fcea9SRasesh Mody 		    !p_block->is_pf ||
16976e4fcea9SRasesh Mody 		    p_block->vector_number != vector_id)
16986e4fcea9SRasesh Mody 			continue;
16996e4fcea9SRasesh Mody 
17006e4fcea9SRasesh Mody 		return igu_id;
17016e4fcea9SRasesh Mody 	}
17026e4fcea9SRasesh Mody 
17036e4fcea9SRasesh Mody 	return ECORE_SB_INVALID_IDX;
17046e4fcea9SRasesh Mody }
17056e4fcea9SRasesh Mody 
ecore_get_igu_sb_id(struct ecore_hwfn * p_hwfn,u16 sb_id)17066e4fcea9SRasesh Mody u16 ecore_get_igu_sb_id(struct ecore_hwfn *p_hwfn, u16 sb_id)
1707ec94dbc5SRasesh Mody {
1708ec94dbc5SRasesh Mody 	u16 igu_sb_id;
1709ec94dbc5SRasesh Mody 
1710ec94dbc5SRasesh Mody 	/* Assuming continuous set of IGU SBs dedicated for given PF */
1711ec94dbc5SRasesh Mody 	if (sb_id == ECORE_SP_SB_ID)
1712ec94dbc5SRasesh Mody 		igu_sb_id = p_hwfn->hw_info.p_igu_info->igu_dsb_id;
171386a2265eSRasesh Mody 	else if (IS_PF(p_hwfn->p_dev))
17146e4fcea9SRasesh Mody 		igu_sb_id = ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1);
171586a2265eSRasesh Mody 	else
171686a2265eSRasesh Mody 		igu_sb_id = ecore_vf_get_igu_sb_id(p_hwfn, sb_id);
1717ec94dbc5SRasesh Mody 
17186e4fcea9SRasesh Mody 	if (igu_sb_id == ECORE_SB_INVALID_IDX)
17196e4fcea9SRasesh Mody 		DP_NOTICE(p_hwfn, true,
17206e4fcea9SRasesh Mody 			  "Slowpath SB vector %04x doesn't exist\n",
17216e4fcea9SRasesh Mody 			  sb_id);
17226e4fcea9SRasesh Mody 	else if (sb_id == ECORE_SP_SB_ID)
1723ec94dbc5SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
1724ec94dbc5SRasesh Mody 			   "Slowpath SB index in IGU is 0x%04x\n", igu_sb_id);
1725ec94dbc5SRasesh Mody 	else
1726ec94dbc5SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
1727ec94dbc5SRasesh Mody 			   "SB [%04x] <--> IGU SB [%04x]\n", sb_id, igu_sb_id);
1728ec94dbc5SRasesh Mody 
1729ec94dbc5SRasesh Mody 	return igu_sb_id;
1730ec94dbc5SRasesh Mody }
1731ec94dbc5SRasesh Mody 
ecore_int_sb_init(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_sb_info * sb_info,void * sb_virt_addr,dma_addr_t sb_phy_addr,u16 sb_id)1732ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_sb_init(struct ecore_hwfn *p_hwfn,
1733ec94dbc5SRasesh Mody 				       struct ecore_ptt *p_ptt,
1734ec94dbc5SRasesh Mody 				       struct ecore_sb_info *sb_info,
1735ec94dbc5SRasesh Mody 				       void *sb_virt_addr,
1736ec94dbc5SRasesh Mody 				       dma_addr_t sb_phy_addr, u16 sb_id)
1737ec94dbc5SRasesh Mody {
1738ec94dbc5SRasesh Mody 	sb_info->sb_virt = sb_virt_addr;
17393b307c55SRasesh Mody 	struct status_block *sb_virt;
17403b307c55SRasesh Mody 
17413b307c55SRasesh Mody 	sb_virt = (struct status_block *)sb_info->sb_virt;
17423b307c55SRasesh Mody 
17433b307c55SRasesh Mody 	sb_info->sb_size = sizeof(*sb_virt);
17443b307c55SRasesh Mody 	sb_info->sb_pi_array = sb_virt->pi_array;
17453b307c55SRasesh Mody 	sb_info->sb_prod_index = &sb_virt->prod_index;
17463b307c55SRasesh Mody 
1747ec94dbc5SRasesh Mody 	sb_info->sb_phys = sb_phy_addr;
1748ec94dbc5SRasesh Mody 
1749ec94dbc5SRasesh Mody 	sb_info->igu_sb_id = ecore_get_igu_sb_id(p_hwfn, sb_id);
1750ec94dbc5SRasesh Mody 
17516e4fcea9SRasesh Mody 	if (sb_info->igu_sb_id == ECORE_SB_INVALID_IDX)
17526e4fcea9SRasesh Mody 		return ECORE_INVAL;
17536e4fcea9SRasesh Mody 
17546e4fcea9SRasesh Mody 	/* Let the igu info reference the client's SB info */
1755ec94dbc5SRasesh Mody 	if (sb_id != ECORE_SP_SB_ID) {
17566e4fcea9SRasesh Mody 		if (IS_PF(p_hwfn->p_dev)) {
17576e4fcea9SRasesh Mody 			struct ecore_igu_info *p_info;
17586e4fcea9SRasesh Mody 			struct ecore_igu_block *p_block;
17596e4fcea9SRasesh Mody 
17606e4fcea9SRasesh Mody 			p_info = p_hwfn->hw_info.p_igu_info;
17616e4fcea9SRasesh Mody 			p_block = &p_info->entry[sb_info->igu_sb_id];
17626e4fcea9SRasesh Mody 
17636e4fcea9SRasesh Mody 			p_block->sb_info = sb_info;
17646e4fcea9SRasesh Mody 			p_block->status &= ~ECORE_IGU_STATUS_FREE;
17656e4fcea9SRasesh Mody 			p_info->usage.free_cnt--;
17666e4fcea9SRasesh Mody 		} else {
17676e4fcea9SRasesh Mody 			ecore_vf_set_sb_info(p_hwfn, sb_id, sb_info);
17686e4fcea9SRasesh Mody 		}
1769ec94dbc5SRasesh Mody 	}
1770ec94dbc5SRasesh Mody #ifdef ECORE_CONFIG_DIRECT_HWFN
1771ec94dbc5SRasesh Mody 	sb_info->p_hwfn = p_hwfn;
1772ec94dbc5SRasesh Mody #endif
1773ec94dbc5SRasesh Mody 	sb_info->p_dev = p_hwfn->p_dev;
1774ec94dbc5SRasesh Mody 
1775ec94dbc5SRasesh Mody 	/* The igu address will hold the absolute address that needs to be
1776ec94dbc5SRasesh Mody 	 * written to for a specific status block
1777ec94dbc5SRasesh Mody 	 */
17783b307c55SRasesh Mody 	if (IS_PF(p_hwfn->p_dev))
1779ec94dbc5SRasesh Mody 		sb_info->igu_addr = (u8 OSAL_IOMEM *)p_hwfn->regview +
17803b307c55SRasesh Mody 				     GTT_BAR0_MAP_REG_IGU_CMD +
17813b307c55SRasesh Mody 				     (sb_info->igu_sb_id << 3);
1782ec94dbc5SRasesh Mody 
17833b307c55SRasesh Mody 	else
17843b307c55SRasesh Mody 		sb_info->igu_addr = (u8 OSAL_IOMEM *)p_hwfn->regview +
178586a2265eSRasesh Mody 		    PXP_VF_BAR0_START_IGU +
17863b307c55SRasesh Mody 				     ((IGU_CMD_INT_ACK_BASE +
17873b307c55SRasesh Mody 				       sb_info->igu_sb_id) << 3);
178886a2265eSRasesh Mody 
1789ec94dbc5SRasesh Mody 	sb_info->flags |= ECORE_SB_INFO_INIT;
1790ec94dbc5SRasesh Mody 
1791ec94dbc5SRasesh Mody 	ecore_int_sb_setup(p_hwfn, p_ptt, sb_info);
1792ec94dbc5SRasesh Mody 
1793ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
1794ec94dbc5SRasesh Mody }
1795ec94dbc5SRasesh Mody 
ecore_int_sb_release(struct ecore_hwfn * p_hwfn,struct ecore_sb_info * sb_info,u16 sb_id)1796ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_sb_release(struct ecore_hwfn *p_hwfn,
1797ec94dbc5SRasesh Mody 					  struct ecore_sb_info *sb_info,
1798ec94dbc5SRasesh Mody 					  u16 sb_id)
1799ec94dbc5SRasesh Mody {
18006e4fcea9SRasesh Mody 	struct ecore_igu_info *p_info;
18016e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
18026e4fcea9SRasesh Mody 
18036e4fcea9SRasesh Mody 	if (sb_info == OSAL_NULL)
18046e4fcea9SRasesh Mody 		return ECORE_SUCCESS;
1805ec94dbc5SRasesh Mody 
1806ec94dbc5SRasesh Mody 	/* zero status block and ack counter */
1807ec94dbc5SRasesh Mody 	sb_info->sb_ack = 0;
18083b307c55SRasesh Mody 	OSAL_MEMSET(sb_info->sb_virt, 0, sb_info->sb_size);
1809ec94dbc5SRasesh Mody 
18106e4fcea9SRasesh Mody 	if (IS_VF(p_hwfn->p_dev)) {
18116e4fcea9SRasesh Mody 		ecore_vf_set_sb_info(p_hwfn, sb_id, OSAL_NULL);
18126e4fcea9SRasesh Mody 		return ECORE_SUCCESS;
1813ec94dbc5SRasesh Mody 	}
1814ec94dbc5SRasesh Mody 
18156e4fcea9SRasesh Mody 	p_info = p_hwfn->hw_info.p_igu_info;
18166e4fcea9SRasesh Mody 	p_block = &p_info->entry[sb_info->igu_sb_id];
18176e4fcea9SRasesh Mody 
18186e4fcea9SRasesh Mody 	/* Vector 0 is reserved to Default SB */
18196e4fcea9SRasesh Mody 	if (p_block->vector_number == 0) {
18206e4fcea9SRasesh Mody 		DP_ERR(p_hwfn, "Do Not free sp sb using this function");
18216e4fcea9SRasesh Mody 		return ECORE_INVAL;
18226e4fcea9SRasesh Mody 	}
18236e4fcea9SRasesh Mody 
18246e4fcea9SRasesh Mody 	/* Lose reference to client's SB info, and fix counters */
18256e4fcea9SRasesh Mody 	p_block->sb_info = OSAL_NULL;
18266e4fcea9SRasesh Mody 	p_block->status |= ECORE_IGU_STATUS_FREE;
18276e4fcea9SRasesh Mody 	p_info->usage.free_cnt++;
18286e4fcea9SRasesh Mody 
1829ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
1830ec94dbc5SRasesh Mody }
1831ec94dbc5SRasesh Mody 
ecore_int_sp_sb_free(struct ecore_hwfn * p_hwfn)1832ec94dbc5SRasesh Mody static void ecore_int_sp_sb_free(struct ecore_hwfn *p_hwfn)
1833ec94dbc5SRasesh Mody {
1834ec94dbc5SRasesh Mody 	struct ecore_sb_sp_info *p_sb = p_hwfn->p_sp_sb;
1835ec94dbc5SRasesh Mody 
1836ec94dbc5SRasesh Mody 	if (!p_sb)
1837ec94dbc5SRasesh Mody 		return;
1838ec94dbc5SRasesh Mody 
1839ec94dbc5SRasesh Mody 	if (p_sb->sb_info.sb_virt) {
1840ec94dbc5SRasesh Mody 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
1841ec94dbc5SRasesh Mody 				       p_sb->sb_info.sb_virt,
1842ec94dbc5SRasesh Mody 				       p_sb->sb_info.sb_phys,
1843ec94dbc5SRasesh Mody 				       SB_ALIGNED_SIZE(p_hwfn));
1844ec94dbc5SRasesh Mody 	}
1845ec94dbc5SRasesh Mody 
1846ec94dbc5SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_sb);
1847ec94dbc5SRasesh Mody }
1848ec94dbc5SRasesh Mody 
ecore_int_sp_sb_alloc(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)1849ec94dbc5SRasesh Mody static enum _ecore_status_t ecore_int_sp_sb_alloc(struct ecore_hwfn *p_hwfn,
1850ec94dbc5SRasesh Mody 						  struct ecore_ptt *p_ptt)
1851ec94dbc5SRasesh Mody {
1852ec94dbc5SRasesh Mody 	struct ecore_sb_sp_info *p_sb;
1853ec94dbc5SRasesh Mody 	dma_addr_t p_phys = 0;
1854ec94dbc5SRasesh Mody 	void *p_virt;
1855ec94dbc5SRasesh Mody 
1856ec94dbc5SRasesh Mody 	/* SB struct */
18573b307c55SRasesh Mody 	p_sb = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*p_sb));
1858ec94dbc5SRasesh Mody 	if (!p_sb) {
18593b307c55SRasesh Mody 		DP_NOTICE(p_hwfn, false,
18603b307c55SRasesh Mody 			  "Failed to allocate `struct ecore_sb_info'\n");
1861ec94dbc5SRasesh Mody 		return ECORE_NOMEM;
1862ec94dbc5SRasesh Mody 	}
1863ec94dbc5SRasesh Mody 
1864ec94dbc5SRasesh Mody 	/* SB ring  */
1865ec94dbc5SRasesh Mody 	p_virt = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
1866ec94dbc5SRasesh Mody 					 &p_phys, SB_ALIGNED_SIZE(p_hwfn));
1867ec94dbc5SRasesh Mody 	if (!p_virt) {
186898abf84eSRasesh Mody 		DP_NOTICE(p_hwfn, false, "Failed to allocate status block\n");
1869ec94dbc5SRasesh Mody 		OSAL_FREE(p_hwfn->p_dev, p_sb);
1870ec94dbc5SRasesh Mody 		return ECORE_NOMEM;
1871ec94dbc5SRasesh Mody 	}
1872ec94dbc5SRasesh Mody 
1873ec94dbc5SRasesh Mody 	/* Status Block setup */
1874ec94dbc5SRasesh Mody 	p_hwfn->p_sp_sb = p_sb;
1875ec94dbc5SRasesh Mody 	ecore_int_sb_init(p_hwfn, p_ptt, &p_sb->sb_info,
1876ec94dbc5SRasesh Mody 			  p_virt, p_phys, ECORE_SP_SB_ID);
1877ec94dbc5SRasesh Mody 
18783b307c55SRasesh Mody 	p_sb->pi_info_arr_size = PIS_PER_SB;
1879ec94dbc5SRasesh Mody 
1880ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
1881ec94dbc5SRasesh Mody }
1882ec94dbc5SRasesh Mody 
ecore_int_register_cb(struct ecore_hwfn * p_hwfn,ecore_int_comp_cb_t comp_cb,void * cookie,u8 * sb_idx,__le16 ** p_fw_cons)1883ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_register_cb(struct ecore_hwfn *p_hwfn,
1884ec94dbc5SRasesh Mody 					   ecore_int_comp_cb_t comp_cb,
1885ec94dbc5SRasesh Mody 					   void *cookie,
1886ec94dbc5SRasesh Mody 					   u8 *sb_idx, __le16 **p_fw_cons)
1887ec94dbc5SRasesh Mody {
1888ec94dbc5SRasesh Mody 	struct ecore_sb_sp_info *p_sp_sb = p_hwfn->p_sp_sb;
1889ec94dbc5SRasesh Mody 	enum _ecore_status_t rc = ECORE_NOMEM;
1890ec94dbc5SRasesh Mody 	u8 pi;
1891ec94dbc5SRasesh Mody 
1892ec94dbc5SRasesh Mody 	/* Look for a free index */
18933b307c55SRasesh Mody 	for (pi = 0; pi < p_sp_sb->pi_info_arr_size; pi++) {
1894ec94dbc5SRasesh Mody 		if (p_sp_sb->pi_info_arr[pi].comp_cb != OSAL_NULL)
1895ec94dbc5SRasesh Mody 			continue;
1896ec94dbc5SRasesh Mody 
1897ec94dbc5SRasesh Mody 		p_sp_sb->pi_info_arr[pi].comp_cb = comp_cb;
1898ec94dbc5SRasesh Mody 		p_sp_sb->pi_info_arr[pi].cookie = cookie;
1899ec94dbc5SRasesh Mody 		*sb_idx = pi;
19003b307c55SRasesh Mody 		*p_fw_cons = &p_sp_sb->sb_info.sb_pi_array[pi];
1901ec94dbc5SRasesh Mody 		rc = ECORE_SUCCESS;
1902ec94dbc5SRasesh Mody 		break;
1903ec94dbc5SRasesh Mody 	}
1904ec94dbc5SRasesh Mody 
1905ec94dbc5SRasesh Mody 	return rc;
1906ec94dbc5SRasesh Mody }
1907ec94dbc5SRasesh Mody 
ecore_int_unregister_cb(struct ecore_hwfn * p_hwfn,u8 pi)1908ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_unregister_cb(struct ecore_hwfn *p_hwfn, u8 pi)
1909ec94dbc5SRasesh Mody {
1910ec94dbc5SRasesh Mody 	struct ecore_sb_sp_info *p_sp_sb = p_hwfn->p_sp_sb;
1911ec94dbc5SRasesh Mody 
1912ec94dbc5SRasesh Mody 	if (p_sp_sb->pi_info_arr[pi].comp_cb == OSAL_NULL)
1913ec94dbc5SRasesh Mody 		return ECORE_NOMEM;
1914ec94dbc5SRasesh Mody 
1915ec94dbc5SRasesh Mody 	p_sp_sb->pi_info_arr[pi].comp_cb = OSAL_NULL;
1916ec94dbc5SRasesh Mody 	p_sp_sb->pi_info_arr[pi].cookie = OSAL_NULL;
1917ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
1918ec94dbc5SRasesh Mody }
1919ec94dbc5SRasesh Mody 
ecore_int_get_sp_sb_id(struct ecore_hwfn * p_hwfn)1920ec94dbc5SRasesh Mody u16 ecore_int_get_sp_sb_id(struct ecore_hwfn *p_hwfn)
1921ec94dbc5SRasesh Mody {
1922ec94dbc5SRasesh Mody 	return p_hwfn->p_sp_sb->sb_info.igu_sb_id;
1923ec94dbc5SRasesh Mody }
1924ec94dbc5SRasesh Mody 
ecore_int_igu_enable_int(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_int_mode int_mode)1925ec94dbc5SRasesh Mody void ecore_int_igu_enable_int(struct ecore_hwfn *p_hwfn,
1926ec94dbc5SRasesh Mody 			      struct ecore_ptt *p_ptt,
1927ec94dbc5SRasesh Mody 			      enum ecore_int_mode int_mode)
1928ec94dbc5SRasesh Mody {
192922d07d93SRasesh Mody 	u32 igu_pf_conf = IGU_PF_CONF_FUNC_EN | IGU_PF_CONF_ATTN_BIT_EN;
1930ec94dbc5SRasesh Mody 
1931ec94dbc5SRasesh Mody #ifndef ASIC_ONLY
193222d07d93SRasesh Mody 	if (CHIP_REV_IS_FPGA(p_hwfn->p_dev)) {
1933ec94dbc5SRasesh Mody 		DP_INFO(p_hwfn, "FPGA - don't enable ATTN generation in IGU\n");
193422d07d93SRasesh Mody 		igu_pf_conf &= ~IGU_PF_CONF_ATTN_BIT_EN;
193522d07d93SRasesh Mody 	}
1936ec94dbc5SRasesh Mody #endif
1937ec94dbc5SRasesh Mody 
1938ec94dbc5SRasesh Mody 	p_hwfn->p_dev->int_mode = int_mode;
1939ec94dbc5SRasesh Mody 	switch (p_hwfn->p_dev->int_mode) {
1940ec94dbc5SRasesh Mody 	case ECORE_INT_MODE_INTA:
1941ec94dbc5SRasesh Mody 		igu_pf_conf |= IGU_PF_CONF_INT_LINE_EN;
1942ec94dbc5SRasesh Mody 		igu_pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN;
1943ec94dbc5SRasesh Mody 		break;
1944ec94dbc5SRasesh Mody 
1945ec94dbc5SRasesh Mody 	case ECORE_INT_MODE_MSI:
1946ec94dbc5SRasesh Mody 		igu_pf_conf |= IGU_PF_CONF_MSI_MSIX_EN;
1947ec94dbc5SRasesh Mody 		igu_pf_conf |= IGU_PF_CONF_SINGLE_ISR_EN;
1948ec94dbc5SRasesh Mody 		break;
1949ec94dbc5SRasesh Mody 
1950ec94dbc5SRasesh Mody 	case ECORE_INT_MODE_MSIX:
1951ec94dbc5SRasesh Mody 		igu_pf_conf |= IGU_PF_CONF_MSI_MSIX_EN;
1952ec94dbc5SRasesh Mody 		break;
1953ec94dbc5SRasesh Mody 	case ECORE_INT_MODE_POLL:
1954ec94dbc5SRasesh Mody 		break;
1955ec94dbc5SRasesh Mody 	}
1956ec94dbc5SRasesh Mody 
1957ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_CONFIGURATION, igu_pf_conf);
1958ec94dbc5SRasesh Mody }
1959ec94dbc5SRasesh Mody 
ecore_int_igu_enable_attn(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)1960ec94dbc5SRasesh Mody static void ecore_int_igu_enable_attn(struct ecore_hwfn *p_hwfn,
1961ec94dbc5SRasesh Mody 				      struct ecore_ptt *p_ptt)
1962ec94dbc5SRasesh Mody {
1963ec94dbc5SRasesh Mody #ifndef ASIC_ONLY
1964ec94dbc5SRasesh Mody 	if (CHIP_REV_IS_FPGA(p_hwfn->p_dev)) {
1965ec94dbc5SRasesh Mody 		DP_INFO(p_hwfn,
1966ec94dbc5SRasesh Mody 			"FPGA - Don't enable Attentions in IGU and MISC\n");
1967ec94dbc5SRasesh Mody 		return;
1968ec94dbc5SRasesh Mody 	}
1969ec94dbc5SRasesh Mody #endif
1970ec94dbc5SRasesh Mody 
1971ec94dbc5SRasesh Mody 	/* Configure AEU signal change to produce attentions */
1972ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0);
1973ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_LEADING_EDGE_LATCH, 0xfff);
1974ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff);
1975ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0xfff);
1976ec94dbc5SRasesh Mody 
19779455b556SRasesh Mody 	/* Flush the writes to IGU */
1978ec94dbc5SRasesh Mody 	OSAL_MMIOWB(p_hwfn->p_dev);
1979ec94dbc5SRasesh Mody 
1980ec94dbc5SRasesh Mody 	/* Unmask AEU signals toward IGU */
1981ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff);
1982ec94dbc5SRasesh Mody }
1983ec94dbc5SRasesh Mody 
1984ec94dbc5SRasesh Mody enum _ecore_status_t
ecore_int_igu_enable(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,enum ecore_int_mode int_mode)1985ec94dbc5SRasesh Mody ecore_int_igu_enable(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
1986ec94dbc5SRasesh Mody 			  enum ecore_int_mode int_mode)
1987ec94dbc5SRasesh Mody {
1988ec94dbc5SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
1989ec94dbc5SRasesh Mody 
1990ec94dbc5SRasesh Mody 	ecore_int_igu_enable_attn(p_hwfn, p_ptt);
1991ec94dbc5SRasesh Mody 
1992ec94dbc5SRasesh Mody 	if ((int_mode != ECORE_INT_MODE_INTA) || IS_LEAD_HWFN(p_hwfn)) {
1993ec94dbc5SRasesh Mody 		rc = OSAL_SLOWPATH_IRQ_REQ(p_hwfn);
1994ec94dbc5SRasesh Mody 		if (rc != ECORE_SUCCESS) {
1995ec94dbc5SRasesh Mody 			DP_NOTICE(p_hwfn, true,
1996ec94dbc5SRasesh Mody 				  "Slowpath IRQ request failed\n");
1997ec94dbc5SRasesh Mody 			return ECORE_NORESOURCES;
1998ec94dbc5SRasesh Mody 		}
1999ec94dbc5SRasesh Mody 		p_hwfn->b_int_requested = true;
2000ec94dbc5SRasesh Mody 	}
2001ec94dbc5SRasesh Mody 
2002ec94dbc5SRasesh Mody 	/* Enable interrupt Generation */
2003ec94dbc5SRasesh Mody 	ecore_int_igu_enable_int(p_hwfn, p_ptt, int_mode);
2004ec94dbc5SRasesh Mody 
2005ec94dbc5SRasesh Mody 	p_hwfn->b_int_enabled = 1;
2006ec94dbc5SRasesh Mody 
2007ec94dbc5SRasesh Mody 	return rc;
2008ec94dbc5SRasesh Mody }
2009ec94dbc5SRasesh Mody 
ecore_int_igu_disable_int(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)2010ec94dbc5SRasesh Mody void ecore_int_igu_disable_int(struct ecore_hwfn *p_hwfn,
2011ec94dbc5SRasesh Mody 			       struct ecore_ptt *p_ptt)
2012ec94dbc5SRasesh Mody {
2013ec94dbc5SRasesh Mody 	p_hwfn->b_int_enabled = 0;
2014ec94dbc5SRasesh Mody 
201586a2265eSRasesh Mody 	if (IS_VF(p_hwfn->p_dev))
201686a2265eSRasesh Mody 		return;
201786a2265eSRasesh Mody 
2018ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_CONFIGURATION, 0);
2019ec94dbc5SRasesh Mody }
2020ec94dbc5SRasesh Mody 
2021ec94dbc5SRasesh Mody #define IGU_CLEANUP_SLEEP_LENGTH		(1000)
ecore_int_igu_cleanup_sb(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u32 igu_sb_id,bool cleanup_set,u16 opaque_fid)202222d07d93SRasesh Mody static void ecore_int_igu_cleanup_sb(struct ecore_hwfn *p_hwfn,
2023ec94dbc5SRasesh Mody 				     struct ecore_ptt *p_ptt,
20246e4fcea9SRasesh Mody 				     u32 igu_sb_id,
20256e4fcea9SRasesh Mody 				     bool cleanup_set,
20266e4fcea9SRasesh Mody 				     u16 opaque_fid)
2027ec94dbc5SRasesh Mody {
20283b307c55SRasesh Mody 	u32 data = 0, cmd_ctrl = 0, sb_bit, sb_bit_addr, pxp_addr;
20293b307c55SRasesh Mody 	u32 sleep_cnt = IGU_CLEANUP_SLEEP_LENGTH, val;
20303b307c55SRasesh Mody 	u8 type = 0;
2031ec94dbc5SRasesh Mody 
2032ec94dbc5SRasesh Mody 	OSAL_BUILD_BUG_ON((IGU_REG_CLEANUP_STATUS_4 -
2033ec94dbc5SRasesh Mody 			   IGU_REG_CLEANUP_STATUS_0) != 0x200);
2034ec94dbc5SRasesh Mody 
2035ec94dbc5SRasesh Mody 	/* USE Control Command Register to perform cleanup. There is an
2036ec94dbc5SRasesh Mody 	 * option to do this using IGU bar, but then it can't be used for VFs.
2037ec94dbc5SRasesh Mody 	 */
2038ec94dbc5SRasesh Mody 
2039ec94dbc5SRasesh Mody 	/* Set the data field */
2040ec94dbc5SRasesh Mody 	SET_FIELD(data, IGU_CLEANUP_CLEANUP_SET, cleanup_set ? 1 : 0);
2041ec94dbc5SRasesh Mody 	SET_FIELD(data, IGU_CLEANUP_CLEANUP_TYPE, type);
2042ec94dbc5SRasesh Mody 	SET_FIELD(data, IGU_CLEANUP_COMMAND_TYPE, IGU_COMMAND_TYPE_SET);
2043ec94dbc5SRasesh Mody 
2044ec94dbc5SRasesh Mody 	/* Set the control register */
20453b307c55SRasesh Mody 	pxp_addr = IGU_CMD_INT_ACK_BASE + igu_sb_id;
2046ec94dbc5SRasesh Mody 	SET_FIELD(cmd_ctrl, IGU_CTRL_REG_PXP_ADDR, pxp_addr);
2047ec94dbc5SRasesh Mody 	SET_FIELD(cmd_ctrl, IGU_CTRL_REG_FID, opaque_fid);
2048ec94dbc5SRasesh Mody 	SET_FIELD(cmd_ctrl, IGU_CTRL_REG_TYPE, IGU_CTRL_CMD_TYPE_WR);
2049ec94dbc5SRasesh Mody 
2050ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_32LSB_DATA, data);
2051ec94dbc5SRasesh Mody 
2052ec94dbc5SRasesh Mody 	OSAL_BARRIER(p_hwfn->p_dev);
2053ec94dbc5SRasesh Mody 
2054ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl);
2055ec94dbc5SRasesh Mody 
20569455b556SRasesh Mody 	/* Flush the write to IGU */
2057ec94dbc5SRasesh Mody 	OSAL_MMIOWB(p_hwfn->p_dev);
2058ec94dbc5SRasesh Mody 
2059ec94dbc5SRasesh Mody 	/* calculate where to read the status bit from */
20606e4fcea9SRasesh Mody 	sb_bit = 1 << (igu_sb_id % 32);
20616e4fcea9SRasesh Mody 	sb_bit_addr = igu_sb_id / 32 * sizeof(u32);
2062ec94dbc5SRasesh Mody 
2063ec94dbc5SRasesh Mody 	sb_bit_addr += IGU_REG_CLEANUP_STATUS_0 + (0x80 * type);
2064ec94dbc5SRasesh Mody 
2065ec94dbc5SRasesh Mody 	/* Now wait for the command to complete */
2066ec94dbc5SRasesh Mody 	while (--sleep_cnt) {
2067ec94dbc5SRasesh Mody 		val = ecore_rd(p_hwfn, p_ptt, sb_bit_addr);
2068ec94dbc5SRasesh Mody 		if ((val & sb_bit) == (cleanup_set ? sb_bit : 0))
2069ec94dbc5SRasesh Mody 			break;
2070ec94dbc5SRasesh Mody 		OSAL_MSLEEP(5);
2071ec94dbc5SRasesh Mody 	}
2072ec94dbc5SRasesh Mody 
2073ec94dbc5SRasesh Mody 	if (!sleep_cnt)
2074ec94dbc5SRasesh Mody 		DP_NOTICE(p_hwfn, true,
2075ec94dbc5SRasesh Mody 			  "Timeout waiting for clear status 0x%08x [for sb %d]\n",
20766e4fcea9SRasesh Mody 			  val, igu_sb_id);
2077ec94dbc5SRasesh Mody }
2078ec94dbc5SRasesh Mody 
ecore_int_igu_init_pure_rt_single(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u16 igu_sb_id,u16 opaque,bool b_set)2079ec94dbc5SRasesh Mody void ecore_int_igu_init_pure_rt_single(struct ecore_hwfn *p_hwfn,
2080ec94dbc5SRasesh Mody 				       struct ecore_ptt *p_ptt,
20816e4fcea9SRasesh Mody 				       u16 igu_sb_id, u16 opaque, bool b_set)
2082ec94dbc5SRasesh Mody {
20836e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
208422d07d93SRasesh Mody 	int pi, i;
2085ec94dbc5SRasesh Mody 
20866e4fcea9SRasesh Mody 	p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_sb_id];
20876e4fcea9SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
20886e4fcea9SRasesh Mody 		   "Cleaning SB [%04x]: func_id= %d is_pf = %d vector_num = 0x%0x\n",
20896e4fcea9SRasesh Mody 		   igu_sb_id, p_block->function_id, p_block->is_pf,
20906e4fcea9SRasesh Mody 		   p_block->vector_number);
20916e4fcea9SRasesh Mody 
2092ec94dbc5SRasesh Mody 	/* Set */
2093ec94dbc5SRasesh Mody 	if (b_set)
20946e4fcea9SRasesh Mody 		ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 1, opaque);
2095ec94dbc5SRasesh Mody 
2096ec94dbc5SRasesh Mody 	/* Clear */
20976e4fcea9SRasesh Mody 	ecore_int_igu_cleanup_sb(p_hwfn, p_ptt, igu_sb_id, 0, opaque);
2098ec94dbc5SRasesh Mody 
209922d07d93SRasesh Mody 	/* Wait for the IGU SB to cleanup */
210022d07d93SRasesh Mody 	for (i = 0; i < IGU_CLEANUP_SLEEP_LENGTH; i++) {
210122d07d93SRasesh Mody 		u32 val;
210222d07d93SRasesh Mody 
210322d07d93SRasesh Mody 		val = ecore_rd(p_hwfn, p_ptt,
210422d07d93SRasesh Mody 			       IGU_REG_WRITE_DONE_PENDING +
21056e4fcea9SRasesh Mody 			       ((igu_sb_id / 32) * 4));
21066e4fcea9SRasesh Mody 		if (val & (1 << (igu_sb_id % 32)))
210722d07d93SRasesh Mody 			OSAL_UDELAY(10);
210822d07d93SRasesh Mody 		else
210922d07d93SRasesh Mody 			break;
211022d07d93SRasesh Mody 	}
211122d07d93SRasesh Mody 	if (i == IGU_CLEANUP_SLEEP_LENGTH)
211222d07d93SRasesh Mody 		DP_NOTICE(p_hwfn, true,
211322d07d93SRasesh Mody 			  "Failed SB[0x%08x] still appearing in WRITE_DONE_PENDING\n",
21146e4fcea9SRasesh Mody 			  igu_sb_id);
211522d07d93SRasesh Mody 
2116ec94dbc5SRasesh Mody 	/* Clear the CAU for the SB */
21173b307c55SRasesh Mody 	for (pi = 0; pi < PIS_PER_SB; pi++)
2118ec94dbc5SRasesh Mody 		ecore_wr(p_hwfn, p_ptt,
21193b307c55SRasesh Mody 			 CAU_REG_PI_MEMORY +
21203b307c55SRasesh Mody 			 (igu_sb_id * PIS_PER_SB + pi) * 4,
21213b307c55SRasesh Mody 			 0);
2122ec94dbc5SRasesh Mody }
2123ec94dbc5SRasesh Mody 
ecore_int_igu_init_pure_rt(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,bool b_set,bool b_slowpath)2124ec94dbc5SRasesh Mody void ecore_int_igu_init_pure_rt(struct ecore_hwfn *p_hwfn,
2125ec94dbc5SRasesh Mody 				struct ecore_ptt *p_ptt,
2126ec94dbc5SRasesh Mody 				bool b_set, bool b_slowpath)
2127ec94dbc5SRasesh Mody {
21286e4fcea9SRasesh Mody 	struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
21296e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
21306e4fcea9SRasesh Mody 	u16 igu_sb_id = 0;
21316e4fcea9SRasesh Mody 	u32 val = 0;
2132ec94dbc5SRasesh Mody 
2133ec94dbc5SRasesh Mody 	/* @@@TBD MichalK temporary... should be moved to init-tool... */
2134ec94dbc5SRasesh Mody 	val = ecore_rd(p_hwfn, p_ptt, IGU_REG_BLOCK_CONFIGURATION);
2135ec94dbc5SRasesh Mody 	val |= IGU_REG_BLOCK_CONFIGURATION_VF_CLEANUP_EN;
2136ec94dbc5SRasesh Mody 	val &= ~IGU_REG_BLOCK_CONFIGURATION_PXP_TPH_INTERFACE_EN;
2137ec94dbc5SRasesh Mody 	ecore_wr(p_hwfn, p_ptt, IGU_REG_BLOCK_CONFIGURATION, val);
2138ec94dbc5SRasesh Mody 	/* end temporary */
2139ec94dbc5SRasesh Mody 
21406e4fcea9SRasesh Mody 	for (igu_sb_id = 0;
21416e4fcea9SRasesh Mody 	     igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
21426e4fcea9SRasesh Mody 	     igu_sb_id++) {
21436e4fcea9SRasesh Mody 		p_block = &p_info->entry[igu_sb_id];
2144ec94dbc5SRasesh Mody 
21456e4fcea9SRasesh Mody 		if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
21466e4fcea9SRasesh Mody 		    !p_block->is_pf ||
21476e4fcea9SRasesh Mody 		    (p_block->status & ECORE_IGU_STATUS_DSB))
21486e4fcea9SRasesh Mody 			continue;
21496e4fcea9SRasesh Mody 
21506e4fcea9SRasesh Mody 		ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt, igu_sb_id,
2151ec94dbc5SRasesh Mody 						  p_hwfn->hw_info.opaque_fid,
2152ec94dbc5SRasesh Mody 						  b_set);
2153ec94dbc5SRasesh Mody 	}
2154ec94dbc5SRasesh Mody 
21556e4fcea9SRasesh Mody 	if (b_slowpath)
21566e4fcea9SRasesh Mody 		ecore_int_igu_init_pure_rt_single(p_hwfn, p_ptt,
21576e4fcea9SRasesh Mody 						  p_info->igu_dsb_id,
21586e4fcea9SRasesh Mody 						  p_hwfn->hw_info.opaque_fid,
21596e4fcea9SRasesh Mody 						  b_set);
21606e4fcea9SRasesh Mody }
21616e4fcea9SRasesh Mody 
ecore_int_igu_reset_cam(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)21626e4fcea9SRasesh Mody int ecore_int_igu_reset_cam(struct ecore_hwfn *p_hwfn,
21636e4fcea9SRasesh Mody 			    struct ecore_ptt *p_ptt)
21646e4fcea9SRasesh Mody {
21656e4fcea9SRasesh Mody 	struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
21666e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block;
21676e4fcea9SRasesh Mody 	int pf_sbs, vf_sbs;
21686e4fcea9SRasesh Mody 	u16 igu_sb_id;
21696e4fcea9SRasesh Mody 	u32 val, rval;
21706e4fcea9SRasesh Mody 
21716e4fcea9SRasesh Mody 	if (!RESC_NUM(p_hwfn, ECORE_SB)) {
21726e4fcea9SRasesh Mody 		/* We're using an old MFW - have to prevent any switching
21736e4fcea9SRasesh Mody 		 * of SBs between PF and VFs as later driver wouldn't be
21746e4fcea9SRasesh Mody 		 * able to tell which belongs to which.
21756e4fcea9SRasesh Mody 		 */
21766e4fcea9SRasesh Mody 		p_info->b_allow_pf_vf_change = false;
21776e4fcea9SRasesh Mody 	} else {
21786e4fcea9SRasesh Mody 		/* Use the numbers the MFW have provided -
21796e4fcea9SRasesh Mody 		 * don't forget MFW accounts for the default SB as well.
21806e4fcea9SRasesh Mody 		 */
21816e4fcea9SRasesh Mody 		p_info->b_allow_pf_vf_change = true;
21826e4fcea9SRasesh Mody 
21836e4fcea9SRasesh Mody 		if (p_info->usage.cnt != RESC_NUM(p_hwfn, ECORE_SB) - 1) {
21846e4fcea9SRasesh Mody 			DP_INFO(p_hwfn,
21856e4fcea9SRasesh Mody 				"MFW notifies of 0x%04x PF SBs; IGU indicates of only 0x%04x\n",
21866e4fcea9SRasesh Mody 				RESC_NUM(p_hwfn, ECORE_SB) - 1,
21876e4fcea9SRasesh Mody 				p_info->usage.cnt);
21886e4fcea9SRasesh Mody 			p_info->usage.cnt = RESC_NUM(p_hwfn, ECORE_SB) - 1;
21896e4fcea9SRasesh Mody 		}
21906e4fcea9SRasesh Mody 
21916e4fcea9SRasesh Mody 		/* TODO - how do we learn about VF SBs from MFW? */
21926e4fcea9SRasesh Mody 		if (IS_PF_SRIOV(p_hwfn)) {
21936e4fcea9SRasesh Mody 			u16 vfs = p_hwfn->p_dev->p_iov_info->total_vfs;
21946e4fcea9SRasesh Mody 
21956e4fcea9SRasesh Mody 			if (vfs != p_info->usage.iov_cnt)
21966e4fcea9SRasesh Mody 				DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
21976e4fcea9SRasesh Mody 					   "0x%04x VF SBs in IGU CAM != PCI configuration 0x%04x\n",
21986e4fcea9SRasesh Mody 					   p_info->usage.iov_cnt, vfs);
21996e4fcea9SRasesh Mody 
22006e4fcea9SRasesh Mody 			/* At this point we know how many SBs we have totally
22016e4fcea9SRasesh Mody 			 * in IGU + number of PF SBs. So we can validate that
22026e4fcea9SRasesh Mody 			 * we'd have sufficient for VF.
22036e4fcea9SRasesh Mody 			 */
22046e4fcea9SRasesh Mody 			if (vfs > p_info->usage.free_cnt +
22056e4fcea9SRasesh Mody 				  p_info->usage.free_cnt_iov -
22066e4fcea9SRasesh Mody 				  p_info->usage.cnt) {
22076e4fcea9SRasesh Mody 				DP_NOTICE(p_hwfn, true,
22086e4fcea9SRasesh Mody 					  "Not enough SBs for VFs - 0x%04x SBs, from which %04x PFs and %04x are required\n",
22096e4fcea9SRasesh Mody 					  p_info->usage.free_cnt +
22106e4fcea9SRasesh Mody 					  p_info->usage.free_cnt_iov,
22116e4fcea9SRasesh Mody 					  p_info->usage.cnt, vfs);
22126e4fcea9SRasesh Mody 				return ECORE_INVAL;
22136e4fcea9SRasesh Mody 			}
22146e4fcea9SRasesh Mody 		}
22156e4fcea9SRasesh Mody 	}
22166e4fcea9SRasesh Mody 
22176e4fcea9SRasesh Mody 	/* Cap the number of VFs SBs by the number of VFs */
22186e4fcea9SRasesh Mody 	if (IS_PF_SRIOV(p_hwfn))
22196e4fcea9SRasesh Mody 		p_info->usage.iov_cnt = p_hwfn->p_dev->p_iov_info->total_vfs;
22206e4fcea9SRasesh Mody 
22216e4fcea9SRasesh Mody 	/* Mark all SBs as free, now in the right PF/VFs division */
22226e4fcea9SRasesh Mody 	p_info->usage.free_cnt = p_info->usage.cnt;
22236e4fcea9SRasesh Mody 	p_info->usage.free_cnt_iov = p_info->usage.iov_cnt;
22246e4fcea9SRasesh Mody 	p_info->usage.orig = p_info->usage.cnt;
22256e4fcea9SRasesh Mody 	p_info->usage.iov_orig = p_info->usage.iov_cnt;
22266e4fcea9SRasesh Mody 
22276e4fcea9SRasesh Mody 	/* We now proceed to re-configure the IGU cam to reflect the initial
22286e4fcea9SRasesh Mody 	 * configuration. We can start with the Default SB.
22296e4fcea9SRasesh Mody 	 */
22306e4fcea9SRasesh Mody 	pf_sbs = p_info->usage.cnt;
22316e4fcea9SRasesh Mody 	vf_sbs = p_info->usage.iov_cnt;
22326e4fcea9SRasesh Mody 
22336e4fcea9SRasesh Mody 	for (igu_sb_id = p_info->igu_dsb_id;
22346e4fcea9SRasesh Mody 	     igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
22356e4fcea9SRasesh Mody 	     igu_sb_id++) {
22366e4fcea9SRasesh Mody 		p_block = &p_info->entry[igu_sb_id];
22376e4fcea9SRasesh Mody 		val = 0;
22386e4fcea9SRasesh Mody 
22396e4fcea9SRasesh Mody 		if (!(p_block->status & ECORE_IGU_STATUS_VALID))
22406e4fcea9SRasesh Mody 			continue;
22416e4fcea9SRasesh Mody 
22426e4fcea9SRasesh Mody 		if (p_block->status & ECORE_IGU_STATUS_DSB) {
22436e4fcea9SRasesh Mody 			p_block->function_id = p_hwfn->rel_pf_id;
22446e4fcea9SRasesh Mody 			p_block->is_pf = 1;
22456e4fcea9SRasesh Mody 			p_block->vector_number = 0;
22466e4fcea9SRasesh Mody 			p_block->status = ECORE_IGU_STATUS_VALID |
22476e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_PF |
22486e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_DSB;
22496e4fcea9SRasesh Mody 		} else if (pf_sbs) {
22506e4fcea9SRasesh Mody 			pf_sbs--;
22516e4fcea9SRasesh Mody 			p_block->function_id = p_hwfn->rel_pf_id;
22526e4fcea9SRasesh Mody 			p_block->is_pf = 1;
22536e4fcea9SRasesh Mody 			p_block->vector_number = p_info->usage.cnt - pf_sbs;
22546e4fcea9SRasesh Mody 			p_block->status = ECORE_IGU_STATUS_VALID |
22556e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_PF |
22566e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_FREE;
22576e4fcea9SRasesh Mody 		} else if (vf_sbs) {
22586e4fcea9SRasesh Mody 			p_block->function_id =
22596e4fcea9SRasesh Mody 				p_hwfn->p_dev->p_iov_info->first_vf_in_pf +
22606e4fcea9SRasesh Mody 				p_info->usage.iov_cnt - vf_sbs;
22616e4fcea9SRasesh Mody 			p_block->is_pf = 0;
22626e4fcea9SRasesh Mody 			p_block->vector_number = 0;
22636e4fcea9SRasesh Mody 			p_block->status = ECORE_IGU_STATUS_VALID |
22646e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_FREE;
22656e4fcea9SRasesh Mody 			vf_sbs--;
22666e4fcea9SRasesh Mody 		} else {
22676e4fcea9SRasesh Mody 			p_block->function_id = 0;
22686e4fcea9SRasesh Mody 			p_block->is_pf = 0;
22696e4fcea9SRasesh Mody 			p_block->vector_number = 0;
22706e4fcea9SRasesh Mody 		}
22716e4fcea9SRasesh Mody 
22726e4fcea9SRasesh Mody 		SET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER,
22736e4fcea9SRasesh Mody 			  p_block->function_id);
22746e4fcea9SRasesh Mody 		SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, p_block->is_pf);
22756e4fcea9SRasesh Mody 		SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER,
22766e4fcea9SRasesh Mody 			  p_block->vector_number);
22776e4fcea9SRasesh Mody 
22786e4fcea9SRasesh Mody 		/* VF entries would be enabled when VF is initializaed */
22796e4fcea9SRasesh Mody 		SET_FIELD(val, IGU_MAPPING_LINE_VALID, p_block->is_pf);
22806e4fcea9SRasesh Mody 
22816e4fcea9SRasesh Mody 		rval = ecore_rd(p_hwfn, p_ptt,
22826e4fcea9SRasesh Mody 				IGU_REG_MAPPING_MEMORY +
22836e4fcea9SRasesh Mody 				sizeof(u32) * igu_sb_id);
22846e4fcea9SRasesh Mody 
22856e4fcea9SRasesh Mody 		if (rval != val) {
22866e4fcea9SRasesh Mody 			ecore_wr(p_hwfn, p_ptt,
22876e4fcea9SRasesh Mody 				 IGU_REG_MAPPING_MEMORY +
22886e4fcea9SRasesh Mody 				 sizeof(u32) * igu_sb_id,
22896e4fcea9SRasesh Mody 				 val);
22906e4fcea9SRasesh Mody 
22916e4fcea9SRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
22926e4fcea9SRasesh Mody 				   "IGU reset: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x [%08x -> %08x]\n",
22936e4fcea9SRasesh Mody 				   igu_sb_id, p_block->function_id,
22946e4fcea9SRasesh Mody 				   p_block->is_pf, p_block->vector_number,
22956e4fcea9SRasesh Mody 				   rval, val);
22966e4fcea9SRasesh Mody 		}
22976e4fcea9SRasesh Mody 	}
22986e4fcea9SRasesh Mody 
22996e4fcea9SRasesh Mody 	return 0;
23006e4fcea9SRasesh Mody }
23016e4fcea9SRasesh Mody 
ecore_int_igu_reset_cam_default(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)23026e4fcea9SRasesh Mody int ecore_int_igu_reset_cam_default(struct ecore_hwfn *p_hwfn,
23036e4fcea9SRasesh Mody 				    struct ecore_ptt *p_ptt)
23046e4fcea9SRasesh Mody {
23056e4fcea9SRasesh Mody 	struct ecore_sb_cnt_info *p_cnt = &p_hwfn->hw_info.p_igu_info->usage;
23066e4fcea9SRasesh Mody 
23076e4fcea9SRasesh Mody 	/* Return all the usage indications to default prior to the reset;
23086e4fcea9SRasesh Mody 	 * The reset expects the !orig to reflect the initial status of the
23096e4fcea9SRasesh Mody 	 * SBs, and would re-calculate the originals based on those.
23106e4fcea9SRasesh Mody 	 */
23116e4fcea9SRasesh Mody 	p_cnt->cnt = p_cnt->orig;
23126e4fcea9SRasesh Mody 	p_cnt->free_cnt = p_cnt->orig;
23136e4fcea9SRasesh Mody 	p_cnt->iov_cnt = p_cnt->iov_orig;
23146e4fcea9SRasesh Mody 	p_cnt->free_cnt_iov = p_cnt->iov_orig;
23156e4fcea9SRasesh Mody 	p_cnt->orig = 0;
23166e4fcea9SRasesh Mody 	p_cnt->iov_orig = 0;
23176e4fcea9SRasesh Mody 
23186e4fcea9SRasesh Mody 	/* TODO - we probably need to re-configure the CAU as well... */
23196e4fcea9SRasesh Mody 	return ecore_int_igu_reset_cam(p_hwfn, p_ptt);
23206e4fcea9SRasesh Mody }
23216e4fcea9SRasesh Mody 
ecore_int_igu_read_cam_block(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u16 igu_sb_id)23226e4fcea9SRasesh Mody static void ecore_int_igu_read_cam_block(struct ecore_hwfn *p_hwfn,
23236e4fcea9SRasesh Mody 					 struct ecore_ptt *p_ptt,
23246e4fcea9SRasesh Mody 					 u16 igu_sb_id)
2325ec94dbc5SRasesh Mody {
2326ec94dbc5SRasesh Mody 	u32 val = ecore_rd(p_hwfn, p_ptt,
23276e4fcea9SRasesh Mody 			   IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_sb_id);
2328ec94dbc5SRasesh Mody 	struct ecore_igu_block *p_block;
2329ec94dbc5SRasesh Mody 
23306e4fcea9SRasesh Mody 	p_block = &p_hwfn->hw_info.p_igu_info->entry[igu_sb_id];
2331ec94dbc5SRasesh Mody 
2332ec94dbc5SRasesh Mody 	/* Fill the block information */
2333ec94dbc5SRasesh Mody 	p_block->function_id = GET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER);
2334ec94dbc5SRasesh Mody 	p_block->is_pf = GET_FIELD(val, IGU_MAPPING_LINE_PF_VALID);
2335ec94dbc5SRasesh Mody 	p_block->vector_number = GET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER);
2336ec94dbc5SRasesh Mody 
23376e4fcea9SRasesh Mody 	p_block->igu_sb_id = igu_sb_id;
2338ec94dbc5SRasesh Mody }
2339ec94dbc5SRasesh Mody 
ecore_int_igu_read_cam(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)2340ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_igu_read_cam(struct ecore_hwfn *p_hwfn,
2341ec94dbc5SRasesh Mody 					    struct ecore_ptt *p_ptt)
2342ec94dbc5SRasesh Mody {
2343ec94dbc5SRasesh Mody 	struct ecore_igu_info *p_igu_info;
2344ec94dbc5SRasesh Mody 	struct ecore_igu_block *p_block;
23456e4fcea9SRasesh Mody 	u32 min_vf = 0, max_vf = 0;
23466e4fcea9SRasesh Mody 	u16 igu_sb_id;
2347ec94dbc5SRasesh Mody 
23486e4fcea9SRasesh Mody 	p_hwfn->hw_info.p_igu_info = OSAL_ZALLOC(p_hwfn->p_dev,
2349ec94dbc5SRasesh Mody 						 GFP_KERNEL,
2350ec94dbc5SRasesh Mody 						 sizeof(*p_igu_info));
2351ec94dbc5SRasesh Mody 	if (!p_hwfn->hw_info.p_igu_info)
2352ec94dbc5SRasesh Mody 		return ECORE_NOMEM;
2353ec94dbc5SRasesh Mody 	p_igu_info = p_hwfn->hw_info.p_igu_info;
2354ec94dbc5SRasesh Mody 
23556e4fcea9SRasesh Mody 	/* Distinguish between existent and onn-existent default SB */
23566e4fcea9SRasesh Mody 	p_igu_info->igu_dsb_id = ECORE_SB_INVALID_IDX;
2357ec94dbc5SRasesh Mody 
23586e4fcea9SRasesh Mody 	/* Find the range of VF ids whose SB belong to this PF */
235922d07d93SRasesh Mody 	if (p_hwfn->p_dev->p_iov_info) {
236022d07d93SRasesh Mody 		struct ecore_hw_sriov_info *p_iov = p_hwfn->p_dev->p_iov_info;
2361ec94dbc5SRasesh Mody 
236222d07d93SRasesh Mody 		min_vf = p_iov->first_vf_in_pf;
236322d07d93SRasesh Mody 		max_vf = p_iov->first_vf_in_pf + p_iov->total_vfs;
236422d07d93SRasesh Mody 	}
2365ec94dbc5SRasesh Mody 
23666e4fcea9SRasesh Mody 	for (igu_sb_id = 0;
23676e4fcea9SRasesh Mody 	     igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
23686e4fcea9SRasesh Mody 	     igu_sb_id++) {
23696e4fcea9SRasesh Mody 		/* Read current entry; Notice it might not belong to this PF */
23706e4fcea9SRasesh Mody 		ecore_int_igu_read_cam_block(p_hwfn, p_ptt, igu_sb_id);
23716e4fcea9SRasesh Mody 		p_block = &p_igu_info->entry[igu_sb_id];
2372ec94dbc5SRasesh Mody 
23736e4fcea9SRasesh Mody 		if ((p_block->is_pf) &&
23746e4fcea9SRasesh Mody 		    (p_block->function_id == p_hwfn->rel_pf_id)) {
23756e4fcea9SRasesh Mody 			p_block->status = ECORE_IGU_STATUS_PF |
23766e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_VALID |
23776e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_FREE;
23786e4fcea9SRasesh Mody 
23796e4fcea9SRasesh Mody 			if (p_igu_info->igu_dsb_id != ECORE_SB_INVALID_IDX)
23806e4fcea9SRasesh Mody 				p_igu_info->usage.cnt++;
23816e4fcea9SRasesh Mody 		} else if (!(p_block->is_pf) &&
23826e4fcea9SRasesh Mody 			   (p_block->function_id >= min_vf) &&
2383ec94dbc5SRasesh Mody 			   (p_block->function_id < max_vf)) {
2384ec94dbc5SRasesh Mody 			/* Available for VFs of this PF */
23856e4fcea9SRasesh Mody 			p_block->status = ECORE_IGU_STATUS_VALID |
23866e4fcea9SRasesh Mody 					  ECORE_IGU_STATUS_FREE;
23876e4fcea9SRasesh Mody 
23886e4fcea9SRasesh Mody 			if (p_igu_info->igu_dsb_id != ECORE_SB_INVALID_IDX)
23896e4fcea9SRasesh Mody 				p_igu_info->usage.iov_cnt++;
2390ec94dbc5SRasesh Mody 		}
2391d9237ae2SRasesh Mody 
23926e4fcea9SRasesh Mody 		/* Mark the First entry belonging to the PF or its VFs
23936e4fcea9SRasesh Mody 		 * as the default SB [we'll reset IGU prior to first usage].
2394d9237ae2SRasesh Mody 		 */
23956e4fcea9SRasesh Mody 		if ((p_block->status & ECORE_IGU_STATUS_VALID) &&
23966e4fcea9SRasesh Mody 		    (p_igu_info->igu_dsb_id == ECORE_SB_INVALID_IDX)) {
23976e4fcea9SRasesh Mody 			p_igu_info->igu_dsb_id = igu_sb_id;
23986e4fcea9SRasesh Mody 			p_block->status |= ECORE_IGU_STATUS_DSB;
23996e4fcea9SRasesh Mody 		}
2400d9237ae2SRasesh Mody 
24016e4fcea9SRasesh Mody 		/* While this isn't suitable for all clients, limit number
24026e4fcea9SRasesh Mody 		 * of prints by having each PF print only its entries with the
24036e4fcea9SRasesh Mody 		 * exception of PF0 which would print everything.
24046e4fcea9SRasesh Mody 		 */
24056e4fcea9SRasesh Mody 		if ((p_block->status & ECORE_IGU_STATUS_VALID) ||
24066e4fcea9SRasesh Mody 		    (p_hwfn->abs_pf_id == 0))
24076e4fcea9SRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
24086e4fcea9SRasesh Mody 				   "IGU_BLOCK: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x\n",
24096e4fcea9SRasesh Mody 				   igu_sb_id, p_block->function_id,
24106e4fcea9SRasesh Mody 				   p_block->is_pf, p_block->vector_number);
24116e4fcea9SRasesh Mody 	}
24126e4fcea9SRasesh Mody 
24136e4fcea9SRasesh Mody 	if (p_igu_info->igu_dsb_id == ECORE_SB_INVALID_IDX) {
2414d9237ae2SRasesh Mody 		DP_NOTICE(p_hwfn, true,
24156e4fcea9SRasesh Mody 			  "IGU CAM returned invalid values igu_dsb_id=0x%x\n",
24166e4fcea9SRasesh Mody 			  p_igu_info->igu_dsb_id);
2417d9237ae2SRasesh Mody 		return ECORE_INVAL;
2418d9237ae2SRasesh Mody 	}
2419d9237ae2SRasesh Mody 
24206e4fcea9SRasesh Mody 	/* All non default SB are considered free at this point */
24216e4fcea9SRasesh Mody 	p_igu_info->usage.free_cnt = p_igu_info->usage.cnt;
24226e4fcea9SRasesh Mody 	p_igu_info->usage.free_cnt_iov = p_igu_info->usage.iov_cnt;
2423ec94dbc5SRasesh Mody 
2424ec94dbc5SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
24256e4fcea9SRasesh Mody 		   "igu_dsb_id=0x%x, num Free SBs - PF: %04x VF: %04x [might change after resource allocation]\n",
24266e4fcea9SRasesh Mody 		   p_igu_info->igu_dsb_id, p_igu_info->usage.cnt,
24276e4fcea9SRasesh Mody 		   p_igu_info->usage.iov_cnt);
2428ec94dbc5SRasesh Mody 
24296e4fcea9SRasesh Mody 	return ECORE_SUCCESS;
24306e4fcea9SRasesh Mody }
24316e4fcea9SRasesh Mody 
24326e4fcea9SRasesh Mody enum _ecore_status_t
ecore_int_igu_relocate_sb(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u16 sb_id,bool b_to_vf)24336e4fcea9SRasesh Mody ecore_int_igu_relocate_sb(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt,
24346e4fcea9SRasesh Mody 			  u16 sb_id, bool b_to_vf)
24356e4fcea9SRasesh Mody {
24366e4fcea9SRasesh Mody 	struct ecore_igu_info *p_info = p_hwfn->hw_info.p_igu_info;
24376e4fcea9SRasesh Mody 	struct ecore_igu_block *p_block = OSAL_NULL;
24386e4fcea9SRasesh Mody 	u16 igu_sb_id = 0, vf_num = 0;
24396e4fcea9SRasesh Mody 	u32 val = 0;
24406e4fcea9SRasesh Mody 
24416e4fcea9SRasesh Mody 	if (IS_VF(p_hwfn->p_dev) || !IS_PF_SRIOV(p_hwfn))
24426e4fcea9SRasesh Mody 		return ECORE_INVAL;
24436e4fcea9SRasesh Mody 
24446e4fcea9SRasesh Mody 	if (sb_id == ECORE_SP_SB_ID)
24456e4fcea9SRasesh Mody 		return ECORE_INVAL;
24466e4fcea9SRasesh Mody 
24476e4fcea9SRasesh Mody 	if (!p_info->b_allow_pf_vf_change) {
24486e4fcea9SRasesh Mody 		DP_INFO(p_hwfn, "Can't relocate SBs as MFW is too old.\n");
2449ec94dbc5SRasesh Mody 		return ECORE_INVAL;
2450ec94dbc5SRasesh Mody 	}
2451ec94dbc5SRasesh Mody 
24526e4fcea9SRasesh Mody 	/* If we're moving a SB from PF to VF, the client had to specify
24536e4fcea9SRasesh Mody 	 * which vector it wants to move.
24546e4fcea9SRasesh Mody 	 */
24556e4fcea9SRasesh Mody 	if (b_to_vf) {
24566e4fcea9SRasesh Mody 		igu_sb_id = ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1);
24576e4fcea9SRasesh Mody 		if (igu_sb_id == ECORE_SB_INVALID_IDX)
24586e4fcea9SRasesh Mody 			return ECORE_INVAL;
24596e4fcea9SRasesh Mody 	}
24606e4fcea9SRasesh Mody 
24616e4fcea9SRasesh Mody 	/* If we're moving a SB from VF to PF, need to validate there isn't
24626e4fcea9SRasesh Mody 	 * already a line configured for that vector.
24636e4fcea9SRasesh Mody 	 */
24646e4fcea9SRasesh Mody 	if (!b_to_vf) {
24656e4fcea9SRasesh Mody 		if (ecore_get_pf_igu_sb_id(p_hwfn, sb_id + 1) !=
24666e4fcea9SRasesh Mody 		    ECORE_SB_INVALID_IDX)
24676e4fcea9SRasesh Mody 			return ECORE_INVAL;
24686e4fcea9SRasesh Mody 	}
24696e4fcea9SRasesh Mody 
24706e4fcea9SRasesh Mody 	/* We need to validate that the SB can actually be relocated.
24716e4fcea9SRasesh Mody 	 * This would also handle the previous case where we've explicitly
24726e4fcea9SRasesh Mody 	 * stated which IGU SB needs to move.
24736e4fcea9SRasesh Mody 	 */
24746e4fcea9SRasesh Mody 	for (; igu_sb_id < ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev);
24756e4fcea9SRasesh Mody 	     igu_sb_id++) {
24766e4fcea9SRasesh Mody 		p_block = &p_info->entry[igu_sb_id];
24776e4fcea9SRasesh Mody 
24786e4fcea9SRasesh Mody 		if (!(p_block->status & ECORE_IGU_STATUS_VALID) ||
24796e4fcea9SRasesh Mody 		    !(p_block->status & ECORE_IGU_STATUS_FREE) ||
24806e4fcea9SRasesh Mody 		    (!!(p_block->status & ECORE_IGU_STATUS_PF) != b_to_vf)) {
24816e4fcea9SRasesh Mody 			if (b_to_vf)
24826e4fcea9SRasesh Mody 				return ECORE_INVAL;
24836e4fcea9SRasesh Mody 			else
24846e4fcea9SRasesh Mody 				continue;
24856e4fcea9SRasesh Mody 		}
24866e4fcea9SRasesh Mody 
24876e4fcea9SRasesh Mody 		break;
24886e4fcea9SRasesh Mody 	}
24896e4fcea9SRasesh Mody 
24906e4fcea9SRasesh Mody 	if (igu_sb_id == ECORE_MAPPING_MEMORY_SIZE(p_hwfn->p_dev)) {
24916e4fcea9SRasesh Mody 		DP_VERBOSE(p_hwfn, (ECORE_MSG_INTR | ECORE_MSG_IOV),
24926e4fcea9SRasesh Mody 			   "Failed to find a free SB to move\n");
24936e4fcea9SRasesh Mody 		return ECORE_INVAL;
24946e4fcea9SRasesh Mody 	}
24956e4fcea9SRasesh Mody 
24966e4fcea9SRasesh Mody 	/* At this point, p_block points to the SB we want to relocate */
24976e4fcea9SRasesh Mody 	if (b_to_vf) {
24986e4fcea9SRasesh Mody 		p_block->status &= ~ECORE_IGU_STATUS_PF;
24996e4fcea9SRasesh Mody 
25006e4fcea9SRasesh Mody 		/* It doesn't matter which VF number we choose, since we're
25016e4fcea9SRasesh Mody 		 * going to disable the line; But let's keep it in range.
25026e4fcea9SRasesh Mody 		 */
25036e4fcea9SRasesh Mody 		vf_num = (u16)p_hwfn->p_dev->p_iov_info->first_vf_in_pf;
25046e4fcea9SRasesh Mody 
25056e4fcea9SRasesh Mody 		p_block->function_id = (u8)vf_num;
25066e4fcea9SRasesh Mody 		p_block->is_pf = 0;
25076e4fcea9SRasesh Mody 		p_block->vector_number = 0;
25086e4fcea9SRasesh Mody 
25096e4fcea9SRasesh Mody 		p_info->usage.cnt--;
25106e4fcea9SRasesh Mody 		p_info->usage.free_cnt--;
25116e4fcea9SRasesh Mody 		p_info->usage.iov_cnt++;
25126e4fcea9SRasesh Mody 		p_info->usage.free_cnt_iov++;
25136e4fcea9SRasesh Mody 
25146e4fcea9SRasesh Mody 		/* TODO - if SBs aren't really the limiting factor,
25156e4fcea9SRasesh Mody 		 * then it might not be accurate [in the since that
25166e4fcea9SRasesh Mody 		 * we might not need decrement the feature].
25176e4fcea9SRasesh Mody 		 */
25186e4fcea9SRasesh Mody 		p_hwfn->hw_info.feat_num[ECORE_PF_L2_QUE]--;
25196e4fcea9SRasesh Mody 		p_hwfn->hw_info.feat_num[ECORE_VF_L2_QUE]++;
25206e4fcea9SRasesh Mody 	} else {
25216e4fcea9SRasesh Mody 		p_block->status |= ECORE_IGU_STATUS_PF;
25226e4fcea9SRasesh Mody 		p_block->function_id = p_hwfn->rel_pf_id;
25236e4fcea9SRasesh Mody 		p_block->is_pf = 1;
25246e4fcea9SRasesh Mody 		p_block->vector_number = sb_id + 1;
25256e4fcea9SRasesh Mody 
25266e4fcea9SRasesh Mody 		p_info->usage.cnt++;
25276e4fcea9SRasesh Mody 		p_info->usage.free_cnt++;
25286e4fcea9SRasesh Mody 		p_info->usage.iov_cnt--;
25296e4fcea9SRasesh Mody 		p_info->usage.free_cnt_iov--;
25306e4fcea9SRasesh Mody 
25316e4fcea9SRasesh Mody 		p_hwfn->hw_info.feat_num[ECORE_PF_L2_QUE]++;
25326e4fcea9SRasesh Mody 		p_hwfn->hw_info.feat_num[ECORE_VF_L2_QUE]--;
25336e4fcea9SRasesh Mody 	}
25346e4fcea9SRasesh Mody 
25356e4fcea9SRasesh Mody 	/* Update the IGU and CAU with the new configuration */
25366e4fcea9SRasesh Mody 	SET_FIELD(val, IGU_MAPPING_LINE_FUNCTION_NUMBER,
25376e4fcea9SRasesh Mody 		  p_block->function_id);
25386e4fcea9SRasesh Mody 	SET_FIELD(val, IGU_MAPPING_LINE_PF_VALID, p_block->is_pf);
25396e4fcea9SRasesh Mody 	SET_FIELD(val, IGU_MAPPING_LINE_VALID, p_block->is_pf);
25406e4fcea9SRasesh Mody 	SET_FIELD(val, IGU_MAPPING_LINE_VECTOR_NUMBER,
25416e4fcea9SRasesh Mody 		  p_block->vector_number);
25426e4fcea9SRasesh Mody 
25436e4fcea9SRasesh Mody 	ecore_wr(p_hwfn, p_ptt,
25446e4fcea9SRasesh Mody 		 IGU_REG_MAPPING_MEMORY + sizeof(u32) * igu_sb_id,
25456e4fcea9SRasesh Mody 		 val);
25466e4fcea9SRasesh Mody 
25476e4fcea9SRasesh Mody 	ecore_int_cau_conf_sb(p_hwfn, p_ptt, 0,
25486e4fcea9SRasesh Mody 			      igu_sb_id, vf_num,
25496e4fcea9SRasesh Mody 			      p_block->is_pf ? 0 : 1);
25506e4fcea9SRasesh Mody 
25516e4fcea9SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_INTR,
25526e4fcea9SRasesh Mody 		   "Relocation: [SB 0x%04x] func_id = %d is_pf = %d vector_num = 0x%x\n",
25536e4fcea9SRasesh Mody 		   igu_sb_id, p_block->function_id,
25546e4fcea9SRasesh Mody 		   p_block->is_pf, p_block->vector_number);
25556e4fcea9SRasesh Mody 
2556ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
2557ec94dbc5SRasesh Mody }
2558ec94dbc5SRasesh Mody 
2559ec94dbc5SRasesh Mody /**
2560ec94dbc5SRasesh Mody  * @brief Initialize igu runtime registers
2561ec94dbc5SRasesh Mody  *
2562ec94dbc5SRasesh Mody  * @param p_hwfn
2563ec94dbc5SRasesh Mody  */
ecore_int_igu_init_rt(struct ecore_hwfn * p_hwfn)2564ec94dbc5SRasesh Mody void ecore_int_igu_init_rt(struct ecore_hwfn *p_hwfn)
2565ec94dbc5SRasesh Mody {
2566ec94dbc5SRasesh Mody 	u32 igu_pf_conf = IGU_PF_CONF_FUNC_EN;
2567ec94dbc5SRasesh Mody 
2568ec94dbc5SRasesh Mody 	STORE_RT_REG(p_hwfn, IGU_REG_PF_CONFIGURATION_RT_OFFSET, igu_pf_conf);
2569ec94dbc5SRasesh Mody }
2570ec94dbc5SRasesh Mody 
2571ec94dbc5SRasesh Mody #define LSB_IGU_CMD_ADDR (IGU_REG_SISR_MDPC_WMASK_LSB_UPPER - \
2572ec94dbc5SRasesh Mody 			  IGU_CMD_INT_ACK_BASE)
2573ec94dbc5SRasesh Mody #define MSB_IGU_CMD_ADDR (IGU_REG_SISR_MDPC_WMASK_MSB_UPPER - \
2574ec94dbc5SRasesh Mody 			  IGU_CMD_INT_ACK_BASE)
ecore_int_igu_read_sisr_reg(struct ecore_hwfn * p_hwfn)2575ec94dbc5SRasesh Mody u64 ecore_int_igu_read_sisr_reg(struct ecore_hwfn *p_hwfn)
2576ec94dbc5SRasesh Mody {
2577ec94dbc5SRasesh Mody 	u32 intr_status_hi = 0, intr_status_lo = 0;
2578ec94dbc5SRasesh Mody 	u64 intr_status = 0;
2579ec94dbc5SRasesh Mody 
2580ec94dbc5SRasesh Mody 	intr_status_lo = REG_RD(p_hwfn,
2581ec94dbc5SRasesh Mody 				GTT_BAR0_MAP_REG_IGU_CMD +
2582ec94dbc5SRasesh Mody 				LSB_IGU_CMD_ADDR * 8);
2583ec94dbc5SRasesh Mody 	intr_status_hi = REG_RD(p_hwfn,
2584ec94dbc5SRasesh Mody 				GTT_BAR0_MAP_REG_IGU_CMD +
2585ec94dbc5SRasesh Mody 				MSB_IGU_CMD_ADDR * 8);
2586ec94dbc5SRasesh Mody 	intr_status = ((u64)intr_status_hi << 32) + (u64)intr_status_lo;
2587ec94dbc5SRasesh Mody 
2588ec94dbc5SRasesh Mody 	return intr_status;
2589ec94dbc5SRasesh Mody }
2590ec94dbc5SRasesh Mody 
ecore_int_sp_dpc_setup(struct ecore_hwfn * p_hwfn)2591ec94dbc5SRasesh Mody static void ecore_int_sp_dpc_setup(struct ecore_hwfn *p_hwfn)
2592ec94dbc5SRasesh Mody {
2593ec94dbc5SRasesh Mody 	OSAL_DPC_INIT(p_hwfn->sp_dpc, p_hwfn);
2594ec94dbc5SRasesh Mody 	p_hwfn->b_sp_dpc_enabled = true;
2595ec94dbc5SRasesh Mody }
2596ec94dbc5SRasesh Mody 
ecore_int_sp_dpc_alloc(struct ecore_hwfn * p_hwfn)2597ec94dbc5SRasesh Mody static enum _ecore_status_t ecore_int_sp_dpc_alloc(struct ecore_hwfn *p_hwfn)
2598ec94dbc5SRasesh Mody {
2599ec94dbc5SRasesh Mody 	p_hwfn->sp_dpc = OSAL_DPC_ALLOC(p_hwfn);
2600ec94dbc5SRasesh Mody 	if (!p_hwfn->sp_dpc)
2601ec94dbc5SRasesh Mody 		return ECORE_NOMEM;
2602ec94dbc5SRasesh Mody 
2603ec94dbc5SRasesh Mody 	return ECORE_SUCCESS;
2604ec94dbc5SRasesh Mody }
2605ec94dbc5SRasesh Mody 
ecore_int_sp_dpc_free(struct ecore_hwfn * p_hwfn)2606ec94dbc5SRasesh Mody static void ecore_int_sp_dpc_free(struct ecore_hwfn *p_hwfn)
2607ec94dbc5SRasesh Mody {
2608ec94dbc5SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->sp_dpc);
2609ec94dbc5SRasesh Mody }
2610ec94dbc5SRasesh Mody 
ecore_int_alloc(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)2611ec94dbc5SRasesh Mody enum _ecore_status_t ecore_int_alloc(struct ecore_hwfn *p_hwfn,
2612ec94dbc5SRasesh Mody 				     struct ecore_ptt *p_ptt)
2613ec94dbc5SRasesh Mody {
2614ec94dbc5SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
2615ec94dbc5SRasesh Mody 
2616ec94dbc5SRasesh Mody 	rc = ecore_int_sp_dpc_alloc(p_hwfn);
2617ec94dbc5SRasesh Mody 	if (rc != ECORE_SUCCESS) {
2618ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev, "Failed to allocate sp dpc mem\n");
2619ec94dbc5SRasesh Mody 		return rc;
2620ec94dbc5SRasesh Mody 	}
2621ec94dbc5SRasesh Mody 
2622ec94dbc5SRasesh Mody 	rc = ecore_int_sp_sb_alloc(p_hwfn, p_ptt);
2623ec94dbc5SRasesh Mody 	if (rc != ECORE_SUCCESS) {
2624ec94dbc5SRasesh Mody 		DP_ERR(p_hwfn->p_dev, "Failed to allocate sp sb mem\n");
2625ec94dbc5SRasesh Mody 		return rc;
2626ec94dbc5SRasesh Mody 	}
2627ec94dbc5SRasesh Mody 
2628e6051bd6SRasesh Mody 	rc = ecore_int_sb_attn_alloc(p_hwfn, p_ptt);
2629e6051bd6SRasesh Mody 	if (rc != ECORE_SUCCESS)
2630e6051bd6SRasesh Mody 		DP_ERR(p_hwfn->p_dev, "Failed to allocate sb attn mem\n");
2631e6051bd6SRasesh Mody 
2632ec94dbc5SRasesh Mody 	return rc;
2633ec94dbc5SRasesh Mody }
2634ec94dbc5SRasesh Mody 
ecore_int_free(struct ecore_hwfn * p_hwfn)2635ec94dbc5SRasesh Mody void ecore_int_free(struct ecore_hwfn *p_hwfn)
2636ec94dbc5SRasesh Mody {
2637ec94dbc5SRasesh Mody 	ecore_int_sp_sb_free(p_hwfn);
2638ec94dbc5SRasesh Mody 	ecore_int_sb_attn_free(p_hwfn);
2639ec94dbc5SRasesh Mody 	ecore_int_sp_dpc_free(p_hwfn);
2640ec94dbc5SRasesh Mody }
2641ec94dbc5SRasesh Mody 
ecore_int_setup(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt)2642ec94dbc5SRasesh Mody void ecore_int_setup(struct ecore_hwfn *p_hwfn, struct ecore_ptt *p_ptt)
2643ec94dbc5SRasesh Mody {
2644ec94dbc5SRasesh Mody 	if (!p_hwfn || !p_hwfn->p_sp_sb || !p_hwfn->p_sb_attn)
2645ec94dbc5SRasesh Mody 		return;
2646ec94dbc5SRasesh Mody 
2647ec94dbc5SRasesh Mody 	ecore_int_sb_setup(p_hwfn, p_ptt, &p_hwfn->p_sp_sb->sb_info);
2648e6051bd6SRasesh Mody 	ecore_int_sb_attn_setup(p_hwfn, p_ptt);
2649ec94dbc5SRasesh Mody 	ecore_int_sp_dpc_setup(p_hwfn);
2650ec94dbc5SRasesh Mody }
2651ec94dbc5SRasesh Mody 
ecore_int_get_num_sbs(struct ecore_hwfn * p_hwfn,struct ecore_sb_cnt_info * p_sb_cnt_info)2652ec94dbc5SRasesh Mody void ecore_int_get_num_sbs(struct ecore_hwfn *p_hwfn,
2653ec94dbc5SRasesh Mody 			   struct ecore_sb_cnt_info *p_sb_cnt_info)
2654ec94dbc5SRasesh Mody {
26556e4fcea9SRasesh Mody 	struct ecore_igu_info *p_igu_info = p_hwfn->hw_info.p_igu_info;
2656ec94dbc5SRasesh Mody 
26576e4fcea9SRasesh Mody 	if (!p_igu_info || !p_sb_cnt_info)
2658ec94dbc5SRasesh Mody 		return;
2659ec94dbc5SRasesh Mody 
26606e4fcea9SRasesh Mody 	OSAL_MEMCPY(p_sb_cnt_info, &p_igu_info->usage,
26616e4fcea9SRasesh Mody 		    sizeof(*p_sb_cnt_info));
2662ec94dbc5SRasesh Mody }
2663ec94dbc5SRasesh Mody 
ecore_int_disable_post_isr_release(struct ecore_dev * p_dev)2664ec94dbc5SRasesh Mody void ecore_int_disable_post_isr_release(struct ecore_dev *p_dev)
2665ec94dbc5SRasesh Mody {
2666ec94dbc5SRasesh Mody 	int i;
2667ec94dbc5SRasesh Mody 
2668ec94dbc5SRasesh Mody 	for_each_hwfn(p_dev, i)
2669ec94dbc5SRasesh Mody 		p_dev->hwfns[i].b_int_requested = false;
2670ec94dbc5SRasesh Mody }
267122d07d93SRasesh Mody 
ecore_int_attn_clr_enable(struct ecore_dev * p_dev,bool clr_enable)267222d07d93SRasesh Mody void ecore_int_attn_clr_enable(struct ecore_dev *p_dev, bool clr_enable)
267322d07d93SRasesh Mody {
267422d07d93SRasesh Mody 	p_dev->attn_clr_en = clr_enable;
267522d07d93SRasesh Mody }
267622d07d93SRasesh Mody 
ecore_int_set_timer_res(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,u8 timer_res,u16 sb_id,bool tx)267722d07d93SRasesh Mody enum _ecore_status_t ecore_int_set_timer_res(struct ecore_hwfn *p_hwfn,
267822d07d93SRasesh Mody 					     struct ecore_ptt *p_ptt,
267922d07d93SRasesh Mody 					     u8 timer_res, u16 sb_id, bool tx)
268022d07d93SRasesh Mody {
268122d07d93SRasesh Mody 	struct cau_sb_entry sb_entry;
2682ababb520SRasesh Mody 	enum _ecore_status_t rc;
268322d07d93SRasesh Mody 
268422d07d93SRasesh Mody 	if (!p_hwfn->hw_init_done) {
268522d07d93SRasesh Mody 		DP_ERR(p_hwfn, "hardware not initialized yet\n");
268622d07d93SRasesh Mody 		return ECORE_INVAL;
268722d07d93SRasesh Mody 	}
268822d07d93SRasesh Mody 
268922d07d93SRasesh Mody 	rc = ecore_dmae_grc2host(p_hwfn, p_ptt, CAU_REG_SB_VAR_MEMORY +
269022d07d93SRasesh Mody 				 sb_id * sizeof(u64),
26913eed444aSRasesh Mody 				 (u64)(osal_uintptr_t)&sb_entry, 2,
26923eed444aSRasesh Mody 				 OSAL_NULL /* default parameters */);
269322d07d93SRasesh Mody 	if (rc != ECORE_SUCCESS) {
269422d07d93SRasesh Mody 		DP_ERR(p_hwfn, "dmae_grc2host failed %d\n", rc);
269522d07d93SRasesh Mody 		return rc;
269622d07d93SRasesh Mody 	}
269722d07d93SRasesh Mody 
269822d07d93SRasesh Mody 	if (tx)
269922d07d93SRasesh Mody 		SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES1, timer_res);
270022d07d93SRasesh Mody 	else
270122d07d93SRasesh Mody 		SET_FIELD(sb_entry.params, CAU_SB_ENTRY_TIMER_RES0, timer_res);
270222d07d93SRasesh Mody 
270322d07d93SRasesh Mody 	rc = ecore_dmae_host2grc(p_hwfn, p_ptt,
270422d07d93SRasesh Mody 				 (u64)(osal_uintptr_t)&sb_entry,
27053eed444aSRasesh Mody 				 CAU_REG_SB_VAR_MEMORY + sb_id * sizeof(u64), 2,
27063eed444aSRasesh Mody 				 OSAL_NULL /* default parameters */);
270722d07d93SRasesh Mody 	if (rc != ECORE_SUCCESS) {
270822d07d93SRasesh Mody 		DP_ERR(p_hwfn, "dmae_host2grc failed %d\n", rc);
270922d07d93SRasesh Mody 		return rc;
271022d07d93SRasesh Mody 	}
271122d07d93SRasesh Mody 
271222d07d93SRasesh Mody 	return rc;
271322d07d93SRasesh Mody }
27141a998268SRasesh Mody 
ecore_int_get_sb_dbg(struct ecore_hwfn * p_hwfn,struct ecore_ptt * p_ptt,struct ecore_sb_info * p_sb,struct ecore_sb_info_dbg * p_info)27151a998268SRasesh Mody enum _ecore_status_t ecore_int_get_sb_dbg(struct ecore_hwfn *p_hwfn,
27161a998268SRasesh Mody 					  struct ecore_ptt *p_ptt,
27171a998268SRasesh Mody 					  struct ecore_sb_info *p_sb,
27181a998268SRasesh Mody 					  struct ecore_sb_info_dbg *p_info)
27191a998268SRasesh Mody {
27201a998268SRasesh Mody 	u16 sbid = p_sb->igu_sb_id;
27213b307c55SRasesh Mody 	u32 i;
27221a998268SRasesh Mody 
27231a998268SRasesh Mody 	if (IS_VF(p_hwfn->p_dev))
27241a998268SRasesh Mody 		return ECORE_INVAL;
27251a998268SRasesh Mody 
27263b307c55SRasesh Mody 	if (sbid >= NUM_OF_SBS(p_hwfn->p_dev))
27271a998268SRasesh Mody 		return ECORE_INVAL;
27281a998268SRasesh Mody 
27291a998268SRasesh Mody 	p_info->igu_prod = ecore_rd(p_hwfn, p_ptt,
27301a998268SRasesh Mody 				    IGU_REG_PRODUCER_MEMORY + sbid * 4);
27311a998268SRasesh Mody 	p_info->igu_cons = ecore_rd(p_hwfn, p_ptt,
27321a998268SRasesh Mody 				    IGU_REG_CONSUMER_MEM + sbid * 4);
27331a998268SRasesh Mody 
27343b307c55SRasesh Mody 	for (i = 0; i < PIS_PER_SB; i++)
27351a998268SRasesh Mody 		p_info->pi[i] = (u16)ecore_rd(p_hwfn, p_ptt,
27361a998268SRasesh Mody 					      CAU_REG_PI_MEMORY +
27373b307c55SRasesh Mody 					      sbid * 4 * PIS_PER_SB +
273840cf1e75SRasesh Mody 					      i * 4);
27391a998268SRasesh Mody 
27401a998268SRasesh Mody 	return ECORE_SUCCESS;
27411a998268SRasesh Mody }
2742797ce8eeSShahed Shaikh 
ecore_pf_flr_igu_cleanup(struct ecore_hwfn * p_hwfn)2743797ce8eeSShahed Shaikh void ecore_pf_flr_igu_cleanup(struct ecore_hwfn *p_hwfn)
2744797ce8eeSShahed Shaikh {
2745797ce8eeSShahed Shaikh 	struct ecore_ptt *p_ptt = p_hwfn->p_main_ptt;
2746797ce8eeSShahed Shaikh 	struct ecore_ptt *p_dpc_ptt = ecore_get_reserved_ptt(p_hwfn,
2747797ce8eeSShahed Shaikh 							     RESERVED_PTT_DPC);
2748797ce8eeSShahed Shaikh 	int i;
2749797ce8eeSShahed Shaikh 
2750797ce8eeSShahed Shaikh 	/* Do not reorder the following cleanup sequence */
2751797ce8eeSShahed Shaikh 	/* Ack all attentions */
2752797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ACK_BITS, 0xfff);
2753797ce8eeSShahed Shaikh 
2754797ce8eeSShahed Shaikh 	/* Clear driver attention */
2755797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn,  p_dpc_ptt,
2756797ce8eeSShahed Shaikh 		((p_hwfn->rel_pf_id << 3) + MISC_REG_AEU_GENERAL_ATTN_0), 0);
2757797ce8eeSShahed Shaikh 
2758797ce8eeSShahed Shaikh 	/* Clear per-PF IGU registers to restore them as if the IGU
2759797ce8eeSShahed Shaikh 	 * was reset for this PF
2760797ce8eeSShahed Shaikh 	 */
2761797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_LEADING_EDGE_LATCH, 0);
2762797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0);
2763797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_CONFIGURATION, 0);
2764797ce8eeSShahed Shaikh 
2765797ce8eeSShahed Shaikh 	/* Execute IGU clean up*/
2766797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_PF_FUNCTIONAL_CLEANUP, 1);
2767797ce8eeSShahed Shaikh 
2768797ce8eeSShahed Shaikh 	/* Clear Stats */
2769797ce8eeSShahed Shaikh 	ecore_wr(p_hwfn, p_ptt, IGU_REG_STATISTIC_NUM_OF_INTA_ASSERTED, 0);
2770797ce8eeSShahed Shaikh 
2771797ce8eeSShahed Shaikh 	for (i = 0; i < IGU_REG_PBA_STS_PF_SIZE; i++)
2772797ce8eeSShahed Shaikh 		ecore_wr(p_hwfn, p_ptt, IGU_REG_PBA_STS_PF + i * 4, 0);
2773797ce8eeSShahed Shaikh }
2774