39 40enum { 41 IDT75P52100 = 4, 42 IDT75N43102 = 5 43}; 44 45/* DBGI command mode */ 46enum { 47 DBGI_MODE_MBUS = 0, 48 DBGI_MODE_IDT52100 = 5 49}; 50 51/* IDT 75P52100 commands */ 52#define IDT_CMD_READ 0 53#define IDT_CMD_WRITE 1 54#define IDT_CMD_SEARCH 2 55#define IDT_CMD_LEARN 3 56 57/* IDT LAR register address and value for 144-bit mode (low 32 bits) */ 58#define IDT_LAR_ADR0 0x180006 59#define IDT_LAR_MODE144 0xffff0000 60 61/* IDT SCR and SSR addresses (low 32 bits) */ 62#define IDT_SCR_ADR0 0x180000 63#define IDT_SSR0_ADR0 0x180002 64#define IDT_SSR1_ADR0 0x180004 65 66/* IDT GMR base address (low 32 bits) */ 67#define IDT_GMR_BASE_ADR0 0x180020 68 69/* IDT data and mask array base addresses (low 32 bits) */ 70#define IDT_DATARY_BASE_ADR0 0 71#define IDT_MSKARY_BASE_ADR0 0x80000 72 73/* IDT 75N43102 commands */ 74#define IDT4_CMD_SEARCH144 3 75#define IDT4_CMD_WRITE 4 76#define IDT4_CMD_READ 5 77 78/* IDT 75N43102 SCR address (low 32 bits) */ 79#define IDT4_SCR_ADR0 0x3 80 81/* IDT 75N43102 GMR base addresses (low 32 bits) */ 82#define IDT4_GMR_BASE0 0x10 83#define IDT4_GMR_BASE1 0x20 84#define IDT4_GMR_BASE2 0x30 85 86/* IDT 75N43102 data and mask array base addresses (low 32 bits) */ 87#define IDT4_DATARY_BASE_ADR0 0x1000000 88#define IDT4_MSKARY_BASE_ADR0 0x2000000 89 90#define MAX_WRITE_ATTEMPTS 5 91 92#define MAX_ROUTES 2048 93 94/* 95 * Issue a command to the TCAM and wait for its completion. The address and 96 * any data required by the command must have been setup by the caller. 97 */ 98static int mc5_cmd_write(adapter_t *adapter, u32 cmd) 99{ 100 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd); 101 return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS, 102 F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1); 103} 104 105static inline void dbgi_wr_addr3(adapter_t *adapter, u32 v1, u32 v2, u32 v3) 106{ 107 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1); 108 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2); 109 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3); 110} 111 112static inline void dbgi_wr_data3(adapter_t *adapter, u32 v1, u32 v2, u32 v3) 113{ 114 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1); 115 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2); 116 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3); 117} 118 119static inline void dbgi_rd_rsp3(adapter_t *adapter, u32 *v1, u32 *v2, u32 *v3) 120{ 121 *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0); 122 *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1); 123 *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2); 124} 125 126/* 127 * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM 128 * command cmd. The data to be written must have been set up by the caller. 129 * Returns -1 on failure, 0 on success. 130 */ 131static int mc5_write(adapter_t *adapter, u32 addr_lo, u32 cmd) 132{ 133 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo); 134 if (mc5_cmd_write(adapter, cmd) == 0) 135 return 0; 136 CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n", addr_lo); 137 return -1; 138} 139 140static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base, 141 u32 data_array_base, u32 write_cmd, 142 int addr_shift) 143{ 144 unsigned int i; 145 adapter_t *adap = mc5->adapter; 146 147 /* 148 * We need the size of the TCAM data and mask arrays in terms of 149 * 72-bit entries. 150 */ 151 unsigned int size72 = mc5->tcam_size; 152 unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX); 153 154 if (mc5->mode == MC5_MODE_144_BIT) { 155 size72 *= 2; /* 1 144-bit entry is 2 72-bit entries */ 156 server_base *= 2; 157 } 158 159 /* Clear the data array */ 160 dbgi_wr_data3(adap, 0, 0, 0); 161 for (i = 0; i < size72; i++) 162 if (mc5_write(adap, data_array_base + (i << addr_shift), 163 write_cmd)) 164 return -1; 165 166 /* Initialize the mask array. */ 167 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 168 for (i = 0; i < size72; i++) { 169 if (i == server_base) /* entering server or routing region */ 170 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0, 171 mc5->mode == MC5_MODE_144_BIT ? 172 0xfffffff9 : 0xfffffffd); 173 if (mc5_write(adap, mask_array_base + (i << addr_shift), 174 write_cmd)) 175 return -1; 176 } 177 return 0; 178} 179 180static int init_idt52100(struct mc5 *mc5) 181{ 182 int i; 183 adapter_t *adap = mc5->adapter; 184 185 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 186 V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15)); 187 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2); 188 189 /* 190 * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and 191 * GMRs 8-9 for ACK- and AOPEN searches. 192 */ 193 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE); 194 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE); 195 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH); 196 t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN); 197 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000); 198 t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN); 199 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH); 200 t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN); 201 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH); 202 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000); 203 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE); 204 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ); 205 206 /* Set DBGI command mode for IDT TCAM. */ 207 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 208 209 /* Set up LAR */ 210 dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0); 211 if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE)) 212 goto err; 213 214 /* Set up SSRs */ 215 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0); 216 if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) || 217 mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE)) 218 goto err; 219 220 /* Set up GMRs */ 221 for (i = 0; i < 32; ++i) { 222 if (i >= 12 && i < 15) 223 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 224 else if (i == 15) 225 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 226 else 227 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 228 229 if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE)) 230 goto err; 231 } 232 233 /* Set up SCR */ 234 dbgi_wr_data3(adap, 1, 0, 0); 235 if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE)) 236 goto err; 237 238 return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0, 239 IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0); 240 err: 241 return -EIO; 242} 243 244static int init_idt43102(struct mc5 *mc5) 245{ 246 int i; 247 adapter_t *adap = mc5->adapter; 248 249 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 250 adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) : 251 V_RDLAT(0xd) | V_SRCHLAT(0x12)); 252 253 /* 254 * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask 255 * for ACK- and AOPEN searches. 256 */ 257 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE); 258 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE); 259 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, 260 IDT4_CMD_SEARCH144 | 0x3800); 261 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144); 262 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800); 263 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800); 264 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800); 265 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE); 266 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ); 267 268 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3); 269 270 /* Set DBGI command mode for IDT TCAM. */ 271 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 272 273 /* Set up GMRs */ 274 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 275 for (i = 0; i < 7; ++i) 276 if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE)) 277 goto err; 278 279 for (i = 0; i < 4; ++i) 280 if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE)) 281 goto err; 282 283 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 284 if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) || 285 mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) || 286 mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE)) 287 goto err; 288 289 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 290 if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE)) 291 goto err; 292 293 /* Set up SCR */ 294 dbgi_wr_data3(adap, 0xf0000000, 0, 0); 295 if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE)) 296 goto err; 297 298 return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0, 299 IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1); 300 err: 301 return -EIO; 302} 303 304/* Put MC5 in DBGI mode. */ 305static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5) 306{ 307 t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, 308 V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN); 309} 310 311/* Put MC5 in M-Bus mode. */ 312static void mc5_dbgi_mode_disable(const struct mc5 *mc5) 313{ 314 t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, 315 V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | 316 V_COMPEN(mc5->mode == MC5_MODE_72_BIT) | 317 V_PRTYEN(mc5->parity_enabled) | F_MBUSEN); 318} 319 320/* 321 * Initialization that requires the OS and protocol layers to already 322 * be intialized goes here. 323 */ 324int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, 325 unsigned int nroutes) 326{ 327 u32 cfg; 328 int err; 329 unsigned int tcam_size = mc5->tcam_size; 330 adapter_t *adap = mc5->adapter; 331 332 if (tcam_size == 0) 333 return 0; 334 335 if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size) 336 return -EINVAL; 337 338 /* Reset the TCAM */ 339 cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE; 340 cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST; 341 t3_write_reg(adap, A_MC5_DB_CONFIG, cfg); 342 if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) { 343 CH_ERR(adap, "TCAM reset timed out\n"); 344 return -1; 345 } 346 347 t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes); 348 t3_write_reg(adap, A_MC5_DB_FILTER_TABLE, 349 tcam_size - nroutes - nfilters); 350 t3_write_reg(adap, A_MC5_DB_SERVER_INDEX, 351 tcam_size - nroutes - nfilters - nservers); 352 353 mc5->parity_enabled = 1; 354 355 /* All the TCAM addresses we access have only the low 32 bits non 0 */ 356 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0); 357 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0); 358 359 mc5_dbgi_mode_enable(mc5); 360 361 switch (mc5->part_type) { 362 case IDT75P52100: 363 err = init_idt52100(mc5); 364 break; 365 case IDT75N43102: 366 err = init_idt43102(mc5); 367 break; 368 default: 369 CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type); 370 err = -EINVAL; 371 break; 372 } 373 374 mc5_dbgi_mode_disable(mc5); 375 return err; 376} 377 378/* 379 * read_mc5_range - dump a part of the memory managed by MC5 380 * @mc5: the MC5 handle 381 * @start: the start address for the dump 382 * @n: number of 72-bit words to read 383 * @buf: result buffer 384 * 385 * Read n 72-bit words from MC5 memory from the given start location. 386 */ 387int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, 388 unsigned int n, u32 *buf) 389{ 390 u32 read_cmd; 391 int err = 0; 392 adapter_t *adap = mc5->adapter; 393 394 if (mc5->part_type == IDT75P52100) 395 read_cmd = IDT_CMD_READ; 396 else if (mc5->part_type == IDT75N43102) 397 read_cmd = IDT4_CMD_READ; 398 else 399 return -EINVAL; 400 401 mc5_dbgi_mode_enable(mc5); 402 403 while (n--) { 404 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); 405 if (mc5_cmd_write(adap, read_cmd)) { 406 err = -EIO; 407 break; 408 } 409 dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); 410 buf += 3; 411 } 412 413 mc5_dbgi_mode_disable(mc5); 414 return 0; 415} 416 417#define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) 418 419/* 420 * MC5 interrupt handler 421 */ 422void t3_mc5_intr_handler(struct mc5 *mc5) 423{ 424 adapter_t *adap = mc5->adapter; 425 u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE); 426 427 if ((cause & F_PARITYERR) && mc5->parity_enabled) { 428 CH_ALERT(adap, "MC5 parity error\n"); 429 mc5->stats.parity_err++; 430 } 431 432 if (cause & F_REQQPARERR) { 433 CH_ALERT(adap, "MC5 request queue parity error\n"); 434 mc5->stats.reqq_parity_err++; 435 } 436 437 if (cause & F_DISPQPARERR) { 438 CH_ALERT(adap, "MC5 dispatch queue parity error\n"); 439 mc5->stats.dispq_parity_err++; 440 } 441 442 if (cause & F_ACTRGNFULL) 443 mc5->stats.active_rgn_full++; 444 if (cause & F_NFASRCHFAIL) 445 mc5->stats.nfa_srch_err++; 446 if (cause & F_UNKNOWNCMD) 447 mc5->stats.unknown_cmd++; 448 if (cause & F_DELACTEMPTY) 449 mc5->stats.del_act_empty++; 450 if (cause & MC5_INT_FATAL) 451 t3_fatal_err(adap); 452 453 t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause); 454} 455 456void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode) 457{ 458#define K * 1024 459 460 static unsigned int tcam_part_size[] = { /* in K 72-bit entries */ 461 64 K, 128 K, 256 K, 32 K 462 }; 463 464#undef K 465 466 u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG); 467 468 mc5->adapter = adapter; 469 mc5->mode = (unsigned char) mode; 470 mc5->part_type = (unsigned char) G_TMTYPE(cfg); 471 if (cfg & F_TMTYPEHI) 472 mc5->part_type |= 4; 473 474 mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)]; 475 if (mode == MC5_MODE_144_BIT) 476 mc5->tcam_size /= 2; 477}
| 38 39enum { 40 IDT75P52100 = 4, 41 IDT75N43102 = 5 42}; 43 44/* DBGI command mode */ 45enum { 46 DBGI_MODE_MBUS = 0, 47 DBGI_MODE_IDT52100 = 5 48}; 49 50/* IDT 75P52100 commands */ 51#define IDT_CMD_READ 0 52#define IDT_CMD_WRITE 1 53#define IDT_CMD_SEARCH 2 54#define IDT_CMD_LEARN 3 55 56/* IDT LAR register address and value for 144-bit mode (low 32 bits) */ 57#define IDT_LAR_ADR0 0x180006 58#define IDT_LAR_MODE144 0xffff0000 59 60/* IDT SCR and SSR addresses (low 32 bits) */ 61#define IDT_SCR_ADR0 0x180000 62#define IDT_SSR0_ADR0 0x180002 63#define IDT_SSR1_ADR0 0x180004 64 65/* IDT GMR base address (low 32 bits) */ 66#define IDT_GMR_BASE_ADR0 0x180020 67 68/* IDT data and mask array base addresses (low 32 bits) */ 69#define IDT_DATARY_BASE_ADR0 0 70#define IDT_MSKARY_BASE_ADR0 0x80000 71 72/* IDT 75N43102 commands */ 73#define IDT4_CMD_SEARCH144 3 74#define IDT4_CMD_WRITE 4 75#define IDT4_CMD_READ 5 76 77/* IDT 75N43102 SCR address (low 32 bits) */ 78#define IDT4_SCR_ADR0 0x3 79 80/* IDT 75N43102 GMR base addresses (low 32 bits) */ 81#define IDT4_GMR_BASE0 0x10 82#define IDT4_GMR_BASE1 0x20 83#define IDT4_GMR_BASE2 0x30 84 85/* IDT 75N43102 data and mask array base addresses (low 32 bits) */ 86#define IDT4_DATARY_BASE_ADR0 0x1000000 87#define IDT4_MSKARY_BASE_ADR0 0x2000000 88 89#define MAX_WRITE_ATTEMPTS 5 90 91#define MAX_ROUTES 2048 92 93/* 94 * Issue a command to the TCAM and wait for its completion. The address and 95 * any data required by the command must have been setup by the caller. 96 */ 97static int mc5_cmd_write(adapter_t *adapter, u32 cmd) 98{ 99 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd); 100 return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS, 101 F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1); 102} 103 104static inline void dbgi_wr_addr3(adapter_t *adapter, u32 v1, u32 v2, u32 v3) 105{ 106 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, v1); 107 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR1, v2); 108 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR2, v3); 109} 110 111static inline void dbgi_wr_data3(adapter_t *adapter, u32 v1, u32 v2, u32 v3) 112{ 113 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1); 114 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2); 115 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3); 116} 117 118static inline void dbgi_rd_rsp3(adapter_t *adapter, u32 *v1, u32 *v2, u32 *v3) 119{ 120 *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0); 121 *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1); 122 *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2); 123} 124 125/* 126 * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM 127 * command cmd. The data to be written must have been set up by the caller. 128 * Returns -1 on failure, 0 on success. 129 */ 130static int mc5_write(adapter_t *adapter, u32 addr_lo, u32 cmd) 131{ 132 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo); 133 if (mc5_cmd_write(adapter, cmd) == 0) 134 return 0; 135 CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n", addr_lo); 136 return -1; 137} 138 139static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base, 140 u32 data_array_base, u32 write_cmd, 141 int addr_shift) 142{ 143 unsigned int i; 144 adapter_t *adap = mc5->adapter; 145 146 /* 147 * We need the size of the TCAM data and mask arrays in terms of 148 * 72-bit entries. 149 */ 150 unsigned int size72 = mc5->tcam_size; 151 unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX); 152 153 if (mc5->mode == MC5_MODE_144_BIT) { 154 size72 *= 2; /* 1 144-bit entry is 2 72-bit entries */ 155 server_base *= 2; 156 } 157 158 /* Clear the data array */ 159 dbgi_wr_data3(adap, 0, 0, 0); 160 for (i = 0; i < size72; i++) 161 if (mc5_write(adap, data_array_base + (i << addr_shift), 162 write_cmd)) 163 return -1; 164 165 /* Initialize the mask array. */ 166 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 167 for (i = 0; i < size72; i++) { 168 if (i == server_base) /* entering server or routing region */ 169 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_DATA0, 170 mc5->mode == MC5_MODE_144_BIT ? 171 0xfffffff9 : 0xfffffffd); 172 if (mc5_write(adap, mask_array_base + (i << addr_shift), 173 write_cmd)) 174 return -1; 175 } 176 return 0; 177} 178 179static int init_idt52100(struct mc5 *mc5) 180{ 181 int i; 182 adapter_t *adap = mc5->adapter; 183 184 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 185 V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15)); 186 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2); 187 188 /* 189 * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and 190 * GMRs 8-9 for ACK- and AOPEN searches. 191 */ 192 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE); 193 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE); 194 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH); 195 t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN); 196 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000); 197 t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN); 198 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH); 199 t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN); 200 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH); 201 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000); 202 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE); 203 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ); 204 205 /* Set DBGI command mode for IDT TCAM. */ 206 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 207 208 /* Set up LAR */ 209 dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0); 210 if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE)) 211 goto err; 212 213 /* Set up SSRs */ 214 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0); 215 if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) || 216 mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE)) 217 goto err; 218 219 /* Set up GMRs */ 220 for (i = 0; i < 32; ++i) { 221 if (i >= 12 && i < 15) 222 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 223 else if (i == 15) 224 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 225 else 226 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 227 228 if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE)) 229 goto err; 230 } 231 232 /* Set up SCR */ 233 dbgi_wr_data3(adap, 1, 0, 0); 234 if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE)) 235 goto err; 236 237 return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0, 238 IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0); 239 err: 240 return -EIO; 241} 242 243static int init_idt43102(struct mc5 *mc5) 244{ 245 int i; 246 adapter_t *adap = mc5->adapter; 247 248 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 249 adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) : 250 V_RDLAT(0xd) | V_SRCHLAT(0x12)); 251 252 /* 253 * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask 254 * for ACK- and AOPEN searches. 255 */ 256 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE); 257 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE); 258 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, 259 IDT4_CMD_SEARCH144 | 0x3800); 260 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144); 261 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800); 262 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800); 263 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800); 264 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE); 265 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ); 266 267 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3); 268 269 /* Set DBGI command mode for IDT TCAM. */ 270 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 271 272 /* Set up GMRs */ 273 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 274 for (i = 0; i < 7; ++i) 275 if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE)) 276 goto err; 277 278 for (i = 0; i < 4; ++i) 279 if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE)) 280 goto err; 281 282 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 283 if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) || 284 mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) || 285 mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE)) 286 goto err; 287 288 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 289 if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE)) 290 goto err; 291 292 /* Set up SCR */ 293 dbgi_wr_data3(adap, 0xf0000000, 0, 0); 294 if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE)) 295 goto err; 296 297 return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0, 298 IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1); 299 err: 300 return -EIO; 301} 302 303/* Put MC5 in DBGI mode. */ 304static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5) 305{ 306 t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, 307 V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_DBGIEN); 308} 309 310/* Put MC5 in M-Bus mode. */ 311static void mc5_dbgi_mode_disable(const struct mc5 *mc5) 312{ 313 t3_write_reg(mc5->adapter, A_MC5_DB_CONFIG, 314 V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | 315 V_COMPEN(mc5->mode == MC5_MODE_72_BIT) | 316 V_PRTYEN(mc5->parity_enabled) | F_MBUSEN); 317} 318 319/* 320 * Initialization that requires the OS and protocol layers to already 321 * be intialized goes here. 322 */ 323int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, 324 unsigned int nroutes) 325{ 326 u32 cfg; 327 int err; 328 unsigned int tcam_size = mc5->tcam_size; 329 adapter_t *adap = mc5->adapter; 330 331 if (tcam_size == 0) 332 return 0; 333 334 if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size) 335 return -EINVAL; 336 337 /* Reset the TCAM */ 338 cfg = t3_read_reg(adap, A_MC5_DB_CONFIG) & ~F_TMMODE; 339 cfg |= V_TMMODE(mc5->mode == MC5_MODE_72_BIT) | F_TMRST; 340 t3_write_reg(adap, A_MC5_DB_CONFIG, cfg); 341 if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) { 342 CH_ERR(adap, "TCAM reset timed out\n"); 343 return -1; 344 } 345 346 t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes); 347 t3_write_reg(adap, A_MC5_DB_FILTER_TABLE, 348 tcam_size - nroutes - nfilters); 349 t3_write_reg(adap, A_MC5_DB_SERVER_INDEX, 350 tcam_size - nroutes - nfilters - nservers); 351 352 mc5->parity_enabled = 1; 353 354 /* All the TCAM addresses we access have only the low 32 bits non 0 */ 355 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0); 356 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0); 357 358 mc5_dbgi_mode_enable(mc5); 359 360 switch (mc5->part_type) { 361 case IDT75P52100: 362 err = init_idt52100(mc5); 363 break; 364 case IDT75N43102: 365 err = init_idt43102(mc5); 366 break; 367 default: 368 CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type); 369 err = -EINVAL; 370 break; 371 } 372 373 mc5_dbgi_mode_disable(mc5); 374 return err; 375} 376 377/* 378 * read_mc5_range - dump a part of the memory managed by MC5 379 * @mc5: the MC5 handle 380 * @start: the start address for the dump 381 * @n: number of 72-bit words to read 382 * @buf: result buffer 383 * 384 * Read n 72-bit words from MC5 memory from the given start location. 385 */ 386int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, 387 unsigned int n, u32 *buf) 388{ 389 u32 read_cmd; 390 int err = 0; 391 adapter_t *adap = mc5->adapter; 392 393 if (mc5->part_type == IDT75P52100) 394 read_cmd = IDT_CMD_READ; 395 else if (mc5->part_type == IDT75N43102) 396 read_cmd = IDT4_CMD_READ; 397 else 398 return -EINVAL; 399 400 mc5_dbgi_mode_enable(mc5); 401 402 while (n--) { 403 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); 404 if (mc5_cmd_write(adap, read_cmd)) { 405 err = -EIO; 406 break; 407 } 408 dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); 409 buf += 3; 410 } 411 412 mc5_dbgi_mode_disable(mc5); 413 return 0; 414} 415 416#define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) 417 418/* 419 * MC5 interrupt handler 420 */ 421void t3_mc5_intr_handler(struct mc5 *mc5) 422{ 423 adapter_t *adap = mc5->adapter; 424 u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE); 425 426 if ((cause & F_PARITYERR) && mc5->parity_enabled) { 427 CH_ALERT(adap, "MC5 parity error\n"); 428 mc5->stats.parity_err++; 429 } 430 431 if (cause & F_REQQPARERR) { 432 CH_ALERT(adap, "MC5 request queue parity error\n"); 433 mc5->stats.reqq_parity_err++; 434 } 435 436 if (cause & F_DISPQPARERR) { 437 CH_ALERT(adap, "MC5 dispatch queue parity error\n"); 438 mc5->stats.dispq_parity_err++; 439 } 440 441 if (cause & F_ACTRGNFULL) 442 mc5->stats.active_rgn_full++; 443 if (cause & F_NFASRCHFAIL) 444 mc5->stats.nfa_srch_err++; 445 if (cause & F_UNKNOWNCMD) 446 mc5->stats.unknown_cmd++; 447 if (cause & F_DELACTEMPTY) 448 mc5->stats.del_act_empty++; 449 if (cause & MC5_INT_FATAL) 450 t3_fatal_err(adap); 451 452 t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause); 453} 454 455void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode) 456{ 457#define K * 1024 458 459 static unsigned int tcam_part_size[] = { /* in K 72-bit entries */ 460 64 K, 128 K, 256 K, 32 K 461 }; 462 463#undef K 464 465 u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG); 466 467 mc5->adapter = adapter; 468 mc5->mode = (unsigned char) mode; 469 mc5->part_type = (unsigned char) G_TMTYPE(cfg); 470 if (cfg & F_TMTYPEHI) 471 mc5->part_type |= 4; 472 473 mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)]; 474 if (mode == MC5_MODE_144_BIT) 475 mc5->tcam_size /= 2; 476}
|