aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_init_ops.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x_init_ops.h')
-rw-r--r--drivers/net/bnx2x_init_ops.h419
1 files changed, 239 insertions, 180 deletions
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
index 32552b9366cb..38b970a14fd7 100644
--- a/drivers/net/bnx2x_init_ops.h
+++ b/drivers/net/bnx2x_init_ops.h
@@ -11,85 +11,68 @@
11 * Maintained by: Eilon Greenstein <eilong@broadcom.com> 11 * Maintained by: Eilon Greenstein <eilong@broadcom.com>
12 * Written by: Vladislav Zolotarov <vladz@broadcom.com> 12 * Written by: Vladislav Zolotarov <vladz@broadcom.com>
13 */ 13 */
14
14#ifndef BNX2X_INIT_OPS_H 15#ifndef BNX2X_INIT_OPS_H
15#define BNX2X_INIT_OPS_H 16#define BNX2X_INIT_OPS_H
16 17
17static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
18static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len); 18static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
19 19
20
20static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, 21static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
21 u32 len) 22 u32 len)
22{ 23{
23 int i; 24 u32 i;
24 25
25 for (i = 0; i < len; i++) { 26 for (i = 0; i < len; i++)
26 REG_WR(bp, addr + i*4, data[i]); 27 REG_WR(bp, addr + i*4, data[i]);
27 if (!(i % 10000)) {
28 touch_softlockup_watchdog();
29 cpu_relax();
30 }
31 }
32} 28}
33 29
34static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, 30static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
35 u16 len) 31 u32 len)
36{ 32{
37 int i; 33 u32 i;
38 34
39 for (i = 0; i < len; i++) { 35 for (i = 0; i < len; i++)
40 REG_WR_IND(bp, addr + i*4, data[i]); 36 REG_WR_IND(bp, addr + i*4, data[i]);
41 if (!(i % 10000)) {
42 touch_softlockup_watchdog();
43 cpu_relax();
44 }
45 }
46} 37}
47 38
48static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) 39static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
49{ 40{
50 int offset = 0; 41 if (bp->dmae_ready)
51 42 bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
52 if (bp->dmae_ready) { 43 else
53 while (len > DMAE_LEN32_WR_MAX) { 44 bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len);
54 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
55 addr + offset, DMAE_LEN32_WR_MAX);
56 offset += DMAE_LEN32_WR_MAX * 4;
57 len -= DMAE_LEN32_WR_MAX;
58 }
59 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
60 addr + offset, len);
61 } else
62 bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
63} 45}
64 46
65static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) 47static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
66{ 48{
67 u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4)); 49 u32 buf_len = (((len*4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len*4));
68 u32 buf_len32 = buf_len / 4; 50 u32 buf_len32 = buf_len/4;
69 int i; 51 u32 i;
70 52
71 memset(bp->gunzip_buf, fill, buf_len); 53 memset(GUNZIP_BUF(bp), (u8)fill, buf_len);
72 54
73 for (i = 0; i < len; i += buf_len32) { 55 for (i = 0; i < len; i += buf_len32) {
74 u32 cur_len = min(buf_len32, len - i); 56 u32 cur_len = min(buf_len32, len - i);
75 57
76 bnx2x_write_big_buf(bp, addr + i * 4, cur_len); 58 bnx2x_write_big_buf(bp, addr + i*4, cur_len);
77 } 59 }
78} 60}
79 61
80static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, 62static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
81 u32 len64) 63 u32 len64)
82{ 64{
83 u32 buf_len32 = FW_BUF_SIZE / 4; 65 u32 buf_len32 = FW_BUF_SIZE/4;
84 u32 len = len64 * 2; 66 u32 len = len64*2;
85 u64 data64 = 0; 67 u64 data64 = 0;
86 int i; 68 u32 i;
87 69
88 /* 64 bit value is in a blob: first low DWORD, then high DWORD */ 70 /* 64 bit value is in a blob: first low DWORD, then high DWORD */
89 data64 = HILO_U64((*(data + 1)), (*data)); 71 data64 = HILO_U64((*(data + 1)), (*data));
72
90 len64 = min((u32)(FW_BUF_SIZE/8), len64); 73 len64 = min((u32)(FW_BUF_SIZE/8), len64);
91 for (i = 0; i < len64; i++) { 74 for (i = 0; i < len64; i++) {
92 u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i; 75 u64 *pdata = ((u64 *)(GUNZIP_BUF(bp))) + i;
93 76
94 *pdata = data64; 77 *pdata = data64;
95 } 78 }
@@ -97,7 +80,7 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
97 for (i = 0; i < len; i += buf_len32) { 80 for (i = 0; i < len; i += buf_len32) {
98 u32 cur_len = min(buf_len32, len - i); 81 u32 cur_len = min(buf_len32, len - i);
99 82
100 bnx2x_write_big_buf(bp, addr + i * 4, cur_len); 83 bnx2x_write_big_buf(bp, addr + i*4, cur_len);
101 } 84 }
102} 85}
103 86
@@ -118,97 +101,81 @@ static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
118static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data) 101static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
119{ 102{
120 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) 103 IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
121 data = bp->tsem_int_table_data; 104 data = INIT_TSEM_INT_TABLE_DATA(bp);
122 else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) 105 else
123 data = bp->csem_int_table_data; 106 IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
124 else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) 107 data = INIT_CSEM_INT_TABLE_DATA(bp);
125 data = bp->usem_int_table_data; 108 else
126 else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) 109 IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
127 data = bp->xsem_int_table_data; 110 data = INIT_USEM_INT_TABLE_DATA(bp);
128 else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) 111 else
129 data = bp->tsem_pram_data; 112 IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
130 else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) 113 data = INIT_XSEM_INT_TABLE_DATA(bp);
131 data = bp->csem_pram_data; 114 else
132 else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) 115 IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
133 data = bp->usem_pram_data; 116 data = INIT_TSEM_PRAM_DATA(bp);
134 else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) 117 else
135 data = bp->xsem_pram_data; 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);
136 126
137 return data; 127 return data;
138} 128}
139 129
140static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) 130static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
141{ 131{
142 int offset = 0; 132 if (bp->dmae_ready)
143 133 bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len);
144 if (bp->dmae_ready) { 134 else
145 while (len > DMAE_LEN32_WR_MAX) { 135 bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len);
146 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
147 addr + offset, DMAE_LEN32_WR_MAX);
148 offset += DMAE_LEN32_WR_MAX * 4;
149 len -= DMAE_LEN32_WR_MAX;
150 }
151 bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
152 addr + offset, len);
153 } else
154 bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
155} 136}
156 137
157static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, 138static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
158 u32 len) 139 u32 len)
159{ 140{
160 /* This is needed for NO_ZIP mode, currently supported 141 data = (const u32 *)bnx2x_sel_blob(bp, addr, (const u8 *)data);
161 in little endian mode only */
162 data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
163 142
164 if ((len * 4) > FW_BUF_SIZE) { 143 if (bp->dmae_ready)
165 BNX2X_ERR("LARGE DMAE OPERATION ! " 144 VIRT_WR_DMAE_LEN(bp, data, addr, len);
166 "addr 0x%x len 0x%x\n", addr, len*4); 145 else
167 return; 146 bnx2x_init_ind_wr(bp, addr, data, len);
168 }
169 memcpy(bp->gunzip_buf, data, len * 4);
170
171 bnx2x_write_big_buf_wb(bp, addr, len);
172} 147}
173 148
174static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, 149static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr, u32 len, u32 blob_off)
175 u32 len, u32 blob_off)
176{ 150{
177 int rc, i; 151 const u8 *data = NULL;
178 const u8 *data = NULL; 152 int rc;
153 u32 i;
179 154
180 data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off; 155 data = bnx2x_sel_blob(bp, addr, data) + blob_off*4;
181
182 if (data == NULL) {
183 panic("Blob not found for addr 0x%x\n", addr);
184 return;
185 }
186 156
187 rc = bnx2x_gunzip(bp, data, len); 157 rc = bnx2x_gunzip(bp, data, len);
188 if (rc) { 158 if (rc)
189 BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
190 BNX2X_ERR("blob_offset=0x%x\n", blob_off);
191 return; 159 return;
192 }
193 160
194 /* gunzip_outlen is in dwords */ 161 /* gunzip_outlen is in dwords */
195 len = bp->gunzip_outlen; 162 len = GUNZIP_OUTLEN(bp);
196 for (i = 0; i < len; i++) 163 for (i = 0; i < len; i++)
197 ((u32 *)bp->gunzip_buf)[i] = 164 ((u32 *)GUNZIP_BUF(bp))[i] =
198 cpu_to_le32(((u32 *)bp->gunzip_buf)[i]); 165 cpu_to_le32(((u32 *)GUNZIP_BUF(bp))[i]);
199 166
200 bnx2x_write_big_buf_wb(bp, addr, len); 167 bnx2x_write_big_buf_wb(bp, addr, len);
201} 168}
202 169
203static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage) 170static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
204{ 171{
205 int hw_wr, i;
206 u16 op_start = 172 u16 op_start =
207 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)]; 173 INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_START)];
208 u16 op_end = 174 u16 op_end =
209 bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)]; 175 INIT_OPS_OFFSETS(bp)[BLOCK_OPS_IDX(block, stage, STAGE_END)];
210 union init_op *op; 176 union init_op *op;
211 u32 op_type, addr, len; 177 int hw_wr;
178 u32 i, op_type, addr, len;
212 const u32 *data, *data_base; 179 const u32 *data, *data_base;
213 180
214 /* If empty block */ 181 /* If empty block */
@@ -222,11 +189,11 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
222 else 189 else
223 hw_wr = OP_WR_ASIC; 190 hw_wr = OP_WR_ASIC;
224 191
225 data_base = bp->init_data; 192 data_base = INIT_DATA(bp);
226 193
227 for (i = op_start; i < op_end; i++) { 194 for (i = op_start; i < op_end; i++) {
228 195
229 op = (union init_op *)&(bp->init_ops[i]); 196 op = (union init_op *)&(INIT_OPS(bp)[i]);
230 197
231 op_type = op->str_wr.op; 198 op_type = op->str_wr.op;
232 addr = op->str_wr.offset; 199 addr = op->str_wr.offset;
@@ -234,7 +201,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
234 data = data_base + op->str_wr.data_off; 201 data = data_base + op->str_wr.data_off;
235 202
236 /* HW/EMUL specific */ 203 /* HW/EMUL specific */
237 if (unlikely((op_type > OP_WB) && (op_type == hw_wr))) 204 if ((op_type > OP_WB) && (op_type == hw_wr))
238 op_type = OP_WR; 205 op_type = OP_WR;
239 206
240 switch (op_type) { 207 switch (op_type) {
@@ -265,35 +232,179 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
265 break; 232 break;
266 default: 233 default:
267 /* happens whenever an op is of a diff HW */ 234 /* happens whenever an op is of a diff HW */
268#if 0
269 DP(NETIF_MSG_HW, "skipping init operation "
270 "index %d[%d:%d]: type %d addr 0x%x "
271 "len %d(0x%x)\n",
272 i, op_start, op_end, op_type, addr, len, len);
273#endif
274 break; 235 break;
275 } 236 }
276 } 237 }
277} 238}
278 239
279/* PXP */ 240
280static void bnx2x_init_pxp(struct bnx2x *bp) 241/****************************************************************************
242* PXP Arbiter
243****************************************************************************/
244/*
245 * This code configures the PCI read/write arbiter
246 * which implements a weighted round robin
247 * between the virtual queues in the chip.
248 *
249 * The values were derived for each PCI max payload and max request size.
250 * since max payload and max request size are only known at run time,
251 * this is done as a separate init stage.
252 */
253
254#define NUM_WR_Q 13
255#define NUM_RD_Q 29
256#define MAX_RD_ORD 3
257#define MAX_WR_ORD 2
258
259/* configuration for one arbiter queue */
260struct arb_line {
261 int l;
262 int add;
263 int ubound;
264};
265
266/* derived configuration for each read queue for each max request size */
267static const struct arb_line read_arb_data[NUM_RD_Q][MAX_RD_ORD + 1] = {
268/* 1 */ { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
269 { {4, 8, 4}, {4, 8, 4}, {4, 8, 4}, {4, 8, 4} },
270 { {4, 3, 3}, {4, 3, 3}, {4, 3, 3}, {4, 3, 3} },
271 { {8, 3, 6}, {16, 3, 11}, {16, 3, 11}, {16, 3, 11} },
272 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25}, {64, 64, 41} },
273 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
274 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
275 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
276 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {64, 3, 41} },
277/* 10 */{ {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
278 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
279 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
280 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
281 { {8, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 21} },
282 { {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, 64, 6}, {16, 64, 11}, {32, 64, 21}, {32, 64, 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/* 20 */{ {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, 3, 6}, {16, 3, 11}, {32, 3, 21}, {32, 3, 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 { {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, 64, 25}, {16, 64, 41}, {32, 64, 81}, {64, 64, 120} }
297};
298
299/* derived configuration for each write queue for each max request size */
300static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = {
301/* 1 */ { {4, 6, 3}, {4, 6, 3}, {4, 6, 3} },
302 { {4, 2, 3}, {4, 2, 3}, {4, 2, 3} },
303 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
304 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
305 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
306 { {8, 2, 6}, {16, 2, 11}, {32, 2, 21} },
307 { {8, 64, 25}, {16, 64, 25}, {32, 64, 25} },
308 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
309 { {8, 2, 6}, {16, 2, 11}, {16, 2, 11} },
310/* 10 */{ {8, 9, 6}, {16, 9, 11}, {32, 9, 21} },
311 { {8, 47, 19}, {16, 47, 19}, {32, 47, 21} },
312 { {8, 9, 6}, {16, 9, 11}, {16, 9, 11} },
313 { {8, 64, 25}, {16, 64, 41}, {32, 64, 81} }
314};
315
316/* register addresses for read queues */
317static const struct arb_line read_arb_addr[NUM_RD_Q-1] = {
318/* 1 */ {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0,
319 PXP2_REG_RQ_BW_RD_UBOUND0},
320 {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
321 PXP2_REG_PSWRQ_BW_UB1},
322 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
323 PXP2_REG_PSWRQ_BW_UB2},
324 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
325 PXP2_REG_PSWRQ_BW_UB3},
326 {PXP2_REG_RQ_BW_RD_L4, PXP2_REG_RQ_BW_RD_ADD4,
327 PXP2_REG_RQ_BW_RD_UBOUND4},
328 {PXP2_REG_RQ_BW_RD_L5, PXP2_REG_RQ_BW_RD_ADD5,
329 PXP2_REG_RQ_BW_RD_UBOUND5},
330 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
331 PXP2_REG_PSWRQ_BW_UB6},
332 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
333 PXP2_REG_PSWRQ_BW_UB7},
334 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
335 PXP2_REG_PSWRQ_BW_UB8},
336/* 10 */{PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
337 PXP2_REG_PSWRQ_BW_UB9},
338 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
339 PXP2_REG_PSWRQ_BW_UB10},
340 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
341 PXP2_REG_PSWRQ_BW_UB11},
342 {PXP2_REG_RQ_BW_RD_L12, PXP2_REG_RQ_BW_RD_ADD12,
343 PXP2_REG_RQ_BW_RD_UBOUND12},
344 {PXP2_REG_RQ_BW_RD_L13, PXP2_REG_RQ_BW_RD_ADD13,
345 PXP2_REG_RQ_BW_RD_UBOUND13},
346 {PXP2_REG_RQ_BW_RD_L14, PXP2_REG_RQ_BW_RD_ADD14,
347 PXP2_REG_RQ_BW_RD_UBOUND14},
348 {PXP2_REG_RQ_BW_RD_L15, PXP2_REG_RQ_BW_RD_ADD15,
349 PXP2_REG_RQ_BW_RD_UBOUND15},
350 {PXP2_REG_RQ_BW_RD_L16, PXP2_REG_RQ_BW_RD_ADD16,
351 PXP2_REG_RQ_BW_RD_UBOUND16},
352 {PXP2_REG_RQ_BW_RD_L17, PXP2_REG_RQ_BW_RD_ADD17,
353 PXP2_REG_RQ_BW_RD_UBOUND17},
354 {PXP2_REG_RQ_BW_RD_L18, PXP2_REG_RQ_BW_RD_ADD18,
355 PXP2_REG_RQ_BW_RD_UBOUND18},
356/* 20 */{PXP2_REG_RQ_BW_RD_L19, PXP2_REG_RQ_BW_RD_ADD19,
357 PXP2_REG_RQ_BW_RD_UBOUND19},
358 {PXP2_REG_RQ_BW_RD_L20, PXP2_REG_RQ_BW_RD_ADD20,
359 PXP2_REG_RQ_BW_RD_UBOUND20},
360 {PXP2_REG_RQ_BW_RD_L22, PXP2_REG_RQ_BW_RD_ADD22,
361 PXP2_REG_RQ_BW_RD_UBOUND22},
362 {PXP2_REG_RQ_BW_RD_L23, PXP2_REG_RQ_BW_RD_ADD23,
363 PXP2_REG_RQ_BW_RD_UBOUND23},
364 {PXP2_REG_RQ_BW_RD_L24, PXP2_REG_RQ_BW_RD_ADD24,
365 PXP2_REG_RQ_BW_RD_UBOUND24},
366 {PXP2_REG_RQ_BW_RD_L25, PXP2_REG_RQ_BW_RD_ADD25,
367 PXP2_REG_RQ_BW_RD_UBOUND25},
368 {PXP2_REG_RQ_BW_RD_L26, PXP2_REG_RQ_BW_RD_ADD26,
369 PXP2_REG_RQ_BW_RD_UBOUND26},
370 {PXP2_REG_RQ_BW_RD_L27, PXP2_REG_RQ_BW_RD_ADD27,
371 PXP2_REG_RQ_BW_RD_UBOUND27},
372 {PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
373 PXP2_REG_PSWRQ_BW_UB28}
374};
375
376/* register addresses for write queues */
377static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
378/* 1 */ {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1,
379 PXP2_REG_PSWRQ_BW_UB1},
380 {PXP2_REG_PSWRQ_BW_L2, PXP2_REG_PSWRQ_BW_ADD2,
381 PXP2_REG_PSWRQ_BW_UB2},
382 {PXP2_REG_PSWRQ_BW_L3, PXP2_REG_PSWRQ_BW_ADD3,
383 PXP2_REG_PSWRQ_BW_UB3},
384 {PXP2_REG_PSWRQ_BW_L6, PXP2_REG_PSWRQ_BW_ADD6,
385 PXP2_REG_PSWRQ_BW_UB6},
386 {PXP2_REG_PSWRQ_BW_L7, PXP2_REG_PSWRQ_BW_ADD7,
387 PXP2_REG_PSWRQ_BW_UB7},
388 {PXP2_REG_PSWRQ_BW_L8, PXP2_REG_PSWRQ_BW_ADD8,
389 PXP2_REG_PSWRQ_BW_UB8},
390 {PXP2_REG_PSWRQ_BW_L9, PXP2_REG_PSWRQ_BW_ADD9,
391 PXP2_REG_PSWRQ_BW_UB9},
392 {PXP2_REG_PSWRQ_BW_L10, PXP2_REG_PSWRQ_BW_ADD10,
393 PXP2_REG_PSWRQ_BW_UB10},
394 {PXP2_REG_PSWRQ_BW_L11, PXP2_REG_PSWRQ_BW_ADD11,
395 PXP2_REG_PSWRQ_BW_UB11},
396/* 10 */{PXP2_REG_PSWRQ_BW_L28, PXP2_REG_PSWRQ_BW_ADD28,
397 PXP2_REG_PSWRQ_BW_UB28},
398 {PXP2_REG_RQ_BW_WR_L29, PXP2_REG_RQ_BW_WR_ADD29,
399 PXP2_REG_RQ_BW_WR_UBOUND29},
400 {PXP2_REG_RQ_BW_WR_L30, PXP2_REG_RQ_BW_WR_ADD30,
401 PXP2_REG_RQ_BW_WR_UBOUND30}
402};
403
404static void bnx2x_init_pxp_arb(struct bnx2x *bp, int r_order, int w_order)
281{ 405{
282 u16 devctl;
283 int r_order, w_order;
284 u32 val, i; 406 u32 val, i;
285 407
286 pci_read_config_word(bp->pdev,
287 bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
288 DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
289 w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
290 if (bp->mrrs == -1)
291 r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
292 else {
293 DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
294 r_order = bp->mrrs;
295 }
296
297 if (r_order > MAX_RD_ORD) { 408 if (r_order > MAX_RD_ORD) {
298 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n", 409 DP(NETIF_MSG_HW, "read order of %d order adjusted to %d\n",
299 r_order, MAX_RD_ORD); 410 r_order, MAX_RD_ORD);
@@ -367,6 +478,11 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
367 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); 478 REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
368 479
369 if (CHIP_IS_E1H(bp)) { 480 if (CHIP_IS_E1H(bp)) {
481 /* MPS w_order optimal TH presently TH
482 * 128 0 0 2
483 * 256 1 1 3
484 * >=512 2 2 3
485 */
370 val = ((w_order == 0) ? 2 : 3); 486 val = ((w_order == 0) ? 2 : 3);
371 REG_WR(bp, PXP2_REG_WR_HC_MPS, val); 487 REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
372 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val); 488 REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
@@ -382,61 +498,4 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
382 } 498 }
383} 499}
384 500
385/*****************************************************************************
386 * Description:
387 * Calculates crc 8 on a word value: polynomial 0-1-2-8
388 * Code was translated from Verilog.
389 ****************************************************************************/
390static u8 calc_crc8(u32 data, u8 crc)
391{
392 u8 D[32];
393 u8 NewCRC[8];
394 u8 C[8];
395 u8 crc_res;
396 u8 i;
397
398 /* split the data into 31 bits */
399 for (i = 0; i < 32; i++) {
400 D[i] = data & 1;
401 data = data >> 1;
402 }
403
404 /* split the crc into 8 bits */
405 for (i = 0; i < 8; i++) {
406 C[i] = crc & 1;
407 crc = crc >> 1;
408 }
409
410 NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
411 D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
412 C[6] ^ C[7];
413 NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
414 D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
415 D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
416 NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
417 D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
418 C[0] ^ C[1] ^ C[4] ^ C[5];
419 NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
420 D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
421 C[1] ^ C[2] ^ C[5] ^ C[6];
422 NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
423 D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
424 C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
425 NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
426 D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
427 C[3] ^ C[4] ^ C[7];
428 NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
429 D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
430 C[5];
431 NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
432 D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
433 C[6];
434
435 crc_res = 0;
436 for (i = 0; i < 8; i++)
437 crc_res |= (NewCRC[i] << i);
438
439 return crc_res;
440}
441
442#endif /* BNX2X_INIT_OPS_H */ 501#endif /* BNX2X_INIT_OPS_H */