Index: c/src/lib/libbsp/m68k/uC5282/ChangeLog
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/ChangeLog	(revision cdb717ecc51d176f20908f9cd0335d2171670434)
+++ c/src/lib/libbsp/m68k/uC5282/ChangeLog	(revision 81291a01e45f2035360b6373c750f41252874e91)
@@ -1,2 +1,6 @@
+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>
 
Index: c/src/lib/libbsp/m68k/uC5282/network/network.c
===================================================================
--- c/src/lib/libbsp/m68k/uC5282/network/network.c	(revision cdb717ecc51d176f20908f9cd0335d2171670434)
+++ c/src/lib/libbsp/m68k/uC5282/network/network.c	(revision 81291a01e45f2035360b6373c750f41252874e91)
@@ -1,4 +1,4 @@
 /*
- * RTEMS/TCPIP driver for MCF5282 Fast Ethernet Controller
+ * RTEMS driver for MCF5282 Fast Ethernet Controller
  */
 
@@ -31,4 +31,9 @@
 #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
 
 /*
@@ -97,46 +102,12 @@
     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];
 
-static rtems_isr
-mcf5282_fec_rx_interrupt_handler( rtems_vector_number v )
-{
-    MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
-    MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_RXF;    
-    enet_driver[0].rxInterrupts++;
-    rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
-}
-
-static rtems_isr
-mcf5282_fec_tx_interrupt_handler( rtems_vector_number v )
-{
-    MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
-    MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF;    
-    enet_driver[0].txInterrupts++;
-    rtems_event_send(enet_driver[0].txDaemonTid, TX_INTERRUPT_EVENT);
-}
-
-/*
- * Allocate buffer descriptors from (non-cached) on-chip static RAM
- * Ensure 128-bit (16-byte) alignment
- */
-static mcf5282BufferDescriptor_t *
-mcf5282_bd_allocate(unsigned int count)
-{
-    extern char __SRAMBASE[];
-    static mcf5282BufferDescriptor_t *bdp = (mcf5282BufferDescriptor_t *)__SRAMBASE;
-    mcf5282BufferDescriptor_t *p = bdp;
-
-    bdp += count;
-    if ((int)bdp & 0xF)
-        bdp = (mcf5282BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
-    return p;
-}
-
-#if UNUSED
 /*
  * Read MII register
@@ -155,5 +126,4 @@
     return MCF5282_FEC_MMFR & 0xFFFF;
 }
-#endif
 
 /*
@@ -174,4 +144,55 @@
 }
 
+static rtems_isr
+mcf5282_fec_rx_interrupt_handler( rtems_vector_number v )
+{
+    MCF5282_FEC_EIR = MCF5282_FEC_EIR_RXF;
+    MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_RXF;    
+    enet_driver[0].rxInterrupts++;
+    rtems_event_send(enet_driver[0].rxDaemonTid, RX_INTERRUPT_EVENT);
+}
+
+static rtems_isr
+mcf5282_fec_tx_interrupt_handler( rtems_vector_number v )
+{
+    MCF5282_FEC_EIR = MCF5282_FEC_EIR_TXF;
+    MCF5282_FEC_EIMR &= ~MCF5282_FEC_EIMR_TXF;    
+    enet_driver[0].txInterrupts++;
+    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
+ */
+static mcf5282BufferDescriptor_t *
+mcf5282_bd_allocate(unsigned int count)
+{
+    extern char __SRAMBASE[];
+    static mcf5282BufferDescriptor_t *bdp = (mcf5282BufferDescriptor_t *)__SRAMBASE;
+    mcf5282BufferDescriptor_t *p = bdp;
+
+    bdp += count;
+    if ((int)bdp & 0xF)
+        bdp = (mcf5282BufferDescriptor_t *)((char *)bdp + (16 - ((int)bdp & 0xF)));
+    return p;
+}
+
 static void
 mcf5282_fec_initialize_hardware(struct mcf5282_enet_struct *sc)
@@ -187,5 +208,5 @@
      */
     MCF5282_FEC_ECR = MCF5282_FEC_ECR_RESET;
-    rtems_task_wake_after(1);
+    rtems_task_wake_after(2);
     MCF5282_FEC_ECR = 0;
 
@@ -268,7 +289,16 @@
 
     /*
-     * Set PHYS to 100 Mb/s, full duplex
-     */
-    setMII(1, 0, 0x2100);
+     * 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,  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);
 
     /*
@@ -294,17 +324,27 @@
     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);
 }
 
@@ -736,5 +776,14 @@
     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);
