Commit | Line | Data |
---|---|---|
94a78b79 VZ |
1 | /* bnx2x_init_ops.h: Broadcom Everest network driver. |
2 | * Static functions needed during the initialization. | |
3 | * This file is "included" in bnx2x_main.c. | |
4 | * | |
3359fced | 5 | * Copyright (c) 2007-2010 Broadcom Corporation |
94a78b79 VZ |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License as published by | |
9 | * the Free Software Foundation. | |
10 | * | |
11 | * Maintained by: Eilon Greenstein <eilong@broadcom.com> | |
12 | * Written by: Vladislav Zolotarov <vladz@broadcom.com> | |
13 | */ | |
573f2035 | 14 | |
94a78b79 VZ |
15 | #ifndef BNX2X_INIT_OPS_H |
16 | #define BNX2X_INIT_OPS_H | |
17 | ||
94a78b79 VZ |
18 | static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len); |
19 | ||
573f2035 | 20 | |
94a78b79 VZ |
21 | static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, |
22 | u32 len) | |
23 | { | |
573f2035 | 24 | u32 i; |
94a78b79 | 25 | |
573f2035 | 26 | for (i = 0; i < len; i++) |
94a78b79 | 27 | REG_WR(bp, addr + i*4, data[i]); |
94a78b79 VZ |
28 | } |
29 | ||
30 | static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, | |
573f2035 | 31 | u32 len) |
94a78b79 | 32 | { |
573f2035 | 33 | u32 i; |
94a78b79 | 34 | |
573f2035 | 35 | for (i = 0; i < len; i++) |
94a78b79 | 36 | REG_WR_IND(bp, addr + i*4, data[i]); |
94a78b79 VZ |
37 | } |
38 | ||
39 | static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) | |
40 | { | |
573f2035 EG |
41 | if (bp->dmae_ready) |
42 | bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); | |
43 | else | |
44 | bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); | |
94a78b79 VZ |
45 | } |
46 | ||
47 | static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) | |
48 | { | |
573f2035 EG |
49 | u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4)); |
50 | u32 buf_len32 = buf_len/4; | |
51 | u32 i; | |
94a78b79 | 52 | |
573f2035 | 53 | memset(GUNZIP_BUF(bp), (u8)fill, buf_len); |
94a78b79 VZ |
54 | |
55 | for (i = 0; i < len; i += buf_len32) { | |
56 | u32 cur_len = min(buf_len32, len - i); | |
57 | ||
573f2035 | 58 | bnx2x_write_big_buf(bp, addr + i*4, cur_len); |
94a78b79 VZ |
59 | } |
60 | } | |
61 | ||
62 | static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, | |
63 | u32 len64) | |
64 | { | |
573f2035 EG |
65 | u32 buf_len32 = FW_BUF_SIZE/4; |
66 | u32 len = len64*2; | |
94a78b79 | 67 | u64 data64 = 0; |
573f2035 | 68 | u32 i; |
94a78b79 VZ |
69 | |
70 | /* 64 bit value is in a blob: first low DWORD, then high DWORD */ | |
71 | data64 = HILO_U64((*(data + 1)), (*data)); | |
573f2035 | 72 | |
94a78b79 VZ |
73 | len64 = min((u32)(FW_BUF_SIZE/8), len64); |
74 | for (i = 0; i < len64; i++) { | |
573f2035 | 75 | u64 *pdata = ((u64 *)(GUNZIP_BUF(bp))) + i; |
94a78b79 VZ |
76 | |
77 | *pdata = data64; | |
78 | } | |
79 | ||
80 | for (i = 0; i < len; i += buf_len32) { | |
81 | u32 cur_len = min(buf_len32, len - i); | |
82 | ||
573f2035 | 83 | bnx2x_write_big_buf(bp, addr + i*4, cur_len); |
94a78b79 VZ |
84 | } |
85 | } | |
86 | ||
87 | /********************************************************* | |
88 | There are different blobs for each PRAM section. | |
89 | In addition, each blob write operation is divided into a few operations | |
90 | in order to decrease the amount of phys. contiguous buffer needed. | |
91 | Thus, when we select a blob the address may be with some offset | |
92 | from the beginning of PRAM section. | |
93 | The same holds for the INT_TABLE sections. | |
94 | **********************************************************/ | |
95 | #define IF_IS_INT_TABLE_ADDR(base, addr) \ | |
96 | if (((base) <= (addr)) && ((base) + 0x400 >= (addr))) | |
97 | ||
98 | #define IF_IS_PRAM_ADDR(base, addr) \ | |
99 | if (((base) <= (addr)) && ((base) + 0x40000 >= (addr))) | |
100 | ||
101 | static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) | |
102 | { | |
103 | IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) | |
573f2035 EG |
104 | data = INIT_TSEM_INT_TABLE_DATA(bp); |
105 | else | |
106 | IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) | |
107 | data = INIT_CSEM_INT_TABLE_DATA(bp); | |
108 | else | |
109 | IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) | |
110 | data = INIT_USEM_INT_TABLE_DATA(bp); | |
111 | else | |
112 | IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) | |
113 | data = INIT_XSEM_INT_TABLE_DATA(bp); | |
114 | else | |
115 | IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) | |
116 | data = INIT_TSEM_PRAM_DATA(bp); | |
117 | else | |
118 | IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) | |
119 | data = INIT_CSEM_PRAM_DATA(bp); | |
120 | else | |
121 | IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) | |
122 | data = INIT_USEM_PRAM_DATA(bp); | |
123 | else | |
124 | IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) | |
125 | data = INIT_XSEM_PRAM_DATA(bp); | |
94a78b79 VZ |
126 | |
127 | return data; | |
128 | } | |
129 | ||
130 | static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) | |
131 | { | |
573f2035 EG |
132 | if (bp->dmae_ready) |
133 | bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); | |
134 | else | |
135 | bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); | |
94a78b79 VZ |
136 | } |
137 | ||
138 | static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, | |
139 | u32 len) | |
140 | { | |
3359fced VZ |
141 | const u32 *old_data = data; |
142 | ||
573f2035 | 143 | data = (const u32 *)bnx2x_sel_blob(bp, addr, (const u8 *)data); |
94a78b79 | 144 | |
3359fced VZ |
145 | if (bp->dmae_ready) { |
146 | if (old_data != data) | |
147 | VIRT_WR_DMAE_LEN(bp, data, addr, len, 1); | |
148 | else | |
149 | VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); | |
150 | } else | |
573f2035 | 151 | bnx2x_init_ind_wr(bp, addr, data, len); |
94a78b79 VZ |
152 | } |
153 | ||
573f2035 | 154 | static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off) |
94a78b79 | 155 | { |
573f2035 EG |
156 | const u8 *data = NULL; |
157 | int rc; | |
158 | u32 i; | |
94a78b79 | 159 | |
573f2035 | 160 | data = bnx2x_sel_blob(bp, addr, data) + blob_off*4; |
94a78b79 VZ |
161 | |
162 | rc = bnx2x_gunzip(bp, data, len); | |
573f2035 | 163 | if (rc) |
94a78b79 | 164 | return; |
94a78b79 VZ |
165 | |
166 | /* gunzip_outlen is in dwords */ | |
573f2035 | 167 | len = GUNZIP_OUTLEN(bp); |
94a78b79 | 168 | for (i = 0; i < len; i++) |
573f2035 EG |
169 | ((u32 *)GUNZIP_BUF(bp))[i] = |
170 | cpu_to_le32(((u32 *)GUNZIP_BUF(bp))[i]); | |
94a78b79 VZ |
171 | |
172 | bnx2x_write_big_buf_wb(bp, addr, len); | |
173 | } | |
174 | ||
175 | static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) | |
176 | { | |
94a78b79 | 177 | u16 op_start = |
573f2035 | 178 | INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_START)]; |
94a78b79 | 179 | u16 op_end = |
573f2035 | 180 | INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_END)]; |
94a78b79 | 181 | union init_op *op; |
573f2035 EG |
182 | int hw_wr; |
183 | u32 i, op_type, addr, len; | |
94a78b79 VZ |
184 | const u32 *data, *data_base; |
185 | ||
186 | /* If empty block */ | |
187 | if (op_start == op_end) | |
188 | return; | |
189 | ||
190 | if (CHIP_REV_IS_FPGA(bp)) | |
191 | hw_wr = OP_WR_FPGA; | |
192 | else if (CHIP_REV_IS_EMUL(bp)) | |
193 | hw_wr = OP_WR_EMUL; | |
194 | else | |
195 | hw_wr = OP_WR_ASIC; | |
196 | ||
573f2035 | 197 | data_base = INIT_DATA(bp); |
94a78b79 VZ |
198 | |
199 | for (i = op_start; i < op_end; i++) { | |
200 | ||
573f2035 | 201 | op = (union init_op *)&(INIT_OPS(bp)[i]); |
94a78b79 VZ |
202 | |
203 | op_type = op->str_wr.op; | |
204 | addr = op->str_wr.offset; | |
205 | len = op->str_wr.data_len; | |
206 | data = data_base + op->str_wr.data_off; | |
207 | ||
208 | /* HW/EMUL specific */ | |
573f2035 | 209 | if ((op_type > OP_WB) && (op_type == hw_wr)) |
94a78b79 VZ |
210 | op_type = OP_WR; |
211 | ||
212 | switch (op_type) { | |
213 | case OP_RD: | |
214 | REG_RD(bp, addr); | |
215 | break; | |
216 | case OP_WR: | |
217 | REG_WR(bp, addr, op->write.val); | |
218 | break; | |
219 | case OP_SW: | |
220 | bnx2x_init_str_wr(bp, addr, data, len); | |
221 | break; | |
222 | case OP_WB: | |
223 | bnx2x_init_wr_wb(bp, addr, data, len); | |
224 | break; | |
225 | case OP_SI: | |
226 | bnx2x_init_ind_wr(bp, addr, data, len); | |
227 | break; | |
228 | case OP_ZR: | |
229 | bnx2x_init_fill(bp, addr, 0, op->zero.len); | |
230 | break; | |
231 | case OP_ZP: | |
232 | bnx2x_init_wr_zp(bp, addr, len, | |
233 | op->str_wr.data_off); | |
234 | break; | |
235 | case OP_WR_64: | |
236 | bnx2x_init_wr_64(bp, addr, data, len); | |
237 | break; | |
238 | default: | |
239 | /* happens whenever an op is of a diff HW */ | |
94a78b79 VZ |
240 | break; |
241 | } | |
242 | } | |
243 | } | |
244 | ||
573f2035 EG |
245 | |
246 | /**************************************************************************** | |
247 | * PXP Arbiter | |
248 | ****************************************************************************/ | |
249 | /* | |
250 | * This code configures the PCI read/write arbiter | |
251 | * which implements a weighted round robin | |
252 | * between the virtual queues in the chip. | |
253 | * | |
254 | * The values were derived for each PCI max payload and max request size. | |
255 | * since max payload and max request size are only known at run time, | |
256 | * this is done as a separate init stage. | |
257 | */ | |
258 | ||
259 | #define NUM_WR_Q 13 | |
260 | #define NUM_RD_Q 29 | |
261 | #define MAX_RD_ORD 3 | |
262 | #define MAX_WR_ORD 2 | |
263 | ||
264 | /* configuration for one arbiter queue */ | |
265 | struct arb_line { | |
266 | int l; | |
267 | int add; | |
268 | int ubound; | |
269 | }; | |
270 | ||
271 | /* derived configuration for each read queue for each max request size */ | |
272 | static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = { | |
273 | /* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} }, | |
274 | { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} }, | |
275 | { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} }, | |
276 | { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} }, | |
277 | { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} }, | |
278 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} }, | |
279 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} }, | |
280 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} }, | |
281 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} }, | |
282 | /* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
283 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
284 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
285 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
286 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
287 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
288 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
289 | { {8, 64, 6}, {16, 64, 11}, {32, 64, 21}, {32, 64, 21} }, | |
290 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
291 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
292 | /* 20 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
293 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
294 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
295 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
296 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
297 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
298 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
299 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
300 | { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} }, | |
301 | { {8, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} } | |
302 | }; | |
303 | ||
304 | /* derived configuration for each write queue for each max request size */ | |
305 | static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = { | |
306 | /* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} }, | |
307 | { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} }, | |
308 | { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} }, | |
309 | { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} }, | |
310 | { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} }, | |
311 | { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} }, | |
312 | { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} }, | |
313 | { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} }, | |
314 | { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} }, | |
315 | /* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} }, | |
316 | { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} }, | |
317 | { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} }, | |
318 | { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} } | |
319 | }; | |
320 | ||
321 | /* register addresses for read queues */ | |
322 | static const struct arb_line read_arb_addr[NUM_RD_Q-1] = { | |
323 | /* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0, | |
324 | PXP2_REG_RQ_BW_RD_UBOUND0}, | |
325 | {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, | |
326 | PXP2_REG_PSWRQ_BW_UB1}, | |
327 | {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2, | |
328 | PXP2_REG_PSWRQ_BW_UB2}, | |
329 | {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3, | |
330 | PXP2_REG_PSWRQ_BW_UB3}, | |
331 | {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4, | |
332 | PXP2_REG_RQ_BW_RD_UBOUND4}, | |
333 | {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5, | |
334 | PXP2_REG_RQ_BW_RD_UBOUND5}, | |
335 | {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6, | |
336 | PXP2_REG_PSWRQ_BW_UB6}, | |
337 | {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7, | |
338 | PXP2_REG_PSWRQ_BW_UB7}, | |
339 | {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8, | |
340 | PXP2_REG_PSWRQ_BW_UB8}, | |
341 | /* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9, | |
342 | PXP2_REG_PSWRQ_BW_UB9}, | |
343 | {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10, | |
344 | PXP2_REG_PSWRQ_BW_UB10}, | |
345 | {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11, | |
346 | PXP2_REG_PSWRQ_BW_UB11}, | |
347 | {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12, | |
348 | PXP2_REG_RQ_BW_RD_UBOUND12}, | |
349 | {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13, | |
350 | PXP2_REG_RQ_BW_RD_UBOUND13}, | |
351 | {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14, | |
352 | PXP2_REG_RQ_BW_RD_UBOUND14}, | |
353 | {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15, | |
354 | PXP2_REG_RQ_BW_RD_UBOUND15}, | |
355 | {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16, | |
356 | PXP2_REG_RQ_BW_RD_UBOUND16}, | |
357 | {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17, | |
358 | PXP2_REG_RQ_BW_RD_UBOUND17}, | |
359 | {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18, | |
360 | PXP2_REG_RQ_BW_RD_UBOUND18}, | |
361 | /* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19, | |
362 | PXP2_REG_RQ_BW_RD_UBOUND19}, | |
363 | {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20, | |
364 | PXP2_REG_RQ_BW_RD_UBOUND20}, | |
365 | {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22, | |
366 | PXP2_REG_RQ_BW_RD_UBOUND22}, | |
367 | {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23, | |
368 | PXP2_REG_RQ_BW_RD_UBOUND23}, | |
369 | {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24, | |
370 | PXP2_REG_RQ_BW_RD_UBOUND24}, | |
371 | {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25, | |
372 | PXP2_REG_RQ_BW_RD_UBOUND25}, | |
373 | {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26, | |
374 | PXP2_REG_RQ_BW_RD_UBOUND26}, | |
375 | {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27, | |
376 | PXP2_REG_RQ_BW_RD_UBOUND27}, | |
377 | {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28, | |
378 | PXP2_REG_PSWRQ_BW_UB28} | |
379 | }; | |
380 | ||
381 | /* register addresses for write queues */ | |
382 | static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { | |
383 | /* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, | |
384 | PXP2_REG_PSWRQ_BW_UB1}, | |
385 | {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2, | |
386 | PXP2_REG_PSWRQ_BW_UB2}, | |
387 | {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3, | |
388 | PXP2_REG_PSWRQ_BW_UB3}, | |
389 | {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6, | |
390 | PXP2_REG_PSWRQ_BW_UB6}, | |
391 | {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7, | |
392 | PXP2_REG_PSWRQ_BW_UB7}, | |
393 | {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8, | |
394 | PXP2_REG_PSWRQ_BW_UB8}, | |
395 | {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9, | |
396 | PXP2_REG_PSWRQ_BW_UB9}, | |
397 | {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10, | |
398 | PXP2_REG_PSWRQ_BW_UB10}, | |
399 | {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11, | |
400 | PXP2_REG_PSWRQ_BW_UB11}, | |
401 | /* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28, | |
402 | PXP2_REG_PSWRQ_BW_UB28}, | |
403 | {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29, | |
404 | PXP2_REG_RQ_BW_WR_UBOUND29}, | |
405 | {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30, | |
406 | PXP2_REG_RQ_BW_WR_UBOUND30} | |
407 | }; | |
408 | ||
409 | static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order) | |
94a78b79 | 410 | { |
94a78b79 VZ |
411 | u32 val, i; |
412 | ||
94a78b79 VZ |
413 | if (r_order > MAX_RD_ORD) { |
414 | DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", | |
415 | r_order, MAX_RD_ORD); | |
416 | r_order = MAX_RD_ORD; | |
417 | } | |
418 | if (w_order > MAX_WR_ORD) { | |
419 | DP(NETIF_MSG_HW, "write order of %d order adjusted to %d\n", | |
420 | w_order, MAX_WR_ORD); | |
421 | w_order = MAX_WR_ORD; | |
422 | } | |
423 | if (CHIP_REV_IS_FPGA(bp)) { | |
424 | DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n"); | |
425 | w_order = 0; | |
426 | } | |
427 | DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); | |
428 | ||
429 | for (i = 0; i < NUM_RD_Q-1; i++) { | |
430 | REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l); | |
431 | REG_WR(bp, read_arb_addr[i].add, | |
432 | read_arb_data[i][r_order].add); | |
433 | REG_WR(bp, read_arb_addr[i].ubound, | |
434 | read_arb_data[i][r_order].ubound); | |
435 | } | |
436 | ||
437 | for (i = 0; i < NUM_WR_Q-1; i++) { | |
438 | if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) || | |
439 | (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) { | |
440 | ||
441 | REG_WR(bp, write_arb_addr[i].l, | |
442 | write_arb_data[i][w_order].l); | |
443 | ||
444 | REG_WR(bp, write_arb_addr[i].add, | |
445 | write_arb_data[i][w_order].add); | |
446 | ||
447 | REG_WR(bp, write_arb_addr[i].ubound, | |
448 | write_arb_data[i][w_order].ubound); | |
449 | } else { | |
450 | ||
451 | val = REG_RD(bp, write_arb_addr[i].l); | |
452 | REG_WR(bp, write_arb_addr[i].l, | |
453 | val | (write_arb_data[i][w_order].l << 10)); | |
454 | ||
455 | val = REG_RD(bp, write_arb_addr[i].add); | |
456 | REG_WR(bp, write_arb_addr[i].add, | |
457 | val | (write_arb_data[i][w_order].add << 10)); | |
458 | ||
459 | val = REG_RD(bp, write_arb_addr[i].ubound); | |
460 | REG_WR(bp, write_arb_addr[i].ubound, | |
461 | val | (write_arb_data[i][w_order].ubound << 7)); | |
462 | } | |
463 | } | |
464 | ||
465 | val = write_arb_data[NUM_WR_Q-1][w_order].add; | |
466 | val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10; | |
467 | val += write_arb_data[NUM_WR_Q-1][w_order].l << 17; | |
468 | REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val); | |
469 | ||
470 | val = read_arb_data[NUM_RD_Q-1][r_order].add; | |
471 | val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10; | |
472 | val += read_arb_data[NUM_RD_Q-1][r_order].l << 17; | |
473 | REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val); | |
474 | ||
475 | REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order); | |
476 | REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order); | |
477 | REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order); | |
478 | REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order); | |
479 | ||
480 | if (r_order == MAX_RD_ORD) | |
481 | REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); | |
482 | ||
483 | REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); | |
484 | ||
485 | if (CHIP_IS_E1H(bp)) { | |
573f2035 EG |
486 | /* MPS w_order optimal TH presently TH |
487 | * 128 0 0 2 | |
488 | * 256 1 1 3 | |
489 | * >=512 2 2 3 | |
490 | */ | |
94a78b79 VZ |
491 | val = ((w_order == 0) ? 2 : 3); |
492 | REG_WR(bp, PXP2_REG_WR_HC_MPS, val); | |
493 | REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); | |
494 | REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val); | |
495 | REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val); | |
496 | REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val); | |
497 | REG_WR(bp, PXP2_REG_WR_QM_MPS, val); | |
498 | REG_WR(bp, PXP2_REG_WR_TM_MPS, val); | |
499 | REG_WR(bp, PXP2_REG_WR_SRC_MPS, val); | |
500 | REG_WR(bp, PXP2_REG_WR_DBG_MPS, val); | |
501 | REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ | |
502 | REG_WR(bp, PXP2_REG_WR_CDU_MPS, val); | |
503 | } | |
504 | } | |
505 | ||
94a78b79 | 506 | #endif /* BNX2X_INIT_OPS_H */ |