1 /************************************************************************** 2 SPDX-License-Identifier: BSD-2-Clause 3 4 Copyright (c) 2007, Chelsio Inc. 5 All rights reserved. 6 7 Redistribution and use in source and binary forms, with or without 8 modification, are permitted provided that the following conditions are met: 9 10 1. Redistributions of source code must retain the above copyright notice, 11 this list of conditions and the following disclaimer. 12 13 2. Neither the name of the Chelsio Corporation nor the names of its 14 contributors may be used to endorse or promote products derived from 15 this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 POSSIBILITY OF SUCH DAMAGE. 28 29 ***************************************************************************/ 30 31 #include <sys/cdefs.h> 32 #include <common/cxgb_common.h> 33 #include <common/cxgb_regs.h> 34 35 enum { 36 IDT75P52100 = 4, 37 IDT75N43102 = 5 38 }; 39 40 /* DBGI command mode */ 41 enum { 42 DBGI_MODE_MBUS = 0, 43 DBGI_MODE_IDT52100 = 5 44 }; 45 46 /* IDT 75P52100 commands */ 47 #define IDT_CMD_READ 0 48 #define IDT_CMD_WRITE 1 49 #define IDT_CMD_SEARCH 2 50 #define IDT_CMD_LEARN 3 51 52 /* IDT LAR register address and value for 144-bit mode (low 32 bits) */ 53 #define IDT_LAR_ADR0 0x180006 54 #define IDT_LAR_MODE144 0xffff0000 55 56 /* IDT SCR and SSR addresses (low 32 bits) */ 57 #define IDT_SCR_ADR0 0x180000 58 #define IDT_SSR0_ADR0 0x180002 59 #define IDT_SSR1_ADR0 0x180004 60 61 /* IDT GMR base address (low 32 bits) */ 62 #define IDT_GMR_BASE_ADR0 0x180020 63 64 /* IDT data and mask array base addresses (low 32 bits) */ 65 #define IDT_DATARY_BASE_ADR0 0 66 #define IDT_MSKARY_BASE_ADR0 0x80000 67 68 /* IDT 75N43102 commands */ 69 #define IDT4_CMD_SEARCH144 3 70 #define IDT4_CMD_WRITE 4 71 #define IDT4_CMD_READ 5 72 73 /* IDT 75N43102 SCR address (low 32 bits) */ 74 #define IDT4_SCR_ADR0 0x3 75 76 /* IDT 75N43102 GMR base addresses (low 32 bits) */ 77 #define IDT4_GMR_BASE0 0x10 78 #define IDT4_GMR_BASE1 0x20 79 #define IDT4_GMR_BASE2 0x30 80 81 /* IDT 75N43102 data and mask array base addresses (low 32 bits) */ 82 #define IDT4_DATARY_BASE_ADR0 0x1000000 83 #define IDT4_MSKARY_BASE_ADR0 0x2000000 84 85 #define MAX_WRITE_ATTEMPTS 5 86 87 #define MAX_ROUTES 2048 88 89 /* 90 * Issue a command to the TCAM and wait for its completion. The address and 91 * any data required by the command must have been setup by the caller. 92 */ 93 static int mc5_cmd_write(adapter_t *adapter, u32 cmd) 94 { 95 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_CMD, cmd); 96 return t3_wait_op_done(adapter, A_MC5_DB_DBGI_RSP_STATUS, 97 F_DBGIRSPVALID, 1, MAX_WRITE_ATTEMPTS, 1); 98 } 99 100 static inline void dbgi_wr_data3(adapter_t *adapter, u32 v1, u32 v2, u32 v3) 101 { 102 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA0, v1); 103 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA1, v2); 104 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_DATA2, v3); 105 } 106 107 static inline void dbgi_rd_rsp3(adapter_t *adapter, u32 *v1, u32 *v2, u32 *v3) 108 { 109 *v1 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA0); 110 *v2 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA1); 111 *v3 = t3_read_reg(adapter, A_MC5_DB_DBGI_RSP_DATA2); 112 } 113 114 /* 115 * Write data to the TCAM register at address (0, 0, addr_lo) using the TCAM 116 * command cmd. The data to be written must have been set up by the caller. 117 * Returns -1 on failure, 0 on success. 118 */ 119 static int mc5_write(adapter_t *adapter, u32 addr_lo, u32 cmd) 120 { 121 t3_write_reg(adapter, A_MC5_DB_DBGI_REQ_ADDR0, addr_lo); 122 if (mc5_cmd_write(adapter, cmd) == 0) 123 return 0; 124 CH_ERR(adapter, "MC5 timeout writing to TCAM address 0x%x\n", addr_lo); 125 return -1; 126 } 127 128 static int init_mask_data_array(struct mc5 *mc5, u32 mask_array_base, 129 u32 data_array_base, u32 write_cmd, 130 int addr_shift) 131 { 132 unsigned int i; 133 adapter_t *adap = mc5->adapter; 134 135 /* 136 * We need the size of the TCAM data and mask arrays in terms of 137 * 72-bit entries. 138 */ 139 unsigned int size72 = mc5->tcam_size; 140 unsigned int server_base = t3_read_reg(adap, A_MC5_DB_SERVER_INDEX); 141 142 if (mc5->mode == MC5_MODE_144_BIT) { 143 size72 *= 2; /* 1 144-bit entry is 2 72-bit entries */ 144 server_base *= 2; 145 } 146 147 /* Clear the data array */ 148 dbgi_wr_data3(adap, 0, 0, 0); 149 for (i = 0; i < size72; i++) 150 if (mc5_write(adap, data_array_base + (i << addr_shift), 151 write_cmd)) 152 return -1; 153 154 /* Initialize the mask array. */ 155 for (i = 0; i < server_base; i++) { 156 dbgi_wr_data3(adap, 0x3fffffff, 0xfff80000, 0xff); 157 if (mc5_write(adap, mask_array_base + (i << addr_shift), 158 write_cmd)) 159 return -1; 160 i++; 161 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 162 if (mc5_write(adap, mask_array_base + (i << addr_shift), 163 write_cmd)) 164 return -1; 165 } 166 167 dbgi_wr_data3(adap, 168 mc5->mode == MC5_MODE_144_BIT ? 0xfffffff9 : 0xfffffffd, 169 0xffffffff, 0xff); 170 for (; i < size72; i++) 171 if (mc5_write(adap, mask_array_base + (i << addr_shift), 172 write_cmd)) 173 return -1; 174 175 return 0; 176 } 177 178 static int init_idt52100(struct mc5 *mc5) 179 { 180 int i; 181 adapter_t *adap = mc5->adapter; 182 183 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 184 V_RDLAT(0x15) | V_LRNLAT(0x15) | V_SRCHLAT(0x15)); 185 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 2); 186 187 /* 188 * Use GMRs 14-15 for ELOOKUP, GMRs 12-13 for SYN lookups, and 189 * GMRs 8-9 for ACK- and AOPEN searches. 190 */ 191 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT_CMD_WRITE); 192 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT_CMD_WRITE); 193 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, IDT_CMD_SEARCH); 194 t3_write_reg(adap, A_MC5_DB_AOPEN_LRN_CMD, IDT_CMD_LEARN); 195 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT_CMD_SEARCH | 0x6000); 196 t3_write_reg(adap, A_MC5_DB_SYN_LRN_CMD, IDT_CMD_LEARN); 197 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT_CMD_SEARCH); 198 t3_write_reg(adap, A_MC5_DB_ACK_LRN_CMD, IDT_CMD_LEARN); 199 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT_CMD_SEARCH); 200 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT_CMD_SEARCH | 0x7000); 201 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT_CMD_WRITE); 202 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT_CMD_READ); 203 204 /* Set DBGI command mode for IDT TCAM. */ 205 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 206 207 /* Set up LAR */ 208 dbgi_wr_data3(adap, IDT_LAR_MODE144, 0, 0); 209 if (mc5_write(adap, IDT_LAR_ADR0, IDT_CMD_WRITE)) 210 goto err; 211 212 /* Set up SSRs */ 213 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0); 214 if (mc5_write(adap, IDT_SSR0_ADR0, IDT_CMD_WRITE) || 215 mc5_write(adap, IDT_SSR1_ADR0, IDT_CMD_WRITE)) 216 goto err; 217 218 /* Set up GMRs */ 219 for (i = 0; i < 32; ++i) { 220 if (i >= 12 && i < 15) 221 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 222 else if (i == 15) 223 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 224 else 225 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 226 227 if (mc5_write(adap, IDT_GMR_BASE_ADR0 + i, IDT_CMD_WRITE)) 228 goto err; 229 } 230 231 /* Set up SCR */ 232 dbgi_wr_data3(adap, 1, 0, 0); 233 if (mc5_write(adap, IDT_SCR_ADR0, IDT_CMD_WRITE)) 234 goto err; 235 236 return init_mask_data_array(mc5, IDT_MSKARY_BASE_ADR0, 237 IDT_DATARY_BASE_ADR0, IDT_CMD_WRITE, 0); 238 err: 239 return -EIO; 240 } 241 242 static int init_idt43102(struct mc5 *mc5) 243 { 244 int i; 245 adapter_t *adap = mc5->adapter; 246 247 t3_write_reg(adap, A_MC5_DB_RSP_LATENCY, 248 adap->params.rev == 0 ? V_RDLAT(0xd) | V_SRCHLAT(0x11) : 249 V_RDLAT(0xd) | V_SRCHLAT(0x12)); 250 251 /* 252 * Use GMRs 24-25 for ELOOKUP, GMRs 20-21 for SYN lookups, and no mask 253 * for ACK- and AOPEN searches. 254 */ 255 t3_write_reg(adap, A_MC5_DB_POPEN_DATA_WR_CMD, IDT4_CMD_WRITE); 256 t3_write_reg(adap, A_MC5_DB_POPEN_MASK_WR_CMD, IDT4_CMD_WRITE); 257 t3_write_reg(adap, A_MC5_DB_AOPEN_SRCH_CMD, 258 IDT4_CMD_SEARCH144 | 0x3800); 259 t3_write_reg(adap, A_MC5_DB_SYN_SRCH_CMD, IDT4_CMD_SEARCH144); 260 t3_write_reg(adap, A_MC5_DB_ACK_SRCH_CMD, IDT4_CMD_SEARCH144 | 0x3800); 261 t3_write_reg(adap, A_MC5_DB_ILOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x3800); 262 t3_write_reg(adap, A_MC5_DB_ELOOKUP_CMD, IDT4_CMD_SEARCH144 | 0x800); 263 t3_write_reg(adap, A_MC5_DB_DATA_WRITE_CMD, IDT4_CMD_WRITE); 264 t3_write_reg(adap, A_MC5_DB_DATA_READ_CMD, IDT4_CMD_READ); 265 266 t3_write_reg(adap, A_MC5_DB_PART_ID_INDEX, 3); 267 268 /* Set DBGI command mode for IDT TCAM. */ 269 t3_write_reg(adap, A_MC5_DB_DBGI_CONFIG, DBGI_MODE_IDT52100); 270 271 /* Set up GMRs */ 272 dbgi_wr_data3(adap, 0xffffffff, 0xffffffff, 0xff); 273 for (i = 0; i < 7; ++i) 274 if (mc5_write(adap, IDT4_GMR_BASE0 + i, IDT4_CMD_WRITE)) 275 goto err; 276 277 for (i = 0; i < 4; ++i) 278 if (mc5_write(adap, IDT4_GMR_BASE2 + i, IDT4_CMD_WRITE)) 279 goto err; 280 281 dbgi_wr_data3(adap, 0xfffffff9, 0xffffffff, 0xff); 282 if (mc5_write(adap, IDT4_GMR_BASE1, IDT4_CMD_WRITE) || 283 mc5_write(adap, IDT4_GMR_BASE1 + 1, IDT4_CMD_WRITE) || 284 mc5_write(adap, IDT4_GMR_BASE1 + 4, IDT4_CMD_WRITE)) 285 goto err; 286 287 dbgi_wr_data3(adap, 0xfffffff9, 0xffff8007, 0xff); 288 if (mc5_write(adap, IDT4_GMR_BASE1 + 5, IDT4_CMD_WRITE)) 289 goto err; 290 291 /* Set up SCR */ 292 dbgi_wr_data3(adap, 0xf0000000, 0, 0); 293 if (mc5_write(adap, IDT4_SCR_ADR0, IDT4_CMD_WRITE)) 294 goto err; 295 296 return init_mask_data_array(mc5, IDT4_MSKARY_BASE_ADR0, 297 IDT4_DATARY_BASE_ADR0, IDT4_CMD_WRITE, 1); 298 err: 299 return -EIO; 300 } 301 302 /* Put MC5 in DBGI mode. */ 303 static inline void mc5_dbgi_mode_enable(const struct mc5 *mc5) 304 { 305 t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_PRTYEN | F_MBUSEN, 306 F_DBGIEN); 307 } 308 309 /* Put MC5 in M-Bus mode. */ 310 static void mc5_dbgi_mode_disable(const struct mc5 *mc5) 311 { 312 t3_set_reg_field(mc5->adapter, A_MC5_DB_CONFIG, F_DBGIEN, 313 V_PRTYEN(mc5->parity_enabled) | F_MBUSEN); 314 } 315 316 /** 317 * t3_mc5_init - initialize MC5 and the TCAM 318 * @mc5: the MC5 handle 319 * @nservers: desired number the TCP servers (listening ports) 320 * @nfilters: desired number of HW filters (classifiers) 321 * @nroutes: desired number of routes 322 * 323 * Initialize MC5 and the TCAM and partition the TCAM for the requested 324 * number of servers, filters, and routes. The number of routes is 325 * typically 0 except for specialized uses of the T3 adapters. 326 */ 327 int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, 328 unsigned int nroutes) 329 { 330 int err; 331 unsigned int tcam_size = mc5->tcam_size; 332 unsigned int mode72 = mc5->mode == MC5_MODE_72_BIT; 333 adapter_t *adap = mc5->adapter; 334 335 if (!tcam_size) 336 return 0; 337 338 if (nroutes > MAX_ROUTES || nroutes + nservers + nfilters > tcam_size) 339 return -EINVAL; 340 341 if (nfilters) 342 mc5->parity_enabled = 0; 343 344 /* Reset the TCAM */ 345 t3_set_reg_field(adap, A_MC5_DB_CONFIG, F_TMMODE | F_COMPEN, 346 V_COMPEN(mode72) | V_TMMODE(mode72) | F_TMRST); 347 if (t3_wait_op_done(adap, A_MC5_DB_CONFIG, F_TMRDY, 1, 500, 0)) { 348 CH_ERR(adap, "TCAM reset timed out\n"); 349 return -1; 350 } 351 352 t3_write_reg(adap, A_MC5_DB_ROUTING_TABLE_INDEX, tcam_size - nroutes); 353 t3_write_reg(adap, A_MC5_DB_FILTER_TABLE, 354 tcam_size - nroutes - nfilters); 355 t3_write_reg(adap, A_MC5_DB_SERVER_INDEX, 356 tcam_size - nroutes - nfilters - nservers); 357 358 /* All the TCAM addresses we access have only the low 32 bits non 0 */ 359 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR1, 0); 360 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR2, 0); 361 362 mc5_dbgi_mode_enable(mc5); 363 364 switch (mc5->part_type) { 365 case IDT75P52100: 366 err = init_idt52100(mc5); 367 break; 368 case IDT75N43102: 369 err = init_idt43102(mc5); 370 break; 371 default: 372 CH_ERR(adap, "Unsupported TCAM type %d\n", mc5->part_type); 373 err = -EINVAL; 374 break; 375 } 376 377 mc5_dbgi_mode_disable(mc5); 378 return err; 379 } 380 381 /** 382 * read_mc5_range - dump a part of the memory managed by MC5 383 * @mc5: the MC5 handle 384 * @start: the start address for the dump 385 * @n: number of 72-bit words to read 386 * @buf: result buffer 387 * 388 * Read n 72-bit words from MC5 memory from the given start location. 389 */ 390 int t3_read_mc5_range(const struct mc5 *mc5, unsigned int start, 391 unsigned int n, u32 *buf) 392 { 393 u32 read_cmd; 394 int err = 0; 395 adapter_t *adap = mc5->adapter; 396 397 if (mc5->part_type == IDT75P52100) 398 read_cmd = IDT_CMD_READ; 399 else if (mc5->part_type == IDT75N43102) 400 read_cmd = IDT4_CMD_READ; 401 else 402 return -EINVAL; 403 404 mc5_dbgi_mode_enable(mc5); 405 406 while (n--) { 407 t3_write_reg(adap, A_MC5_DB_DBGI_REQ_ADDR0, start++); 408 if (mc5_cmd_write(adap, read_cmd)) { 409 err = -EIO; 410 break; 411 } 412 dbgi_rd_rsp3(adap, buf + 2, buf + 1, buf); 413 buf += 3; 414 } 415 416 mc5_dbgi_mode_disable(mc5); 417 return err; 418 } 419 420 #define MC5_INT_FATAL (F_PARITYERR | F_REQQPARERR | F_DISPQPARERR) 421 422 /** 423 * t3_mc5_intr_handler - MC5 interrupt handler 424 * @mc5: the MC5 handle 425 * 426 * The MC5 interrupt handler. 427 */ 428 void t3_mc5_intr_handler(struct mc5 *mc5) 429 { 430 adapter_t *adap = mc5->adapter; 431 u32 cause = t3_read_reg(adap, A_MC5_DB_INT_CAUSE); 432 433 if ((cause & F_PARITYERR) && mc5->parity_enabled) { 434 CH_ALERT(adap, "MC5 parity error\n"); 435 mc5->stats.parity_err++; 436 } 437 438 if (cause & F_REQQPARERR) { 439 CH_ALERT(adap, "MC5 request queue parity error\n"); 440 mc5->stats.reqq_parity_err++; 441 } 442 443 if (cause & F_DISPQPARERR) { 444 CH_ALERT(adap, "MC5 dispatch queue parity error\n"); 445 mc5->stats.dispq_parity_err++; 446 } 447 448 if (cause & F_ACTRGNFULL) 449 mc5->stats.active_rgn_full++; 450 if (cause & F_NFASRCHFAIL) 451 mc5->stats.nfa_srch_err++; 452 if (cause & F_UNKNOWNCMD) 453 mc5->stats.unknown_cmd++; 454 if (cause & F_DELACTEMPTY) 455 mc5->stats.del_act_empty++; 456 if (cause & MC5_INT_FATAL) 457 t3_fatal_err(adap); 458 459 t3_write_reg(adap, A_MC5_DB_INT_CAUSE, cause); 460 } 461 462 /** 463 * t3_mc5_prep - initialize the SW state for MC5 464 * @adapter: the adapter 465 * @mc5: the MC5 handle 466 * @mode: whether the TCAM will be in 72- or 144-bit mode 467 * 468 * Initialize the SW state associated with MC5. Among other things 469 * this determines the size of the attached TCAM. 470 */ 471 void __devinit t3_mc5_prep(adapter_t *adapter, struct mc5 *mc5, int mode) 472 { 473 #define K * 1024 474 475 static unsigned int tcam_part_size[] = { /* in K 72-bit entries */ 476 64 K, 128 K, 256 K, 32 K 477 }; 478 479 #undef K 480 481 u32 cfg = t3_read_reg(adapter, A_MC5_DB_CONFIG); 482 483 mc5->adapter = adapter; 484 mc5->parity_enabled = 1; 485 mc5->mode = (unsigned char) mode; 486 mc5->part_type = (unsigned char) G_TMTYPE(cfg); 487 if (cfg & F_TMTYPEHI) 488 mc5->part_type |= 4; 489 490 mc5->tcam_size = tcam_part_size[G_TMPARTSIZE(cfg)]; 491 if (mode == MC5_MODE_144_BIT) 492 mc5->tcam_size /= 2; 493 } 494