Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.14-rc2 812 lines 24 kB view raw
1/***************************************************************************** 2 * * 3 * File: subr.c * 4 * $Revision: 1.27 $ * 5 * $Date: 2005/06/22 01:08:36 $ * 6 * Description: * 7 * Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. * 8 * part of the Chelsio 10Gb Ethernet Driver. * 9 * * 10 * This program is free software; you can redistribute it and/or modify * 11 * it under the terms of the GNU General Public License, version 2, as * 12 * published by the Free Software Foundation. * 13 * * 14 * You should have received a copy of the GNU General Public License along * 15 * with this program; if not, write to the Free Software Foundation, Inc., * 16 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 17 * * 18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * 19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * 20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * 21 * * 22 * http://www.chelsio.com * 23 * * 24 * Copyright (c) 2003 - 2005 Chelsio Communications, Inc. * 25 * All rights reserved. * 26 * * 27 * Maintainers: maintainers@chelsio.com * 28 * * 29 * Authors: Dimitrios Michailidis <dm@chelsio.com> * 30 * Tina Yang <tainay@chelsio.com> * 31 * Felix Marti <felix@chelsio.com> * 32 * Scott Bardone <sbardone@chelsio.com> * 33 * Kurt Ottaway <kottaway@chelsio.com> * 34 * Frank DiMambro <frank@chelsio.com> * 35 * * 36 * History: * 37 * * 38 ****************************************************************************/ 39 40#include "common.h" 41#include "elmer0.h" 42#include "regs.h" 43#include "gmac.h" 44#include "cphy.h" 45#include "sge.h" 46#include "espi.h" 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 * 57 * Wait until an operation is completed by checking a bit in a register 58 * up to @attempts times. Returns %0 if the operation completes and %1 59 * otherwise. 60 */ 61static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, 62 int attempts, int delay) 63{ 64 while (1) { 65 u32 val = readl(adapter->regs + reg) & mask; 66 67 if (!!val == polarity) 68 return 0; 69 if (--attempts == 0) 70 return 1; 71 if (delay) 72 udelay(delay); 73 } 74} 75 76#define TPI_ATTEMPTS 50 77 78/* 79 * Write a register over the TPI interface (unlocked and locked versions). 80 */ 81static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) 82{ 83 int tpi_busy; 84 85 writel(addr, adapter->regs + A_TPI_ADDR); 86 writel(value, adapter->regs + A_TPI_WR_DATA); 87 writel(F_TPIWR, adapter->regs + A_TPI_CSR); 88 89 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, 90 TPI_ATTEMPTS, 3); 91 if (tpi_busy) 92 CH_ALERT("%s: TPI write to 0x%x failed\n", 93 adapter->name, addr); 94 return tpi_busy; 95} 96 97int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) 98{ 99 int ret; 100 101 spin_lock(&(adapter)->tpi_lock); 102 ret = __t1_tpi_write(adapter, addr, value); 103 spin_unlock(&(adapter)->tpi_lock); 104 return ret; 105} 106 107/* 108 * Read a register over the TPI interface (unlocked and locked versions). 109 */ 110static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) 111{ 112 int tpi_busy; 113 114 writel(addr, adapter->regs + A_TPI_ADDR); 115 writel(0, adapter->regs + A_TPI_CSR); 116 117 tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1, 118 TPI_ATTEMPTS, 3); 119 if (tpi_busy) 120 CH_ALERT("%s: TPI read from 0x%x failed\n", 121 adapter->name, addr); 122 else 123 *valp = readl(adapter->regs + A_TPI_RD_DATA); 124 return tpi_busy; 125} 126 127int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) 128{ 129 int ret; 130 131 spin_lock(&(adapter)->tpi_lock); 132 ret = __t1_tpi_read(adapter, addr, valp); 133 spin_unlock(&(adapter)->tpi_lock); 134 return ret; 135} 136 137/* 138 * Called when a port's link settings change to propagate the new values to the 139 * associated PHY and MAC. After performing the common tasks it invokes an 140 * OS-specific handler. 141 */ 142/* static */ void link_changed(adapter_t *adapter, int port_id) 143{ 144 int link_ok, speed, duplex, fc; 145 struct cphy *phy = adapter->port[port_id].phy; 146 struct link_config *lc = &adapter->port[port_id].link_config; 147 148 phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); 149 150 lc->speed = speed < 0 ? SPEED_INVALID : speed; 151 lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; 152 if (!(lc->requested_fc & PAUSE_AUTONEG)) 153 fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); 154 155 if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { 156 /* Set MAC speed, duplex, and flow control to match PHY. */ 157 struct cmac *mac = adapter->port[port_id].mac; 158 159 mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); 160 lc->fc = (unsigned char)fc; 161 } 162 t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc); 163} 164 165static int t1_pci_intr_handler(adapter_t *adapter) 166{ 167 u32 pcix_cause; 168 169 pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause); 170 171 if (pcix_cause) { 172 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 173 pcix_cause); 174 t1_fatal_err(adapter); /* PCI errors are fatal */ 175 } 176 return 0; 177} 178 179 180/* 181 * Wait until Elmer's MI1 interface is ready for new operations. 182 */ 183static int mi1_wait_until_ready(adapter_t *adapter, int mi1_reg) 184{ 185 int attempts = 100, busy; 186 187 do { 188 u32 val; 189 190 __t1_tpi_read(adapter, mi1_reg, &val); 191 busy = val & F_MI1_OP_BUSY; 192 if (busy) 193 udelay(10); 194 } while (busy && --attempts); 195 if (busy) 196 CH_ALERT("%s: MDIO operation timed out\n", 197 adapter->name); 198 return busy; 199} 200 201/* 202 * MI1 MDIO initialization. 203 */ 204static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi) 205{ 206 u32 clkdiv = bi->clock_elmer0 / (2 * bi->mdio_mdc) - 1; 207 u32 val = F_MI1_PREAMBLE_ENABLE | V_MI1_MDI_INVERT(bi->mdio_mdiinv) | 208 V_MI1_MDI_ENABLE(bi->mdio_mdien) | V_MI1_CLK_DIV(clkdiv); 209 210 if (!(bi->caps & SUPPORTED_10000baseT_Full)) 211 val |= V_MI1_SOF(1); 212 t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val); 213} 214 215static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr, 216 int reg_addr, unsigned int *valp) 217{ 218 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 219 220 spin_lock(&(adapter)->tpi_lock); 221 222 /* Write the address we want. */ 223 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 224 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); 225 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 226 MI1_OP_INDIRECT_ADDRESS); 227 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 228 229 /* Write the operation we want. */ 230 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ); 231 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 232 233 /* Read the data. */ 234 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 235 spin_unlock(&(adapter)->tpi_lock); 236 return 0; 237} 238 239static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr, 240 int reg_addr, unsigned int val) 241{ 242 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 243 244 spin_lock(&(adapter)->tpi_lock); 245 246 /* Write the address we want. */ 247 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 248 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, reg_addr); 249 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, 250 MI1_OP_INDIRECT_ADDRESS); 251 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 252 253 /* Write the data. */ 254 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); 255 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE); 256 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 257 spin_unlock(&(adapter)->tpi_lock); 258 return 0; 259} 260 261static struct mdio_ops mi1_mdio_ext_ops = { 262 mi1_mdio_init, 263 mi1_mdio_ext_read, 264 mi1_mdio_ext_write 265}; 266 267enum { 268 CH_BRD_N110_1F, 269 CH_BRD_N210_1F, 270}; 271 272static struct board_info t1_board[] = { 273 274{ CHBT_BOARD_N110, 1/*ports#*/, 275 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 276 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 277 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 278 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 279 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 280 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 281 "Chelsio N110 1x10GBaseX NIC" }, 282 283{ CHBT_BOARD_N210, 1/*ports#*/, 284 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2, 285 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 286 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/, 287 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/, 288 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops, 289 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 290 "Chelsio N210 1x10GBaseX NIC" }, 291 292}; 293 294struct pci_device_id t1_pci_tbl[] = { 295 CH_DEVICE(7, 0, CH_BRD_N110_1F), 296 CH_DEVICE(10, 1, CH_BRD_N210_1F), 297 { 0, } 298}; 299 300MODULE_DEVICE_TABLE(pci, t1_pci_tbl); 301 302/* 303 * Return the board_info structure with a given index. Out-of-range indices 304 * return NULL. 305 */ 306const struct board_info *t1_get_board_info(unsigned int board_id) 307{ 308 return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL; 309} 310 311struct chelsio_vpd_t { 312 u32 format_version; 313 u8 serial_number[16]; 314 u8 mac_base_address[6]; 315 u8 pad[2]; /* make multiple-of-4 size requirement explicit */ 316}; 317 318#define EEPROMSIZE (8 * 1024) 319#define EEPROM_MAX_POLL 4 320 321/* 322 * Read SEEPROM. A zero is written to the flag register when the addres is 323 * written to the Control register. The hardware device will set the flag to a 324 * one when 4B have been transferred to the Data register. 325 */ 326int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data) 327{ 328 int i = EEPROM_MAX_POLL; 329 u16 val; 330 331 if (addr >= EEPROMSIZE || (addr & 3)) 332 return -EINVAL; 333 334 pci_write_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, (u16)addr); 335 do { 336 udelay(50); 337 pci_read_config_word(adapter->pdev, A_PCICFG_VPD_ADDR, &val); 338 } while (!(val & F_VPD_OP_FLAG) && --i); 339 340 if (!(val & F_VPD_OP_FLAG)) { 341 CH_ERR("%s: reading EEPROM address 0x%x failed\n", 342 adapter->name, addr); 343 return -EIO; 344 } 345 pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data); 346 *data = le32_to_cpu(*data); 347 return 0; 348} 349 350static int t1_eeprom_vpd_get(adapter_t *adapter, struct chelsio_vpd_t *vpd) 351{ 352 int addr, ret = 0; 353 354 for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32)) 355 ret = t1_seeprom_read(adapter, addr, 356 (u32 *)((u8 *)vpd + addr)); 357 358 return ret; 359} 360 361/* 362 * Read a port's MAC address from the VPD ROM. 363 */ 364static int vpd_macaddress_get(adapter_t *adapter, int index, u8 mac_addr[]) 365{ 366 struct chelsio_vpd_t vpd; 367 368 if (t1_eeprom_vpd_get(adapter, &vpd)) 369 return 1; 370 memcpy(mac_addr, vpd.mac_base_address, 5); 371 mac_addr[5] = vpd.mac_base_address[5] + index; 372 return 0; 373} 374 375/* 376 * Set up the MAC/PHY according to the requested link settings. 377 * 378 * If the PHY can auto-negotiate first decide what to advertise, then 379 * enable/disable auto-negotiation as desired and reset. 380 * 381 * If the PHY does not auto-negotiate we just reset it. 382 * 383 * If auto-negotiation is off set the MAC to the proper speed/duplex/FC, 384 * otherwise do it later based on the outcome of auto-negotiation. 385 */ 386int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc) 387{ 388 unsigned int fc = lc->requested_fc & (PAUSE_RX | PAUSE_TX); 389 390 if (lc->supported & SUPPORTED_Autoneg) { 391 lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); 392 if (fc) { 393 lc->advertising |= ADVERTISED_ASYM_PAUSE; 394 if (fc == (PAUSE_RX | PAUSE_TX)) 395 lc->advertising |= ADVERTISED_PAUSE; 396 } 397 phy->ops->advertise(phy, lc->advertising); 398 399 if (lc->autoneg == AUTONEG_DISABLE) { 400 lc->speed = lc->requested_speed; 401 lc->duplex = lc->requested_duplex; 402 lc->fc = (unsigned char)fc; 403 mac->ops->set_speed_duplex_fc(mac, lc->speed, 404 lc->duplex, fc); 405 /* Also disables autoneg */ 406 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); 407 phy->ops->reset(phy, 0); 408 } else 409 phy->ops->autoneg_enable(phy); /* also resets PHY */ 410 } else { 411 mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); 412 lc->fc = (unsigned char)fc; 413 phy->ops->reset(phy, 0); 414 } 415 return 0; 416} 417 418/* 419 * External interrupt handler for boards using elmer0. 420 */ 421int elmer0_ext_intr_handler(adapter_t *adapter) 422{ 423 struct cphy *phy; 424 int phy_cause; 425 u32 cause; 426 427 t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); 428 429 switch (board_info(adapter)->board) { 430 case CHBT_BOARD_N210: 431 case CHBT_BOARD_N110: 432 if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ 433 phy = adapter->port[0].phy; 434 phy_cause = phy->ops->interrupt_handler(phy); 435 if (phy_cause & cphy_cause_link_change) 436 link_changed(adapter, 0); 437 } 438 break; 439 } 440 t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); 441 return 0; 442} 443 444/* Enables all interrupts. */ 445void t1_interrupts_enable(adapter_t *adapter) 446{ 447 unsigned int i; 448 u32 pl_intr; 449 450 adapter->slow_intr_mask = F_PL_INTR_SGE_ERR; 451 452 t1_sge_intr_enable(adapter->sge); 453 if (adapter->espi) { 454 adapter->slow_intr_mask |= F_PL_INTR_ESPI; 455 t1_espi_intr_enable(adapter->espi); 456 } 457 458 /* Enable MAC/PHY interrupts for each port. */ 459 for_each_port(adapter, i) { 460 adapter->port[i].mac->ops->interrupt_enable(adapter->port[i].mac); 461 adapter->port[i].phy->ops->interrupt_enable(adapter->port[i].phy); 462 } 463 464 /* Enable PCIX & external chip interrupts on ASIC boards. */ 465 pl_intr = readl(adapter->regs + A_PL_ENABLE); 466 467 /* PCI-X interrupts */ 468 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 469 0xffffffff); 470 471 adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 472 pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 473 writel(pl_intr, adapter->regs + A_PL_ENABLE); 474} 475 476/* Disables all interrupts. */ 477void t1_interrupts_disable(adapter_t* adapter) 478{ 479 unsigned int i; 480 481 t1_sge_intr_disable(adapter->sge); 482 if (adapter->espi) 483 t1_espi_intr_disable(adapter->espi); 484 485 /* Disable MAC/PHY interrupts for each port. */ 486 for_each_port(adapter, i) { 487 adapter->port[i].mac->ops->interrupt_disable(adapter->port[i].mac); 488 adapter->port[i].phy->ops->interrupt_disable(adapter->port[i].phy); 489 } 490 491 /* Disable PCIX & external chip interrupts. */ 492 writel(0, adapter->regs + A_PL_ENABLE); 493 494 /* PCI-X interrupts */ 495 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); 496 497 adapter->slow_intr_mask = 0; 498} 499 500/* Clears all interrupts */ 501void t1_interrupts_clear(adapter_t* adapter) 502{ 503 unsigned int i; 504 u32 pl_intr; 505 506 507 t1_sge_intr_clear(adapter->sge); 508 if (adapter->espi) 509 t1_espi_intr_clear(adapter->espi); 510 511 /* Clear MAC/PHY interrupts for each port. */ 512 for_each_port(adapter, i) { 513 adapter->port[i].mac->ops->interrupt_clear(adapter->port[i].mac); 514 adapter->port[i].phy->ops->interrupt_clear(adapter->port[i].phy); 515 } 516 517 /* Enable interrupts for external devices. */ 518 pl_intr = readl(adapter->regs + A_PL_CAUSE); 519 520 writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX, 521 adapter->regs + A_PL_CAUSE); 522 523 /* PCI-X interrupts */ 524 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff); 525} 526 527/* 528 * Slow path interrupt handler for ASICs. 529 */ 530int t1_slow_intr_handler(adapter_t *adapter) 531{ 532 u32 cause = readl(adapter->regs + A_PL_CAUSE); 533 534 cause &= adapter->slow_intr_mask; 535 if (!cause) 536 return 0; 537 if (cause & F_PL_INTR_SGE_ERR) 538 t1_sge_intr_error_handler(adapter->sge); 539 if (cause & F_PL_INTR_ESPI) 540 t1_espi_intr_handler(adapter->espi); 541 if (cause & F_PL_INTR_PCIX) 542 t1_pci_intr_handler(adapter); 543 if (cause & F_PL_INTR_EXT) 544 t1_elmer0_ext_intr(adapter); 545 546 /* Clear the interrupts just processed. */ 547 writel(cause, adapter->regs + A_PL_CAUSE); 548 (void)readl(adapter->regs + A_PL_CAUSE); /* flush writes */ 549 return 1; 550} 551 552/* Pause deadlock avoidance parameters */ 553#define DROP_MSEC 16 554#define DROP_PKTS_CNT 1 555 556static void set_csum_offload(adapter_t *adapter, u32 csum_bit, int enable) 557{ 558 u32 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); 559 560 if (enable) 561 val |= csum_bit; 562 else 563 val &= ~csum_bit; 564 writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); 565} 566 567void t1_tp_set_ip_checksum_offload(adapter_t *adapter, int enable) 568{ 569 set_csum_offload(adapter, F_IP_CSUM, enable); 570} 571 572void t1_tp_set_udp_checksum_offload(adapter_t *adapter, int enable) 573{ 574 set_csum_offload(adapter, F_UDP_CSUM, enable); 575} 576 577void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable) 578{ 579 set_csum_offload(adapter, F_TCP_CSUM, enable); 580} 581 582static void t1_tp_reset(adapter_t *adapter, unsigned int tp_clk) 583{ 584 u32 val; 585 586 val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | 587 F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; 588 val |= F_TP_IN_ESPI_CHECK_IP_CSUM | 589 F_TP_IN_ESPI_CHECK_TCP_CSUM; 590 writel(val, adapter->regs + A_TP_IN_CONFIG); 591 writel(F_TP_OUT_CSPI_CPL | 592 F_TP_OUT_ESPI_ETHERNET | 593 F_TP_OUT_ESPI_GENERATE_IP_CSUM | 594 F_TP_OUT_ESPI_GENERATE_TCP_CSUM, 595 adapter->regs + A_TP_OUT_CONFIG); 596 597 val = readl(adapter->regs + A_TP_GLOBAL_CONFIG); 598 val &= ~(F_IP_CSUM | F_UDP_CSUM | F_TCP_CSUM); 599 writel(val, adapter->regs + A_TP_GLOBAL_CONFIG); 600 601 /* 602 * Enable pause frame deadlock prevention. 603 */ 604 if (is_T2(adapter)) { 605 u32 drop_ticks = DROP_MSEC * (tp_clk / 1000); 606 607 writel(F_ENABLE_TX_DROP | F_ENABLE_TX_ERROR | 608 V_DROP_TICKS_CNT(drop_ticks) | 609 V_NUM_PKTS_DROPPED(DROP_PKTS_CNT), 610 adapter->regs + A_TP_TX_DROP_CONFIG); 611 } 612 613 writel(F_TP_RESET, adapter->regs + A_TP_RESET); 614} 615 616int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, 617 struct adapter_params *p) 618{ 619 p->chip_version = bi->chip_term; 620 if (p->chip_version == CHBT_TERM_T1 || 621 p->chip_version == CHBT_TERM_T2) { 622 u32 val = readl(adapter->regs + A_TP_PC_CONFIG); 623 624 val = G_TP_PC_REV(val); 625 if (val == 2) 626 p->chip_revision = TERM_T1B; 627 else if (val == 3) 628 p->chip_revision = TERM_T2; 629 else 630 return -1; 631 } else 632 return -1; 633 return 0; 634} 635 636/* 637 * Enable board components other than the Chelsio chip, such as external MAC 638 * and PHY. 639 */ 640static int board_init(adapter_t *adapter, const struct board_info *bi) 641{ 642 switch (bi->board) { 643 case CHBT_BOARD_N110: 644 case CHBT_BOARD_N210: 645 writel(V_TPIPAR(0xf), adapter->regs + A_TPI_PAR); 646 t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); 647 break; 648 } 649 return 0; 650} 651 652/* 653 * Initialize and configure the Terminator HW modules. Note that external 654 * MAC and PHYs are initialized separately. 655 */ 656int t1_init_hw_modules(adapter_t *adapter) 657{ 658 int err = -EIO; 659 const struct board_info *bi = board_info(adapter); 660 661 if (!bi->clock_mc4) { 662 u32 val = readl(adapter->regs + A_MC4_CFG); 663 664 writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG); 665 writel(F_M_BUS_ENABLE | F_TCAM_RESET, 666 adapter->regs + A_MC5_CONFIG); 667 } 668 669 if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac, 670 bi->espi_nports)) 671 goto out_err; 672 673 t1_tp_reset(adapter, bi->clock_core); 674 675 err = t1_sge_configure(adapter->sge, &adapter->params.sge); 676 if (err) 677 goto out_err; 678 679 err = 0; 680 out_err: 681 return err; 682} 683 684/* 685 * Determine a card's PCI mode. 686 */ 687static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p) 688{ 689 static unsigned short speed_map[] = { 33, 66, 100, 133 }; 690 u32 pci_mode; 691 692 pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode); 693 p->speed = speed_map[G_PCI_MODE_CLK(pci_mode)]; 694 p->width = (pci_mode & F_PCI_MODE_64BIT) ? 64 : 32; 695 p->is_pcix = (pci_mode & F_PCI_MODE_PCIX) != 0; 696} 697 698/* 699 * Release the structures holding the SW per-Terminator-HW-module state. 700 */ 701void t1_free_sw_modules(adapter_t *adapter) 702{ 703 unsigned int i; 704 705 for_each_port(adapter, i) { 706 struct cmac *mac = adapter->port[i].mac; 707 struct cphy *phy = adapter->port[i].phy; 708 709 if (mac) 710 mac->ops->destroy(mac); 711 if (phy) 712 phy->ops->destroy(phy); 713 } 714 715 if (adapter->sge) 716 t1_sge_destroy(adapter->sge); 717 if (adapter->espi) 718 t1_espi_destroy(adapter->espi); 719} 720 721static void __devinit init_link_config(struct link_config *lc, 722 const struct board_info *bi) 723{ 724 lc->supported = bi->caps; 725 lc->requested_speed = lc->speed = SPEED_INVALID; 726 lc->requested_duplex = lc->duplex = DUPLEX_INVALID; 727 lc->requested_fc = lc->fc = PAUSE_RX | PAUSE_TX; 728 if (lc->supported & SUPPORTED_Autoneg) { 729 lc->advertising = lc->supported; 730 lc->autoneg = AUTONEG_ENABLE; 731 lc->requested_fc |= PAUSE_AUTONEG; 732 } else { 733 lc->advertising = 0; 734 lc->autoneg = AUTONEG_DISABLE; 735 } 736} 737 738 739/* 740 * Allocate and initialize the data structures that hold the SW state of 741 * the Terminator HW modules. 742 */ 743int __devinit t1_init_sw_modules(adapter_t *adapter, 744 const struct board_info *bi) 745{ 746 unsigned int i; 747 748 adapter->params.brd_info = bi; 749 adapter->params.nports = bi->port_number; 750 adapter->params.stats_update_period = bi->gmac->stats_update_period; 751 752 adapter->sge = t1_sge_create(adapter, &adapter->params.sge); 753 if (!adapter->sge) { 754 CH_ERR("%s: SGE initialization failed\n", 755 adapter->name); 756 goto error; 757 } 758 759 if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) { 760 CH_ERR("%s: ESPI initialization failed\n", 761 adapter->name); 762 goto error; 763 } 764 765 board_init(adapter, bi); 766 bi->mdio_ops->init(adapter, bi); 767 if (bi->gphy->reset) 768 bi->gphy->reset(adapter); 769 if (bi->gmac->reset) 770 bi->gmac->reset(adapter); 771 772 for_each_port(adapter, i) { 773 u8 hw_addr[6]; 774 struct cmac *mac; 775 int phy_addr = bi->mdio_phybaseaddr + i; 776 777 adapter->port[i].phy = bi->gphy->create(adapter, phy_addr, 778 bi->mdio_ops); 779 if (!adapter->port[i].phy) { 780 CH_ERR("%s: PHY %d initialization failed\n", 781 adapter->name, i); 782 goto error; 783 } 784 785 adapter->port[i].mac = mac = bi->gmac->create(adapter, i); 786 if (!mac) { 787 CH_ERR("%s: MAC %d initialization failed\n", 788 adapter->name, i); 789 goto error; 790 } 791 792 /* 793 * Get the port's MAC addresses either from the EEPROM if one 794 * exists or the one hardcoded in the MAC. 795 */ 796 if (vpd_macaddress_get(adapter, i, hw_addr)) { 797 CH_ERR("%s: could not read MAC address from VPD ROM\n", 798 adapter->port[i].dev->name); 799 goto error; 800 } 801 memcpy(adapter->port[i].dev->dev_addr, hw_addr, ETH_ALEN); 802 init_link_config(&adapter->port[i].link_config, bi); 803 } 804 805 get_pci_mode(adapter, &adapter->params.pci); 806 t1_interrupts_clear(adapter); 807 return 0; 808 809 error: 810 t1_free_sw_modules(adapter); 811 return -1; 812}