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>

authored by Divy Le Ray and committed by Jeff Garzik 59cf8107 f2d961c9

+91 -37
+5 -2
drivers/net/cxgb3/common.h
··· 478 struct adapter *adapter; 479 unsigned int offset; 480 unsigned int nucast; /* # of address filters for unicast MACs */ 481 - unsigned int tcnt; 482 - unsigned int xcnt; 483 unsigned int toggle_cnt; 484 unsigned int txen; 485 struct mac_stats stats;
··· 478 struct adapter *adapter; 479 unsigned int offset; 480 unsigned int nucast; /* # of address filters for unicast MACs */ 481 + unsigned int tx_tcnt; 482 + unsigned int tx_xcnt; 483 + u64 tx_mcnt; 484 + unsigned int rx_xcnt; 485 + u64 rx_mcnt; 486 unsigned int toggle_cnt; 487 unsigned int txen; 488 struct mac_stats stats;
+4 -6
drivers/net/cxgb3/cxgb3_main.c
··· 194 195 if (link_stat != netif_carrier_ok(dev)) { 196 if (link_stat) { 197 - t3_set_reg_field(adapter, 198 - A_XGM_TXFIFO_CFG + mac->offset, 199 - F_ENDROPPKT, 0); 200 netif_carrier_on(dev); 201 } else { 202 netif_carrier_off(dev); 203 - t3_set_reg_field(adapter, 204 - A_XGM_TXFIFO_CFG + mac->offset, 205 - F_ENDROPPKT, F_ENDROPPKT); 206 } 207 208 link_report(dev);
··· 194 195 if (link_stat != netif_carrier_ok(dev)) { 196 if (link_stat) { 197 + t3_mac_enable(mac, MAC_DIRECTION_RX); 198 netif_carrier_on(dev); 199 } else { 200 netif_carrier_off(dev); 201 + pi->phy.ops->power_down(&pi->phy, 1); 202 + t3_mac_disable(mac, MAC_DIRECTION_RX); 203 + t3_link_start(&pi->phy, mac, &pi->link_config); 204 } 205 206 link_report(dev);
+82 -29
drivers/net/cxgb3/xgmac.c
··· 367 int idx = macidx(mac); 368 struct adapter *adap = mac->adapter; 369 unsigned int oft = mac->offset; 370 - 371 if (which & MAC_DIRECTION_TX) { 372 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); ··· 377 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 378 379 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx); 380 - mac->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, 381 - A_TP_PIO_DATA))); 382 - mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 383 - A_XGM_TX_SPI4_SOP_EOP_CNT))); 384 mac->txen = F_TXEN; 385 mac->toggle_cnt = 0; 386 } ··· 399 { 400 int idx = macidx(mac); 401 struct adapter *adap = mac->adapter; 402 403 if (which & MAC_DIRECTION_TX) { 404 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); ··· 409 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 410 mac->txen = 0; 411 } 412 - if (which & MAC_DIRECTION_RX) 413 t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); 414 return 0; 415 } 416 417 int t3b2_mac_watchdog_task(struct cmac *mac) 418 { 419 struct adapter *adap = mac->adapter; 420 - unsigned int tcnt, xcnt; 421 int status; 422 423 - t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac)); 424 - tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA))); 425 - xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 426 - A_XGM_TX_SPI4_SOP_EOP_CNT + 427 - mac->offset))); 428 - 429 - if (tcnt != mac->tcnt && xcnt == 0 && mac->xcnt == 0) { 430 - if (mac->toggle_cnt > 4) { 431 - t3b2_mac_reset(mac); 432 - mac->toggle_cnt = 0; 433 - status = 2; 434 } else { 435 - t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); 436 - t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); 437 - t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 438 - mac->txen); 439 - t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); 440 - mac->toggle_cnt++; 441 - status = 1; 442 - } 443 } else { 444 mac->toggle_cnt = 0; 445 - status = 0; 446 } 447 - mac->tcnt = tcnt; 448 - mac->xcnt = xcnt; 449 450 return status; 451 } 452
··· 367 int idx = macidx(mac); 368 struct adapter *adap = mac->adapter; 369 unsigned int oft = mac->offset; 370 + struct mac_stats *s = &mac->stats; 371 + 372 if (which & MAC_DIRECTION_TX) { 373 t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); 374 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); ··· 376 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 377 378 t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx); 379 + mac->tx_mcnt = s->tx_frames; 380 + mac->tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, 381 + A_TP_PIO_DATA))); 382 + mac->tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 383 + A_XGM_TX_SPI4_SOP_EOP_CNT + 384 + oft))); 385 + mac->rx_mcnt = s->rx_frames; 386 + mac->rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 387 + A_XGM_RX_SPI4_SOP_EOP_CNT + 388 + oft))); 389 mac->txen = F_TXEN; 390 mac->toggle_cnt = 0; 391 } ··· 392 { 393 int idx = macidx(mac); 394 struct adapter *adap = mac->adapter; 395 + int val; 396 397 if (which & MAC_DIRECTION_TX) { 398 t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); ··· 401 t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); 402 mac->txen = 0; 403 } 404 + if (which & MAC_DIRECTION_RX) { 405 + t3_set_reg_field(mac->adapter, A_XGM_RESET_CTRL + mac->offset, 406 + F_PCS_RESET_, 0); 407 + msleep(100); 408 t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); 409 + val = F_MAC_RESET_; 410 + if (is_10G(adap)) 411 + val |= F_PCS_RESET_; 412 + else if (uses_xaui(adap)) 413 + val |= F_PCS_RESET_ | F_XG2G_RESET_; 414 + else 415 + val |= F_RGMII_RESET_ | F_XG2G_RESET_; 416 + t3_write_reg(mac->adapter, A_XGM_RESET_CTRL + mac->offset, val); 417 + } 418 return 0; 419 } 420 421 int t3b2_mac_watchdog_task(struct cmac *mac) 422 { 423 struct adapter *adap = mac->adapter; 424 + struct mac_stats *s = &mac->stats; 425 + unsigned int tx_tcnt, tx_xcnt; 426 + unsigned int tx_mcnt = s->tx_frames; 427 + unsigned int rx_mcnt = s->rx_frames; 428 + unsigned int rx_xcnt; 429 int status; 430 431 + if (tx_mcnt == mac->tx_mcnt) { 432 + tx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 433 + A_XGM_TX_SPI4_SOP_EOP_CNT + 434 + mac->offset))); 435 + if (tx_xcnt == 0) { 436 + t3_write_reg(adap, A_TP_PIO_ADDR, 437 + A_TP_TX_DROP_CNT_CH0 + macidx(mac)); 438 + tx_tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, 439 + A_TP_PIO_DATA))); 440 } else { 441 + mac->toggle_cnt = 0; 442 + return 0; 443 + } 444 } else { 445 mac->toggle_cnt = 0; 446 + return 0; 447 } 448 449 + if (((tx_tcnt != mac->tx_tcnt) && 450 + (tx_xcnt == 0) && (mac->tx_xcnt == 0)) || 451 + ((mac->tx_mcnt == tx_mcnt) && 452 + (tx_xcnt != 0) && (mac->tx_xcnt != 0))) { 453 + if (mac->toggle_cnt > 4) 454 + status = 2; 455 + else 456 + status = 1; 457 + } else { 458 + mac->toggle_cnt = 0; 459 + return 0; 460 + } 461 + 462 + if (rx_mcnt != mac->rx_mcnt) 463 + rx_xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, 464 + A_XGM_RX_SPI4_SOP_EOP_CNT + 465 + mac->offset))); 466 + else 467 + return 0; 468 + 469 + if (mac->rx_mcnt != s->rx_frames && rx_xcnt == 0 && mac->rx_xcnt == 0) 470 + status = 2; 471 + 472 + mac->tx_tcnt = tx_tcnt; 473 + mac->tx_xcnt = tx_xcnt; 474 + mac->tx_mcnt = s->tx_frames; 475 + mac->rx_xcnt = rx_xcnt; 476 + mac->rx_mcnt = s->rx_frames; 477 + if (status == 1) { 478 + t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); 479 + t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */ 480 + t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, mac->txen); 481 + t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); /* flush */ 482 + mac->toggle_cnt++; 483 + } else if (status == 2) { 484 + t3b2_mac_reset(mac); 485 + mac->toggle_cnt = 0; 486 + } 487 return status; 488 } 489