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

net/wan/fsl_ucc_hdlc: error counters

Extract error information from rx and tx buffer descriptors,
and update error counters.

Signed-off-by: Mathias Thore <mathias.thore@infinera.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Mathias Thore and committed by
David S. Miller
ba59d570 2af1ccd5

+51 -8
+44 -7
drivers/net/wan/fsl_ucc_hdlc.c
··· 36 36 #define DRV_NAME "ucc_hdlc" 37 37 38 38 #define TDM_PPPOHT_SLIC_MAXIN 39 + #define RX_BD_ERRORS (R_CD_S | R_OV_S | R_CR_S | R_AB_S | R_NO_S | R_LG_S) 39 40 40 41 static struct ucc_tdm_info utdm_primary_info = { 41 42 .uf_info = { ··· 431 430 return NETDEV_TX_OK; 432 431 } 433 432 433 + static int hdlc_tx_restart(struct ucc_hdlc_private *priv) 434 + { 435 + u32 cecr_subblock; 436 + 437 + cecr_subblock = 438 + ucc_fast_get_qe_cr_subblock(priv->ut_info->uf_info.ucc_num); 439 + 440 + qe_issue_cmd(QE_RESTART_TX, cecr_subblock, 441 + QE_CR_PROTOCOL_UNSPECIFIED, 0); 442 + return 0; 443 + } 444 + 434 445 static int hdlc_tx_done(struct ucc_hdlc_private *priv) 435 446 { 436 447 /* Start from the next BD that should be filled */ 437 448 struct net_device *dev = priv->ndev; 438 449 struct qe_bd *bd; /* BD pointer */ 439 450 u16 bd_status; 451 + int tx_restart = 0; 440 452 441 453 bd = priv->dirty_tx; 442 454 bd_status = ioread16be(&bd->status); ··· 457 443 /* Normal processing. */ 458 444 while ((bd_status & T_R_S) == 0) { 459 445 struct sk_buff *skb; 446 + 447 + if (bd_status & T_UN_S) { /* Underrun */ 448 + dev->stats.tx_fifo_errors++; 449 + tx_restart = 1; 450 + } 451 + if (bd_status & T_CT_S) { /* Carrier lost */ 452 + dev->stats.tx_carrier_errors++; 453 + tx_restart = 1; 454 + } 460 455 461 456 /* BD contains already transmitted buffer. */ 462 457 /* Handle the transmitted buffer and release */ ··· 498 475 } 499 476 priv->dirty_tx = bd; 500 477 478 + if (tx_restart) 479 + hdlc_tx_restart(priv); 480 + 501 481 return 0; 502 482 } 503 483 ··· 519 493 520 494 /* while there are received buffers and BD is full (~R_E) */ 521 495 while (!((bd_status & (R_E_S)) || (--rx_work_limit < 0))) { 522 - if (bd_status & R_OV_S) 523 - dev->stats.rx_over_errors++; 524 - if (bd_status & R_CR_S) { 525 - dev->stats.rx_crc_errors++; 526 - dev->stats.rx_dropped++; 496 + if (bd_status & (RX_BD_ERRORS)) { 497 + dev->stats.rx_errors++; 498 + 499 + if (bd_status & R_CD_S) 500 + dev->stats.collisions++; 501 + if (bd_status & R_OV_S) 502 + dev->stats.rx_fifo_errors++; 503 + if (bd_status & R_CR_S) 504 + dev->stats.rx_crc_errors++; 505 + if (bd_status & R_AB_S) 506 + dev->stats.rx_over_errors++; 507 + if (bd_status & R_NO_S) 508 + dev->stats.rx_frame_errors++; 509 + if (bd_status & R_LG_S) 510 + dev->stats.rx_length_errors++; 511 + 527 512 goto recycle; 528 513 } 529 514 bdbuffer = priv->rx_buffer + ··· 583 546 netif_receive_skb(skb); 584 547 585 548 recycle: 586 - iowrite16be(bd_status | R_E_S | R_I_S, &bd->status); 549 + iowrite16be((bd_status & R_W_S) | R_E_S | R_I_S, &bd->status); 587 550 588 551 /* update to point at the next bd */ 589 552 if (bd_status & R_W_S) { ··· 659 622 660 623 /* Errors and other events */ 661 624 if (ucce >> 16 & UCC_HDLC_UCCE_BSY) 662 - dev->stats.rx_errors++; 625 + dev->stats.rx_missed_errors++; 663 626 if (ucce >> 16 & UCC_HDLC_UCCE_TXE) 664 627 dev->stats.tx_errors++; 665 628
+7 -1
include/soc/fsl/qe/ucc_fast.h
··· 41 41 #define R_L_S 0x0800 /* last */ 42 42 #define R_F_S 0x0400 /* first */ 43 43 #define R_CM_S 0x0200 /* continuous mode */ 44 + #define R_LG_S 0x0020 /* frame length */ 45 + #define R_NO_S 0x0010 /* nonoctet */ 46 + #define R_AB_S 0x0008 /* abort */ 44 47 #define R_CR_S 0x0004 /* crc */ 45 - #define R_OV_S 0x0002 /* crc */ 48 + #define R_OV_S 0x0002 /* overrun */ 49 + #define R_CD_S 0x0001 /* carrier detect */ 46 50 47 51 /* transmit BD's status */ 48 52 #define T_R_S 0x8000 /* ready bit */ ··· 55 51 #define T_L_S 0x0800 /* last */ 56 52 #define T_TC_S 0x0400 /* crc */ 57 53 #define T_TM_S 0x0200 /* continuous mode */ 54 + #define T_UN_S 0x0002 /* hdlc underrun */ 55 + #define T_CT_S 0x0001 /* hdlc carrier lost */ 58 56 59 57 /* Rx Data buffer must be 4 bytes aligned in most cases */ 60 58 #define UCC_FAST_RX_ALIGN 4