From 81291a01e45f2035360b6373c750f41252874e91 Mon Sep 17 00:00:00 2001 From: Eric Norum Date: Wed, 29 Jun 2005 20:09:14 +0000 Subject: Add duplex negotation support. --- c/src/lib/libbsp/m68k/uC5282/ChangeLog | 4 + c/src/lib/libbsp/m68k/uC5282/network/network.c | 141 +++++++++++++++++-------- 2 files changed, 99 insertions(+), 46 deletions(-) diff --git a/c/src/lib/libbsp/m68k/uC5282/ChangeLog b/c/src/lib/libbsp/m68k/uC5282/ChangeLog index 2ea36056b2..b9a0d570c7 100644 --- a/c/src/lib/libbsp/m68k/uC5282/ChangeLog +++ b/c/src/lib/libbsp/m68k/uC5282/ChangeLog @@ -1,3 +1,7 @@ +2005-06-28 Eric Norum + + * network/network.c: Add full/half-duplex auto-negotiation support. + 2005-06-20 Eric Norum * network/network.c: Clean up transmit buffer realignment. Many thanks to diff --git a/c/src/lib/libbsp/m68k/uC5282/network/network.c b/c/src/lib/libbsp/m68k/uC5282/network/network.c index 368c3e4059..6d7b140d3e 100644 --- a/c/src/lib/libbsp/m68k/uC5282/network/network.c +++ b/c/src/lib/libbsp/m68k/uC5282/network/network.c @@ -1,5 +1,5 @@ /* - * RTEMS/TCPIP driver for MCF5282 Fast Ethernet Controller + * RTEMS driver for MCF5282 Fast Ethernet Controller */ #include @@ -30,6 +30,11 @@ #define FEC_INTC0_TX_VECTOR (64+23) #define FEC_INTC0_RX_VECTOR (64+27) +#define MII_VECTOR (64+7) /* IRQ7* pin connected to external transceiver */ +#define MII_EPPAR MCF5282_EPORT_EPPAR_EPPA7_LEVEL +#define MII_EPDDR MCF5282_EPORT_EPDDR_EPDD7 +#define MII_EPIER MCF5282_EPORT_EPIER_EPIE7 +#define MII_EPPDR MCF5282_EPORT_EPPDR_EPPD7 /* * Default number of buffer descriptors set aside for this driver. @@ -96,12 +101,48 @@ struct mcf5282_enet_struct { */ unsigned long rxInterrupts; unsigned long txInterrupts; + unsigned long miiInterrupts; unsigned long txRawWait; unsigned long txRealign; unsigned long txRealignDrop; + uint16_t mii_sr2; }; static struct mcf5282_enet_struct enet_driver[NIFACES]; +/* + * Read MII register + * Busy-waits, but transfer time should be short! + */ +static int +getMII(int phyNumber, int regNumber) +{ + MCF5282_FEC_MMFR = (0x1 << 30) | + (0x2 << 28) | + (phyNumber << 23) | + (regNumber << 18) | + (0x2 << 16); + while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0); + MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII; + return MCF5282_FEC_MMFR & 0xFFFF; +} + +/* + * Write MII register + * Busy-waits, but transfer time should be short! + */ +static void +setMII(int phyNumber, int regNumber, int value) +{ + MCF5282_FEC_MMFR = (0x1 << 30) | + (0x1 << 28) | + (phyNumber << 23) | + (regNumber << 18) | + (0x2 << 16) | + (value & 0xFFFF); + while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0); + MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII; +} + static rtems_isr mcf5282_fec_rx_interrupt_handler( rtems_vector_number v ) { @@ -120,6 +161,22 @@ mcf5282_fec_tx_interrupt_handler( rtems_vector_number v ) rtems_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT); } +static rtems_isr +mcf5282_mii_interrupt_handler( rtems_vector_number v ) +{ + uint16 sr2; + + enet_driver[0].miiInterrupts++; + getMII(1, 19); /* Read and clear interrupt status bits */ + enet_driver[0].mii_sr2 = sr2 = getMII(1, 17); + if (((sr2 & 0x200) != 0) + && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) == 0)) + MCF5282_FEC_TCR |= MCF5282_FEC_TCR_FDEN; + else if (((sr2 & 0x200) == 0) + && ((MCF5282_FEC_TCR & MCF5282_FEC_TCR_FDEN) != 0)) + MCF5282_FEC_TCR &= ~MCF5282_FEC_TCR_FDEN; +} + /* * Allocate buffer descriptors from (non-cached) on-chip static RAM * Ensure 128-bit (16-byte) alignment @@ -137,42 +194,6 @@ mcf5282_bd_allocate(unsigned int count) return p; } -#if UNUSED -/* - * Read MII register - * Busy-waits, but transfer time should be short! - */ -static int -getMII(int phyNumber, int regNumber) -{ - MCF5282_FEC_MMFR = (0x1 << 30) | - (0x2 << 28) | - (phyNumber << 23) | - (regNumber << 18) | - (0x2 << 16); - while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0); - MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII; - return MCF5282_FEC_MMFR & 0xFFFF; -} -#endif - -/* - * Write MII register - * Busy-waits, but transfer time should be short! - */ -static void -setMII(int phyNumber, int regNumber, int value) -{ - MCF5282_FEC_MMFR = (0x1 << 30) | - (0x1 << 28) | - (phyNumber << 23) | - (regNumber << 18) | - (0x2 << 16) | - (value & 0xFFFF); - while ((MCF5282_FEC_EIR & MCF5282_FEC_EIR_MII) == 0); - MCF5282_FEC_EIR = MCF5282_FEC_EIR_MII; -} - static void mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc) { @@ -186,7 +207,7 @@ mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc) * Issue reset to FEC */ MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET; - rtems_task_wake_after(1); + rtems_task_wake_after(2); MCF5282_FEC_ECR = 0; /* @@ -267,9 +288,18 @@ mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc) MCF5282_FEC_MSCR = MCF5282_FEC_MSCR_MII_SPEED(i); /* - * Set PHYS to 100 Mb/s, full duplex + * Set PHYS + * Advertise 100 Mb/s, full-duplex, IEEE-802.3 + * Turn off auto-negotiate + * Enable speed-change, duplex-change and link-status-change interrupts + * Start auto-negotiate */ - setMII(1, 0, 0x2100); + setMII(1, 4, 0x0181); + setMII(1, 0, 0x0000); + rtems_task_wake_after(2); + sc->mii_sr2 = getMII(1, 17); + setMII(1, 18, 0x0072); + setMII(1, 0, 0x1000); /* * Set up receive buffer descriptors @@ -293,19 +323,29 @@ mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc) status = rtems_interrupt_catch( mcf5282_fec_tx_interrupt_handler, FEC_INTC0_TX_VECTOR, &old_handler ); if (status != RTEMS_SUCCESSFUL) rtems_panic ("Can't attach MCF5282 FEC TX interrupt handler: %s\n", - rtems_status_text(status)); - status = rtems_interrupt_catch(mcf5282_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler); - if (status != RTEMS_SUCCESSFUL) - rtems_panic ("Can't attach MCF5282 FEC RX interrupt handler: %s\n", - rtems_status_text(status)); + rtems_status_text(status)); bsp_allocate_interrupt(FEC_IRQ_LEVEL, FEC_IRQ_TX_PRIORITY); MCF5282_INTC0_ICR23 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) | MCF5282_INTC_ICR_IP(FEC_IRQ_TX_PRIORITY); MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT23 | MCF5282_INTC_IMRL_MASKALL); + + status = rtems_interrupt_catch(mcf5282_fec_rx_interrupt_handler, FEC_INTC0_RX_VECTOR, &old_handler); + if (status != RTEMS_SUCCESSFUL) + rtems_panic ("Can't attach MCF5282 FEC RX interrupt handler: %s\n", + rtems_status_text(status)); bsp_allocate_interrupt(FEC_IRQ_LEVEL, FEC_IRQ_RX_PRIORITY); MCF5282_INTC0_ICR27 = MCF5282_INTC_ICR_IL(FEC_IRQ_LEVEL) | MCF5282_INTC_ICR_IP(FEC_IRQ_RX_PRIORITY); MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT27 | MCF5282_INTC_IMRL_MASKALL); + + status = rtems_interrupt_catch(mcf5282_mii_interrupt_handler, MII_VECTOR, &old_handler); + if (status != RTEMS_SUCCESSFUL) + rtems_panic ("Can't attach MCF5282 FEC MII interrupt handler: %s\n", + rtems_status_text(status)); + MCF5282_EPORT_EPPAR &= ~MII_EPPAR; + MCF5282_EPORT_EPDDR &= ~MII_EPDDR; + MCF5282_EPORT_EPIER |= MII_EPIER; + MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT7 | MCF5282_INTC_IMRL_MASKALL); } /* @@ -735,7 +775,16 @@ enet_stats(struct mcf5282_enet_struct *sc) printf(" Carrier Error:%-10lu", MCF5282_FEC_IEEE_T_CSERR); printf(" Tx SQE Error:%-10lu", MCF5282_FEC_IEEE_T_SQE); printf("Tx Pause Frames:%-10lu\n", MCF5282_FEC_IEEE_T_FDXFC); - printf(" Tx Octets OK:%-10lu\n", MCF5282_FEC_IEEE_T_OCTETS_OK); + printf(" Tx Octets OK:%-10lu", MCF5282_FEC_IEEE_T_OCTETS_OK); + printf(" MII interrupts:%-10lu\n", sc->miiInterrupts); + if ((sc->mii_sr2 & 0x400) == 0) { + printf("LINK DOWN!\n"); + } + else { + printf("Link speed %d Mb/s, %s-duplex.\n", + sc->mii_sr2 & 0x4000 ? 100 : 10, + sc->mii_sr2 & 0x200 ? "full" : "half"); + } printf(" EIR:%8.8lx ", MCF5282_FEC_EIR); printf("EIMR:%8.8lx ", MCF5282_FEC_EIMR); printf("RDAR:%8.8lx ", MCF5282_FEC_RDAR); -- cgit v1.2.3