1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (C) 2003-2005 Chelsio Communications. All rights reserved. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" /* ch_subr.c */ 27 28 #include "common.h" 29 #include "elmer0.h" 30 #include "regs.h" 31 32 #include "gmac.h" 33 #include "cphy.h" 34 #include "sge.h" 35 #include "tp.h" 36 #include "espi.h" 37 38 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 39 #include "mc3.h" 40 #include "mc4.h" 41 #include "mc5.h" 42 #include "ulp.h" 43 #endif 44 #ifdef CONFIG_CHELSIO_T1_COUGAR 45 #include "cspi.h" 46 #endif 47 48 /* 49 * t1_wait_op_done - wait until an operation is completed 50 * @adapter: the adapter performing the operation 51 * @reg: the register to check for completion 52 * @mask: a single-bit field within @reg that indicates completion 53 * @polarity: the value of the field when the operation is completed 54 * @attempts: number of check iterations 55 * @delay: delay in usecs between iterations 56 * @attempts: number of check iterations 57 * @delay: delay in usecs between iterations 58 * 59 * Wait until an operation is completed by checking a bit in a register 60 * up to @attempts times. Returns %0 if the operation completes and %1 61 * otherwise. 62 */ 63 int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, 64 int attempts, int delay) 65 { 66 while (attempts) { 67 u32 val = t1_read_reg_4(adapter, reg) & mask; 68 if (!!val == polarity) 69 return (0); 70 if (--attempts == 0) 71 return (1); 72 if (delay) 73 DELAY_US(delay); 74 } 75 76 return (1); 77 } 78 79 /* #define TPI_ATTEMPTS 50 */ 80 #define TPI_ATTEMPTS 100 81 82 /* 83 * Write a register over the TPI interface (unlocked and locked versions). 84 */ 85 int 86 __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) 87 { 88 int tpi_busy; 89 90 t1_write_reg_4(adapter, A_TPI_ADDR, addr); 91 t1_write_reg_4(adapter, A_TPI_WR_DATA, value); 92 t1_write_reg_4(adapter, A_TPI_CSR, F_TPIWR); 93 94 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, 95 TPI_ATTEMPTS, 3); 96 if (tpi_busy) 97 CH_ALERT("%s: TPI write to 0x%x failed\n", 98 adapter_name(adapter), addr); 99 return (tpi_busy); 100 } 101 102 int 103 t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) 104 { 105 int ret; 106 107 TPI_LOCK(adapter); 108 ret = __t1_tpi_write(adapter, addr, value); 109 TPI_UNLOCK(adapter); 110 return (ret); 111 } 112 113 /* 114 * Read a register over the TPI interface (unlocked and locked versions). 115 */ 116 int 117 __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) 118 { 119 int tpi_busy; 120 121 t1_write_reg_4(adapter, A_TPI_ADDR, addr); 122 t1_write_reg_4(adapter, A_TPI_CSR, 0); 123 124 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, 125 TPI_ATTEMPTS, 3); 126 127 if (tpi_busy) 128 CH_ALERT("%s: TPI read from 0x%x failed\n", 129 adapter_name(adapter), addr); 130 else 131 *valp = t1_read_reg_4(adapter, A_TPI_RD_DATA); 132 return (tpi_busy); 133 } 134 135 int 136 t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) 137 { 138 int ret; 139 140 TPI_LOCK(adapter); 141 ret = __t1_tpi_read(adapter, addr, valp); 142 TPI_UNLOCK(adapter); 143 return (ret); 144 } 145 146 /* 147 * Set a TPI parameter. 148 */ 149 static void t1_tpi_par(adapter_t *adapter, u32 value) 150 { 151 t1_write_reg_4(adapter, A_TPI_PAR, V_TPIPAR(value)); 152 } 153 154 /* 155 * Called when a port's link settings change to propagate the new values to the 156 * associated PHY and MAC. After performing the common tasks it invokes an 157 * OS-specific handler. 158 */ 159 void 160 link_changed(adapter_t *adapter, int port_id) 161 { 162 int link_ok, speed, duplex, fc; 163 struct cphy *phy = adapter->port[port_id].phy; 164 struct link_config *lc = &adapter->port[port_id].link_config; 165 166 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); 167 168 lc->speed = speed < 0 ? SPEED_INVALID : speed; 169 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; 170 if (!(lc->requested_fc & PAUSE_AUTONEG)) 171 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); 172 173 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { 174 /* Set MAC speed, duplex, and flow control to match PHY. */ 175 struct cmac *mac = adapter->port[port_id].mac; 176 177 mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); 178 lc->fc = (unsigned char)fc; 179 } 180 t1_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); 181 } 182 183 static int t1_pci_intr_handler(adapter_t *adapter) 184 { 185 u32 pcix_cause; 186 187 (void) t1_os_pci_read_config_4(adapter, A_PCICFG_INTR_CAUSE, 188 &pcix_cause); 189 190 if (pcix_cause) { 191 (void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_CAUSE, 192 pcix_cause); 193 t1_fatal_err(adapter); /* PCI errors are fatal */ 194 } 195 return (0); 196 } 197 198 #ifdef CONFIG_CHELSIO_T1_1G 199 #include "fpga_defs.h" 200 201 /* 202 * PHY interrupt handler for FPGA boards. 203 */ 204 static int fpga_phy_intr_handler(adapter_t *adapter) 205 { 206 int p; 207 u32 cause = t1_read_reg_4(adapter, FPGA_GMAC_ADDR_INTERRUPT_CAUSE); 208 209 for_each_port(adapter, p) 210 if (cause & (1 << p)) { 211 struct cphy *phy = adapter->port[p].phy; 212 int phy_cause = phy->ops->interrupt_handler(phy); 213 214 if (phy_cause & cphy_cause_link_change) 215 link_changed(adapter, p); 216 } 217 t1_write_reg_4(adapter, FPGA_GMAC_ADDR_INTERRUPT_CAUSE, cause); 218 return (0); 219 } 220 221 /* 222 * Slow path interrupt handler for FPGAs. 223 */ 224 static int fpga_slow_intr(adapter_t *adapter) 225 { 226 u32 cause = t1_read_reg_4(adapter, A_PL_CAUSE); 227 228 cause &= ~F_PL_INTR_SGE_DATA; 229 if (cause & F_PL_INTR_SGE_ERR) 230 (void) t1_sge_intr_error_handler(adapter->sge); 231 232 if (cause & FPGA_PCIX_INTERRUPT_GMAC) 233 (void) fpga_phy_intr_handler(adapter); 234 235 if (cause & FPGA_PCIX_INTERRUPT_TP) { 236 /* 237 * FPGA doesn't support MC4 interrupts and it requires 238 * this odd layer of indirection for MC5. 239 */ 240 u32 tp_cause = t1_read_reg_4(adapter, 241 FPGA_TP_ADDR_INTERRUPT_CAUSE); 242 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 243 if (tp_cause & FPGA_TP_INTERRUPT_MC5) 244 t1_mc5_intr_handler(adapter->mc5); 245 #endif 246 /* Clear TP interrupt */ 247 t1_write_reg_4(adapter, FPGA_TP_ADDR_INTERRUPT_CAUSE, 248 tp_cause); 249 } 250 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 251 if (cause & FPGA_PCIX_INTERRUPT_MC3) 252 (void) t1_mc3_intr_handler(adapter->mc3); 253 #endif 254 if (cause & FPGA_PCIX_INTERRUPT_PCIX) 255 (void) t1_pci_intr_handler(adapter); 256 257 /* Clear the interrupts just processed. */ 258 if (cause) 259 t1_write_reg_4(adapter, A_PL_CAUSE, cause); 260 261 return (cause != 0); 262 } 263 264 /* 265 * FPGA MDIO initialization. 266 */ 267 static void fpga_mdio_init(adapter_t *adapter, const struct board_info *bi) 268 { 269 (void) bi; /* avoid warnings */ 270 t1_write_reg_4(adapter, A_MI0_CLK, V_MI0_CLK_DIV(3)); 271 } 272 273 /* 274 * FPGA MDIO read/write operations. 275 */ 276 static int fpga_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr, 277 int reg_addr, unsigned int *val) 278 { 279 if (mmd_addr) 280 return (-EINVAL); 281 282 /* Check if MDI is busy; this shouldn't happen. */ 283 if (t1_read_reg_4(adapter, A_MI0_CSR) & F_MI0_BUSY) { 284 CH_ALERT("%s: MDIO busy at start of read\n", 285 adapter_name(adapter)); 286 return (-EBUSY); 287 } 288 t1_write_reg_4(adapter, A_MI0_ADDR, 289 V_MI0_PHY_REG_ADDR(reg_addr) | V_MI0_PHY_ADDR(phy_addr)); 290 *val = t1_read_reg_4(adapter, A_MI0_DATA_EXT); 291 292 return (0); 293 } 294 295 static int fpga_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, 296 int reg_addr, unsigned int val) 297 { 298 if (mmd_addr) 299 return (-EINVAL); 300 301 /* Check if MDI is busy; this shouldn't happen. */ 302 if (t1_read_reg_4(adapter, A_MI0_CSR) & F_MI0_BUSY) { 303 CH_ALERT("%s: MDIO busy at start of write\n", 304 adapter_name(adapter)); 305 return (-EBUSY); 306 } 307 t1_write_reg_4(adapter, A_MI0_ADDR, 308 V_MI0_PHY_REG_ADDR(reg_addr) | V_MI0_PHY_ADDR(phy_addr)); 309 t1_write_reg_4(adapter, A_MI0_DATA_EXT, val); 310 return (0); 311 } 312 313 static struct mdio_ops fpga_mdio_ops = { 314 fpga_mdio_init, 315 fpga_mdio_read, 316 fpga_mdio_write 317 }; 318 #endif 319 320 /* 321 * Wait until Elmer's MI1 interface is ready for new operations. 322 */ 323 static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg) 324 { 325 int attempts = 100, busy; 326 327 do { 328 u32 val; 329 330 (void) __t1_tpi_read(adapter, mi1_reg, &val); 331 busy = val & F_MI1_OP_BUSY; 332 if (busy) 333 DELAY_US(10); 334 } while (busy && --attempts); 335 if (busy) 336 CH_ALERT("%s: MDIO operation timed out\n", 337 adapter_name(adapter)); 338 return (busy); 339 } 340 341 /* 342 * MI1 MDIO initialization. 343 */ 344 static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi) 345 { 346 u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1; 347 u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) | 348 V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv); 349 350 if (!(bi->caps & SUPPORTED_10000baseT_Full)) 351 val |= V_MI1_SOF(1); 352 (void) t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val); 353 } 354 355 #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR) 356 /* 357 * Elmer MI1 MDIO read/write operations. 358 */ 359 static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr, 360 int reg_addr, unsigned int *valp) 361 { 362 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); 363 364 if (mmd_addr) 365 return (-EINVAL); 366 367 TPI_LOCK(adapter); 368 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 369 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 370 MI1_OP_DIRECT_READ); 371 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 372 (void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 373 TPI_UNLOCK(adapter); 374 return (0); 375 } 376 377 static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr, 378 int reg_addr, unsigned int val) 379 { 380 u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr); 381 382 if (mmd_addr) 383 return (-EINVAL); 384 385 TPI_LOCK(adapter); 386 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 387 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); 388 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 389 MI1_OP_DIRECT_WRITE); 390 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 391 TPI_UNLOCK(adapter); 392 return (0); 393 } 394 395 #if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR) 396 static struct mdio_ops mi1_mdio_ops = { 397 mi1_mdio_init, 398 mi1_mdio_read, 399 mi1_mdio_write 400 }; 401 #endif 402 403 #endif 404 405 #if 0 406 static int mi1_mdio_ext_readinc(adapter_t *adapter, int phy_addr, int mmd_addr, 407 int reg_addr, unsigned int *valp) 408 { 409 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 410 411 TPI_LOCK(adapter); 412 413 /* Write the address we want. */ 414 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 415 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); 416 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 417 MI1_OP_INDIRECT_ADDRESS); 418 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 419 420 /* Write the operation we want. */ 421 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 422 MI1_OP_INDIRECT_READ_INC); 423 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 424 425 /* Read the data. */ 426 (void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 427 TPI_UNLOCK(adapter); 428 return (0); 429 } 430 #endif 431 432 static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, 433 int reg_addr, unsigned int *valp) 434 { 435 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 436 437 TPI_LOCK(adapter); 438 439 /* Write the address we want. */ 440 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 441 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); 442 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 443 MI1_OP_INDIRECT_ADDRESS); 444 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 445 446 /* Write the operation we want. */ 447 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 448 MI1_OP_INDIRECT_READ); 449 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 450 451 /* Read the data. */ 452 (void) __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 453 TPI_UNLOCK(adapter); 454 return (0); 455 } 456 457 static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, 458 int reg_addr, unsigned int val) 459 { 460 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 461 462 TPI_LOCK(adapter); 463 464 /* Write the address we want. */ 465 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 466 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); 467 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 468 MI1_OP_INDIRECT_ADDRESS); 469 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 470 471 /* Write the data. */ 472 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); 473 (void) __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 474 MI1_OP_INDIRECT_WRITE); 475 (void) mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 476 TPI_UNLOCK(adapter); 477 return (0); 478 } 479 480 static struct mdio_ops mi1_mdio_ext_ops = { 481 mi1_mdio_init, 482 mi1_mdio_ext_read, 483 mi1_mdio_ext_write 484 }; 485 486 enum { 487 CH_BRD_T110_1CU, 488 CH_BRD_N110_1F, 489 CH_BRD_N210_1F, 490 CH_BRD_T210_1F, 491 CH_BRD_T210_1CU, 492 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 493 #ifdef CONFIG_CHELSIO_T1_1G 494 CH_BRD_T204_4CU, 495 CH_BRD_T204V_4CU, 496 CH_BRD_6800_4CU, 497 CH_BRD_7500_4CU, 498 CH_BRD_7500_4F, 499 CH_BRD_T101_1CU_LB, 500 CH_BRD_T101_1F_LB, 501 #endif 502 CH_BRD_8000_1F, 503 CH_BRD_T110_1F, 504 #ifdef CONFIG_CHELSIO_T1_COUGAR 505 #ifdef CONFIG_CHELSIO_T1_1G 506 CH_BRD_COUGAR_4CU, 507 #endif 508 CH_BRD_COUGAR_1F, 509 #endif 510 #ifdef CONFIG_USERMODE 511 CH_BRD_SIMUL, 512 #endif 513 #endif 514 }; 515 516 static struct board_info t1_board[] = { 517 518 { CHBT_BOARD_CHT110, 1/*ports#*/, 519 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T1, 520 CHBT_MAC_PM3393, CHBT_PHY_MY3126, 521 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/, 522 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, 523 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, 524 &t1_my3126_ops, &mi1_mdio_ext_ops, 525 "Chelsio T110 1x10GBase-CX4 TOE" }, 526 527 { CHBT_BOARD_N110, 1/*ports#*/, 528 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 529 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 530 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 531 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 532 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 533 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 534 "Chelsio N110 1x10GBaseX NIC" }, 535 536 { CHBT_BOARD_N210, 1/*ports#*/, 537 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2, 538 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 539 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 540 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 541 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 542 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 543 "Chelsio N210 1x10GBaseX NIC" }, 544 545 { CHBT_BOARD_CHT210, 1/*ports#*/, 546 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, 547 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 548 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, 549 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 550 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 551 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 552 "Chelsio T210 1x10GBaseX TOE" }, 553 554 { CHBT_BOARD_CHT210, 1/*ports#*/, 555 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2, 556 CHBT_MAC_PM3393, CHBT_PHY_MY3126, 557 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/, 558 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, 559 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, 560 &t1_my3126_ops, &mi1_mdio_ext_ops, 561 "Chelsio T210 1x10GBase-CX4 TOE" }, 562 563 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 564 #ifdef CONFIG_CHELSIO_T1_1G 565 { CHBT_BOARD_CHT204, 4/*ports#*/, 566 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | 567 SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_IXF1010, CHBT_PHY_88E1111, 568 100000000/*clk-core*/, 133000000/*clk-mc3*/, 100000000/*clk-mc4*/, 569 4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 570 0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops, 571 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 572 "Chelsio T204 4x100/1000BaseT TOE" }, 573 { CHBT_BOARD_CHT204V, 4/*ports#*/, 574 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | 575 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | 576 SUPPORTED_PAUSE | SUPPORTED_TP /*caps*/, CHBT_TERM_T2, CHBT_MAC_VSC7321, CHBT_PHY_88E1111, 577 100000000/*clk-core*/, 133000000/*clk-mc3*/, 100000000/*clk-mc4*/, 578 4/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 579 0/*mdiinv*/, 1/*mdc*/, 4/*phybaseaddr*/, &t1_vsc7326_ops, 580 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 581 "Chelsio T204V 4x100/1000BaseT TOE" }, 582 583 { CHBT_BOARD_6800, 1/*ports#*/, 584 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | 585 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | 586 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP /*caps*/, 587 CHBT_TERM_FPGA, CHBT_MAC_CHELSIO_A, CHBT_PHY_88E1041, 588 16000000/*clk-core*/, 16000000/*clk-mc3*/, 16000000/*clk-mc4*/, 589 0/*espi-ports*/, 0/*clk-cspi*/, 0/*clk-elmer0*/, 0/*mdien*/, 590 0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_chelsio_mac_ops, &t1_mv88e1xxx_ops, &fpga_mdio_ops, 591 "Chelsio FPGA 4x10/100/1000BaseT TOE" }, 592 593 { CHBT_BOARD_7500, 4/*ports#*/, 594 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | 595 SUPPORTED_TP /*caps*/, CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1041, 596 87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/, 597 4/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/, 598 0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_ixf1010_ops, 599 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 600 "Chelsio 7500 4x100/1000BaseT TOE" }, 601 602 { CHBT_BOARD_7500, 4/*ports#*/, 603 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE /*caps*/, 604 CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1041, 605 87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/, 606 4/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/, 607 0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_ixf1010_ops, 608 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 609 "Chelsio 7500 4x1000BaseX TOE" }, 610 611 { CHBT_BOARD_CHT101, 1/*ports#*/, 612 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | 613 SUPPORTED_TP | SUPPORTED_PAUSE | SUPPORTED_LOOPBACK /*caps*/, CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1111, 614 83300000/*clk-core*/, 83300000/*clk-mc3*/, 83300000/*clk-mc4*/, 615 2/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/, 616 0/*mdiinv*/, 4/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops, 617 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 618 "Chelsio T101 1x100/1000BaseT TOE" }, 619 620 { CHBT_BOARD_CHT101, 1/*ports#*/, 621 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_PAUSE | SUPPORTED_LOOPBACK /*caps*/, 622 CHBT_TERM_T1, CHBT_MAC_IXF1010, CHBT_PHY_88E1111, 623 83300000/*clk-core*/, 83300000/*clk-mc3*/, 83300000/*clk-mc4*/, 624 2/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/, 625 0/*mdiinv*/, 4/*mdc*/, 4/*phybaseaddr*/, &t1_ixf1010_ops, 626 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 627 "Chelsio T101 1x1000BaseX TOE" }, 628 #endif 629 630 { CHBT_BOARD_8000, 1/*ports#*/, 631 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 632 CHBT_MAC_PM3393, CHBT_PHY_XPAK, 633 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/, 634 1/*espi-ports*/, 0/*clk-cspi*/, 40/*clk-elmer0*/, 1/*mdien*/, 635 1/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 636 &t1_xpak_ops, &mi1_mdio_ext_ops, 637 "Chelsio 8000 1x10GBaseX TOE" }, 638 639 { CHBT_BOARD_CHT110, 1/*ports#*/, 640 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 641 CHBT_MAC_PM3393, CHBT_PHY_XPAK, 642 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/, 643 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/, 644 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops, 645 &t1_xpak_ops, &mi1_mdio_ext_ops, 646 "Chelsio T110 1x10GBaseX TOE" }, 647 648 #ifdef CONFIG_CHELSIO_T1_COUGAR 649 #ifdef CONFIG_CHELSIO_T1_1G 650 { CHBT_BOARD_COUGAR, 4/*ports#*/, 651 SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | 652 SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | 653 SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_TP /*caps*/, 654 CHBT_TERM_T1, CHBT_MAC_VSC7321, CHBT_PHY_88E1041, 655 87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/, 656 4/*espi-ports*/, 333300000/*clk-cspi*/, 40/*clk-elmer0*/, 0/*mdien*/, 657 0/*mdiinv*/, 4/*mdc*/, 0/*phybaseaddr*/, &t1_vsc7321_ops, 658 &t1_mv88e1xxx_ops, &mi1_mdio_ops, 659 "Chelsio Cougar 4x100/1000BaseT TOE" }, 660 #endif 661 662 { CHBT_BOARD_COUGAR, 1/*ports#*/, 663 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 664 CHBT_MAC_VSC7321, CHBT_PHY_XPAK, 665 87500000/*clk-core*/, 87500000/*clk-mc3*/, 87500000/*clk-mc4*/, 666 1/*espi-ports*/, 333300000/*clk-cspi*/, 40/*clk-elmer0*/, 1/*mdien*/, 667 1/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_vsc7321_ops, 668 &t1_xpak_ops, &mi1_mdio_ext_ops, 669 "Chelsio Cougar 1x10GBaseX TOE" }, 670 #endif 671 672 #ifdef CONFIG_USERMODE 673 { CHBT_BOARD_SIMUL, 1/*ports#*/, 674 0/*caps*/, CHBT_TERM_T1, CHBT_MAC_DUMMY, CHBT_PHY_DUMMY, 675 125000000/*clk-core*/, 125000000/*clk-mc3*/, 125000000/*clk-mc4*/, 676 1/*espi-ports*/, 0/*clk-cspi*/, 0/*clk-elmer0*/, 0/*mdien*/, 677 0/*mdiinv*/, 0/*mdc*/, 0/*phybaseaddr*/, &t1_dummy_mac_ops, 678 &t1_dummy_phy_ops, NULL, "Chelsio simulation environment TOE" }, 679 #endif 680 #endif 681 }; 682 683 struct pci_device_id t1_pci_tbl[] = { 684 CH_DEVICE(8, 0, CH_BRD_T110_1CU), 685 CH_DEVICE(8, 1, CH_BRD_T110_1CU), 686 CH_DEVICE(7, 0, CH_BRD_N110_1F), 687 CH_DEVICE(10, 1, CH_BRD_N210_1F), 688 CH_DEVICE(11, 1, CH_BRD_T210_1F), 689 CH_DEVICE(14, 1, CH_BRD_T210_1CU), 690 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 691 #ifdef CONFIG_CHELSIO_T1_1G 692 CH_DEVICE(12, 1, CH_BRD_T204_4CU), 693 CH_DEVICE(13, 1, CH_BRD_T204V_4CU), 694 CH_DEVICE(1, 0, CH_BRD_6800_4CU), 695 CH_DEVICE(2, 1, CH_BRD_7500_4CU), 696 CH_DEVICE(2, 3, CH_BRD_7500_4F), 697 CH_DEVICE(4, 0, CH_BRD_T101_1CU_LB), 698 CH_DEVICE(4, 2, CH_BRD_T101_1F_LB), 699 #endif 700 CH_DEVICE(3, 0, CH_BRD_8000_1F), 701 CH_DEVICE(3, 1, CH_BRD_8000_1F), 702 CH_DEVICE(6, 0, CH_BRD_T110_1F), 703 CH_DEVICE(6, 1, CH_BRD_T110_1F), 704 #ifdef CONFIG_CHELSIO_T1_COUGAR 705 #ifdef CONFIG_CHELSIO_T1_1G 706 CH_DEVICE(5, 0, CH_BRD_COUGAR_4CU), 707 #endif 708 CH_DEVICE(5, 1, CH_BRD_COUGAR_1F), 709 #endif 710 #ifdef CONFIG_USERMODE 711 CH_DEVICE(0x5000, PCI_ANY_ID, CH_BRD_SIMUL), 712 #endif 713 #endif 714 { 0, } 715 }; 716 717 #ifndef CH_DEVICE_COMMON 718 /* 719 * Return the board_info structure with a given index. Out-of-range indices 720 * return NULL. 721 */ 722 const struct board_info * 723 t1_get_board_info(unsigned int board_id) 724 { 725 return (board_id < DIMOF(t1_board) ? &t1_board[board_id] : NULL); 726 } 727 #else 728 /* 729 * Return the board_info structure that corresponds to a given PCI devid/ssid 730 * pair. Return NULL if the id combination is unknown. 731 */ 732 const struct board_info *t1_get_board_info_from_ids(unsigned int devid, 733 unsigned short ssid) 734 { 735 struct pci_device_id *p; 736 737 for (p = t1_pci_tbl; p->devid; ++p) 738 if (p->devid == devid && p->ssid == ssid) 739 return (&t1_board[p->board_info_index]); 740 return (NULL); 741 } 742 #endif 743 744 typedef struct { 745 u32 format_version; 746 u8 serial_number[16]; 747 u8 mac_base_address[6]; 748 u8 pad[2]; /* make multiple-of-4 size requirement explicit */ 749 } chelsio_vpd_t; 750 751 #define EEPROMSIZE (8 * 1024) 752 #define EEPROM_MAX_POLL 4 753 754 /* 755 * Read SEEPROM. A zero is written to the flag register when the addres is 756 * written to the Control register. The hardware device will set the flag to a 757 * one when 4B have been transferred to the Data register. 758 */ 759 int 760 t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data) 761 { 762 int i = EEPROM_MAX_POLL; 763 u16 val; 764 765 if (addr >= EEPROMSIZE || (addr & 3)) 766 return (-EINVAL); 767 768 (void) t1_os_pci_write_config_2(adapter, A_PCICFG_VPD_ADDR, (u16)addr); 769 do { 770 DELAY_US(50); 771 (void) t1_os_pci_read_config_2(adapter, 772 A_PCICFG_VPD_ADDR, &val); 773 } while (!(val & F_VPD_OP_FLAG) && --i); 774 775 if (!(val & F_VPD_OP_FLAG)) { 776 CH_ERR("%s: reading EEPROM address 0x%x failed\n", 777 adapter_name(adapter), addr); 778 return (-EIO); 779 } 780 (void) t1_os_pci_read_config_4(adapter, A_PCICFG_VPD_DATA, data); 781 *data = le32_to_cpu(*data); 782 return (0); 783 } 784 785 static int t1_eeprom_vpd_get(adapter_t *adapter, chelsio_vpd_t *vpd) 786 { 787 int addr, ret = 0; 788 789 for (addr = 0; !ret && addr < sizeof (*vpd); addr += sizeof (u32)) 790 ret = t1_seeprom_read(adapter, addr, 791 (u32 *)((u8 *)vpd + addr)); 792 793 return (ret); 794 } 795 796 /* 797 * Read a port's MAC address from the VPD ROM. 798 */ 799 static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[]) 800 { 801 chelsio_vpd_t vpd; 802 803 if (t1_eeprom_vpd_get(adapter, &vpd)) 804 return (1); 805 memcpy(mac_addr, vpd.mac_base_address, 5); 806 mac_addr[5] = vpd.mac_base_address[5] + index; 807 return (0); 808 } 809 810 /* 811 * Set up the MAC/PHY according to the requested link settings. 812 * 813 * If the PHY can auto-negotiate first decide what to advertise, then 814 * enable/disable auto-negotiation as desired and reset. 815 * 816 * If the PHY does not auto-negotiate we just reset it. 817 * 818 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC, 819 * otherwise do it later based on the outcome of auto-negotiation. 820 */ 821 int 822 t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) 823 { 824 unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); 825 826 if (lc->supported & SUPPORTED_Autoneg) { 827 lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); 828 if (fc) { 829 if (fc == ((PAUSE_RX | PAUSE_TX) & !is_T2(mac->adapter))) 830 lc->advertising |= ADVERTISED_PAUSE; 831 else { 832 lc->advertising |= ADVERTISED_ASYM_PAUSE; 833 if (fc == PAUSE_RX) 834 lc->advertising |= ADVERTISED_PAUSE; 835 } 836 } 837 phy->ops->advertise(phy, lc->advertising); 838 839 if (lc->autoneg == AUTONEG_DISABLE) { 840 lc->speed = lc->requested_speed; 841 lc->duplex = lc->requested_duplex; 842 lc->fc = (unsigned char)fc; 843 mac->ops->set_speed_duplex_fc(mac, lc->speed, 844 lc->duplex, fc); 845 /* Also disables autoneg */ 846 phy->state = PHY_AUTONEG_RDY; 847 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); 848 phy->ops->reset(phy, 0); 849 } else { 850 phy->state = PHY_AUTONEG_EN; 851 phy->ops->autoneg_enable(phy); /* also resets PHY */ 852 } 853 } else { 854 phy->state = PHY_AUTONEG_RDY; 855 mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); 856 lc->fc = (unsigned char)fc; 857 phy->ops->reset(phy, 0); 858 } 859 return 0; 860 } 861 862 /* 863 * External interrupt handler for boards using elmer0. 864 */ 865 int 866 elmer0_ext_intr_handler(adapter_t *adapter) 867 { 868 struct cphy *phy; 869 int phy_cause; 870 u32 cause; 871 872 (void) t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); 873 874 switch (board_info(adapter)->board) { 875 #ifdef CONFIG_CHELSIO_T1_1G 876 case CHBT_BOARD_CHT204: 877 case CHBT_BOARD_CHT204V: { 878 int i, port_bit; 879 for_each_port(adapter, i) { 880 port_bit = i ? i + 1 : 0; 881 if (!(cause & (1 << port_bit))) continue; 882 883 phy = adapter->port[i].phy; 884 phy_cause = phy->ops->interrupt_handler(phy); 885 if (phy_cause & cphy_cause_link_change) 886 link_changed(adapter, i); 887 } 888 break; 889 } 890 case CHBT_BOARD_CHT101: 891 if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */ 892 phy = adapter->port[0].phy; 893 phy_cause = phy->ops->interrupt_handler(phy); 894 if (phy_cause & cphy_cause_link_change) 895 link_changed(adapter, 0); 896 } 897 break; 898 case CHBT_BOARD_7500: { 899 int p; 900 /* 901 * Elmer0's interrupt cause isn't useful here because there is 902 * only one bit that can be set for all 4 ports. This means 903 * we are forced to check every PHY's interrupt status 904 * register to see who initiated the interrupt. 905 */ 906 for_each_port(adapter, p) { 907 phy = adapter->port[p].phy; 908 phy_cause = phy->ops->interrupt_handler(phy); 909 if (phy_cause & cphy_cause_link_change) 910 link_changed(adapter, p); 911 } 912 break; 913 } 914 #endif 915 case CHBT_BOARD_CHT210: 916 case CHBT_BOARD_N210: 917 case CHBT_BOARD_N110: 918 if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ 919 phy = adapter->port[0].phy; 920 phy_cause = phy->ops->interrupt_handler(phy); 921 if (phy_cause & cphy_cause_link_change) 922 link_changed(adapter, 0); 923 } 924 break; 925 case CHBT_BOARD_8000: 926 case CHBT_BOARD_CHT110: 927 CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n", 928 cause); 929 if (cause & ELMER0_GP_BIT1) { /* PMC3393 INTB */ 930 struct cmac *mac = adapter->port[0].mac; 931 932 mac->ops->interrupt_handler(mac); 933 } 934 if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */ 935 u32 mod_detect; 936 937 (void) t1_tpi_read(adapter, A_ELMER0_GPI_STAT, 938 &mod_detect); 939 CH_MSG(adapter, INFO, LINK, "XPAK %s\n", 940 mod_detect ? "removed" : "inserted"); 941 } 942 break; 943 #ifdef CONFIG_CHELSIO_T1_COUGAR 944 case CHBT_BOARD_COUGAR: 945 if (adapter->params.nports == 1) { 946 if (cause & ELMER0_GP_BIT1) { /* Vitesse MAC */ 947 struct cmac *mac = adapter->port[0].mac; 948 mac->ops->interrupt_handler(mac); 949 } 950 if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */ 951 } 952 } else { 953 int i, port_bit; 954 955 for_each_port(adapter, i) { 956 port_bit = i ? i + 1 : 0; 957 if (!(cause & (1 << port_bit))) continue; 958 959 phy = adapter->port[i].phy; 960 phy_cause = phy->ops->interrupt_handler(phy); 961 if (phy_cause & cphy_cause_link_change) 962 link_changed(adapter, i); 963 } 964 } 965 break; 966 #endif 967 } 968 (void) t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); 969 return (0); 970 } 971 972 /* Enables all interrupts. */ 973 void 974 t1_interrupts_enable(adapter_t *adapter) 975 { 976 unsigned int i; 977 978 adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP; 979 (void) t1_sge_intr_enable(adapter->sge); 980 t1_tp_intr_enable(adapter->tp); 981 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 982 if (adapter->mc4) { 983 adapter->slow_intr_mask |= F_PL_INTR_MC3 | F_PL_INTR_MC4 | 984 F_PL_INTR_ULP | F_PL_INTR_MC5; 985 /* 986 * T2 -- Disable interrupts for now b/c we are not clearing 987 * correctly yet. 988 */ 989 /* t1_ulp_intr_enable(adapter->ulp); */ 990 t1_ulp_intr_disable(adapter->ulp); 991 992 t1_mc3_intr_enable(adapter->mc3); 993 t1_mc4_intr_enable(adapter->mc4); 994 t1_mc5_intr_enable(adapter->mc5); 995 } 996 #endif 997 if (adapter->espi) { 998 adapter->slow_intr_mask |= F_PL_INTR_ESPI; 999 t1_espi_intr_enable(adapter->espi); 1000 } 1001 1002 /* Enable MAC/PHY interrupts for each port. */ 1003 for_each_port(adapter, i) { 1004 adapter->port[i].mac->ops->interrupt_enable(adapter-> 1005 port[i].mac); 1006 adapter->port[i].phy->ops->interrupt_enable(adapter-> 1007 port[i].phy); 1008 } 1009 1010 /* Enable PCIX & external chip interrupts on ASIC boards. */ 1011 if (t1_is_asic(adapter)) { 1012 u32 pl_intr = t1_read_reg_4(adapter, A_PL_ENABLE); 1013 1014 /* PCI-X interrupts */ 1015 (void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_ENABLE, 1016 0xffffffff); 1017 1018 adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 1019 pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 1020 t1_write_reg_4(adapter, A_PL_ENABLE, pl_intr); 1021 } 1022 } 1023 1024 /* Disables all interrupts. */ 1025 void 1026 t1_interrupts_disable(adapter_t * adapter) 1027 { 1028 unsigned int i; 1029 1030 (void) t1_sge_intr_disable(adapter->sge); 1031 t1_tp_intr_disable(adapter->tp); 1032 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1033 if (adapter->mc4) { 1034 t1_ulp_intr_disable(adapter->ulp); 1035 t1_mc3_intr_disable(adapter->mc3); 1036 t1_mc4_intr_disable(adapter->mc4); 1037 t1_mc5_intr_disable(adapter->mc5); 1038 } 1039 #endif 1040 if (adapter->espi) 1041 t1_espi_intr_disable(adapter->espi); 1042 1043 /* Disable MAC/PHY interrupts for each port. */ 1044 for_each_port(adapter, i) { 1045 adapter->port[i].mac->ops->interrupt_disable(adapter-> 1046 port[i].mac); 1047 adapter->port[i].phy->ops->interrupt_disable(adapter-> 1048 port[i].phy); 1049 } 1050 1051 /* Disable PCIX & external chip interrupts. */ 1052 if (t1_is_asic(adapter)) 1053 t1_write_reg_4(adapter, A_PL_ENABLE, 0); 1054 1055 /* PCI-X interrupts */ 1056 (void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_ENABLE, 0); 1057 1058 adapter->slow_intr_mask = 0; 1059 } 1060 1061 /* Clears all interrupts */ 1062 void 1063 t1_interrupts_clear(adapter_t * adapter) 1064 { 1065 unsigned int i; 1066 1067 (void) t1_sge_intr_clear(adapter->sge); 1068 t1_tp_intr_clear(adapter->tp); 1069 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1070 if (adapter->mc4) { 1071 t1_ulp_intr_clear(adapter->ulp); 1072 t1_mc3_intr_clear(adapter->mc3); 1073 t1_mc4_intr_clear(adapter->mc4); 1074 t1_mc5_intr_clear(adapter->mc5); 1075 } 1076 #endif 1077 if (adapter->espi) 1078 t1_espi_intr_clear(adapter->espi); 1079 1080 /* Clear MAC/PHY interrupts for each port. */ 1081 for_each_port(adapter, i) { 1082 adapter->port[i].mac->ops->interrupt_clear(adapter-> 1083 port[i].mac); 1084 adapter->port[i].phy->ops->interrupt_clear(adapter-> 1085 port[i].phy); 1086 } 1087 1088 /* Enable interrupts for external devices. */ 1089 if (t1_is_asic(adapter)) { 1090 u32 pl_intr = t1_read_reg_4(adapter, A_PL_CAUSE); 1091 1092 t1_write_reg_4(adapter, A_PL_CAUSE, 1093 pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX); 1094 } 1095 1096 /* PCI-X interrupts */ 1097 (void) t1_os_pci_write_config_4(adapter, A_PCICFG_INTR_CAUSE, 1098 0xffffffff); 1099 } 1100 1101 /* 1102 * Slow path interrupt handler for ASICs. 1103 */ 1104 static int asic_slow_intr(adapter_t *adapter) 1105 { 1106 u32 cause = t1_read_reg_4(adapter, A_PL_CAUSE); 1107 1108 cause &= adapter->slow_intr_mask; 1109 if (!cause) 1110 return (0); 1111 if (cause & F_PL_INTR_SGE_ERR) 1112 (void) t1_sge_intr_error_handler(adapter->sge); 1113 if (cause & F_PL_INTR_TP) 1114 (void) t1_tp_intr_handler(adapter->tp); 1115 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1116 if (cause & F_PL_INTR_MC3) 1117 (void) t1_mc3_intr_handler(adapter->mc3); 1118 if (cause & F_PL_INTR_MC4) 1119 (void) t1_mc4_intr_handler(adapter->mc4); 1120 if (cause & F_PL_INTR_ULP) 1121 (void) t1_ulp_intr_handler(adapter->ulp); 1122 if (cause & F_PL_INTR_MC5) 1123 (void) t1_mc5_intr_handler(adapter->mc5); 1124 #endif 1125 if (cause & F_PL_INTR_ESPI) 1126 (void) t1_espi_intr_handler(adapter->espi); 1127 if (cause & F_PL_INTR_PCIX) 1128 (void) t1_pci_intr_handler(adapter); 1129 if (cause & F_PL_INTR_EXT) 1130 t1_os_elmer0_ext_intr(adapter); 1131 1132 /* Clear the interrupts just processed. */ 1133 t1_write_reg_4(adapter, A_PL_CAUSE, cause); 1134 (void) t1_read_reg_4(adapter, A_PL_CAUSE); /* flush writes */ 1135 return (1); 1136 } 1137 1138 int 1139 t1_slow_intr_handler(adapter_t *adapter) 1140 { 1141 #ifdef CONFIG_CHELSIO_T1_1G 1142 if (!t1_is_asic(adapter)) 1143 return (fpga_slow_intr(adapter)); 1144 #endif 1145 return (asic_slow_intr(adapter)); 1146 } 1147 1148 /* Power sequencing is a work-around for Intel's XPAKs. */ 1149 static void 1150 power_sequence_xpak(adapter_t * adapter) 1151 { 1152 u32 mod_detect; 1153 u32 gpo; 1154 1155 /* Check for XPAK */ 1156 (void) t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect); 1157 if (!(ELMER0_GP_BIT5 & mod_detect)) { 1158 /* XPAK is present */ 1159 (void) t1_tpi_read(adapter, A_ELMER0_GPO, &gpo); 1160 gpo |= ELMER0_GP_BIT18; 1161 (void) t1_tpi_write(adapter, A_ELMER0_GPO, gpo); 1162 } 1163 } 1164 1165 int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, 1166 struct adapter_params *p) 1167 { 1168 p->chip_version = bi->chip_term; 1169 p->is_asic = (p->chip_version != CHBT_TERM_FPGA); 1170 if (p->chip_version == CHBT_TERM_T1 || 1171 p->chip_version == CHBT_TERM_T2 || 1172 p->chip_version == CHBT_TERM_FPGA) { 1173 u32 val = t1_read_reg_4(adapter, A_TP_PC_CONFIG); 1174 1175 val = G_TP_PC_REV(val); 1176 if (val == 2) 1177 p->chip_revision = TERM_T1B; 1178 else if (val == 3) 1179 p->chip_revision = TERM_T2; 1180 else 1181 return (-1); 1182 } else 1183 return (-1); 1184 return (0); 1185 } 1186 1187 /* 1188 * Enable board components other than the Chelsio chip, such as external MAC 1189 * and PHY. 1190 */ 1191 static int board_init(adapter_t *adapter, const struct board_info *bi) 1192 { 1193 switch (bi->board) { 1194 case CHBT_BOARD_8000: 1195 case CHBT_BOARD_N110: 1196 case CHBT_BOARD_N210: 1197 case CHBT_BOARD_CHT210: 1198 case CHBT_BOARD_COUGAR: 1199 t1_tpi_par(adapter, 0xf); 1200 (void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); 1201 break; 1202 case CHBT_BOARD_CHT110: 1203 t1_tpi_par(adapter, 0xf); 1204 (void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800); 1205 1206 /* 1207 * TBD XXX Might not need. This fixes a problem 1208 * described in the Intel SR XPAK errata. 1209 */ 1210 power_sequence_xpak(adapter); 1211 break; 1212 #ifdef CONFIG_CHELSIO_T1_1G 1213 case CHBT_BOARD_CHT204: 1214 case CHBT_BOARD_CHT204V: 1215 t1_tpi_par(adapter, 0xf); 1216 (void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x804); 1217 break; 1218 case CHBT_BOARD_CHT101: 1219 case CHBT_BOARD_7500: 1220 t1_tpi_par(adapter, 0xf); 1221 (void) t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804); 1222 break; 1223 #endif 1224 } 1225 return (0); 1226 } 1227 1228 /* 1229 * Initialize and configure the Terminator HW modules. Note that external 1230 * MAC and PHYs are initialized separately. 1231 */ 1232 int 1233 t1_init_hw_modules(adapter_t *adapter) 1234 { 1235 int err = -EIO; 1236 const struct board_info *bi = board_info(adapter); 1237 1238 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1239 if (adapter->mc3 && t1_mc3_init(adapter->mc3, bi->clock_mc3)) 1240 goto out_err; 1241 if (adapter->mc4 && t1_mc4_init(adapter->mc4, bi->clock_mc4)) 1242 goto out_err; 1243 if (adapter->mc5 && t1_mc5_init(adapter->mc5, 1244 adapter->params.mc5.nservers, 1245 adapter->params.mc5.nroutes, 1, 0)) 1246 goto out_err; 1247 if (adapter->ulp && t1_ulp_init(adapter->ulp, 1248 adapter->params.tp.pm_tx_base)) 1249 goto out_err; 1250 #endif 1251 if (!adapter->mc4) { 1252 u32 val = t1_read_reg_4(adapter, A_MC4_CFG); 1253 1254 t1_write_reg_4(adapter, A_MC4_CFG, val | F_READY | F_MC4_SLOW); 1255 t1_write_reg_4(adapter, A_MC5_CONFIG, 1256 F_M_BUS_ENABLE | F_TCAM_RESET); 1257 } 1258 1259 #ifdef CONFIG_CHELSIO_T1_COUGAR 1260 if (adapter->cspi && t1_cspi_init(adapter->cspi)) 1261 goto out_err; 1262 #endif 1263 if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac, 1264 bi->espi_nports)) 1265 goto out_err; 1266 1267 if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core)) 1268 goto out_err; 1269 1270 err = t1_sge_configure(adapter->sge, &adapter->params.sge); 1271 if (err) 1272 goto out_err; 1273 1274 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1275 (void) t1_tp_set_coalescing_size(adapter->tp, 1276 min(adapter->params.sge.large_buf_capacity, 1277 TP_MAX_RX_COALESCING_SIZE)); 1278 #endif 1279 err = 0; 1280 out_err: 1281 return (err); 1282 } 1283 1284 /* 1285 * Determine a card's PCI mode. 1286 */ 1287 static void __devinit get_pci_mode(adapter_t *adapter, struct pci_params *p) 1288 { 1289 static unsigned short speed_map[] = { 33, 66, 100, 133 }; 1290 u32 pci_mode; 1291 1292 (void) t1_os_pci_read_config_4(adapter, A_PCICFG_MODE, &pci_mode); 1293 p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)]; 1294 p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32; 1295 p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0; 1296 } 1297 1298 /* 1299 * Release the structures holding the SW per-Terminator-HW-module state. 1300 */ 1301 void 1302 t1_free_sw_modules(adapter_t *adapter) 1303 { 1304 unsigned int i; 1305 1306 for_each_port(adapter, i) { 1307 struct cmac *mac = adapter->port[i].mac; 1308 struct cphy *phy = adapter->port[i].phy; 1309 1310 if (mac) 1311 mac->ops->destroy(mac); 1312 if (phy) 1313 phy->ops->destroy(phy); 1314 } 1315 1316 if (adapter->sge) 1317 (void) t1_sge_destroy(adapter->sge); 1318 if (adapter->tp) 1319 t1_tp_destroy(adapter->tp); 1320 if (adapter->espi) 1321 t1_espi_destroy(adapter->espi); 1322 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1323 if (adapter->mc5) 1324 t1_mc5_destroy(adapter->mc5); 1325 if (adapter->mc3) 1326 t1_mc3_destroy(adapter->mc3); 1327 if (adapter->mc4) 1328 t1_mc4_destroy(adapter->mc4); 1329 if (adapter->ulp) 1330 t1_ulp_destroy(adapter->ulp); 1331 #endif 1332 #ifdef CONFIG_CHELSIO_T1_COUGAR 1333 if (adapter->cspi) 1334 t1_cspi_destroy(adapter->cspi); 1335 #endif 1336 } 1337 1338 static void __devinit init_link_config(struct link_config *lc, 1339 const struct board_info *bi) 1340 { 1341 lc->supported = bi->caps; 1342 lc->requested_speed = lc->speed = SPEED_INVALID; 1343 lc->requested_duplex = lc->duplex = DUPLEX_INVALID; 1344 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; 1345 if (lc->supported & SUPPORTED_Autoneg) { 1346 lc->advertising = lc->supported; 1347 lc->autoneg = AUTONEG_ENABLE; 1348 lc->requested_fc |= PAUSE_AUTONEG; 1349 } else { 1350 lc->advertising = 0; 1351 lc->autoneg = AUTONEG_DISABLE; 1352 } 1353 } 1354 1355 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1356 void init_mtus(unsigned short mtus[]) 1357 { 1358 mtus[0] = 68; 1359 mtus[1] = 508; 1360 mtus[2] = 576; 1361 mtus[3] = 1492; 1362 mtus[4] = 1500; 1363 mtus[5] = 2000; 1364 mtus[6] = 4000; 1365 mtus[7] = 9000; 1366 } 1367 #endif 1368 1369 /* 1370 * Allocate and initialize the data structures that hold the SW state of 1371 * the Terminator HW modules. 1372 */ 1373 int __devinit t1_init_sw_modules(adapter_t *adapter, 1374 const struct board_info *bi) 1375 { 1376 unsigned int i; 1377 1378 adapter->params.brd_info = bi; 1379 adapter->params.nports = bi->port_number; 1380 adapter->params.stats_update_period = bi->gmac->stats_update_period; 1381 1382 adapter->sge = t1_sge_create(adapter, &adapter->params.sge); 1383 if (!adapter->sge) { 1384 CH_ERR("%s: SGE initialization failed\n", 1385 adapter_name(adapter)); 1386 goto error; 1387 } 1388 1389 #ifdef CONFIG_CHELSIO_T1_OFFLOAD 1390 if (bi->clock_mc4) { 1391 /* 1392 * Must wait 200us after power up before touching the 1393 * memory controllers. 1394 */ 1395 DELAY_US(200); 1396 1397 adapter->mc3 = t1_mc3_create(adapter); 1398 if (!adapter->mc3) { 1399 CH_ERR("%s: MC3 initialization failed\n", 1400 adapter_name(adapter)); 1401 goto error; 1402 } 1403 1404 adapter->mc4 = t1_mc4_create(adapter); 1405 if (!adapter->mc4) { 1406 CH_ERR("%s: MC4 initialization failed\n", 1407 adapter_name(adapter)); 1408 goto error; 1409 } 1410 1411 if (!adapter->params.mc5.mode) 1412 adapter->params.mc5.mode = MC5_MODE_144_BIT; 1413 adapter->mc5 = t1_mc5_create(adapter, 1414 adapter->params.mc5.mode); 1415 if (!adapter->mc5) { 1416 CH_ERR("%s: MC5 initialization failed\n", 1417 adapter_name(adapter)); 1418 goto error; 1419 } 1420 1421 adapter->ulp = t1_ulp_create(adapter); 1422 if (!adapter->ulp) { 1423 CH_ERR("%s: ULP initialization failed\n", 1424 adapter_name(adapter)); 1425 goto error; 1426 } 1427 1428 adapter->params.tp.pm_size = t1_mc3_get_size(adapter->mc3); 1429 adapter->params.tp.cm_size = t1_mc4_get_size(adapter->mc4); 1430 1431 adapter->params.mc5.nservers = DEFAULT_SERVER_REGION_LEN; 1432 adapter->params.mc5.nroutes = DEFAULT_RT_REGION_LEN; 1433 1434 init_mtus(adapter->params.mtus); 1435 } 1436 #endif 1437 1438 #ifdef CONFIG_CHELSIO_T1_COUGAR 1439 if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) { 1440 CH_ERR("%s: CSPI initialization failed\n", 1441 adapter_name(adapter)); 1442 goto error; 1443 } 1444 #endif 1445 1446 if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) { 1447 CH_ERR("%s: ESPI initialization failed\n", 1448 adapter_name(adapter)); 1449 goto error; 1450 } 1451 1452 adapter->tp = t1_tp_create(adapter, &adapter->params.tp); 1453 if (!adapter->tp) { 1454 CH_ERR("%s: TP initialization failed\n", 1455 adapter_name(adapter)); 1456 goto error; 1457 } 1458 1459 (void) board_init(adapter, bi); 1460 bi->mdio_ops->init(adapter, bi); 1461 if (bi->gphy->reset) 1462 bi->gphy->reset(adapter); 1463 if (bi->gmac->reset) 1464 bi->gmac->reset(adapter); 1465 1466 for_each_port(adapter, i) { 1467 u8 hw_addr[6]; 1468 struct cmac *mac; 1469 int phy_addr = bi->mdio_phybaseaddr + i; 1470 1471 adapter->port[i].phy = bi->gphy->create(adapter, phy_addr, 1472 bi->mdio_ops); 1473 if (!adapter->port[i].phy) { 1474 CH_ERR("%s: PHY %d initialization failed\n", 1475 adapter_name(adapter), i); 1476 goto error; 1477 } 1478 1479 adapter->port[i].mac = mac = bi->gmac->create(adapter, i); 1480 if (!mac) { 1481 CH_ERR("%s: MAC %d initialization failed\n", 1482 adapter_name(adapter), i); 1483 goto error; 1484 } 1485 1486 /* 1487 * Get the port's MAC addresses either from the EEPROM if one 1488 * exists or the one hardcoded in the MAC. 1489 */ 1490 if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY) 1491 mac->ops->macaddress_get(mac, hw_addr); 1492 else if (vpd_macaddress_get(adapter, i, hw_addr)) { 1493 CH_ERR("%s: could not read MAC address from VPD ROM\n", 1494 port_name(adapter, i)); 1495 goto error; 1496 } 1497 t1_os_set_hw_addr(adapter, i, hw_addr); 1498 init_link_config(&adapter->port[i].link_config, bi); 1499 } 1500 1501 get_pci_mode(adapter, &adapter->params.pci); 1502 t1_interrupts_clear(adapter); 1503 return (0); 1504 1505 error: 1506 t1_free_sw_modules(adapter); 1507 return (-1); 1508 } 1509