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