This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

lan91cxx enhancements


Index: devs/eth/smsc/lan91cxx/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/ChangeLog,v
retrieving revision 1.10
diff -u -p -5 -r1.10 ChangeLog
--- devs/eth/smsc/lan91cxx/current/ChangeLog	16 Aug 2002 13:16:25 -0000	1.10
+++ devs/eth/smsc/lan91cxx/current/ChangeLog	28 Aug 2002 16:59:48 -0000
@@ -1,5 +1,11 @@
+2002-08-28  Mark Salter  <msalter@redhat.com>
+
+	* src/smsc_lan91cxx.h: Support 32-bit data reads.
+	* src/if_lan91cxx.c: Fix standalone (RedBoot) interrupt handling.
+	Support 32-bit data reads.
+
 2002-08-16  Mark Salter  <msalter@redhat.com>
 
 	* src/if_lan91cxx.c: Add support for 91C111. Platform-specific
 	include file is now included from within smsc_lan91cxx.h so
 	that register access functions may be overridden if necessary.
Index: devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c,v
retrieving revision 1.9
diff -u -p -5 -r1.9 if_lan91cxx.c
--- devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c	16 Aug 2002 13:16:26 -0000	1.9
+++ devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c	28 Aug 2002 16:59:49 -0000
@@ -133,10 +133,12 @@ static void lan91cxx_write_phy(struct et
 static cyg_uint16 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
 				    cyg_uint8 phyreg);
 #endif
 
 static void lan91cxx_poll(struct eth_drv_sc *sc);
+
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
 static cyg_interrupt lan91cxx_interrupt;
 static cyg_handle_t  lan91cxx_interrupt_handle;
 
 // This ISR is called when the ethernet interrupt occurs
 static int
@@ -153,10 +155,11 @@ lan91cxx_isr(cyg_vector_t vector, cyg_ad
 
     cyg_drv_interrupt_mask(cpd->interrupt);
     cyg_drv_interrupt_acknowledge(cpd->interrupt);
     return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
 }
+#endif
 
 // The deliver function (ex-DSR)  handles the ethernet [logical] processing
 static void
 lan91cxx_deliver(struct eth_drv_sc *sc)
 {
@@ -236,21 +239,25 @@ smsc_lan91cxx_init(struct cyg_netdevtab_
 #endif
     put_att(sc, LAN91CXX_ECSR, ecsr);
         
 #endif
 
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
     // Initialize environment, setup interrupt handler
     cyg_drv_interrupt_create(cpd->interrupt,
                             99, // Priority - what goes here?
                              (cyg_addrword_t)sc, //  Data item passed to interrupt handler
                              (cyg_ISR_t *)lan91cxx_isr,
                              (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
                              &lan91cxx_interrupt_handle,
                              &lan91cxx_interrupt);
     cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
     cyg_drv_interrupt_acknowledge(cpd->interrupt);
+#ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
     cyg_drv_interrupt_unmask(cpd->interrupt);
+#endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
     
     // probe chip by reading the signature in BS register
     val = get_banksel(sc);
 #if DEBUG & 9
     diag_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
@@ -360,10 +367,12 @@ lan91cxx_start(struct eth_drv_sc *sc, un
     struct ifnet *ifp = &sc->sc_arpcom.ac_if;
 #endif
     DEBUG_FUNCTION();
 
 #ifdef LAN91CXX_IS_LAN91C111
+    HAL_DELAY_US(100000);
+
     // 91C111 Errata. Internal PHY comes up disabled. Must enable here.
     phy_ctl = lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_CTRL);
     phy_ctl &= ~LAN91CXX_PHY_CTRL_MII_DIS;
     lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, phy_ctl);
 
@@ -916,10 +925,13 @@ static void
 lan91cxx_RxEvent(struct eth_drv_sc *sc)
 {
     struct lan91cxx_priv_data *cpd = 
         (struct lan91cxx_priv_data *)sc->driver_private;
     unsigned short stat, len;
+#ifdef LAN91CXX_32BIT_RX
+    cyg_uint32 val;
+#endif
 
     DEBUG_FUNCTION();
 
     stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
 #if DEBUG & 1
@@ -943,12 +955,18 @@ lan91cxx_RxEvent(struct eth_drv_sc *sc)
     cpd->rxpacket = 0xff & (stat >> 8);
 
     // Read status and (word) length
     put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
                                  LAN91CXX_POINTER_AUTO_INCR | 0x0000));
+#ifdef LAN91CXX_32BIT_RX
+    val = get_data(sc);
+    stat = val & 0xffff;
+    len = ((val >> 16) & 0xffff) - 6;   // minus header/footer words
+#else
     stat = get_data(sc);
     len = get_data(sc) - 6;             // minus header/footer words
+#endif
 
 #ifdef KEEP_STATISTICS
     if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
     //if ( stat & LAN91CXX_RX_STATUS_BCAST    ) INCR_STAT(  );
     if ( stat & LAN91CXX_RX_STATUS_BADCRC   ) INCR_STAT( rx_crc_errors );
@@ -1000,29 +1018,36 @@ lan91cxx_recv(struct eth_drv_sc *sc, str
 #if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || defined(KEEP_STATISTICS)
     struct lan91cxx_priv_data *cpd = 
         (struct lan91cxx_priv_data *)sc->driver_private;
 #endif
     int i, mlen=0, plen;
-    unsigned short *data=NULL, val;
+    rxd_t *data=NULL, val;
     unsigned char *cp, cval;
 
     DEBUG_FUNCTION();
 
     INCR_STAT( rx_deliver );
 
     put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
                                  LAN91CXX_POINTER_AUTO_INCR));
-    // Skip status word
-    (void)get_data(sc);
+    val = get_data(sc);
 
-    plen = get_data(sc) - 6;            // packet length (minus header/footer)
+    // packet length (minus header/footer)
+#ifdef LAN91CXX_32BIT_RX
+    plen = (val >> 16) - 6;
+#else
+    plen = get_data(sc) - 6;
+#endif
+    if (val & LAN91CXX_RX_STATUS_ODDFRM)
+	plen++;
 
     for (i = 0;  i < sg_len;  i++) {
-        data = (unsigned short *)sg_list[i].buf;
+        data = (rxd_t *)sg_list[i].buf;
         mlen = sg_list[i].len;
 
-        CYG_ASSERT(0 == (mlen & 1) || (i == (sg_len-1)), "odd length");
+        CYG_ASSERT(0 == (mlen & (sizeof(*data) - 1)) || (i == (sg_len-1)), "odd length");
+
 #if DEBUG & 1
         diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
 #endif
         if (data) {
             while (mlen >= sizeof(*data)) {
@@ -1037,18 +1062,28 @@ lan91cxx_recv(struct eth_drv_sc *sc, str
                 mlen -= sizeof(*data);
                 plen -= sizeof(*data);
             }
         }
     }
-    val = get_data(sc); // Read control word unconditionally
+    val = get_data(sc); // Read control word (and potential data) unconditionally
+#ifdef LAN91CXX_32BIT_RX
+    if (plen & 2) {
+	if (data)
+	    *(cyg_uint16 *)data = val & 0xffff;
+	cp = (unsigned char *)data + 2;
+	val >>= 16;
+	mlen -= 2;
+    } else
+#endif
+	cp = (unsigned char *)data;
+
     CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX, 
                "Controlbyte is not for Rx");
     CYG_ASSERT( (1 == mlen) == (0 != (val & LAN91CXX_CONTROLBYTE_ODD)), 
                 "Controlbyte does not match");
     if (data && (1 == mlen) && (val & LAN91CXX_CONTROLBYTE_ODD)) {
         cval = val & 0x00ff;    // last byte contains data
-        cp = (unsigned char*)data;
         *cp = cval;
     }
 
     val = get_reg(sc, LAN91CXX_FIFO_PORTS);
 #if DEBUG & 4
Index: devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h,v
retrieving revision 1.6
diff -u -p -5 -r1.6 smsc_lan91cxx.h
--- devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h	16 Aug 2002 13:16:26 -0000	1.6
+++ devs/eth/smsc/lan91cxx/current/src/smsc_lan91cxx.h	28 Aug 2002 16:59:49 -0000
@@ -326,10 +326,16 @@ typedef struct lan91cxx_priv_data {
 
 // ------------------------------------------------------------------------
 
 #include CYGDAT_DEVS_ETH_SMSC_LAN91CXX_INL
 
+#ifdef LAN91CXX_32BIT_RX
+typedef cyg_uint32 rxd_t;
+#else
+typedef cyg_uint16 rxd_t;
+#endif
+
 #ifndef SMSC_PLATFORM_DEFINED_GET_REG
 static __inline__ unsigned short
 get_reg(struct eth_drv_sc *sc, int regno)
 {
     struct lan91cxx_priv_data *cpd =
@@ -378,21 +384,25 @@ put_data(struct eth_drv_sc *sc, unsigned
 }
 #endif // SMSC_PLATFORM_DEFINED_PUT_DATA
 
 #ifndef SMSC_PLATFORM_DEFINED_GET_DATA
 // Assumes bank2 has been selected
-static __inline__ unsigned short
+static __inline__ rxd_t
 get_data(struct eth_drv_sc *sc)
 {
-    unsigned short val;
+    rxd_t val;
     struct lan91cxx_priv_data *cpd =
         (struct lan91cxx_priv_data *)sc->driver_private;
 	
+#ifdef LAN91CXX_32BIT_RX
+    HAL_READ_UINT32(cpd->base+((LAN91CXX_DATA_HIGH & 0x7) << cpd->addrsh), val);
+#else
     HAL_READ_UINT16(cpd->base+((LAN91CXX_DATA & 0x7) << cpd->addrsh), val);
+#endif
 
 #if DEBUG & 2
-    diag_printf("read data 0x%04x\n", val);
+    diag_printf("read data 0x%x\n", val);
 #endif
     return val;
 }
 #endif // SMSC_PLATFORM_DEFINED_GET_DATA
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]