diff options
Diffstat (limited to 'drivers/net/bnx2x_init.h')
| -rw-r--r-- | drivers/net/bnx2x_init.h | 352 |
1 files changed, 297 insertions, 55 deletions
diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h index 370686eef97c..4c7750789b62 100644 --- a/drivers/net/bnx2x_init.h +++ b/drivers/net/bnx2x_init.h | |||
| @@ -22,7 +22,8 @@ | |||
| 22 | #define INIT_ASIC 0x4 | 22 | #define INIT_ASIC 0x4 |
| 23 | #define INIT_HARDWARE 0x7 | 23 | #define INIT_HARDWARE 0x7 |
| 24 | 24 | ||
| 25 | #define STORM_INTMEM_SIZE (0x5800 / 4) | 25 | #define STORM_INTMEM_SIZE_E1 (0x5800 / 4) |
| 26 | #define STORM_INTMEM_SIZE_E1H (0x10000 / 4) | ||
| 26 | #define TSTORM_INTMEM_ADDR 0x1a0000 | 27 | #define TSTORM_INTMEM_ADDR 0x1a0000 |
| 27 | #define CSTORM_INTMEM_ADDR 0x220000 | 28 | #define CSTORM_INTMEM_ADDR 0x220000 |
| 28 | #define XSTORM_INTMEM_ADDR 0x2a0000 | 29 | #define XSTORM_INTMEM_ADDR 0x2a0000 |
| @@ -30,7 +31,7 @@ | |||
| 30 | 31 | ||
| 31 | 32 | ||
| 32 | /* Init operation types and structures */ | 33 | /* Init operation types and structures */ |
| 33 | 34 | /* Common for both E1 and E1H */ | |
| 34 | #define OP_RD 0x1 /* read single register */ | 35 | #define OP_RD 0x1 /* read single register */ |
| 35 | #define OP_WR 0x2 /* write single register */ | 36 | #define OP_WR 0x2 /* write single register */ |
| 36 | #define OP_IW 0x3 /* write single register using mailbox */ | 37 | #define OP_IW 0x3 /* write single register using mailbox */ |
| @@ -38,7 +39,37 @@ | |||
| 38 | #define OP_SI 0x5 /* copy a string using mailbox */ | 39 | #define OP_SI 0x5 /* copy a string using mailbox */ |
| 39 | #define OP_ZR 0x6 /* clear memory */ | 40 | #define OP_ZR 0x6 /* clear memory */ |
| 40 | #define OP_ZP 0x7 /* unzip then copy with DMAE */ | 41 | #define OP_ZP 0x7 /* unzip then copy with DMAE */ |
| 41 | #define OP_WB 0x8 /* copy a string using DMAE */ | 42 | #define OP_WR_64 0x8 /* write 64 bit pattern */ |
| 43 | #define OP_WB 0x9 /* copy a string using DMAE */ | ||
| 44 | |||
| 45 | /* Operation specific for E1 */ | ||
| 46 | #define OP_RD_E1 0xa /* read single register */ | ||
| 47 | #define OP_WR_E1 0xb /* write single register */ | ||
| 48 | #define OP_IW_E1 0xc /* write single register using mailbox */ | ||
| 49 | #define OP_SW_E1 0xd /* copy a string to the device */ | ||
| 50 | #define OP_SI_E1 0xe /* copy a string using mailbox */ | ||
| 51 | #define OP_ZR_E1 0xf /* clear memory */ | ||
| 52 | #define OP_ZP_E1 0x10 /* unzip then copy with DMAE */ | ||
| 53 | #define OP_WR_64_E1 0x11 /* write 64 bit pattern on E1 */ | ||
| 54 | #define OP_WB_E1 0x12 /* copy a string using DMAE */ | ||
| 55 | |||
| 56 | /* Operation specific for E1H */ | ||
| 57 | #define OP_RD_E1H 0x13 /* read single register */ | ||
| 58 | #define OP_WR_E1H 0x14 /* write single register */ | ||
| 59 | #define OP_IW_E1H 0x15 /* write single register using mailbox */ | ||
| 60 | #define OP_SW_E1H 0x16 /* copy a string to the device */ | ||
| 61 | #define OP_SI_E1H 0x17 /* copy a string using mailbox */ | ||
| 62 | #define OP_ZR_E1H 0x18 /* clear memory */ | ||
| 63 | #define OP_ZP_E1H 0x19 /* unzip then copy with DMAE */ | ||
| 64 | #define OP_WR_64_E1H 0x1a /* write 64 bit pattern on E1H */ | ||
| 65 | #define OP_WB_E1H 0x1b /* copy a string using DMAE */ | ||
| 66 | |||
| 67 | /* FPGA and EMUL specific operations */ | ||
| 68 | #define OP_WR_EMUL_E1H 0x1c /* write single register on E1H Emul */ | ||
| 69 | #define OP_WR_EMUL 0x1d /* write single register on Emulation */ | ||
| 70 | #define OP_WR_FPGA 0x1e /* write single register on FPGA */ | ||
| 71 | #define OP_WR_ASIC 0x1f /* write single register on ASIC */ | ||
| 72 | |||
| 42 | 73 | ||
| 43 | struct raw_op { | 74 | struct raw_op { |
| 44 | u32 op :8; | 75 | u32 op :8; |
| @@ -87,10 +118,6 @@ union init_op { | |||
| 87 | #include "bnx2x_init_values.h" | 118 | #include "bnx2x_init_values.h" |
| 88 | 119 | ||
| 89 | static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); | 120 | static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val); |
| 90 | |||
| 91 | static void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, | ||
| 92 | u32 dst_addr, u32 len32); | ||
| 93 | |||
| 94 | static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len); | 121 | static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len); |
| 95 | 122 | ||
| 96 | static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, | 123 | static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, |
| @@ -107,9 +134,6 @@ static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data, | |||
| 107 | } | 134 | } |
| 108 | } | 135 | } |
| 109 | 136 | ||
| 110 | #define INIT_MEM_WR(reg, data, reg_off, len) \ | ||
| 111 | bnx2x_init_str_wr(bp, reg + reg_off*4, data, len) | ||
| 112 | |||
| 113 | static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, | 137 | static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, |
| 114 | u16 len) | 138 | u16 len) |
| 115 | { | 139 | { |
| @@ -124,11 +148,117 @@ static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data, | |||
| 124 | } | 148 | } |
| 125 | } | 149 | } |
| 126 | 150 | ||
| 151 | static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len) | ||
| 152 | { | ||
| 153 | #ifdef USE_DMAE | ||
| 154 | int offset = 0; | ||
| 155 | |||
| 156 | if (bp->dmae_ready) { | ||
| 157 | while (len > DMAE_LEN32_WR_MAX) { | ||
| 158 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, | ||
| 159 | addr + offset, DMAE_LEN32_WR_MAX); | ||
| 160 | offset += DMAE_LEN32_WR_MAX * 4; | ||
| 161 | len -= DMAE_LEN32_WR_MAX; | ||
| 162 | } | ||
| 163 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, | ||
| 164 | addr + offset, len); | ||
| 165 | } else | ||
| 166 | bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); | ||
| 167 | #else | ||
| 168 | bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len); | ||
| 169 | #endif | ||
| 170 | } | ||
| 171 | |||
| 172 | static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) | ||
| 173 | { | ||
| 174 | if ((len * 4) > FW_BUF_SIZE) { | ||
| 175 | BNX2X_ERR("LARGE DMAE OPERATION ! addr 0x%x len 0x%x\n", | ||
| 176 | addr, len*4); | ||
| 177 | return; | ||
| 178 | } | ||
| 179 | memset(bp->gunzip_buf, fill, len * 4); | ||
| 180 | |||
| 181 | bnx2x_write_big_buf(bp, addr, len); | ||
| 182 | } | ||
| 183 | |||
| 184 | static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data, | ||
| 185 | u32 len64) | ||
| 186 | { | ||
| 187 | u32 buf_len32 = FW_BUF_SIZE/4; | ||
| 188 | u32 len = len64*2; | ||
| 189 | u64 data64 = 0; | ||
| 190 | int i; | ||
| 191 | |||
| 192 | /* 64 bit value is in a blob: first low DWORD, then high DWORD */ | ||
| 193 | data64 = HILO_U64((*(data + 1)), (*data)); | ||
| 194 | len64 = min((u32)(FW_BUF_SIZE/8), len64); | ||
| 195 | for (i = 0; i < len64; i++) { | ||
| 196 | u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i; | ||
| 197 | |||
| 198 | *pdata = data64; | ||
| 199 | } | ||
| 200 | |||
| 201 | for (i = 0; i < len; i += buf_len32) { | ||
| 202 | u32 cur_len = min(buf_len32, len - i); | ||
| 203 | |||
| 204 | bnx2x_write_big_buf(bp, addr + i * 4, cur_len); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | /********************************************************* | ||
| 209 | There are different blobs for each PRAM section. | ||
| 210 | In addition, each blob write operation is divided into a few operations | ||
| 211 | in order to decrease the amount of phys. contigious buffer needed. | ||
| 212 | Thus, when we select a blob the address may be with some offset | ||
| 213 | from the beginning of PRAM section. | ||
| 214 | The same holds for the INT_TABLE sections. | ||
| 215 | **********************************************************/ | ||
| 216 | #define IF_IS_INT_TABLE_ADDR(base, addr) \ | ||
| 217 | if (((base) <= (addr)) && ((base) + 0x400 >= (addr))) | ||
| 218 | |||
| 219 | #define IF_IS_PRAM_ADDR(base, addr) \ | ||
| 220 | if (((base) <= (addr)) && ((base) + 0x40000 >= (addr))) | ||
| 221 | |||
| 222 | static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1) | ||
| 223 | { | ||
| 224 | IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr) | ||
| 225 | data = is_e1 ? tsem_int_table_data_e1 : | ||
| 226 | tsem_int_table_data_e1h; | ||
| 227 | else | ||
| 228 | IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr) | ||
| 229 | data = is_e1 ? csem_int_table_data_e1 : | ||
| 230 | csem_int_table_data_e1h; | ||
| 231 | else | ||
| 232 | IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr) | ||
| 233 | data = is_e1 ? usem_int_table_data_e1 : | ||
| 234 | usem_int_table_data_e1h; | ||
| 235 | else | ||
| 236 | IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr) | ||
| 237 | data = is_e1 ? xsem_int_table_data_e1 : | ||
| 238 | xsem_int_table_data_e1h; | ||
| 239 | else | ||
| 240 | IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr) | ||
| 241 | data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h; | ||
| 242 | else | ||
| 243 | IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr) | ||
| 244 | data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h; | ||
| 245 | else | ||
| 246 | IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr) | ||
| 247 | data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h; | ||
| 248 | else | ||
| 249 | IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr) | ||
| 250 | data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h; | ||
| 251 | |||
| 252 | return data; | ||
| 253 | } | ||
| 254 | |||
| 127 | static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, | 255 | static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, |
| 128 | u32 len, int gunzip) | 256 | u32 len, int gunzip, int is_e1, u32 blob_off) |
| 129 | { | 257 | { |
| 130 | int offset = 0; | 258 | int offset = 0; |
| 131 | 259 | ||
| 260 | data = bnx2x_sel_blob(addr, data, is_e1) + blob_off; | ||
| 261 | |||
| 132 | if (gunzip) { | 262 | if (gunzip) { |
| 133 | int rc; | 263 | int rc; |
| 134 | #ifdef __BIG_ENDIAN | 264 | #ifdef __BIG_ENDIAN |
| @@ -143,64 +273,59 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data, | |||
| 143 | #endif | 273 | #endif |
| 144 | rc = bnx2x_gunzip(bp, (u8 *)data, len); | 274 | rc = bnx2x_gunzip(bp, (u8 *)data, len); |
| 145 | if (rc) { | 275 | if (rc) { |
| 146 | DP(NETIF_MSG_HW, "gunzip failed ! rc %d\n", rc); | 276 | BNX2X_ERR("gunzip failed ! rc %d\n", rc); |
| 147 | return; | 277 | return; |
| 148 | } | 278 | } |
| 149 | len = bp->gunzip_outlen; | 279 | len = bp->gunzip_outlen; |
| 150 | #ifdef __BIG_ENDIAN | 280 | #ifdef __BIG_ENDIAN |
| 151 | kfree(temp); | 281 | kfree(temp); |
| 152 | for (i = 0; i < len; i++) | 282 | for (i = 0; i < len; i++) |
| 153 | ((u32 *)bp->gunzip_buf)[i] = | 283 | ((u32 *)bp->gunzip_buf)[i] = |
| 154 | swab32(((u32 *)bp->gunzip_buf)[i]); | 284 | swab32(((u32 *)bp->gunzip_buf)[i]); |
| 155 | #endif | 285 | #endif |
| 156 | } else { | 286 | } else { |
| 157 | if ((len * 4) > FW_BUF_SIZE) { | 287 | if ((len * 4) > FW_BUF_SIZE) { |
| 158 | BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len*4); | 288 | BNX2X_ERR("LARGE DMAE OPERATION ! " |
| 289 | "addr 0x%x len 0x%x\n", addr, len*4); | ||
| 159 | return; | 290 | return; |
| 160 | } | 291 | } |
| 161 | memcpy(bp->gunzip_buf, data, len * 4); | 292 | memcpy(bp->gunzip_buf, data, len * 4); |
| 162 | } | 293 | } |
| 163 | 294 | ||
| 164 | while (len > DMAE_LEN32_MAX) { | 295 | if (bp->dmae_ready) { |
| 165 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, | 296 | while (len > DMAE_LEN32_WR_MAX) { |
| 166 | addr + offset, DMAE_LEN32_MAX); | 297 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, |
| 167 | offset += DMAE_LEN32_MAX * 4; | 298 | addr + offset, DMAE_LEN32_WR_MAX); |
| 168 | len -= DMAE_LEN32_MAX; | 299 | offset += DMAE_LEN32_WR_MAX * 4; |
| 169 | } | 300 | len -= DMAE_LEN32_WR_MAX; |
| 170 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len); | 301 | } |
| 171 | } | ||
| 172 | |||
| 173 | #define INIT_MEM_WB(reg, data, reg_off, len) \ | ||
| 174 | bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 0) | ||
| 175 | |||
| 176 | #define INIT_GUNZIP_DMAE(reg, data, reg_off, len) \ | ||
| 177 | bnx2x_init_wr_wb(bp, reg + reg_off*4, data, len, 1) | ||
| 178 | |||
| 179 | static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len) | ||
| 180 | { | ||
| 181 | int offset = 0; | ||
| 182 | |||
| 183 | if ((len * 4) > FW_BUF_SIZE) { | ||
| 184 | BNX2X_ERR("LARGE DMAE OPERATION ! len 0x%x\n", len * 4); | ||
| 185 | return; | ||
| 186 | } | ||
| 187 | memset(bp->gunzip_buf, fill, len * 4); | ||
| 188 | |||
| 189 | while (len > DMAE_LEN32_MAX) { | ||
| 190 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, | 302 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, |
| 191 | addr + offset, DMAE_LEN32_MAX); | 303 | addr + offset, len); |
| 192 | offset += DMAE_LEN32_MAX * 4; | 304 | } else |
| 193 | len -= DMAE_LEN32_MAX; | 305 | bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len); |
| 194 | } | ||
| 195 | bnx2x_write_dmae(bp, bp->gunzip_mapping + offset, addr + offset, len); | ||
| 196 | } | 306 | } |
| 197 | 307 | ||
| 198 | static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) | 308 | static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) |
| 199 | { | 309 | { |
| 200 | int i; | 310 | int is_e1 = CHIP_IS_E1(bp); |
| 311 | int is_e1h = CHIP_IS_E1H(bp); | ||
| 312 | int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h); | ||
| 313 | int hw_wr, i; | ||
| 201 | union init_op *op; | 314 | union init_op *op; |
| 202 | u32 op_type, addr, len; | 315 | u32 op_type, addr, len; |
| 203 | const u32 *data; | 316 | const u32 *data, *data_base; |
| 317 | |||
| 318 | if (CHIP_REV_IS_FPGA(bp)) | ||
| 319 | hw_wr = OP_WR_FPGA; | ||
| 320 | else if (CHIP_REV_IS_EMUL(bp)) | ||
| 321 | hw_wr = OP_WR_EMUL; | ||
| 322 | else | ||
| 323 | hw_wr = OP_WR_ASIC; | ||
| 324 | |||
| 325 | if (is_e1) | ||
| 326 | data_base = init_data_e1; | ||
| 327 | else /* CHIP_IS_E1H(bp) */ | ||
| 328 | data_base = init_data_e1h; | ||
| 204 | 329 | ||
| 205 | for (i = op_start; i < op_end; i++) { | 330 | for (i = op_start; i < op_end; i++) { |
| 206 | 331 | ||
| @@ -209,7 +334,30 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) | |||
| 209 | op_type = op->str_wr.op; | 334 | op_type = op->str_wr.op; |
| 210 | addr = op->str_wr.offset; | 335 | addr = op->str_wr.offset; |
| 211 | len = op->str_wr.data_len; | 336 | len = op->str_wr.data_len; |
| 212 | data = init_data + op->str_wr.data_off; | 337 | data = data_base + op->str_wr.data_off; |
| 338 | |||
| 339 | /* carefull! it must be in order */ | ||
| 340 | if (unlikely(op_type > OP_WB)) { | ||
| 341 | |||
| 342 | /* If E1 only */ | ||
| 343 | if (op_type <= OP_WB_E1) { | ||
| 344 | if (is_e1) | ||
| 345 | op_type -= (OP_RD_E1 - OP_RD); | ||
| 346 | |||
| 347 | /* If E1H only */ | ||
| 348 | } else if (op_type <= OP_WB_E1H) { | ||
| 349 | if (is_e1h) | ||
| 350 | op_type -= (OP_RD_E1H - OP_RD); | ||
| 351 | } | ||
| 352 | |||
| 353 | /* HW/EMUL specific */ | ||
| 354 | if (op_type == hw_wr) | ||
| 355 | op_type = OP_WR; | ||
| 356 | |||
| 357 | /* EMUL on E1H is special */ | ||
| 358 | if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h) | ||
| 359 | op_type = OP_WR; | ||
| 360 | } | ||
| 213 | 361 | ||
| 214 | switch (op_type) { | 362 | switch (op_type) { |
| 215 | case OP_RD: | 363 | case OP_RD: |
| @@ -222,7 +370,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) | |||
| 222 | bnx2x_init_str_wr(bp, addr, data, len); | 370 | bnx2x_init_str_wr(bp, addr, data, len); |
| 223 | break; | 371 | break; |
| 224 | case OP_WB: | 372 | case OP_WB: |
| 225 | bnx2x_init_wr_wb(bp, addr, data, len, 0); | 373 | bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0); |
| 226 | break; | 374 | break; |
| 227 | case OP_SI: | 375 | case OP_SI: |
| 228 | bnx2x_init_ind_wr(bp, addr, data, len); | 376 | bnx2x_init_ind_wr(bp, addr, data, len); |
| @@ -231,10 +379,21 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) | |||
| 231 | bnx2x_init_fill(bp, addr, 0, op->zero.len); | 379 | bnx2x_init_fill(bp, addr, 0, op->zero.len); |
| 232 | break; | 380 | break; |
| 233 | case OP_ZP: | 381 | case OP_ZP: |
| 234 | bnx2x_init_wr_wb(bp, addr, data, len, 1); | 382 | bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1, |
| 383 | op->str_wr.data_off); | ||
| 384 | break; | ||
| 385 | case OP_WR_64: | ||
| 386 | bnx2x_init_wr_64(bp, addr, data, len); | ||
| 235 | break; | 387 | break; |
| 236 | default: | 388 | default: |
| 237 | BNX2X_ERR("BAD init operation!\n"); | 389 | /* happens whenever an op is of a diff HW */ |
| 390 | #if 0 | ||
| 391 | DP(NETIF_MSG_HW, "skipping init operation " | ||
| 392 | "index %d[%d:%d]: type %d addr 0x%x " | ||
| 393 | "len %d(0x%x)\n", | ||
| 394 | i, op_start, op_end, op_type, addr, len, len); | ||
| 395 | #endif | ||
| 396 | break; | ||
| 238 | } | 397 | } |
| 239 | } | 398 | } |
| 240 | } | 399 | } |
| @@ -245,7 +404,7 @@ static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end) | |||
| 245 | ****************************************************************************/ | 404 | ****************************************************************************/ |
| 246 | /* | 405 | /* |
| 247 | * This code configures the PCI read/write arbiter | 406 | * This code configures the PCI read/write arbiter |
| 248 | * which implements a wighted round robin | 407 | * which implements a weighted round robin |
| 249 | * between the virtual queues in the chip. | 408 | * between the virtual queues in the chip. |
| 250 | * | 409 | * |
| 251 | * The values were derived for each PCI max payload and max request size. | 410 | * The values were derived for each PCI max payload and max request size. |
| @@ -315,7 +474,7 @@ static const struct arb_line write_arb_data[NUM_WR_Q][MAX_WR_ORD + 1] = { | |||
| 315 | {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} } | 474 | {{8 , 64 , 25}, {16 , 64 , 41}, {32 , 64 , 81} } |
| 316 | }; | 475 | }; |
| 317 | 476 | ||
| 318 | /* register adresses for read queues */ | 477 | /* register addresses for read queues */ |
| 319 | static const struct arb_line read_arb_addr[NUM_RD_Q-1] = { | 478 | static const struct arb_line read_arb_addr[NUM_RD_Q-1] = { |
| 320 | {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0, | 479 | {PXP2_REG_RQ_BW_RD_L0, PXP2_REG_RQ_BW_RD_ADD0, |
| 321 | PXP2_REG_RQ_BW_RD_UBOUND0}, | 480 | PXP2_REG_RQ_BW_RD_UBOUND0}, |
| @@ -375,7 +534,7 @@ static const struct arb_line read_arb_addr[NUM_RD_Q-1] = { | |||
| 375 | PXP2_REG_PSWRQ_BW_UB28} | 534 | PXP2_REG_PSWRQ_BW_UB28} |
| 376 | }; | 535 | }; |
| 377 | 536 | ||
| 378 | /* register adresses for wrtie queues */ | 537 | /* register addresses for write queues */ |
| 379 | static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { | 538 | static const struct arb_line write_arb_addr[NUM_WR_Q-1] = { |
| 380 | {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, | 539 | {PXP2_REG_PSWRQ_BW_L1, PXP2_REG_PSWRQ_BW_ADD1, |
| 381 | PXP2_REG_PSWRQ_BW_UB1}, | 540 | PXP2_REG_PSWRQ_BW_UB1}, |
| @@ -424,6 +583,10 @@ static void bnx2x_init_pxp(struct bnx2x *bp) | |||
| 424 | w_order, MAX_WR_ORD); | 583 | w_order, MAX_WR_ORD); |
| 425 | w_order = MAX_WR_ORD; | 584 | w_order = MAX_WR_ORD; |
| 426 | } | 585 | } |
| 586 | if (CHIP_REV_IS_FPGA(bp)) { | ||
| 587 | DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n"); | ||
| 588 | w_order = 0; | ||
| 589 | } | ||
| 427 | DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); | 590 | DP(NETIF_MSG_HW, "read order %d write order %d\n", r_order, w_order); |
| 428 | 591 | ||
| 429 | for (i = 0; i < NUM_RD_Q-1; i++) { | 592 | for (i = 0; i < NUM_RD_Q-1; i++) { |
| @@ -481,7 +644,20 @@ static void bnx2x_init_pxp(struct bnx2x *bp) | |||
| 481 | REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); | 644 | REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00); |
| 482 | 645 | ||
| 483 | REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); | 646 | REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order)); |
| 484 | REG_WR(bp, PXP2_REG_WR_DMAE_TH, (128 << w_order)/16); | 647 | |
| 648 | if (CHIP_IS_E1H(bp)) { | ||
| 649 | REG_WR(bp, PXP2_REG_WR_HC_MPS, w_order+1); | ||
| 650 | REG_WR(bp, PXP2_REG_WR_USDM_MPS, w_order+1); | ||
| 651 | REG_WR(bp, PXP2_REG_WR_CSDM_MPS, w_order+1); | ||
| 652 | REG_WR(bp, PXP2_REG_WR_TSDM_MPS, w_order+1); | ||
| 653 | REG_WR(bp, PXP2_REG_WR_XSDM_MPS, w_order+1); | ||
| 654 | REG_WR(bp, PXP2_REG_WR_QM_MPS, w_order+1); | ||
| 655 | REG_WR(bp, PXP2_REG_WR_TM_MPS, w_order+1); | ||
| 656 | REG_WR(bp, PXP2_REG_WR_SRC_MPS, w_order+1); | ||
| 657 | REG_WR(bp, PXP2_REG_WR_DBG_MPS, w_order+1); | ||
| 658 | REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */ | ||
| 659 | REG_WR(bp, PXP2_REG_WR_CDU_MPS, w_order+1); | ||
| 660 | } | ||
| 485 | } | 661 | } |
| 486 | 662 | ||
| 487 | 663 | ||
| @@ -564,6 +740,72 @@ static u8 calc_crc8(u32 data, u8 crc) | |||
| 564 | return crc_res; | 740 | return crc_res; |
| 565 | } | 741 | } |
| 566 | 742 | ||
| 743 | /* regiesers addresses are not in order | ||
| 744 | so these arrays help simplify the code */ | ||
| 745 | static const int cm_start[E1H_FUNC_MAX][9] = { | ||
| 746 | {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START, | ||
| 747 | XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START, | ||
| 748 | XSEM_FUNC0_START}, | ||
| 749 | {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START, | ||
| 750 | XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START, | ||
| 751 | XSEM_FUNC1_START}, | ||
| 752 | {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START, | ||
| 753 | XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START, | ||
| 754 | XSEM_FUNC2_START}, | ||
| 755 | {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START, | ||
| 756 | XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START, | ||
| 757 | XSEM_FUNC3_START}, | ||
| 758 | {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START, | ||
| 759 | XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START, | ||
| 760 | XSEM_FUNC4_START}, | ||
| 761 | {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START, | ||
| 762 | XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START, | ||
| 763 | XSEM_FUNC5_START}, | ||
| 764 | {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START, | ||
| 765 | XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START, | ||
| 766 | XSEM_FUNC6_START}, | ||
| 767 | {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START, | ||
| 768 | XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START, | ||
| 769 | XSEM_FUNC7_START} | ||
| 770 | }; | ||
| 771 | |||
| 772 | static const int cm_end[E1H_FUNC_MAX][9] = { | ||
| 773 | {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END, | ||
| 774 | XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END, | ||
| 775 | XSEM_FUNC0_END}, | ||
| 776 | {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END, | ||
| 777 | XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END, | ||
| 778 | XSEM_FUNC1_END}, | ||
| 779 | {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END, | ||
| 780 | XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END, | ||
| 781 | XSEM_FUNC2_END}, | ||
| 782 | {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END, | ||
| 783 | XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END, | ||
| 784 | XSEM_FUNC3_END}, | ||
| 785 | {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END, | ||
| 786 | XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END, | ||
| 787 | XSEM_FUNC4_END}, | ||
| 788 | {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END, | ||
| 789 | XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END, | ||
| 790 | XSEM_FUNC5_END}, | ||
| 791 | {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END, | ||
| 792 | XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END, | ||
| 793 | XSEM_FUNC6_END}, | ||
| 794 | {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END, | ||
| 795 | XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END, | ||
| 796 | XSEM_FUNC7_END}, | ||
| 797 | }; | ||
| 798 | |||
| 799 | static const int hc_limits[E1H_FUNC_MAX][2] = { | ||
| 800 | {HC_FUNC0_START, HC_FUNC0_END}, | ||
| 801 | {HC_FUNC1_START, HC_FUNC1_END}, | ||
| 802 | {HC_FUNC2_START, HC_FUNC2_END}, | ||
| 803 | {HC_FUNC3_START, HC_FUNC3_END}, | ||
| 804 | {HC_FUNC4_START, HC_FUNC4_END}, | ||
| 805 | {HC_FUNC5_START, HC_FUNC5_END}, | ||
| 806 | {HC_FUNC6_START, HC_FUNC6_END}, | ||
| 807 | {HC_FUNC7_START, HC_FUNC7_END} | ||
| 808 | }; | ||
| 567 | 809 | ||
| 568 | #endif /* BNX2X_INIT_H */ | 810 | #endif /* BNX2X_INIT_H */ |
| 569 | 811 | ||
