summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorEric Norum <WENorum@lbl.gov>2005-06-29 20:09:14 +0000
committerEric Norum <WENorum@lbl.gov>2005-06-29 20:09:14 +0000
commit81291a01e45f2035360b6373c750f41252874e91 (patch)
tree649196a96e98a504ed04b2db741ce00eb1744ed2 /c
parentMinor tweak to make it easier to insert some code to test realignment. (diff)
downloadrtems-81291a01e45f2035360b6373c750f41252874e91.tar.bz2
Add duplex negotation support.
Diffstat (limited to 'c')
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/ChangeLog4
-rw-r--r--c/src/lib/libbsp/m68k/uC5282/network/network.c141
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 <norume@aps.anl.gov>
+
+ * network/network.c: Add full/half-duplex auto-negotiation support.
+
2005-06-20 Eric Norum <norume@aps.anl.gov>
* 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 <bsp.h>
@@ -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);