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