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