xref: /dpdk/drivers/net/bnx2x/ecore_init.h (revision 0cb4150f82ff77e1c74826ae425f36388d9172fb)
1688654bfSRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause
29eb5dc09SRasesh Mody  * Copyright (c) 2007-2013 Broadcom Corporation.
3b5bf7719SStephen Hemminger  *
4b5bf7719SStephen Hemminger  * Eric Davis        <edavis@broadcom.com>
5b5bf7719SStephen Hemminger  * David Christensen <davidch@broadcom.com>
6b5bf7719SStephen Hemminger  * Gary Zambrano     <zambrano@broadcom.com>
7b5bf7719SStephen Hemminger  *
8b5bf7719SStephen Hemminger  * Copyright (c) 2013-2015 Brocade Communications Systems, Inc.
9e3de5dadSRasesh Mody  * Copyright (c) 2015-2018 Cavium Inc.
10b5bf7719SStephen Hemminger  * All rights reserved.
11e3de5dadSRasesh Mody  * www.cavium.com
12b5bf7719SStephen Hemminger  */
13b5bf7719SStephen Hemminger 
14b5bf7719SStephen Hemminger #ifndef ECORE_INIT_H
15b5bf7719SStephen Hemminger #define ECORE_INIT_H
16b5bf7719SStephen Hemminger 
17b5bf7719SStephen Hemminger /* Init operation types and structures */
18b5bf7719SStephen Hemminger enum {
19b5bf7719SStephen Hemminger 	OP_RD = 0x1,	/* read a single register */
20b5bf7719SStephen Hemminger 	OP_WR,		/* write a single register */
21b5bf7719SStephen Hemminger 	OP_SW,		/* copy a string to the device */
22b5bf7719SStephen Hemminger 	OP_ZR,		/* clear memory */
23b5bf7719SStephen Hemminger 	OP_ZP,		/* unzip then copy with DMAE */
24b5bf7719SStephen Hemminger 	OP_WR_64,	/* write 64 bit pattern */
25b5bf7719SStephen Hemminger 	OP_WB,		/* copy a string using DMAE */
26b5bf7719SStephen Hemminger 	OP_WB_ZR,	/* Clear a string using DMAE or indirect-wr */
27b5bf7719SStephen Hemminger 	OP_IF_MODE_OR,  /* Skip the following ops if all init modes don't match */
28b5bf7719SStephen Hemminger 	OP_IF_MODE_AND, /* Skip the following ops if any init modes don't match */
29b5bf7719SStephen Hemminger 	OP_MAX
30b5bf7719SStephen Hemminger };
31b5bf7719SStephen Hemminger 
32b5bf7719SStephen Hemminger enum {
33b5bf7719SStephen Hemminger 	STAGE_START,
34b5bf7719SStephen Hemminger 	STAGE_END,
35b5bf7719SStephen Hemminger };
36b5bf7719SStephen Hemminger 
37b5bf7719SStephen Hemminger /* Returns the index of start or end of a specific block stage in ops array*/
38b5bf7719SStephen Hemminger #define BLOCK_OPS_IDX(block, stage, end) \
39b5bf7719SStephen Hemminger 	(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
40b5bf7719SStephen Hemminger 
41b5bf7719SStephen Hemminger 
42b5bf7719SStephen Hemminger /* structs for the various opcodes */
43b5bf7719SStephen Hemminger struct raw_op {
44b5bf7719SStephen Hemminger 	uint32_t op:8;
45b5bf7719SStephen Hemminger 	uint32_t offset:24;
46b5bf7719SStephen Hemminger 	uint32_t raw_data;
47b5bf7719SStephen Hemminger };
48b5bf7719SStephen Hemminger 
49b5bf7719SStephen Hemminger struct op_read {
50b5bf7719SStephen Hemminger 	uint32_t op:8;
51b5bf7719SStephen Hemminger 	uint32_t offset:24;
52b5bf7719SStephen Hemminger 	uint32_t val;
53b5bf7719SStephen Hemminger };
54b5bf7719SStephen Hemminger 
55b5bf7719SStephen Hemminger struct op_write {
56b5bf7719SStephen Hemminger 	uint32_t op:8;
57b5bf7719SStephen Hemminger 	uint32_t offset:24;
58b5bf7719SStephen Hemminger 	uint32_t val;
59b5bf7719SStephen Hemminger };
60b5bf7719SStephen Hemminger 
61b5bf7719SStephen Hemminger struct op_arr_write {
62b5bf7719SStephen Hemminger 	uint32_t op:8;
63b5bf7719SStephen Hemminger 	uint32_t offset:24;
64b5bf7719SStephen Hemminger #ifdef __BIG_ENDIAN
65b5bf7719SStephen Hemminger 	uint16_t data_len;
66b5bf7719SStephen Hemminger 	uint16_t data_off;
67b5bf7719SStephen Hemminger #else /* __LITTLE_ENDIAN */
68b5bf7719SStephen Hemminger 	uint16_t data_off;
69b5bf7719SStephen Hemminger 	uint16_t data_len;
70b5bf7719SStephen Hemminger #endif
71b5bf7719SStephen Hemminger };
72b5bf7719SStephen Hemminger 
73b5bf7719SStephen Hemminger struct op_zero {
74b5bf7719SStephen Hemminger 	uint32_t op:8;
75b5bf7719SStephen Hemminger 	uint32_t offset:24;
76b5bf7719SStephen Hemminger 	uint32_t len;
77b5bf7719SStephen Hemminger };
78b5bf7719SStephen Hemminger 
79b5bf7719SStephen Hemminger struct op_if_mode {
80b5bf7719SStephen Hemminger 	uint32_t op:8;
81b5bf7719SStephen Hemminger 	uint32_t cmd_offset:24;
82b5bf7719SStephen Hemminger 	uint32_t mode_bit_map;
83b5bf7719SStephen Hemminger };
84b5bf7719SStephen Hemminger 
85b5bf7719SStephen Hemminger 
86b5bf7719SStephen Hemminger union init_op {
87b5bf7719SStephen Hemminger 	struct op_read		read;
88b5bf7719SStephen Hemminger 	struct op_write		write;
89b5bf7719SStephen Hemminger 	struct op_arr_write	arr_wr;
90b5bf7719SStephen Hemminger 	struct op_zero		zero;
91b5bf7719SStephen Hemminger 	struct raw_op		raw;
92b5bf7719SStephen Hemminger 	struct op_if_mode	if_mode;
93b5bf7719SStephen Hemminger };
94b5bf7719SStephen Hemminger 
95b5bf7719SStephen Hemminger 
96b5bf7719SStephen Hemminger /* Init Phases */
97b5bf7719SStephen Hemminger enum {
98b5bf7719SStephen Hemminger 	PHASE_COMMON,
99b5bf7719SStephen Hemminger 	PHASE_PORT0,
100b5bf7719SStephen Hemminger 	PHASE_PORT1,
101b5bf7719SStephen Hemminger 	PHASE_PF0,
102b5bf7719SStephen Hemminger 	PHASE_PF1,
103b5bf7719SStephen Hemminger 	PHASE_PF2,
104b5bf7719SStephen Hemminger 	PHASE_PF3,
105b5bf7719SStephen Hemminger 	PHASE_PF4,
106b5bf7719SStephen Hemminger 	PHASE_PF5,
107b5bf7719SStephen Hemminger 	PHASE_PF6,
108b5bf7719SStephen Hemminger 	PHASE_PF7,
109b5bf7719SStephen Hemminger 	NUM_OF_INIT_PHASES
110b5bf7719SStephen Hemminger };
111b5bf7719SStephen Hemminger 
112b5bf7719SStephen Hemminger /* Init Modes */
113b5bf7719SStephen Hemminger enum {
114b5bf7719SStephen Hemminger 	MODE_ASIC                      = 0x00000001,
115b5bf7719SStephen Hemminger 	MODE_FPGA                      = 0x00000002,
116b5bf7719SStephen Hemminger 	MODE_EMUL                      = 0x00000004,
117b5bf7719SStephen Hemminger 	MODE_E2                        = 0x00000008,
118b5bf7719SStephen Hemminger 	MODE_E3                        = 0x00000010,
119b5bf7719SStephen Hemminger 	MODE_PORT2                     = 0x00000020,
120b5bf7719SStephen Hemminger 	MODE_PORT4                     = 0x00000040,
121b5bf7719SStephen Hemminger 	MODE_SF                        = 0x00000080,
122b5bf7719SStephen Hemminger 	MODE_MF                        = 0x00000100,
123b5bf7719SStephen Hemminger 	MODE_MF_SD                     = 0x00000200,
124b5bf7719SStephen Hemminger 	MODE_MF_SI                     = 0x00000400,
125b5bf7719SStephen Hemminger 	MODE_MF_AFEX                   = 0x00000800,
126b5bf7719SStephen Hemminger 	MODE_E3_A0                     = 0x00001000,
127b5bf7719SStephen Hemminger 	MODE_E3_B0                     = 0x00002000,
128b5bf7719SStephen Hemminger 	MODE_COS3                      = 0x00004000,
129b5bf7719SStephen Hemminger 	MODE_COS6                      = 0x00008000,
130b5bf7719SStephen Hemminger 	MODE_LITTLE_ENDIAN             = 0x00010000,
131b5bf7719SStephen Hemminger 	MODE_BIG_ENDIAN                = 0x00020000,
132b5bf7719SStephen Hemminger };
133b5bf7719SStephen Hemminger 
134b5bf7719SStephen Hemminger /* Init Blocks */
135b5bf7719SStephen Hemminger enum {
136b5bf7719SStephen Hemminger 	BLOCK_ATC,
137b5bf7719SStephen Hemminger 	BLOCK_BRB1,
138b5bf7719SStephen Hemminger 	BLOCK_CCM,
139b5bf7719SStephen Hemminger 	BLOCK_CDU,
140b5bf7719SStephen Hemminger 	BLOCK_CFC,
141b5bf7719SStephen Hemminger 	BLOCK_CSDM,
142b5bf7719SStephen Hemminger 	BLOCK_CSEM,
143b5bf7719SStephen Hemminger 	BLOCK_DBG,
144b5bf7719SStephen Hemminger 	BLOCK_DMAE,
145b5bf7719SStephen Hemminger 	BLOCK_DORQ,
146b5bf7719SStephen Hemminger 	BLOCK_HC,
147b5bf7719SStephen Hemminger 	BLOCK_IGU,
148b5bf7719SStephen Hemminger 	BLOCK_MISC,
149b5bf7719SStephen Hemminger 	BLOCK_NIG,
150b5bf7719SStephen Hemminger 	BLOCK_PBF,
151b5bf7719SStephen Hemminger 	BLOCK_PGLUE_B,
152b5bf7719SStephen Hemminger 	BLOCK_PRS,
153b5bf7719SStephen Hemminger 	BLOCK_PXP2,
154b5bf7719SStephen Hemminger 	BLOCK_PXP,
155b5bf7719SStephen Hemminger 	BLOCK_QM,
156b5bf7719SStephen Hemminger 	BLOCK_SRC,
157b5bf7719SStephen Hemminger 	BLOCK_TCM,
158b5bf7719SStephen Hemminger 	BLOCK_TM,
159b5bf7719SStephen Hemminger 	BLOCK_TSDM,
160b5bf7719SStephen Hemminger 	BLOCK_TSEM,
161b5bf7719SStephen Hemminger 	BLOCK_UCM,
162b5bf7719SStephen Hemminger 	BLOCK_UPB,
163b5bf7719SStephen Hemminger 	BLOCK_USDM,
164b5bf7719SStephen Hemminger 	BLOCK_USEM,
165b5bf7719SStephen Hemminger 	BLOCK_XCM,
166b5bf7719SStephen Hemminger 	BLOCK_XPB,
167b5bf7719SStephen Hemminger 	BLOCK_XSDM,
168b5bf7719SStephen Hemminger 	BLOCK_XSEM,
169b5bf7719SStephen Hemminger 	BLOCK_MISC_AEU,
170b5bf7719SStephen Hemminger 	NUM_OF_INIT_BLOCKS
171b5bf7719SStephen Hemminger };
172b5bf7719SStephen Hemminger 
173*0cb4150fSRasesh Mody #include "bnx2x.h"
174b5bf7719SStephen Hemminger 
175b5bf7719SStephen Hemminger /* Vnics per mode */
176b5bf7719SStephen Hemminger #define ECORE_PORT2_MODE_NUM_VNICS 4
177b5bf7719SStephen Hemminger 
178b5bf7719SStephen Hemminger 
179b5bf7719SStephen Hemminger /* QM queue numbers */
180b5bf7719SStephen Hemminger #define ECORE_ETH_Q		0
181b5bf7719SStephen Hemminger #define ECORE_TOE_Q		3
182b5bf7719SStephen Hemminger #define ECORE_TOE_ACK_Q		6
183b5bf7719SStephen Hemminger #define ECORE_ISCSI_Q		9
184b5bf7719SStephen Hemminger #define ECORE_ISCSI_ACK_Q	11
185b5bf7719SStephen Hemminger #define ECORE_FCOE_Q		10
186b5bf7719SStephen Hemminger 
187b5bf7719SStephen Hemminger /* Vnics per mode */
188b5bf7719SStephen Hemminger #define ECORE_PORT4_MODE_NUM_VNICS 2
189b5bf7719SStephen Hemminger 
190b5bf7719SStephen Hemminger /* COS offset for port1 in E3 B0 4port mode */
191b5bf7719SStephen Hemminger #define ECORE_E3B0_PORT1_COS_OFFSET 3
192b5bf7719SStephen Hemminger 
193b5bf7719SStephen Hemminger /* QM Register addresses */
194b5bf7719SStephen Hemminger #define ECORE_Q_VOQ_REG_ADDR(pf_q_num)\
195b5bf7719SStephen Hemminger 	(QM_REG_QVOQIDX_0 + 4 * (pf_q_num))
196b5bf7719SStephen Hemminger #define ECORE_VOQ_Q_REG_ADDR(cos, pf_q_num)\
197b5bf7719SStephen Hemminger 	(QM_REG_VOQQMASK_0_LSB + 4 * ((cos) * 2 + ((pf_q_num) >> 5)))
198b5bf7719SStephen Hemminger #define ECORE_Q_CMDQ_REG_ADDR(pf_q_num)\
199b5bf7719SStephen Hemminger 	(QM_REG_BYTECRDCMDQ_0 + 4 * ((pf_q_num) >> 4))
200b5bf7719SStephen Hemminger 
201b5bf7719SStephen Hemminger /* extracts the QM queue number for the specified port and vnic */
202b5bf7719SStephen Hemminger #define ECORE_PF_Q_NUM(q_num, port, vnic)\
203b5bf7719SStephen Hemminger 	((((port) << 1) | (vnic)) * 16 + (q_num))
204b5bf7719SStephen Hemminger 
205b5bf7719SStephen Hemminger 
206b5bf7719SStephen Hemminger /* Maps the specified queue to the specified COS */
ecore_map_q_cos(struct bnx2x_softc * sc,uint32_t q_num,uint32_t new_cos)207b5bf7719SStephen Hemminger static inline void ecore_map_q_cos(struct bnx2x_softc *sc, uint32_t q_num, uint32_t new_cos)
208b5bf7719SStephen Hemminger {
209b5bf7719SStephen Hemminger 	/* find current COS mapping */
210b5bf7719SStephen Hemminger 	uint32_t curr_cos = REG_RD(sc, QM_REG_QVOQIDX_0 + q_num * 4);
211b5bf7719SStephen Hemminger 
212b5bf7719SStephen Hemminger 	/* check if queue->COS mapping has changed */
213b5bf7719SStephen Hemminger 	if (curr_cos != new_cos) {
214b5bf7719SStephen Hemminger 		uint32_t num_vnics = ECORE_PORT2_MODE_NUM_VNICS;
215b5bf7719SStephen Hemminger 		uint32_t reg_addr, reg_bit_map, vnic;
216b5bf7719SStephen Hemminger 
217b5bf7719SStephen Hemminger 		/* update parameters for 4port mode */
218b5bf7719SStephen Hemminger 		if (INIT_MODE_FLAGS(sc) & MODE_PORT4) {
219b5bf7719SStephen Hemminger 			num_vnics = ECORE_PORT4_MODE_NUM_VNICS;
220*0cb4150fSRasesh Mody 			if (SC_PORT(sc)) {
221b5bf7719SStephen Hemminger 				curr_cos += ECORE_E3B0_PORT1_COS_OFFSET;
222b5bf7719SStephen Hemminger 				new_cos += ECORE_E3B0_PORT1_COS_OFFSET;
223b5bf7719SStephen Hemminger 			}
224b5bf7719SStephen Hemminger 		}
225b5bf7719SStephen Hemminger 
226b5bf7719SStephen Hemminger 		/* change queue mapping for each VNIC */
227b5bf7719SStephen Hemminger 		for (vnic = 0; vnic < num_vnics; vnic++) {
228b5bf7719SStephen Hemminger 			uint32_t pf_q_num =
229*0cb4150fSRasesh Mody 				ECORE_PF_Q_NUM(q_num, SC_PORT(sc), vnic);
230b5bf7719SStephen Hemminger 			uint32_t q_bit_map = 1 << (pf_q_num & 0x1f);
231b5bf7719SStephen Hemminger 
232b5bf7719SStephen Hemminger 			/* overwrite queue->VOQ mapping */
233b5bf7719SStephen Hemminger 			REG_WR(sc, ECORE_Q_VOQ_REG_ADDR(pf_q_num), new_cos);
234b5bf7719SStephen Hemminger 
235b5bf7719SStephen Hemminger 			/* clear queue bit from current COS bit map */
236b5bf7719SStephen Hemminger 			reg_addr = ECORE_VOQ_Q_REG_ADDR(curr_cos, pf_q_num);
237b5bf7719SStephen Hemminger 			reg_bit_map = REG_RD(sc, reg_addr);
238b5bf7719SStephen Hemminger 			REG_WR(sc, reg_addr, reg_bit_map & (~q_bit_map));
239b5bf7719SStephen Hemminger 
240b5bf7719SStephen Hemminger 			/* set queue bit in new COS bit map */
241b5bf7719SStephen Hemminger 			reg_addr = ECORE_VOQ_Q_REG_ADDR(new_cos, pf_q_num);
242b5bf7719SStephen Hemminger 			reg_bit_map = REG_RD(sc, reg_addr);
243b5bf7719SStephen Hemminger 			REG_WR(sc, reg_addr, reg_bit_map | q_bit_map);
244b5bf7719SStephen Hemminger 
245b5bf7719SStephen Hemminger 			/* set/clear queue bit in command-queue bit map
246b5bf7719SStephen Hemminger 			(E2/E3A0 only, valid COS values are 0/1) */
247b5bf7719SStephen Hemminger 			if (!(INIT_MODE_FLAGS(sc) & MODE_E3_B0)) {
248b5bf7719SStephen Hemminger 				reg_addr = ECORE_Q_CMDQ_REG_ADDR(pf_q_num);
249b5bf7719SStephen Hemminger 				reg_bit_map = REG_RD(sc, reg_addr);
250b5bf7719SStephen Hemminger 				q_bit_map = 1 << (2 * (pf_q_num & 0xf));
251b5bf7719SStephen Hemminger 				reg_bit_map = new_cos ?
252b5bf7719SStephen Hemminger 					      (reg_bit_map | q_bit_map) :
253b5bf7719SStephen Hemminger 					      (reg_bit_map & (~q_bit_map));
254b5bf7719SStephen Hemminger 				REG_WR(sc, reg_addr, reg_bit_map);
255b5bf7719SStephen Hemminger 			}
256b5bf7719SStephen Hemminger 		}
257b5bf7719SStephen Hemminger 	}
258b5bf7719SStephen Hemminger }
259b5bf7719SStephen Hemminger 
260b5bf7719SStephen Hemminger /* Configures the QM according to the specified per-traffic-type COSes */
ecore_dcb_config_qm(struct bnx2x_softc * sc,enum cos_mode mode,struct priority_cos * traffic_cos)261b5bf7719SStephen Hemminger static inline void ecore_dcb_config_qm(struct bnx2x_softc *sc, enum cos_mode mode,
262b5bf7719SStephen Hemminger 				       struct priority_cos *traffic_cos)
263b5bf7719SStephen Hemminger {
264b5bf7719SStephen Hemminger 	ecore_map_q_cos(sc, ECORE_FCOE_Q,
265b5bf7719SStephen Hemminger 			traffic_cos[LLFC_TRAFFIC_TYPE_FCOE].cos);
266b5bf7719SStephen Hemminger 	ecore_map_q_cos(sc, ECORE_ISCSI_Q,
267b5bf7719SStephen Hemminger 			traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
268b5bf7719SStephen Hemminger 	ecore_map_q_cos(sc, ECORE_ISCSI_ACK_Q,
269b5bf7719SStephen Hemminger 		traffic_cos[LLFC_TRAFFIC_TYPE_ISCSI].cos);
270b5bf7719SStephen Hemminger 	if (mode != STATIC_COS) {
271b5bf7719SStephen Hemminger 		/* required only in OVERRIDE_COS mode */
272b5bf7719SStephen Hemminger 		ecore_map_q_cos(sc, ECORE_ETH_Q,
273b5bf7719SStephen Hemminger 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
274b5bf7719SStephen Hemminger 		ecore_map_q_cos(sc, ECORE_TOE_Q,
275b5bf7719SStephen Hemminger 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
276b5bf7719SStephen Hemminger 		ecore_map_q_cos(sc, ECORE_TOE_ACK_Q,
277b5bf7719SStephen Hemminger 				traffic_cos[LLFC_TRAFFIC_TYPE_NW].cos);
278b5bf7719SStephen Hemminger 	}
279b5bf7719SStephen Hemminger }
280b5bf7719SStephen Hemminger 
281b5bf7719SStephen Hemminger 
282b5bf7719SStephen Hemminger /*
28398a7ea33SJerin Jacob  * congestion management port init api description
284b5bf7719SStephen Hemminger  * the api works as follows:
285b5bf7719SStephen Hemminger  * the driver should pass the cmng_init_input struct, the port_init function
286b5bf7719SStephen Hemminger  * will prepare the required internal ram structure which will be passed back
287b5bf7719SStephen Hemminger  * to the driver (cmng_init) that will write it into the internal ram.
288b5bf7719SStephen Hemminger  *
289b5bf7719SStephen Hemminger  * IMPORTANT REMARKS:
290b5bf7719SStephen Hemminger  * 1. the cmng_init struct does not represent the contiguous internal ram
291b5bf7719SStephen Hemminger  *    structure. the driver should use the XSTORM_CMNG_PERPORT_VARS_OFFSET
292b5bf7719SStephen Hemminger  *    offset in order to write the port sub struct and the
293b5bf7719SStephen Hemminger  *    PFID_FROM_PORT_AND_VNIC offset for writing the vnic sub struct (in other
294b5bf7719SStephen Hemminger  *    words - don't use memcpy!).
295b5bf7719SStephen Hemminger  * 2. although the cmng_init struct is filled for the maximal vnic number
296b5bf7719SStephen Hemminger  *    possible, the driver should only write the valid vnics into the internal
297b5bf7719SStephen Hemminger  *    ram according to the appropriate port mode.
298b5bf7719SStephen Hemminger  */
299b5bf7719SStephen Hemminger #define BITS_TO_BYTES(x) ((x)/8)
300b5bf7719SStephen Hemminger 
301b5bf7719SStephen Hemminger /* CMNG constants, as derived from system spec calculations */
302b5bf7719SStephen Hemminger 
303b5bf7719SStephen Hemminger /* default MIN rate in case VNIC min rate is configured to zero- 100Mbps */
304b5bf7719SStephen Hemminger #define DEF_MIN_RATE 100
305b5bf7719SStephen Hemminger 
306b5bf7719SStephen Hemminger /* resolution of the rate shaping timer - 400 usec */
307b5bf7719SStephen Hemminger #define RS_PERIODIC_TIMEOUT_USEC 400
308b5bf7719SStephen Hemminger 
309b5bf7719SStephen Hemminger /*
310b5bf7719SStephen Hemminger  *  number of bytes in single QM arbitration cycle -
311b5bf7719SStephen Hemminger  *  coefficient for calculating the fairness timer
312b5bf7719SStephen Hemminger  */
313b5bf7719SStephen Hemminger #define QM_ARB_BYTES 160000
314b5bf7719SStephen Hemminger 
315b5bf7719SStephen Hemminger /* resolution of Min algorithm 1:100 */
316b5bf7719SStephen Hemminger #define MIN_RES 100
317b5bf7719SStephen Hemminger 
318b5bf7719SStephen Hemminger /*
319b5bf7719SStephen Hemminger  *  how many bytes above threshold for
320b5bf7719SStephen Hemminger  *  the minimal credit of Min algorithm
321b5bf7719SStephen Hemminger  */
322b5bf7719SStephen Hemminger #define MIN_ABOVE_THRESH 32768
323b5bf7719SStephen Hemminger 
324b5bf7719SStephen Hemminger /*
325b5bf7719SStephen Hemminger  *  Fairness algorithm integration time coefficient -
326b5bf7719SStephen Hemminger  *  for calculating the actual Tfair
327b5bf7719SStephen Hemminger  */
328b5bf7719SStephen Hemminger #define T_FAIR_COEF ((MIN_ABOVE_THRESH + QM_ARB_BYTES) * 8 * MIN_RES)
329b5bf7719SStephen Hemminger 
330b5bf7719SStephen Hemminger /* Memory of fairness algorithm - 2 cycles */
331b5bf7719SStephen Hemminger #define FAIR_MEM 2
332b5bf7719SStephen Hemminger #define SAFC_TIMEOUT_USEC 52
333b5bf7719SStephen Hemminger 
334b5bf7719SStephen Hemminger #define SDM_TICKS 4
335b5bf7719SStephen Hemminger 
336b5bf7719SStephen Hemminger 
ecore_init_max(const struct cmng_init_input * input_data,uint32_t r_param,struct cmng_init * ram_data)337b5bf7719SStephen Hemminger static inline void ecore_init_max(const struct cmng_init_input *input_data,
338b5bf7719SStephen Hemminger 				  uint32_t r_param, struct cmng_init *ram_data)
339b5bf7719SStephen Hemminger {
340b5bf7719SStephen Hemminger 	uint32_t vnic;
341b5bf7719SStephen Hemminger 	struct cmng_vnic *vdata = &ram_data->vnic;
342b5bf7719SStephen Hemminger 	struct cmng_struct_per_port *pdata = &ram_data->port;
343b5bf7719SStephen Hemminger 	/*
344b5bf7719SStephen Hemminger 	 * rate shaping per-port variables
345b5bf7719SStephen Hemminger 	 *  100 micro seconds in SDM ticks = 25
346b5bf7719SStephen Hemminger 	 *  since each tick is 4 microSeconds
347b5bf7719SStephen Hemminger 	 */
348b5bf7719SStephen Hemminger 
349b5bf7719SStephen Hemminger 	pdata->rs_vars.rs_periodic_timeout =
350b5bf7719SStephen Hemminger 	RS_PERIODIC_TIMEOUT_USEC / SDM_TICKS;
351b5bf7719SStephen Hemminger 
352b5bf7719SStephen Hemminger 	/* this is the threshold below which no timer arming will occur.
353b5bf7719SStephen Hemminger 	 *  1.25 coefficient is for the threshold to be a little bigger
354b5bf7719SStephen Hemminger 	 *  then the real time to compensate for timer in-accuracy
355b5bf7719SStephen Hemminger 	 */
356b5bf7719SStephen Hemminger 	pdata->rs_vars.rs_threshold =
357b5bf7719SStephen Hemminger 	(5 * RS_PERIODIC_TIMEOUT_USEC * r_param)/4;
358b5bf7719SStephen Hemminger 
359b5bf7719SStephen Hemminger 	/* rate shaping per-vnic variables */
360b5bf7719SStephen Hemminger 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
361b5bf7719SStephen Hemminger 		/* global vnic counter */
362b5bf7719SStephen Hemminger 		vdata->vnic_max_rate[vnic].vn_counter.rate =
363b5bf7719SStephen Hemminger 		input_data->vnic_max_rate[vnic];
364b5bf7719SStephen Hemminger 		/*
365b5bf7719SStephen Hemminger 		 * maximal Mbps for this vnic
366b5bf7719SStephen Hemminger 		 * the quota in each timer period - number of bytes
367b5bf7719SStephen Hemminger 		 * transmitted in this period
368b5bf7719SStephen Hemminger 		 */
369b5bf7719SStephen Hemminger 		vdata->vnic_max_rate[vnic].vn_counter.quota =
370b5bf7719SStephen Hemminger 			RS_PERIODIC_TIMEOUT_USEC *
371b5bf7719SStephen Hemminger 			(uint32_t)vdata->vnic_max_rate[vnic].vn_counter.rate / 8;
372b5bf7719SStephen Hemminger 	}
373b5bf7719SStephen Hemminger 
374b5bf7719SStephen Hemminger }
375b5bf7719SStephen Hemminger 
ecore_init_max_per_vn(uint16_t vnic_max_rate,struct rate_shaping_vars_per_vn * ram_data)376b5bf7719SStephen Hemminger static inline void ecore_init_max_per_vn(uint16_t vnic_max_rate,
377b5bf7719SStephen Hemminger 				  struct rate_shaping_vars_per_vn *ram_data)
378b5bf7719SStephen Hemminger {
379b5bf7719SStephen Hemminger 	/* global vnic counter */
380b5bf7719SStephen Hemminger 	ram_data->vn_counter.rate = vnic_max_rate;
381b5bf7719SStephen Hemminger 
382b5bf7719SStephen Hemminger 	/*
383b5bf7719SStephen Hemminger 	* maximal Mbps for this vnic
384b5bf7719SStephen Hemminger 	* the quota in each timer period - number of bytes
385b5bf7719SStephen Hemminger 	* transmitted in this period
386b5bf7719SStephen Hemminger 	*/
387b5bf7719SStephen Hemminger 	ram_data->vn_counter.quota =
388b5bf7719SStephen Hemminger 		RS_PERIODIC_TIMEOUT_USEC * (uint32_t)vnic_max_rate / 8;
389b5bf7719SStephen Hemminger }
390b5bf7719SStephen Hemminger 
ecore_init_min(const struct cmng_init_input * input_data,uint32_t r_param,struct cmng_init * ram_data)391b5bf7719SStephen Hemminger static inline void ecore_init_min(const struct cmng_init_input *input_data,
392b5bf7719SStephen Hemminger 				  uint32_t r_param, struct cmng_init *ram_data)
393b5bf7719SStephen Hemminger {
394b5bf7719SStephen Hemminger 	uint32_t vnic, fair_periodic_timeout_usec, vnicWeightSum, tFair;
395b5bf7719SStephen Hemminger 	struct cmng_vnic *vdata = &ram_data->vnic;
396b5bf7719SStephen Hemminger 	struct cmng_struct_per_port *pdata = &ram_data->port;
397b5bf7719SStephen Hemminger 
398b5bf7719SStephen Hemminger 	/* this is the resolution of the fairness timer */
399b5bf7719SStephen Hemminger 	fair_periodic_timeout_usec = QM_ARB_BYTES / r_param;
400b5bf7719SStephen Hemminger 
401b5bf7719SStephen Hemminger 	/*
402b5bf7719SStephen Hemminger 	 * fairness per-port variables
403b5bf7719SStephen Hemminger 	 * for 10G it is 1000usec. for 1G it is 10000usec.
404b5bf7719SStephen Hemminger 	 */
405b5bf7719SStephen Hemminger 	tFair = T_FAIR_COEF / input_data->port_rate;
406b5bf7719SStephen Hemminger 
407b5bf7719SStephen Hemminger 	/* this is the threshold below which we won't arm the timer anymore */
408*0cb4150fSRasesh Mody 	pdata->fair_vars.fair_threshold = QM_ARB_BYTES +
409*0cb4150fSRasesh Mody 					  input_data->fairness_thr;
410*0cb4150fSRasesh Mody 
411*0cb4150fSRasesh Mody 	/*New limitation - minimal packet size to cause timeout to be armed */
412*0cb4150fSRasesh Mody 	pdata->fair_vars.size_thr = input_data->size_thr;
413b5bf7719SStephen Hemminger 
414b5bf7719SStephen Hemminger 	/*
415b5bf7719SStephen Hemminger 	 *  we multiply by 1e3/8 to get bytes/msec. We don't want the credits
416b5bf7719SStephen Hemminger 	 *  to pass a credit of the T_FAIR*FAIR_MEM (algorithm resolution)
417b5bf7719SStephen Hemminger 	 */
418b5bf7719SStephen Hemminger 	pdata->fair_vars.upper_bound = r_param * tFair * FAIR_MEM;
419b5bf7719SStephen Hemminger 
420b5bf7719SStephen Hemminger 	/* since each tick is 4 microSeconds */
421b5bf7719SStephen Hemminger 	pdata->fair_vars.fairness_timeout =
422b5bf7719SStephen Hemminger 				fair_periodic_timeout_usec / SDM_TICKS;
423b5bf7719SStephen Hemminger 
424b5bf7719SStephen Hemminger 	/* calculate sum of weights */
425b5bf7719SStephen Hemminger 	vnicWeightSum = 0;
426b5bf7719SStephen Hemminger 
427b5bf7719SStephen Hemminger 	for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++)
428b5bf7719SStephen Hemminger 		vnicWeightSum += input_data->vnic_min_rate[vnic];
429b5bf7719SStephen Hemminger 
430b5bf7719SStephen Hemminger 	/* global vnic counter */
431b5bf7719SStephen Hemminger 	if (vnicWeightSum > 0) {
432b5bf7719SStephen Hemminger 		/* fairness per-vnic variables */
433b5bf7719SStephen Hemminger 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
434b5bf7719SStephen Hemminger 			/*
435b5bf7719SStephen Hemminger 			 *  this is the credit for each period of the fairness
436b5bf7719SStephen Hemminger 			 *  algorithm - number of bytes in T_FAIR (this vnic
437b5bf7719SStephen Hemminger 			 *  share of the port rate)
438b5bf7719SStephen Hemminger 			 */
439b5bf7719SStephen Hemminger 			vdata->vnic_min_rate[vnic].vn_credit_delta =
440b5bf7719SStephen Hemminger 				((uint32_t)(input_data->vnic_min_rate[vnic]) * 100 *
441b5bf7719SStephen Hemminger 				(T_FAIR_COEF / (8 * 100 * vnicWeightSum)));
442b5bf7719SStephen Hemminger 			if (vdata->vnic_min_rate[vnic].vn_credit_delta <
443b5bf7719SStephen Hemminger 			    pdata->fair_vars.fair_threshold +
444b5bf7719SStephen Hemminger 			    MIN_ABOVE_THRESH) {
445b5bf7719SStephen Hemminger 				vdata->vnic_min_rate[vnic].vn_credit_delta =
446b5bf7719SStephen Hemminger 					pdata->fair_vars.fair_threshold +
447b5bf7719SStephen Hemminger 					MIN_ABOVE_THRESH;
448b5bf7719SStephen Hemminger 			}
449b5bf7719SStephen Hemminger 		}
450b5bf7719SStephen Hemminger 	}
451b5bf7719SStephen Hemminger }
452b5bf7719SStephen Hemminger 
ecore_init_fw_wrr(const struct cmng_init_input * input_data,uint32_t r_param __rte_unused,struct cmng_init * ram_data)453b5bf7719SStephen Hemminger static inline void ecore_init_fw_wrr(const struct cmng_init_input *input_data,
454*0cb4150fSRasesh Mody 				     uint32_t r_param __rte_unused,
455b5bf7719SStephen Hemminger 				     struct cmng_init *ram_data)
456b5bf7719SStephen Hemminger {
457b5bf7719SStephen Hemminger 	uint32_t vnic, cos;
458b5bf7719SStephen Hemminger 	uint32_t cosWeightSum = 0;
459b5bf7719SStephen Hemminger 	struct cmng_vnic *vdata = &ram_data->vnic;
460b5bf7719SStephen Hemminger 	struct cmng_struct_per_port *pdata = &ram_data->port;
461b5bf7719SStephen Hemminger 
462b5bf7719SStephen Hemminger 	for (cos = 0; cos < MAX_COS_NUMBER; cos++)
463b5bf7719SStephen Hemminger 		cosWeightSum += input_data->cos_min_rate[cos];
464b5bf7719SStephen Hemminger 
465b5bf7719SStephen Hemminger 	if (cosWeightSum > 0) {
466b5bf7719SStephen Hemminger 
467b5bf7719SStephen Hemminger 		for (vnic = 0; vnic < ECORE_PORT2_MODE_NUM_VNICS; vnic++) {
468b5bf7719SStephen Hemminger 			/*
469b5bf7719SStephen Hemminger 			 *  Since cos and vnic shouldn't work together the rate
470b5bf7719SStephen Hemminger 			 *  to divide between the coses is the port rate.
471b5bf7719SStephen Hemminger 			 */
472b5bf7719SStephen Hemminger 			uint32_t *ccd = vdata->vnic_min_rate[vnic].cos_credit_delta;
473b5bf7719SStephen Hemminger 			for (cos = 0; cos < MAX_COS_NUMBER; cos++) {
474b5bf7719SStephen Hemminger 				/*
475b5bf7719SStephen Hemminger 				 * this is the credit for each period of
476b5bf7719SStephen Hemminger 				 * the fairness algorithm - number of bytes
477b5bf7719SStephen Hemminger 				 * in T_FAIR (this cos share of the vnic rate)
478b5bf7719SStephen Hemminger 				 */
479b5bf7719SStephen Hemminger 				ccd[cos] =
480b5bf7719SStephen Hemminger 				    ((uint32_t)input_data->cos_min_rate[cos] * 100 *
481b5bf7719SStephen Hemminger 				    (T_FAIR_COEF / (8 * 100 * cosWeightSum)));
482b5bf7719SStephen Hemminger 				 if (ccd[cos] < pdata->fair_vars.fair_threshold
483b5bf7719SStephen Hemminger 						+ MIN_ABOVE_THRESH) {
484b5bf7719SStephen Hemminger 					ccd[cos] =
485b5bf7719SStephen Hemminger 					    pdata->fair_vars.fair_threshold +
486b5bf7719SStephen Hemminger 					    MIN_ABOVE_THRESH;
487b5bf7719SStephen Hemminger 				}
488b5bf7719SStephen Hemminger 			}
489b5bf7719SStephen Hemminger 		}
490b5bf7719SStephen Hemminger 	}
491b5bf7719SStephen Hemminger }
492b5bf7719SStephen Hemminger 
493*0cb4150fSRasesh Mody static inline void
ecore_init_safc(const struct cmng_init_input * input_data __rte_unused,struct cmng_init * ram_data)494*0cb4150fSRasesh Mody ecore_init_safc(const struct cmng_init_input *input_data __rte_unused,
495*0cb4150fSRasesh Mody 		struct cmng_init *ram_data)
496b5bf7719SStephen Hemminger {
497b5bf7719SStephen Hemminger 	/* in microSeconds */
498b5bf7719SStephen Hemminger 	ram_data->port.safc_vars.safc_timeout_usec = SAFC_TIMEOUT_USEC;
499b5bf7719SStephen Hemminger }
500b5bf7719SStephen Hemminger 
501b5bf7719SStephen Hemminger /* Congestion management port init */
ecore_init_cmng(const struct cmng_init_input * input_data,struct cmng_init * ram_data)502b5bf7719SStephen Hemminger static inline void ecore_init_cmng(const struct cmng_init_input *input_data,
503b5bf7719SStephen Hemminger 				   struct cmng_init *ram_data)
504b5bf7719SStephen Hemminger {
505b5bf7719SStephen Hemminger 	uint32_t r_param;
506b5bf7719SStephen Hemminger 	ECORE_MEMSET(ram_data, 0, sizeof(struct cmng_init));
507b5bf7719SStephen Hemminger 
508b5bf7719SStephen Hemminger 	ram_data->port.flags = input_data->flags;
509b5bf7719SStephen Hemminger 
510b5bf7719SStephen Hemminger 	/*
511b5bf7719SStephen Hemminger 	 *  number of bytes transmitted in a rate of 10Gbps
512b5bf7719SStephen Hemminger 	 *  in one usec = 1.25KB.
513b5bf7719SStephen Hemminger 	 */
514b5bf7719SStephen Hemminger 	r_param = BITS_TO_BYTES(input_data->port_rate);
515b5bf7719SStephen Hemminger 	ecore_init_max(input_data, r_param, ram_data);
516b5bf7719SStephen Hemminger 	ecore_init_min(input_data, r_param, ram_data);
517*0cb4150fSRasesh Mody 	ecore_init_fw_wrr(input_data, r_param, ram_data);
518*0cb4150fSRasesh Mody 	ecore_init_safc(input_data, ram_data);
519b5bf7719SStephen Hemminger }
520b5bf7719SStephen Hemminger 
521b5bf7719SStephen Hemminger 
522b5bf7719SStephen Hemminger 
523b5bf7719SStephen Hemminger 
524b5bf7719SStephen Hemminger /* Returns the index of start or end of a specific block stage in ops array*/
525b5bf7719SStephen Hemminger #define BLOCK_OPS_IDX(block, stage, end) \
526b5bf7719SStephen Hemminger 			(2*(((block)*NUM_OF_INIT_PHASES) + (stage)) + (end))
527b5bf7719SStephen Hemminger 
528b5bf7719SStephen Hemminger 
529b5bf7719SStephen Hemminger #define INITOP_SET		0	/* set the HW directly */
530b5bf7719SStephen Hemminger #define INITOP_CLEAR		1	/* clear the HW directly */
531b5bf7719SStephen Hemminger #define INITOP_INIT		2	/* set the init-value array */
532b5bf7719SStephen Hemminger 
533b5bf7719SStephen Hemminger /****************************************************************************
534b5bf7719SStephen Hemminger * ILT management
535b5bf7719SStephen Hemminger ****************************************************************************/
536b5bf7719SStephen Hemminger struct ilt_line {
537b5bf7719SStephen Hemminger 	ecore_dma_addr_t page_mapping;
538b5bf7719SStephen Hemminger 	void *page;
539b5bf7719SStephen Hemminger 	uint32_t size;
540b5bf7719SStephen Hemminger };
541b5bf7719SStephen Hemminger 
542b5bf7719SStephen Hemminger struct ilt_client_info {
543b5bf7719SStephen Hemminger 	uint32_t page_size;
544b5bf7719SStephen Hemminger 	uint16_t start;
545b5bf7719SStephen Hemminger 	uint16_t end;
546b5bf7719SStephen Hemminger 	uint16_t client_num;
547b5bf7719SStephen Hemminger 	uint16_t flags;
548b5bf7719SStephen Hemminger #define ILT_CLIENT_SKIP_INIT	0x1
549b5bf7719SStephen Hemminger #define ILT_CLIENT_SKIP_MEM	0x2
550b5bf7719SStephen Hemminger };
551b5bf7719SStephen Hemminger 
552b5bf7719SStephen Hemminger struct ecore_ilt {
553b5bf7719SStephen Hemminger 	uint32_t start_line;
554b5bf7719SStephen Hemminger 	struct ilt_line		*lines;
555b5bf7719SStephen Hemminger 	struct ilt_client_info	clients[4];
556b5bf7719SStephen Hemminger #define ILT_CLIENT_CDU	0
557b5bf7719SStephen Hemminger #define ILT_CLIENT_QM	1
558b5bf7719SStephen Hemminger #define ILT_CLIENT_SRC	2
559b5bf7719SStephen Hemminger #define ILT_CLIENT_TM	3
560b5bf7719SStephen Hemminger };
561b5bf7719SStephen Hemminger 
562b5bf7719SStephen Hemminger /****************************************************************************
563b5bf7719SStephen Hemminger * SRC configuration
564b5bf7719SStephen Hemminger ****************************************************************************/
565b5bf7719SStephen Hemminger struct src_ent {
566b5bf7719SStephen Hemminger 	uint8_t opaque[56];
567b5bf7719SStephen Hemminger 	uint64_t next;
568b5bf7719SStephen Hemminger };
569b5bf7719SStephen Hemminger 
570b5bf7719SStephen Hemminger /****************************************************************************
571b5bf7719SStephen Hemminger * Parity configuration
572b5bf7719SStephen Hemminger ****************************************************************************/
573*0cb4150fSRasesh Mody #define BLOCK_PRTY_INFO(block, en_mask, m1, m1h, m2, m3) \
574b5bf7719SStephen Hemminger { \
575b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_MASK, \
576b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_STS_CLR, \
577*0cb4150fSRasesh Mody 	en_mask, {m1, m1h, m2, m3}, #block \
578b5bf7719SStephen Hemminger }
579b5bf7719SStephen Hemminger 
580*0cb4150fSRasesh Mody #define BLOCK_PRTY_INFO_0(block, en_mask, m1, m1h, m2, m3) \
581b5bf7719SStephen Hemminger { \
582b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_MASK_0, \
583b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_STS_CLR_0, \
584*0cb4150fSRasesh Mody 	en_mask, {m1, m1h, m2, m3}, #block "_0" \
585b5bf7719SStephen Hemminger }
586b5bf7719SStephen Hemminger 
587*0cb4150fSRasesh Mody #define BLOCK_PRTY_INFO_1(block, en_mask, m1, m1h, m2, m3) \
588b5bf7719SStephen Hemminger { \
589b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_MASK_1, \
590b5bf7719SStephen Hemminger 	block##_REG_##block##_PRTY_STS_CLR_1, \
591*0cb4150fSRasesh Mody 	en_mask, {m1, m1h, m2, m3}, #block "_1" \
592b5bf7719SStephen Hemminger }
593b5bf7719SStephen Hemminger 
594b5bf7719SStephen Hemminger static const struct {
595b5bf7719SStephen Hemminger 	uint32_t mask_addr;
596b5bf7719SStephen Hemminger 	uint32_t sts_clr_addr;
597b5bf7719SStephen Hemminger 	uint32_t en_mask;		/* Mask to enable parity attentions */
598b5bf7719SStephen Hemminger 	struct {
599*0cb4150fSRasesh Mody 		uint32_t e1;		/* 57710 */
600b5bf7719SStephen Hemminger 		uint32_t e1h;	/* 57711 */
601b5bf7719SStephen Hemminger 		uint32_t e2;		/* 57712 */
602b5bf7719SStephen Hemminger 		uint32_t e3;		/* 578xx */
603b5bf7719SStephen Hemminger 	} reg_mask;		/* Register mask (all valid bits) */
604b5bf7719SStephen Hemminger 	char name[8];		/* Block's longest name is 7 characters long
605b5bf7719SStephen Hemminger 				 * (name + suffix)
606b5bf7719SStephen Hemminger 				 */
607b5bf7719SStephen Hemminger } ecore_blocks_parity_data[] = {
608b5bf7719SStephen Hemminger 	/* bit 19 masked */
609*0cb4150fSRasesh Mody 	/* REG_WR(sc, PXP_REG_PXP_PRTY_MASK, 0x80000); */
610b5bf7719SStephen Hemminger 	/* bit 5,18,20-31 */
611*0cb4150fSRasesh Mody 	/* REG_WR(sc, PXP2_REG_PXP2_PRTY_MASK_0, 0xfff40020); */
612b5bf7719SStephen Hemminger 	/* bit 5 */
613*0cb4150fSRasesh Mody 	/* REG_WR(sc, PXP2_REG_PXP2_PRTY_MASK_1, 0x20);	*/
614*0cb4150fSRasesh Mody 	/* REG_WR(sc, HC_REG_HC_PRTY_MASK, 0x0); */
615*0cb4150fSRasesh Mody 	/* REG_WR(sc, MISC_REG_MISC_PRTY_MASK, 0x0); */
616b5bf7719SStephen Hemminger 
617b5bf7719SStephen Hemminger 	/* Block IGU, MISC, PXP and PXP2 parity errors as long as we don't
618b5bf7719SStephen Hemminger 	 * want to handle "system kill" flow at the moment.
619b5bf7719SStephen Hemminger 	 */
620*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(PXP, 0x7ffffff, 0x3ffffff, 0x3ffffff, 0x7ffffff,
621b5bf7719SStephen Hemminger 			0x7ffffff),
622*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(PXP2,	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
623b5bf7719SStephen Hemminger 			  0xffffffff),
624*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(PXP2,	0x1ffffff, 0x7f, 0x7f, 0x7ff, 0x1ffffff),
625*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(HC, 0x7, 0x7, 0x7, 0, 0),
626*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(NIG, 0xffffffff, 0x3fffffff, 0xffffffff, 0, 0),
627*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(NIG,	0xffffffff, 0, 0, 0xffffffff, 0xffffffff),
628*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(NIG,	0xffff, 0, 0, 0xff, 0xffff),
629*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(IGU, 0x7ff, 0, 0, 0x7ff, 0x7ff),
630*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(MISC, 0x1, 0x1, 0x1, 0x1, 0x1),
631*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(QM, 0, 0x1ff, 0xfff, 0xfff, 0xfff),
632*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(ATC, 0x1f, 0, 0, 0x1f, 0x1f),
633*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(PGLUE_B, 0x3, 0, 0, 0x3, 0x3),
634*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(DORQ, 0, 0x3, 0x3, 0x3, 0x3),
635b5bf7719SStephen Hemminger 	{GRCBASE_UPB + PB_REG_PB_PRTY_MASK,
636b5bf7719SStephen Hemminger 		GRCBASE_UPB + PB_REG_PB_PRTY_STS_CLR, 0xf,
637*0cb4150fSRasesh Mody 		{0xf, 0xf, 0xf, 0xf}, "UPB"},
638b5bf7719SStephen Hemminger 	{GRCBASE_XPB + PB_REG_PB_PRTY_MASK,
639b5bf7719SStephen Hemminger 		GRCBASE_XPB + PB_REG_PB_PRTY_STS_CLR, 0,
640*0cb4150fSRasesh Mody 		{0xf, 0xf, 0xf, 0xf}, "XPB"},
641*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(SRC, 0x4, 0x7, 0x7, 0x7, 0x7),
642*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(CDU, 0, 0x1f, 0x1f, 0x1f, 0x1f),
643*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(CFC, 0, 0xf, 0xf, 0xf, 0x3f),
644*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(DBG, 0, 0x1, 0x1, 0x1, 0x1),
645*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(DMAE, 0, 0xf, 0xf, 0xf, 0xf),
646*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(BRB1, 0, 0xf, 0xf, 0xf, 0xf),
647*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(PRS, (1 << 6), 0xff, 0xff, 0xff, 0xff),
648*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(PBF, 0, 0, 0x3ffff, 0xfffff, 0xfffffff),
649*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(TM, 0, 0, 0x7f, 0x7f, 0x7f),
650*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(TSDM, 0x18, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
651*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(CSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
652*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(USDM, 0x38, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
653*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(XSDM, 0x8, 0x7ff, 0x7ff, 0x7ff, 0x7ff),
654*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(TCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
655*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(CCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
656*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(UCM, 0, 0, 0x7ffffff, 0x7ffffff, 0x7ffffff),
657*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO(XCM, 0, 0, 0x3fffffff, 0x3fffffff, 0x3fffffff),
658*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(TSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
659*0cb4150fSRasesh Mody 			  0xffffffff),
660*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(TSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
661*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(USEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
662*0cb4150fSRasesh Mody 			  0xffffffff),
663*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(USEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
664*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(CSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
665*0cb4150fSRasesh Mody 			  0xffffffff),
666*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(CSEM, 0, 0x3, 0x1f, 0x1f, 0x1f),
667*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_0(XSEM, 0, 0xffffffff, 0xffffffff, 0xffffffff,
668*0cb4150fSRasesh Mody 			  0xffffffff),
669*0cb4150fSRasesh Mody 	BLOCK_PRTY_INFO_1(XSEM, 0, 0x3, 0x1f, 0x3f, 0x3f),
670b5bf7719SStephen Hemminger };
671b5bf7719SStephen Hemminger 
672b5bf7719SStephen Hemminger 
673b5bf7719SStephen Hemminger /* [28] MCP Latched rom_parity
674b5bf7719SStephen Hemminger  * [29] MCP Latched ump_rx_parity
675b5bf7719SStephen Hemminger  * [30] MCP Latched ump_tx_parity
676b5bf7719SStephen Hemminger  * [31] MCP Latched scpad_parity
677b5bf7719SStephen Hemminger  */
678*0cb4150fSRasesh Mody #define MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS	\
679b5bf7719SStephen Hemminger 	(AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY | \
680b5bf7719SStephen Hemminger 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY | \
681*0cb4150fSRasesh Mody 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY)
682*0cb4150fSRasesh Mody 
683*0cb4150fSRasesh Mody #define MISC_AEU_ENABLE_MCP_PRTY_BITS	\
684*0cb4150fSRasesh Mody 	(MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS | \
685b5bf7719SStephen Hemminger 	 AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY)
686b5bf7719SStephen Hemminger 
687b5bf7719SStephen Hemminger /* Below registers control the MCP parity attention output. When
688b5bf7719SStephen Hemminger  * MISC_AEU_ENABLE_MCP_PRTY_BITS are set - attentions are
689b5bf7719SStephen Hemminger  * enabled, when cleared - disabled.
690b5bf7719SStephen Hemminger  */
691*0cb4150fSRasesh Mody static const struct {
692*0cb4150fSRasesh Mody 	uint32_t addr;
693*0cb4150fSRasesh Mody 	uint32_t bits;
694*0cb4150fSRasesh Mody } mcp_attn_ctl_regs[] = {
695*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0,
696*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_BITS },
697*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_NIG_0,
698*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
699*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_PXP_0,
700*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
701*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0,
702*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_BITS },
703*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_NIG_1,
704*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS },
705*0cb4150fSRasesh Mody 	{ MISC_REG_AEU_ENABLE4_PXP_1,
706*0cb4150fSRasesh Mody 		MISC_AEU_ENABLE_MCP_PRTY_SUB_BITS }
707b5bf7719SStephen Hemminger };
708b5bf7719SStephen Hemminger 
ecore_set_mcp_parity(struct bnx2x_softc * sc,uint8_t enable)709b5bf7719SStephen Hemminger static inline void ecore_set_mcp_parity(struct bnx2x_softc *sc, uint8_t enable)
710b5bf7719SStephen Hemminger {
711*0cb4150fSRasesh Mody 	unsigned int i;
712b5bf7719SStephen Hemminger 	uint32_t reg_val;
713b5bf7719SStephen Hemminger 
714*0cb4150fSRasesh Mody 	for (i = 0; i < ARRAY_SIZE(mcp_attn_ctl_regs); i++) {
715*0cb4150fSRasesh Mody 		reg_val = REG_RD(sc, mcp_attn_ctl_regs[i].addr);
716b5bf7719SStephen Hemminger 
717b5bf7719SStephen Hemminger 		if (enable)
718*0cb4150fSRasesh Mody 			reg_val |= mcp_attn_ctl_regs[i].bits;
719b5bf7719SStephen Hemminger 		else
720*0cb4150fSRasesh Mody 			reg_val &= ~mcp_attn_ctl_regs[i].bits;
721b5bf7719SStephen Hemminger 
722*0cb4150fSRasesh Mody 		REG_WR(sc, mcp_attn_ctl_regs[i].addr, reg_val);
723b5bf7719SStephen Hemminger 	}
724b5bf7719SStephen Hemminger }
725b5bf7719SStephen Hemminger 
ecore_parity_reg_mask(struct bnx2x_softc * sc,int idx)726b5bf7719SStephen Hemminger static inline uint32_t ecore_parity_reg_mask(struct bnx2x_softc *sc, int idx)
727b5bf7719SStephen Hemminger {
728*0cb4150fSRasesh Mody 	if (CHIP_IS_E1(sc))
729*0cb4150fSRasesh Mody 		return ecore_blocks_parity_data[idx].reg_mask.e1;
730*0cb4150fSRasesh Mody 	else if (CHIP_IS_E1H(sc))
731b5bf7719SStephen Hemminger 		return ecore_blocks_parity_data[idx].reg_mask.e1h;
732b5bf7719SStephen Hemminger 	else if (CHIP_IS_E2(sc))
733b5bf7719SStephen Hemminger 		return ecore_blocks_parity_data[idx].reg_mask.e2;
734b5bf7719SStephen Hemminger 	else /* CHIP_IS_E3 */
735b5bf7719SStephen Hemminger 		return ecore_blocks_parity_data[idx].reg_mask.e3;
736b5bf7719SStephen Hemminger }
737b5bf7719SStephen Hemminger 
ecore_disable_blocks_parity(struct bnx2x_softc * sc)738b5bf7719SStephen Hemminger static inline void ecore_disable_blocks_parity(struct bnx2x_softc *sc)
739b5bf7719SStephen Hemminger {
740*0cb4150fSRasesh Mody 	unsigned int i;
741b5bf7719SStephen Hemminger 
742*0cb4150fSRasesh Mody 	for (i = 0; i < ARRAY_SIZE(ecore_blocks_parity_data); i++) {
743b5bf7719SStephen Hemminger 		uint32_t dis_mask = ecore_parity_reg_mask(sc, i);
744b5bf7719SStephen Hemminger 
745b5bf7719SStephen Hemminger 		if (dis_mask) {
746b5bf7719SStephen Hemminger 			REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
747b5bf7719SStephen Hemminger 			       dis_mask);
748ba7eeb03SRasesh Mody 			ECORE_MSG(sc, "Setting parity mask "
749b5bf7719SStephen Hemminger 						 "for %s to\t\t0x%x",
750b5bf7719SStephen Hemminger 				    ecore_blocks_parity_data[i].name, dis_mask);
751b5bf7719SStephen Hemminger 		}
752b5bf7719SStephen Hemminger 	}
753b5bf7719SStephen Hemminger 
754b5bf7719SStephen Hemminger 	/* Disable MCP parity attentions */
755*0cb4150fSRasesh Mody 	ecore_set_mcp_parity(sc, false);
756b5bf7719SStephen Hemminger }
757b5bf7719SStephen Hemminger 
758b5bf7719SStephen Hemminger /**
759b5bf7719SStephen Hemminger  * Clear the parity error status registers.
760b5bf7719SStephen Hemminger  */
ecore_clear_blocks_parity(struct bnx2x_softc * sc)761b5bf7719SStephen Hemminger static inline void ecore_clear_blocks_parity(struct bnx2x_softc *sc)
762b5bf7719SStephen Hemminger {
763*0cb4150fSRasesh Mody 	unsigned int i;
764b5bf7719SStephen Hemminger 	uint32_t reg_val, mcp_aeu_bits =
765b5bf7719SStephen Hemminger 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_ROM_PARITY |
766b5bf7719SStephen Hemminger 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_SCPAD_PARITY |
767b5bf7719SStephen Hemminger 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_RX_PARITY |
768b5bf7719SStephen Hemminger 		AEU_INPUTS_ATTN_BITS_MCP_LATCHED_UMP_TX_PARITY;
769b5bf7719SStephen Hemminger 
770b5bf7719SStephen Hemminger 	/* Clear SEM_FAST parities */
771b5bf7719SStephen Hemminger 	REG_WR(sc, XSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
772b5bf7719SStephen Hemminger 	REG_WR(sc, TSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
773b5bf7719SStephen Hemminger 	REG_WR(sc, USEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
774b5bf7719SStephen Hemminger 	REG_WR(sc, CSEM_REG_FAST_MEMORY + SEM_FAST_REG_PARITY_RST, 0x1);
775b5bf7719SStephen Hemminger 
776*0cb4150fSRasesh Mody 	for (i = 0; i < ARRAY_SIZE(ecore_blocks_parity_data); i++) {
777b5bf7719SStephen Hemminger 		uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
778b5bf7719SStephen Hemminger 
779b5bf7719SStephen Hemminger 		if (reg_mask) {
780b5bf7719SStephen Hemminger 			reg_val = REG_RD(sc, ecore_blocks_parity_data[i].
781b5bf7719SStephen Hemminger 					 sts_clr_addr);
782b5bf7719SStephen Hemminger 			if (reg_val & reg_mask)
783ba7eeb03SRasesh Mody 				ECORE_MSG(sc, "Parity errors in %s: 0x%x",
784b5bf7719SStephen Hemminger 					   ecore_blocks_parity_data[i].name,
785b5bf7719SStephen Hemminger 					   reg_val & reg_mask);
786b5bf7719SStephen Hemminger 		}
787b5bf7719SStephen Hemminger 	}
788b5bf7719SStephen Hemminger 
789b5bf7719SStephen Hemminger 	/* Check if there were parity attentions in MCP */
790b5bf7719SStephen Hemminger 	reg_val = REG_RD(sc, MISC_REG_AEU_AFTER_INVERT_4_MCP);
791b5bf7719SStephen Hemminger 	if (reg_val & mcp_aeu_bits)
792ba7eeb03SRasesh Mody 		ECORE_MSG(sc, "Parity error in MCP: 0x%x",
793b5bf7719SStephen Hemminger 			   reg_val & mcp_aeu_bits);
794b5bf7719SStephen Hemminger 
795b5bf7719SStephen Hemminger 	/* Clear parity attentions in MCP:
796b5bf7719SStephen Hemminger 	 * [7]  clears Latched rom_parity
797b5bf7719SStephen Hemminger 	 * [8]  clears Latched ump_rx_parity
798b5bf7719SStephen Hemminger 	 * [9]  clears Latched ump_tx_parity
799b5bf7719SStephen Hemminger 	 * [10] clears Latched scpad_parity (both ports)
800b5bf7719SStephen Hemminger 	 */
801b5bf7719SStephen Hemminger 	REG_WR(sc, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0x780);
802b5bf7719SStephen Hemminger }
803b5bf7719SStephen Hemminger 
ecore_enable_blocks_parity(struct bnx2x_softc * sc)804b5bf7719SStephen Hemminger static inline void ecore_enable_blocks_parity(struct bnx2x_softc *sc)
805b5bf7719SStephen Hemminger {
806*0cb4150fSRasesh Mody 	unsigned int i;
807b5bf7719SStephen Hemminger 
808*0cb4150fSRasesh Mody 	for (i = 0; i < ARRAY_SIZE(ecore_blocks_parity_data); i++) {
809b5bf7719SStephen Hemminger 		uint32_t reg_mask = ecore_parity_reg_mask(sc, i);
810b5bf7719SStephen Hemminger 
811b5bf7719SStephen Hemminger 		if (reg_mask)
812b5bf7719SStephen Hemminger 			REG_WR(sc, ecore_blocks_parity_data[i].mask_addr,
813b5bf7719SStephen Hemminger 				ecore_blocks_parity_data[i].en_mask & reg_mask);
814b5bf7719SStephen Hemminger 	}
815b5bf7719SStephen Hemminger 
816b5bf7719SStephen Hemminger 	/* Enable MCP parity attentions */
817*0cb4150fSRasesh Mody 	ecore_set_mcp_parity(sc, true);
818b5bf7719SStephen Hemminger }
819b5bf7719SStephen Hemminger 
820b5bf7719SStephen Hemminger 
821b5bf7719SStephen Hemminger #endif /* ECORE_INIT_H */
822