aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/chelsio/subr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/chelsio/subr.c')
-rw-r--r--drivers/net/chelsio/subr.c265
1 files changed, 165 insertions, 100 deletions
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index e4473ec43d26..d41d15a71e4d 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -43,6 +43,7 @@
43#include "gmac.h" 43#include "gmac.h"
44#include "cphy.h" 44#include "cphy.h"
45#include "sge.h" 45#include "sge.h"
46#include "tp.h"
46#include "espi.h" 47#include "espi.h"
47 48
48/** 49/**
@@ -59,7 +60,7 @@
59 * otherwise. 60 * otherwise.
60 */ 61 */
61static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity, 62static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
62 int attempts, int delay) 63 int attempts, int delay)
63{ 64{
64 while (1) { 65 while (1) {
65 u32 val = readl(adapter->regs + reg) & mask; 66 u32 val = readl(adapter->regs + reg) & mask;
@@ -78,7 +79,7 @@ static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
78/* 79/*
79 * Write a register over the TPI interface (unlocked and locked versions). 80 * Write a register over the TPI interface (unlocked and locked versions).
80 */ 81 */
81static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value) 82int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
82{ 83{
83 int tpi_busy; 84 int tpi_busy;
84 85
@@ -98,16 +99,16 @@ int t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
98{ 99{
99 int ret; 100 int ret;
100 101
101 spin_lock(&(adapter)->tpi_lock); 102 spin_lock(&adapter->tpi_lock);
102 ret = __t1_tpi_write(adapter, addr, value); 103 ret = __t1_tpi_write(adapter, addr, value);
103 spin_unlock(&(adapter)->tpi_lock); 104 spin_unlock(&adapter->tpi_lock);
104 return ret; 105 return ret;
105} 106}
106 107
107/* 108/*
108 * Read a register over the TPI interface (unlocked and locked versions). 109 * Read a register over the TPI interface (unlocked and locked versions).
109 */ 110 */
110static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp) 111int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
111{ 112{
112 int tpi_busy; 113 int tpi_busy;
113 114
@@ -128,18 +129,26 @@ int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
128{ 129{
129 int ret; 130 int ret;
130 131
131 spin_lock(&(adapter)->tpi_lock); 132 spin_lock(&adapter->tpi_lock);
132 ret = __t1_tpi_read(adapter, addr, valp); 133 ret = __t1_tpi_read(adapter, addr, valp);
133 spin_unlock(&(adapter)->tpi_lock); 134 spin_unlock(&adapter->tpi_lock);
134 return ret; 135 return ret;
135} 136}
136 137
137/* 138/*
139 * Set a TPI parameter.
140 */
141static void t1_tpi_par(adapter_t *adapter, u32 value)
142{
143 writel(V_TPIPAR(value), adapter->regs + A_TPI_PAR);
144}
145
146/*
138 * Called when a port's link settings change to propagate the new values to the 147 * 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 148 * associated PHY and MAC. After performing the common tasks it invokes an
140 * OS-specific handler. 149 * OS-specific handler.
141 */ 150 */
142/* static */ void link_changed(adapter_t *adapter, int port_id) 151void t1_link_changed(adapter_t *adapter, int port_id)
143{ 152{
144 int link_ok, speed, duplex, fc; 153 int link_ok, speed, duplex, fc;
145 struct cphy *phy = adapter->port[port_id].phy; 154 struct cphy *phy = adapter->port[port_id].phy;
@@ -159,7 +168,7 @@ int t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
159 mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc); 168 mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
160 lc->fc = (unsigned char)fc; 169 lc->fc = (unsigned char)fc;
161 } 170 }
162 t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc); 171 t1_link_negotiated(adapter, port_id, link_ok, speed, duplex, fc);
163} 172}
164 173
165static int t1_pci_intr_handler(adapter_t *adapter) 174static int t1_pci_intr_handler(adapter_t *adapter)
@@ -217,7 +226,7 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
217{ 226{
218 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 227 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
219 228
220 spin_lock(&(adapter)->tpi_lock); 229 spin_lock(&adapter->tpi_lock);
221 230
222 /* Write the address we want. */ 231 /* Write the address we want. */
223 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 232 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
@@ -227,12 +236,13 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
227 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 236 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
228 237
229 /* Write the operation we want. */ 238 /* Write the operation we want. */
230 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ); 239 __t1_tpi_write(adapter,
240 A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
231 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 241 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
232 242
233 /* Read the data. */ 243 /* Read the data. */
234 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp); 244 __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
235 spin_unlock(&(adapter)->tpi_lock); 245 spin_unlock(&adapter->tpi_lock);
236 return 0; 246 return 0;
237} 247}
238 248
@@ -241,7 +251,7 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
241{ 251{
242 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr); 252 u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
243 253
244 spin_lock(&(adapter)->tpi_lock); 254 spin_lock(&adapter->tpi_lock);
245 255
246 /* Write the address we want. */ 256 /* Write the address we want. */
247 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr); 257 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
@@ -254,7 +264,7 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
254 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val); 264 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
255 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE); 265 __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE);
256 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP); 266 mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
257 spin_unlock(&(adapter)->tpi_lock); 267 spin_unlock(&adapter->tpi_lock);
258 return 0; 268 return 0;
259} 269}
260 270
@@ -265,12 +275,25 @@ static struct mdio_ops mi1_mdio_ext_ops = {
265}; 275};
266 276
267enum { 277enum {
278 CH_BRD_T110_1CU,
268 CH_BRD_N110_1F, 279 CH_BRD_N110_1F,
269 CH_BRD_N210_1F, 280 CH_BRD_N210_1F,
281 CH_BRD_T210_1F,
282 CH_BRD_T210_1CU,
283 CH_BRD_N204_4CU,
270}; 284};
271 285
272static struct board_info t1_board[] = { 286static struct board_info t1_board[] = {
273 287
288{ CHBT_BOARD_CHT110, 1/*ports#*/,
289 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T1,
290 CHBT_MAC_PM3393, CHBT_PHY_MY3126,
291 125000000/*clk-core*/, 150000000/*clk-mc3*/, 125000000/*clk-mc4*/,
292 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/,
293 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops,
294 &t1_my3126_ops, &mi1_mdio_ext_ops,
295 "Chelsio T110 1x10GBase-CX4 TOE" },
296
274{ CHBT_BOARD_N110, 1/*ports#*/, 297{ CHBT_BOARD_N110, 1/*ports#*/,
275 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1, 298 SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
276 CHBT_MAC_PM3393, CHBT_PHY_88X2010, 299 CHBT_MAC_PM3393, CHBT_PHY_88X2010,
@@ -289,12 +312,36 @@ static struct board_info t1_board[] = {
289 &t1_mv88x201x_ops, &mi1_mdio_ext_ops, 312 &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
290 "Chelsio N210 1x10GBaseX NIC" }, 313 "Chelsio N210 1x10GBaseX NIC" },
291 314
315{ CHBT_BOARD_CHT210, 1/*ports#*/,
316 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2,
317 CHBT_MAC_PM3393, CHBT_PHY_88X2010,
318 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/,
319 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
320 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
321 &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
322 "Chelsio T210 1x10GBaseX TOE" },
323
324{ CHBT_BOARD_CHT210, 1/*ports#*/,
325 SUPPORTED_10000baseT_Full /*caps*/, CHBT_TERM_T2,
326 CHBT_MAC_PM3393, CHBT_PHY_MY3126,
327 125000000/*clk-core*/, 133000000/*clk-mc3*/, 125000000/*clk-mc4*/,
328 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 1/*mdien*/,
329 1/*mdiinv*/, 1/*mdc*/, 1/*phybaseaddr*/, &t1_pm3393_ops,
330 &t1_my3126_ops, &mi1_mdio_ext_ops,
331 "Chelsio T210 1x10GBase-CX4 TOE" },
332
333
292}; 334};
293 335
294struct pci_device_id t1_pci_tbl[] = { 336struct pci_device_id t1_pci_tbl[] = {
337 CH_DEVICE(8, 0, CH_BRD_T110_1CU),
338 CH_DEVICE(8, 1, CH_BRD_T110_1CU),
295 CH_DEVICE(7, 0, CH_BRD_N110_1F), 339 CH_DEVICE(7, 0, CH_BRD_N110_1F),
296 CH_DEVICE(10, 1, CH_BRD_N210_1F), 340 CH_DEVICE(10, 1, CH_BRD_N210_1F),
297 { 0, } 341 CH_DEVICE(11, 1, CH_BRD_T210_1F),
342 CH_DEVICE(14, 1, CH_BRD_T210_1CU),
343 CH_DEVICE(16, 1, CH_BRD_N204_4CU),
344 { 0 }
298}; 345};
299 346
300MODULE_DEVICE_TABLE(pci, t1_pci_tbl); 347MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
@@ -390,9 +437,14 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
390 if (lc->supported & SUPPORTED_Autoneg) { 437 if (lc->supported & SUPPORTED_Autoneg) {
391 lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE); 438 lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
392 if (fc) { 439 if (fc) {
393 lc->advertising |= ADVERTISED_ASYM_PAUSE; 440 if (fc == ((PAUSE_RX | PAUSE_TX) &
394 if (fc == (PAUSE_RX | PAUSE_TX)) 441 (mac->adapter->params.nports < 2)))
395 lc->advertising |= ADVERTISED_PAUSE; 442 lc->advertising |= ADVERTISED_PAUSE;
443 else {
444 lc->advertising |= ADVERTISED_ASYM_PAUSE;
445 if (fc == PAUSE_RX)
446 lc->advertising |= ADVERTISED_PAUSE;
447 }
396 } 448 }
397 phy->ops->advertise(phy, lc->advertising); 449 phy->ops->advertise(phy, lc->advertising);
398 450
@@ -403,11 +455,15 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
403 mac->ops->set_speed_duplex_fc(mac, lc->speed, 455 mac->ops->set_speed_duplex_fc(mac, lc->speed,
404 lc->duplex, fc); 456 lc->duplex, fc);
405 /* Also disables autoneg */ 457 /* Also disables autoneg */
458 phy->state = PHY_AUTONEG_RDY;
406 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex); 459 phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
407 phy->ops->reset(phy, 0); 460 phy->ops->reset(phy, 0);
408 } else 461 } else {
462 phy->state = PHY_AUTONEG_EN;
409 phy->ops->autoneg_enable(phy); /* also resets PHY */ 463 phy->ops->autoneg_enable(phy); /* also resets PHY */
464 }
410 } else { 465 } else {
466 phy->state = PHY_AUTONEG_RDY;
411 mac->ops->set_speed_duplex_fc(mac, -1, -1, fc); 467 mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
412 lc->fc = (unsigned char)fc; 468 lc->fc = (unsigned char)fc;
413 phy->ops->reset(phy, 0); 469 phy->ops->reset(phy, 0);
@@ -418,7 +474,7 @@ int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc)
418/* 474/*
419 * External interrupt handler for boards using elmer0. 475 * External interrupt handler for boards using elmer0.
420 */ 476 */
421int elmer0_ext_intr_handler(adapter_t *adapter) 477int t1_elmer0_ext_intr_handler(adapter_t *adapter)
422{ 478{
423 struct cphy *phy; 479 struct cphy *phy;
424 int phy_cause; 480 int phy_cause;
@@ -427,14 +483,33 @@ int elmer0_ext_intr_handler(adapter_t *adapter)
427 t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause); 483 t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);
428 484
429 switch (board_info(adapter)->board) { 485 switch (board_info(adapter)->board) {
486 case CHBT_BOARD_CHT210:
430 case CHBT_BOARD_N210: 487 case CHBT_BOARD_N210:
431 case CHBT_BOARD_N110: 488 case CHBT_BOARD_N110:
432 if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */ 489 if (cause & ELMER0_GP_BIT6) { /* Marvell 88x2010 interrupt */
433 phy = adapter->port[0].phy; 490 phy = adapter->port[0].phy;
434 phy_cause = phy->ops->interrupt_handler(phy); 491 phy_cause = phy->ops->interrupt_handler(phy);
435 if (phy_cause & cphy_cause_link_change) 492 if (phy_cause & cphy_cause_link_change)
436 link_changed(adapter, 0); 493 t1_link_changed(adapter, 0);
494 }
495 break;
496 case CHBT_BOARD_8000:
497 case CHBT_BOARD_CHT110:
498 CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
499 cause);
500 if (cause & ELMER0_GP_BIT1) { /* PMC3393 INTB */
501 struct cmac *mac = adapter->port[0].mac;
502
503 mac->ops->interrupt_handler(mac);
437 } 504 }
505 if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */
506 u32 mod_detect;
507
508 t1_tpi_read(adapter,
509 A_ELMER0_GPI_STAT, &mod_detect);
510 CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
511 mod_detect ? "removed" : "inserted");
512 }
438 break; 513 break;
439 } 514 }
440 t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause); 515 t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
@@ -445,11 +520,11 @@ int elmer0_ext_intr_handler(adapter_t *adapter)
445void t1_interrupts_enable(adapter_t *adapter) 520void t1_interrupts_enable(adapter_t *adapter)
446{ 521{
447 unsigned int i; 522 unsigned int i;
448 u32 pl_intr;
449 523
450 adapter->slow_intr_mask = F_PL_INTR_SGE_ERR; 524 adapter->slow_intr_mask = F_PL_INTR_SGE_ERR | F_PL_INTR_TP;
451 525
452 t1_sge_intr_enable(adapter->sge); 526 t1_sge_intr_enable(adapter->sge);
527 t1_tp_intr_enable(adapter->tp);
453 if (adapter->espi) { 528 if (adapter->espi) {
454 adapter->slow_intr_mask |= F_PL_INTR_ESPI; 529 adapter->slow_intr_mask |= F_PL_INTR_ESPI;
455 t1_espi_intr_enable(adapter->espi); 530 t1_espi_intr_enable(adapter->espi);
@@ -462,15 +537,17 @@ void t1_interrupts_enable(adapter_t *adapter)
462 } 537 }
463 538
464 /* Enable PCIX & external chip interrupts on ASIC boards. */ 539 /* Enable PCIX & external chip interrupts on ASIC boards. */
465 pl_intr = readl(adapter->regs + A_PL_ENABLE); 540 if (t1_is_asic(adapter)) {
541 u32 pl_intr = readl(adapter->regs + A_PL_ENABLE);
466 542
467 /* PCI-X interrupts */ 543 /* PCI-X interrupts */
468 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 544 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE,
469 0xffffffff); 545 0xffffffff);
470 546
471 adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 547 adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
472 pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX; 548 pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
473 writel(pl_intr, adapter->regs + A_PL_ENABLE); 549 writel(pl_intr, adapter->regs + A_PL_ENABLE);
550 }
474} 551}
475 552
476/* Disables all interrupts. */ 553/* Disables all interrupts. */
@@ -479,6 +556,7 @@ void t1_interrupts_disable(adapter_t* adapter)
479 unsigned int i; 556 unsigned int i;
480 557
481 t1_sge_intr_disable(adapter->sge); 558 t1_sge_intr_disable(adapter->sge);
559 t1_tp_intr_disable(adapter->tp);
482 if (adapter->espi) 560 if (adapter->espi)
483 t1_espi_intr_disable(adapter->espi); 561 t1_espi_intr_disable(adapter->espi);
484 562
@@ -489,7 +567,8 @@ void t1_interrupts_disable(adapter_t* adapter)
489 } 567 }
490 568
491 /* Disable PCIX & external chip interrupts. */ 569 /* Disable PCIX & external chip interrupts. */
492 writel(0, adapter->regs + A_PL_ENABLE); 570 if (t1_is_asic(adapter))
571 writel(0, adapter->regs + A_PL_ENABLE);
493 572
494 /* PCI-X interrupts */ 573 /* PCI-X interrupts */
495 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0); 574 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0);
@@ -501,10 +580,9 @@ void t1_interrupts_disable(adapter_t* adapter)
501void t1_interrupts_clear(adapter_t* adapter) 580void t1_interrupts_clear(adapter_t* adapter)
502{ 581{
503 unsigned int i; 582 unsigned int i;
504 u32 pl_intr;
505
506 583
507 t1_sge_intr_clear(adapter->sge); 584 t1_sge_intr_clear(adapter->sge);
585 t1_tp_intr_clear(adapter->tp);
508 if (adapter->espi) 586 if (adapter->espi)
509 t1_espi_intr_clear(adapter->espi); 587 t1_espi_intr_clear(adapter->espi);
510 588
@@ -515,10 +593,12 @@ void t1_interrupts_clear(adapter_t* adapter)
515 } 593 }
516 594
517 /* Enable interrupts for external devices. */ 595 /* Enable interrupts for external devices. */
518 pl_intr = readl(adapter->regs + A_PL_CAUSE); 596 if (t1_is_asic(adapter)) {
597 u32 pl_intr = readl(adapter->regs + A_PL_CAUSE);
519 598
520 writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX, 599 writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX,
521 adapter->regs + A_PL_CAUSE); 600 adapter->regs + A_PL_CAUSE);
601 }
522 602
523 /* PCI-X interrupts */ 603 /* PCI-X interrupts */
524 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff); 604 pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, 0xffffffff);
@@ -527,7 +607,7 @@ void t1_interrupts_clear(adapter_t* adapter)
527/* 607/*
528 * Slow path interrupt handler for ASICs. 608 * Slow path interrupt handler for ASICs.
529 */ 609 */
530int t1_slow_intr_handler(adapter_t *adapter) 610static int asic_slow_intr(adapter_t *adapter)
531{ 611{
532 u32 cause = readl(adapter->regs + A_PL_CAUSE); 612 u32 cause = readl(adapter->regs + A_PL_CAUSE);
533 613
@@ -536,89 +616,50 @@ int t1_slow_intr_handler(adapter_t *adapter)
536 return 0; 616 return 0;
537 if (cause & F_PL_INTR_SGE_ERR) 617 if (cause & F_PL_INTR_SGE_ERR)
538 t1_sge_intr_error_handler(adapter->sge); 618 t1_sge_intr_error_handler(adapter->sge);
619 if (cause & F_PL_INTR_TP)
620 t1_tp_intr_handler(adapter->tp);
539 if (cause & F_PL_INTR_ESPI) 621 if (cause & F_PL_INTR_ESPI)
540 t1_espi_intr_handler(adapter->espi); 622 t1_espi_intr_handler(adapter->espi);
541 if (cause & F_PL_INTR_PCIX) 623 if (cause & F_PL_INTR_PCIX)
542 t1_pci_intr_handler(adapter); 624 t1_pci_intr_handler(adapter);
543 if (cause & F_PL_INTR_EXT) 625 if (cause & F_PL_INTR_EXT)
544 t1_elmer0_ext_intr(adapter); 626 t1_elmer0_ext_intr_handler(adapter);
545 627
546 /* Clear the interrupts just processed. */ 628 /* Clear the interrupts just processed. */
547 writel(cause, adapter->regs + A_PL_CAUSE); 629 writel(cause, adapter->regs + A_PL_CAUSE);
548 (void)readl(adapter->regs + A_PL_CAUSE); /* flush writes */ 630 readl(adapter->regs + A_PL_CAUSE); /* flush writes */
549 return 1; 631 return 1;
550} 632}
551 633
552/* Pause deadlock avoidance parameters */ 634int t1_slow_intr_handler(adapter_t *adapter)
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{ 635{
574 set_csum_offload(adapter, F_UDP_CSUM, enable); 636 return asic_slow_intr(adapter);
575} 637}
576 638
577void t1_tp_set_tcp_checksum_offload(adapter_t *adapter, int enable) 639/* Power sequencing is a work-around for Intel's XPAKs. */
640static void power_sequence_xpak(adapter_t* adapter)
578{ 641{
579 set_csum_offload(adapter, F_TCP_CSUM, enable); 642 u32 mod_detect;
580} 643 u32 gpo;
581 644
582static void t1_tp_reset(adapter_t *adapter, unsigned int tp_clk) 645 /* Check for XPAK */
583{ 646 t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
584 u32 val; 647 if (!(ELMER0_GP_BIT5 & mod_detect)) {
585 648 /* XPAK is present */
586 val = F_TP_IN_CSPI_CPL | F_TP_IN_CSPI_CHECK_IP_CSUM | 649 t1_tpi_read(adapter, A_ELMER0_GPO, &gpo);
587 F_TP_IN_CSPI_CHECK_TCP_CSUM | F_TP_IN_ESPI_ETHERNET; 650 gpo |= ELMER0_GP_BIT18;
588 val |= F_TP_IN_ESPI_CHECK_IP_CSUM | 651 t1_tpi_write(adapter, A_ELMER0_GPO, gpo);
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 } 652 }
612
613 writel(F_TP_RESET, adapter->regs + A_TP_RESET);
614} 653}
615 654
616int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi, 655int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
617 struct adapter_params *p) 656 struct adapter_params *p)
618{ 657{
619 p->chip_version = bi->chip_term; 658 p->chip_version = bi->chip_term;
659 p->is_asic = (p->chip_version != CHBT_TERM_FPGA);
620 if (p->chip_version == CHBT_TERM_T1 || 660 if (p->chip_version == CHBT_TERM_T1 ||
621 p->chip_version == CHBT_TERM_T2) { 661 p->chip_version == CHBT_TERM_T2 ||
662 p->chip_version == CHBT_TERM_FPGA) {
622 u32 val = readl(adapter->regs + A_TP_PC_CONFIG); 663 u32 val = readl(adapter->regs + A_TP_PC_CONFIG);
623 664
624 val = G_TP_PC_REV(val); 665 val = G_TP_PC_REV(val);
@@ -640,10 +681,22 @@ int __devinit t1_get_board_rev(adapter_t *adapter, const struct board_info *bi,
640static int board_init(adapter_t *adapter, const struct board_info *bi) 681static int board_init(adapter_t *adapter, const struct board_info *bi)
641{ 682{
642 switch (bi->board) { 683 switch (bi->board) {
684 case CHBT_BOARD_8000:
643 case CHBT_BOARD_N110: 685 case CHBT_BOARD_N110:
644 case CHBT_BOARD_N210: 686 case CHBT_BOARD_N210:
645 writel(V_TPIPAR(0xf), adapter->regs + A_TPI_PAR); 687 case CHBT_BOARD_CHT210:
646 t1_tpi_write(adapter, A_ELMER0_GPO, 0x800); 688 case CHBT_BOARD_COUGAR:
689 t1_tpi_par(adapter, 0xf);
690 t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
691 break;
692 case CHBT_BOARD_CHT110:
693 t1_tpi_par(adapter, 0xf);
694 t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);
695
696 /* TBD XXX Might not need. This fixes a problem
697 * described in the Intel SR XPAK errata.
698 */
699 power_sequence_xpak(adapter);
647 break; 700 break;
648 } 701 }
649 return 0; 702 return 0;
@@ -670,7 +723,8 @@ int t1_init_hw_modules(adapter_t *adapter)
670 bi->espi_nports)) 723 bi->espi_nports))
671 goto out_err; 724 goto out_err;
672 725
673 t1_tp_reset(adapter, bi->clock_core); 726 if (t1_tp_reset(adapter->tp, &adapter->params.tp, bi->clock_core))
727 goto out_err;
674 728
675 err = t1_sge_configure(adapter->sge, &adapter->params.sge); 729 err = t1_sge_configure(adapter->sge, &adapter->params.sge);
676 if (err) 730 if (err)
@@ -714,6 +768,8 @@ void t1_free_sw_modules(adapter_t *adapter)
714 768
715 if (adapter->sge) 769 if (adapter->sge)
716 t1_sge_destroy(adapter->sge); 770 t1_sge_destroy(adapter->sge);
771 if (adapter->tp)
772 t1_tp_destroy(adapter->tp);
717 if (adapter->espi) 773 if (adapter->espi)
718 t1_espi_destroy(adapter->espi); 774 t1_espi_destroy(adapter->espi);
719} 775}
@@ -762,6 +818,13 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
762 goto error; 818 goto error;
763 } 819 }
764 820
821 adapter->tp = t1_tp_create(adapter, &adapter->params.tp);
822 if (!adapter->tp) {
823 CH_ERR("%s: TP initialization failed\n",
824 adapter->name);
825 goto error;
826 }
827
765 board_init(adapter, bi); 828 board_init(adapter, bi);
766 bi->mdio_ops->init(adapter, bi); 829 bi->mdio_ops->init(adapter, bi);
767 if (bi->gphy->reset) 830 if (bi->gphy->reset)
@@ -793,7 +856,9 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
793 * Get the port's MAC addresses either from the EEPROM if one 856 * Get the port's MAC addresses either from the EEPROM if one
794 * exists or the one hardcoded in the MAC. 857 * exists or the one hardcoded in the MAC.
795 */ 858 */
796 if (vpd_macaddress_get(adapter, i, hw_addr)) { 859 if (!t1_is_asic(adapter) || bi->chip_mac == CHBT_MAC_DUMMY)
860 mac->ops->macaddress_get(mac, hw_addr);
861 else if (vpd_macaddress_get(adapter, i, hw_addr)) {
797 CH_ERR("%s: could not read MAC address from VPD ROM\n", 862 CH_ERR("%s: could not read MAC address from VPD ROM\n",
798 adapter->port[i].dev->name); 863 adapter->port[i].dev->name);
799 goto error; 864 goto error;
@@ -806,7 +871,7 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
806 t1_interrupts_clear(adapter); 871 t1_interrupts_clear(adapter);
807 return 0; 872 return 0;
808 873
809 error: 874error:
810 t1_free_sw_modules(adapter); 875 t1_free_sw_modules(adapter);
811 return -1; 876 return -1;
812} 877}