aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorEilon Greenstein <eilong@broadcom.com>2008-06-23 23:29:02 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-23 23:29:02 -0400
commitad8d394804b355bc623decc50748cd01dbc0783b (patch)
treebe2d1c7fc15fc6e1bd17a7d87c697254407fa865 /drivers/net/bnx2x_main.c
parentc18487ee24381b40df3b8b4f54dd13ee9367a1ce (diff)
bnx2x: New init infrastructure
This new initialization code supports the 57711 HW. It also supports the emulation and FPGA for the 57711 and 57710 initializations values (very small amount of code which is very helpful in the lab - less than 30 lines). The initialization is done via DMAE after the DMAE block is ready - before it is ready, some of the initialization is done via PCI configuration transactions (referred to as indirect write). A mutex to protect the DMAE from being overlapped was added. There are few new registers which needs to be initialized by SW - the full comment for those registers is added to the register file. A place holder for the 57711 (referred to as E1H) microcode was added- the microcode itself is too big and it is split over the following 4 patches Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c166
1 files changed, 103 insertions, 63 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 7b547f03b565..efa942688f84 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -137,7 +137,6 @@ static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val)
137 PCICFG_VENDOR_ID_OFFSET); 137 PCICFG_VENDOR_ID_OFFSET);
138} 138}
139 139
140#ifdef BNX2X_IND_RD
141static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) 140static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
142{ 141{
143 u32 val; 142 u32 val;
@@ -149,7 +148,6 @@ static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr)
149 148
150 return val; 149 return val;
151} 150}
152#endif
153 151
154static const u32 dmae_reg_go_c[] = { 152static const u32 dmae_reg_go_c[] = {
155 DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3, 153 DMAE_REG_GO_C0, DMAE_REG_GO_C1, DMAE_REG_GO_C2, DMAE_REG_GO_C3,
@@ -169,19 +167,29 @@ static void bnx2x_post_dmae(struct bnx2x *bp, struct dmae_command *dmae,
169 for (i = 0; i < (sizeof(struct dmae_command)/4); i++) { 167 for (i = 0; i < (sizeof(struct dmae_command)/4); i++) {
170 REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i)); 168 REG_WR(bp, cmd_offset + i*4, *(((u32 *)dmae) + i));
171 169
172/* DP(NETIF_MSG_DMAE, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n", 170 DP(BNX2X_MSG_OFF, "DMAE cmd[%d].%d (0x%08x) : 0x%08x\n",
173 idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i)); */ 171 idx, i, cmd_offset + i*4, *(((u32 *)dmae) + i));
174 } 172 }
175 REG_WR(bp, dmae_reg_go_c[idx], 1); 173 REG_WR(bp, dmae_reg_go_c[idx], 1);
176} 174}
177 175
178void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, 176void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
179 u32 dst_addr, u32 len32) 177 u32 len32)
180{ 178{
181 struct dmae_command *dmae = &bp->dmae; 179 struct dmae_command *dmae = &bp->init_dmae;
182 int port = bp->port;
183 u32 *wb_comp = bnx2x_sp(bp, wb_comp); 180 u32 *wb_comp = bnx2x_sp(bp, wb_comp);
184 int timeout = 200; 181 int cnt = 200;
182
183 if (!bp->dmae_ready) {
184 u32 *data = bnx2x_sp(bp, wb_data[0]);
185
186 DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)"
187 " using indirect\n", dst_addr, len32);
188 bnx2x_init_ind_wr(bp, dst_addr, data, len32);
189 return;
190 }
191
192 mutex_lock(&bp->dmae_mutex);
185 193
186 memset(dmae, 0, sizeof(struct dmae_command)); 194 memset(dmae, 0, sizeof(struct dmae_command));
187 195
@@ -193,7 +201,7 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
193#else 201#else
194 DMAE_CMD_ENDIANITY_DW_SWAP | 202 DMAE_CMD_ENDIANITY_DW_SWAP |
195#endif 203#endif
196 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 204 (bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
197 dmae->src_addr_lo = U64_LO(dma_addr); 205 dmae->src_addr_lo = U64_LO(dma_addr);
198 dmae->src_addr_hi = U64_HI(dma_addr); 206 dmae->src_addr_hi = U64_HI(dma_addr);
199 dmae->dst_addr_lo = dst_addr >> 2; 207 dmae->dst_addr_lo = dst_addr >> 2;
@@ -201,48 +209,62 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr,
201 dmae->len = len32; 209 dmae->len = len32;
202 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); 210 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
203 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); 211 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
204 dmae->comp_val = BNX2X_WB_COMP_VAL; 212 dmae->comp_val = DMAE_COMP_VAL;
205 213
206/* 214 DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
207 DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
208 DP_LEVEL "src_addr [%x:%08x] len [%d *4] " 215 DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
209 "dst_addr [%x:%08x (%08x)]\n" 216 "dst_addr [%x:%08x (%08x)]\n"
210 DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", 217 DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
211 dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, 218 dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
212 dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr, 219 dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, dst_addr,
213 dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val); 220 dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
214*/ 221 DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
215/*
216 DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
217 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], 222 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
218 bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); 223 bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
219*/
220 224
221 *wb_comp = 0; 225 *wb_comp = 0;
222 226
223 bnx2x_post_dmae(bp, dmae, port * 8); 227 bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
224 228
225 udelay(5); 229 udelay(5);
226 /* adjust timeout for emulation/FPGA */ 230
227 if (CHIP_REV_IS_SLOW(bp)) 231 while (*wb_comp != DMAE_COMP_VAL) {
228 timeout *= 100; 232 DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp);
229 while (*wb_comp != BNX2X_WB_COMP_VAL) { 233
230/* DP(NETIF_MSG_DMAE, "wb_comp 0x%08x\n", *wb_comp); */ 234 /* adjust delay for emulation/FPGA */
231 udelay(5); 235 if (CHIP_REV_IS_SLOW(bp))
232 if (!timeout) { 236 msleep(100);
237 else
238 udelay(5);
239
240 if (!cnt) {
233 BNX2X_ERR("dmae timeout!\n"); 241 BNX2X_ERR("dmae timeout!\n");
234 break; 242 break;
235 } 243 }
236 timeout--; 244 cnt--;
237 } 245 }
246
247 mutex_unlock(&bp->dmae_mutex);
238} 248}
239 249
240void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) 250void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
241{ 251{
242 struct dmae_command *dmae = &bp->dmae; 252 struct dmae_command *dmae = &bp->init_dmae;
243 int port = bp->port;
244 u32 *wb_comp = bnx2x_sp(bp, wb_comp); 253 u32 *wb_comp = bnx2x_sp(bp, wb_comp);
245 int timeout = 200; 254 int cnt = 200;
255
256 if (!bp->dmae_ready) {
257 u32 *data = bnx2x_sp(bp, wb_data[0]);
258 int i;
259
260 DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)"
261 " using indirect\n", src_addr, len32);
262 for (i = 0; i < len32; i++)
263 data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4);
264 return;
265 }
266
267 mutex_lock(&bp->dmae_mutex);
246 268
247 memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4); 269 memset(bnx2x_sp(bp, wb_data[0]), 0, sizeof(u32) * 4);
248 memset(dmae, 0, sizeof(struct dmae_command)); 270 memset(dmae, 0, sizeof(struct dmae_command));
@@ -255,7 +277,7 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
255#else 277#else
256 DMAE_CMD_ENDIANITY_DW_SWAP | 278 DMAE_CMD_ENDIANITY_DW_SWAP |
257#endif 279#endif
258 (port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0)); 280 (bp->port ? DMAE_CMD_PORT_1 : DMAE_CMD_PORT_0));
259 dmae->src_addr_lo = src_addr >> 2; 281 dmae->src_addr_lo = src_addr >> 2;
260 dmae->src_addr_hi = 0; 282 dmae->src_addr_hi = 0;
261 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data)); 283 dmae->dst_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_data));
@@ -263,38 +285,64 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32)
263 dmae->len = len32; 285 dmae->len = len32;
264 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp)); 286 dmae->comp_addr_lo = U64_LO(bnx2x_sp_mapping(bp, wb_comp));
265 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp)); 287 dmae->comp_addr_hi = U64_HI(bnx2x_sp_mapping(bp, wb_comp));
266 dmae->comp_val = BNX2X_WB_COMP_VAL; 288 dmae->comp_val = DMAE_COMP_VAL;
267 289
268/* 290 DP(BNX2X_MSG_OFF, "dmae: opcode 0x%08x\n"
269 DP(NETIF_MSG_DMAE, "dmae: opcode 0x%08x\n"
270 DP_LEVEL "src_addr [%x:%08x] len [%d *4] " 291 DP_LEVEL "src_addr [%x:%08x] len [%d *4] "
271 "dst_addr [%x:%08x (%08x)]\n" 292 "dst_addr [%x:%08x (%08x)]\n"
272 DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n", 293 DP_LEVEL "comp_addr [%x:%08x] comp_val 0x%08x\n",
273 dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo, 294 dmae->opcode, dmae->src_addr_hi, dmae->src_addr_lo,
274 dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr, 295 dmae->len, dmae->dst_addr_hi, dmae->dst_addr_lo, src_addr,
275 dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val); 296 dmae->comp_addr_hi, dmae->comp_addr_lo, dmae->comp_val);
276*/
277 297
278 *wb_comp = 0; 298 *wb_comp = 0;
279 299
280 bnx2x_post_dmae(bp, dmae, port * 8); 300 bnx2x_post_dmae(bp, dmae, (bp->port)*MAX_DMAE_C_PER_PORT);
281 301
282 udelay(5); 302 udelay(5);
283 while (*wb_comp != BNX2X_WB_COMP_VAL) { 303
284 udelay(5); 304 while (*wb_comp != DMAE_COMP_VAL) {
285 if (!timeout) { 305
306 /* adjust delay for emulation/FPGA */
307 if (CHIP_REV_IS_SLOW(bp))
308 msleep(100);
309 else
310 udelay(5);
311
312 if (!cnt) {
286 BNX2X_ERR("dmae timeout!\n"); 313 BNX2X_ERR("dmae timeout!\n");
287 break; 314 break;
288 } 315 }
289 timeout--; 316 cnt--;
290 } 317 }
291/* 318 DP(BNX2X_MSG_OFF, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
292 DP(NETIF_MSG_DMAE, "data [0x%08x 0x%08x 0x%08x 0x%08x]\n",
293 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1], 319 bp->slowpath->wb_data[0], bp->slowpath->wb_data[1],
294 bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]); 320 bp->slowpath->wb_data[2], bp->slowpath->wb_data[3]);
295*/ 321
322 mutex_unlock(&bp->dmae_mutex);
323}
324
325/* used only for slowpath so not inlined */
326static void bnx2x_wb_wr(struct bnx2x *bp, int reg, u32 val_hi, u32 val_lo)
327{
328 u32 wb_write[2];
329
330 wb_write[0] = val_hi;
331 wb_write[1] = val_lo;
332 REG_WR_DMAE(bp, reg, wb_write, 2);
296} 333}
297 334
335#ifdef USE_WB_RD
336static u64 bnx2x_wb_rd(struct bnx2x *bp, int reg)
337{
338 u32 wb_data[2];
339
340 REG_RD_DMAE(bp, reg, wb_data, 2);
341
342 return HILO_U64(wb_data[0], wb_data[1]);
343}
344#endif
345
298static int bnx2x_mc_assert(struct bnx2x *bp) 346static int bnx2x_mc_assert(struct bnx2x *bp)
299{ 347{
300 int i, j, rc = 0; 348 int i, j, rc = 0;
@@ -3438,17 +3486,12 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
3438 int count, i; 3486 int count, i;
3439 u32 val = 0; 3487 u32 val = 0;
3440 3488
3441 switch (CHIP_REV(bp)) { 3489 if (CHIP_REV_IS_FPGA(bp))
3442 case CHIP_REV_EMUL:
3443 factor = 200;
3444 break;
3445 case CHIP_REV_FPGA:
3446 factor = 120; 3490 factor = 120;
3447 break; 3491 else if (CHIP_REV_IS_EMUL(bp))
3448 default: 3492 factor = 200;
3493 else
3449 factor = 1; 3494 factor = 1;
3450 break;
3451 }
3452 3495
3453 DP(NETIF_MSG_HW, "start part1\n"); 3496 DP(NETIF_MSG_HW, "start part1\n");
3454 3497
@@ -3777,10 +3820,14 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
3777 bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END); 3820 bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
3778 bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END); 3821 bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
3779 3822
3780 bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); 3823 bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0,
3781 bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); 3824 STORM_INTMEM_SIZE_E1);
3782 bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); 3825 bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0,
3783 bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE); 3826 STORM_INTMEM_SIZE_E1);
3827 bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0,
3828 STORM_INTMEM_SIZE_E1);
3829 bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0,
3830 STORM_INTMEM_SIZE_E1);
3784 3831
3785 bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END); 3832 bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
3786 bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END); 3833 bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
@@ -3990,8 +4037,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
3990#endif 4037#endif
3991 /* Port DQ comes here */ 4038 /* Port DQ comes here */
3992 /* Port BRB1 comes here */ 4039 /* Port BRB1 comes here */
3993 bnx2x_init_block(bp, func ? PRS_PORT1_START : PRS_PORT0_START, 4040 /* Port PRS comes here */
3994 func ? PRS_PORT1_END : PRS_PORT0_END);
3995 /* Port TSDM comes here */ 4041 /* Port TSDM comes here */
3996 /* Port CSDM comes here */ 4042 /* Port CSDM comes here */
3997 /* Port USDM comes here */ 4043 /* Port USDM comes here */
@@ -7264,12 +7310,6 @@ static int __devinit bnx2x_init_board(struct pci_dev *pdev,
7264 7310
7265 bnx2x_get_hwinfo(bp); 7311 bnx2x_get_hwinfo(bp);
7266 7312
7267 if (CHIP_REV(bp) == CHIP_REV_FPGA) {
7268 printk(KERN_ERR PFX "FPGA detected. MCP disabled,"
7269 " will only init first device\n");
7270 onefunc = 1;
7271 nomcp = 1;
7272 }
7273 7313
7274 if (nomcp) { 7314 if (nomcp) {
7275 printk(KERN_ERR PFX "MCP disabled, will only" 7315 printk(KERN_ERR PFX "MCP disabled, will only"