aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/xgmac.c
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2007-04-09 23:10:27 -0400
committerJeff Garzik <jeff@garzik.org>2007-04-11 11:54:43 -0400
commit59cf81076a85e1df273155298c462574b49cc0fe (patch)
treed03245a0621b241fe5afa0e86bc65c8db28001e1 /drivers/net/cxgb3/xgmac.c
parentf2d961c9827bab4b64a1b4ea30c68cf5ab2b2330 (diff)
cxgb3 - MAC watchdog update
The MAC watchdog was failing if the peer interface was brought down. Signed-off-by: Divy Le Ray <divy@chelsio.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/cxgb3/xgmac.c')
-rw-r--r--drivers/net/cxgb3/xgmac.c107
1 files changed, 80 insertions, 27 deletions
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index 94aaff005a35..a506792f9575 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -367,7 +367,8 @@ int t3_mac_enable(struct cmac *mac, int which)
367 int idx = macidx(mac); 367 int idx = macidx(mac);
368 struct adapter *adap = mac->adapter; 368 struct adapter *adap = mac->adapter;
369 unsigned int oft = mac->offset; 369 unsigned int oft = mac->offset;
370 370 struct mac_stats *s = &mac->stats;
371
371 if (which & MAC_DIRECTION_TX) { 372 if (which & MAC_DIRECTION_TX) {
372 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); 373 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN);
373 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); 374 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx);
@@ -376,10 +377,16 @@ int t3_mac_enable(struct cmac *mac, int which)
376 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 377 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
377 378
378 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx); 379 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx);
379 mac->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, 380 mac->tx_mcnt = s->tx_frames;
380 A_TP_PIO_DATA))); 381 mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
381 mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 382 A_TP_PIO_DATA)));
382 A_XGM_TX_SPI4_SOP_EOP_CNT))); 383 mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
384 A_XGM_TX_SPI4_SOP_EOP_CNT +
385 oft)));
386 mac->rx_mcnt = s->rx_frames;
387 mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
388 A_XGM_RX_SPI4_SOP_EOP_CNT +
389 oft)));
383 mac->txen = F_TXEN; 390 mac->txen = F_TXEN;
384 mac->toggle_cnt = 0; 391 mac->toggle_cnt = 0;
385 } 392 }
@@ -392,6 +399,7 @@ int t3_mac_disable(struct cmac *mac, int which)
392{ 399{
393 int idx = macidx(mac); 400 int idx = macidx(mac);
394 struct adapter *adap = mac->adapter; 401 struct adapter *adap = mac->adapter;
402 int val;
395 403
396 if (which & MAC_DIRECTION_TX) { 404 if (which & MAC_DIRECTION_TX) {
397 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); 405 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
@@ -401,44 +409,89 @@ int t3_mac_disable(struct cmac *mac, int which)
401 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 409 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx);
402 mac->txen = 0; 410 mac->txen = 0;
403 } 411 }
404 if (which & MAC_DIRECTION_RX) 412 if (which & MAC_DIRECTION_RX) {
413 t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset,
414 F_PCS_RESET_, 0);
415 msleep(100);
405 t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); 416 t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0);
417 val = F_MAC_RESET_;
418 if (is_10G(adap))
419 val |= F_PCS_RESET_;
420 else if (uses_xaui(adap))
421 val |= F_PCS_RESET_ | F_XG2G_RESET_;
422 else
423 val |= F_RGMII_RESET_ | F_XG2G_RESET_;
424 t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val);
425 }
406 return 0; 426 return 0;
407} 427}
408 428
409int t3b2_mac_watchdog_task(struct cmac *mac) 429int t3b2_mac_watchdog_task(struct cmac *mac)
410{ 430{
411 struct adapter *adap = mac->adapter; 431 struct adapter *adap = mac->adapter;
412 unsigned int tcnt, xcnt; 432 struct mac_stats *s = &mac->stats;
433 unsigned int tx_tcnt, tx_xcnt;
434 unsigned int tx_mcnt = s->tx_frames;
435 unsigned int rx_mcnt = s->rx_frames;
436 unsigned int rx_xcnt;
413 int status; 437 int status;
414 438
415 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac)); 439 if (tx_mcnt == mac->tx_mcnt) {
416 tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA))); 440 tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
417 xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 441 A_XGM_TX_SPI4_SOP_EOP_CNT +
418 A_XGM_TX_SPI4_SOP_EOP_CNT + 442 mac->offset)));
419 mac->offset))); 443 if (tx_xcnt == 0) {
420 444 t3_write_reg(adap, A_TP_PIO_ADDR,
421 if (tcnt != mac->tcnt && xcnt == 0 && mac->xcnt == 0) { 445 A_TP_TX_DROP_CNT_CH0 + macidx(mac));
422 if (mac->toggle_cnt > 4) { 446 tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap,
423 t3b2_mac_reset(mac); 447 A_TP_PIO_DATA)));
448 } else {
424 mac->toggle_cnt = 0; 449 mac->toggle_cnt = 0;
450 return 0;
451 }
452 } else {
453 mac->toggle_cnt = 0;
454 return 0;
455 }
456
457 if (((tx_tcnt != mac->tx_tcnt) &&
458 (tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
459 ((mac->tx_mcnt == tx_mcnt) &&
460 (tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
461 if (mac->toggle_cnt > 4)
425 status = 2; 462 status = 2;
426 } else { 463 else
427 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
428 t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
429 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset,
430 mac->txen);
431 t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset);
432 mac->toggle_cnt++;
433 status = 1; 464 status = 1;
434 }
435 } else { 465 } else {
436 mac->toggle_cnt = 0; 466 mac->toggle_cnt = 0;
437 status = 0; 467 return 0;
438 } 468 }
439 mac->tcnt = tcnt;
440 mac->xcnt = xcnt;
441 469
470 if (rx_mcnt != mac->rx_mcnt)
471 rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap,
472 A_XGM_RX_SPI4_SOP_EOP_CNT +
473 mac->offset)));
474 else
475 return 0;
476
477 if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0)
478 status = 2;
479
480 mac->tx_tcnt = tx_tcnt;
481 mac->tx_xcnt = tx_xcnt;
482 mac->tx_mcnt = s->tx_frames;
483 mac->rx_xcnt = rx_xcnt;
484 mac->rx_mcnt = s->rx_frames;
485 if (status == 1) {
486 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0);
487 t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
488 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen);
489 t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */
490 mac->toggle_cnt++;
491 } else if (status == 2) {
492 t3b2_mac_reset(mac);
493 mac->toggle_cnt = 0;
494 }
442 return status; 495 return status;
443} 496}
444 497