diff options
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 166 |
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 | ||
141 | static u32 bnx2x_reg_rd_ind(struct bnx2x *bp, u32 addr) | 140 | static 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 | ||
154 | static const u32 dmae_reg_go_c[] = { | 152 | static 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 | ||
178 | void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, | 176 | void 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 | ||
240 | void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) | 250 | void 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 */ | ||
326 | static 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 | ||
336 | static 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 | |||
298 | static int bnx2x_mc_assert(struct bnx2x *bp) | 346 | static 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" |