Mercurial > ecos
changeset 1887:f1416dacc556
Try to improve error detection and recovery
| author | gthomas |
|---|---|
| date | Thu, 03 Feb 2005 16:01:10 +0000 |
| parents | 5f0c796f46a6 |
| children | 6940990001c4 |
| files | packages/devs/eth/powerpc/ppc405/current/ChangeLog packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h |
| diffstat | 3 files changed, 42 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/eth/powerpc/ppc405/current/ChangeLog +++ b/packages/devs/eth/powerpc/ppc405/current/ChangeLog @@ -1,3 +1,8 @@ +2005-02-03 Gary Thomas <gary@mlbassoc.com> + + * src/ppc405_enet.h: + * src/if_ppc405.c: Improve error detection and recovery. + 2003-10-02 Gary Thomas <gary@mlbassoc.com> * src/ppc405_enet.h: Let default ESA be a pointer so that platforms
--- a/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c +++ b/packages/devs/eth/powerpc/ppc405/current/src/if_ppc405.c @@ -9,7 +9,7 @@ // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. -// Copyright (C) 2002, 2003 Gary Thomas +// Copyright (C) 2002, 2003, 2005 Gary Thomas // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free @@ -405,6 +405,7 @@ ppc405_eth_init(struct cyg_netdevtab_ent os_printf("PPC405_ETH - Warning! ESA unknown\n"); memcpy(&enaddr, qi->enaddr, sizeof(enaddr)); } + memcpy(qi->cfg_enaddr, enaddr, sizeof(enaddr)); // Configure the device if (!ppc405_eth_reset(sc, enaddr, 0)) { @@ -612,6 +613,7 @@ ppc405_eth_int(struct eth_drv_sc *sc) { struct ppc405_eth_info *qi = (struct ppc405_eth_info *)sc->driver_private; unsigned long event, tx_event, rx_event, tx_deir, rx_deir; + bool need_reset = false; CYGARC_MFDCR(MAL0_TXEOBISR, tx_event); if (tx_event != 0) { @@ -625,12 +627,17 @@ ppc405_eth_int(struct eth_drv_sc *sc) } if ((event = EMAC0_ISR) != 0) { if ((event & ~(EMAC0_ISR_SE0|EMAC0_ISR_SE1)) != 0) { + // Error other than signal quality os_printf("EMAC0_ISR: %x\n", event); - } - if ((event & (EMAC0_ISR_TE0|EMAC0_ISR_TE1)) != 0) { - // Some problem with transmit - CYGARC_MTDCR(MAL0_TXCASR, MAL_CASR_C0); - qi->tnext = qi->tbase; + if ((event & (EMAC0_ISR_TE0|EMAC0_ISR_TE1)) != 0) { + // Some problem with transmit - should be easily recoverable + CYGARC_MTDCR(MAL0_TXCASR, MAL_CASR_C0); + qi->tnext = qi->tbase; + } + if ((event & (EMAC0_ISR_OVR|EMAC0_ISR_BP|EMAC0_ISR_RP|EMAC0_ISR_ALE|EMAC0_ISR_BFCS)) != 0) { + // Rx errors - reset device + need_reset = true; + } } EMAC0_ISR = event; // Reset the bits we handled } @@ -639,11 +646,11 @@ ppc405_eth_int(struct eth_drv_sc *sc) CYGARC_MFDCR(MAL0_TXDEIR, tx_deir); CYGARC_MFDCR(MAL0_RXDEIR, rx_deir); if (dump_mal0_esr) { - os_printf("MAL0_ESR: %x, Tx: %x, Rx: %x\n", event, tx_deir, rx_deir); - os_printf("Tx buffer headers\n"); - diag_dump_buf((void *)qi->tbase, qi->txnum*sizeof(mal_bd_t)); - os_printf("Rx buffer headers\n"); - diag_dump_buf((void *)qi->rbase, qi->rxnum*sizeof(mal_bd_t)); + os_printf("MAL0_ESR: %x, Tx: %x, Rx: %x\n", event, tx_deir, rx_deir); + os_printf("Tx buffer headers\n"); + diag_dump_buf((void *)qi->tbase, qi->txnum*sizeof(mal_bd_t)); + os_printf("Rx buffer headers\n"); + diag_dump_buf((void *)qi->rbase, qi->rxnum*sizeof(mal_bd_t)); } if (tx_deir != 0) { // Fix Tx descriptor problems @@ -659,6 +666,14 @@ ppc405_eth_int(struct eth_drv_sc *sc) } CYGARC_MTDCR(MAL0_ESR, event); // Clear events just handled } + if (need_reset) { + // Something has gone awry - try resetting the device + os_printf("\n... PPC405 ethernet - hard reset after failure\n"); + ppc405_eth_stop(sc); + if (!ppc405_eth_reset(sc, qi->cfg_enaddr, 0)) { + os_printf("!! Failed? !!\n"); + } + } } //
--- a/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h +++ b/packages/devs/eth/powerpc/ppc405/current/src/ppc405_enet.h @@ -160,16 +160,16 @@ // // Interrupt status // -#define EMAC0_ISR_OVR 0x02000000 -#define EMAC0_ISR_PP 0x01000000 -#define EMAC0_ISR_BP 0x00800000 -#define EMAC0_ISR_RP 0x00400000 -#define EMAC0_ISR_SE 0x00200000 -#define EMAC0_ISR_ALE 0x00100000 -#define EMAC0_ISR_BFCS 0x00080000 -#define EMAC0_ISR_PTLE 0x00040000 -#define EMAC0_ISR_ORE 0x00020000 -#define EMAC0_ISR_IRE 0x00010000 +#define EMAC0_ISR_OVR 0x02000000 // Rx overrun +#define EMAC0_ISR_PP 0x01000000 // Pause packet received +#define EMAC0_ISR_BP 0x00800000 // Rx bad packet +#define EMAC0_ISR_RP 0x00400000 // Rx runt packet +#define EMAC0_ISR_SE 0x00200000 // Rx short event +#define EMAC0_ISR_ALE 0x00100000 // Rx alignment error +#define EMAC0_ISR_BFCS 0x00080000 // Rx bad FCS +#define EMAC0_ISR_PTLE 0x00040000 // Rx packet too long +#define EMAC0_ISR_ORE 0x00020000 // Rx packet out of range +#define EMAC0_ISR_IRE 0x00010000 // Rx packet in range error #define EMAC0_ISR_DBDM 0x00000200 #define EMAC0_ISR_DB0 0x00000100 #define EMAC0_ISR_SE0 0x00000080 @@ -356,5 +356,6 @@ struct ppc405_eth_info { #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED unsigned long ints; // Mask of interrupts in progress #endif + unsigned char cfg_enaddr[6]; // Last configured ESA };
