]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/smsc/lan91cxx/v2_0/src/if_lan91cxx.c
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / smsc / lan91cxx / v2_0 / src / if_lan91cxx.c
1 //==========================================================================
2 //
3 //      dev/if_lan91cxx.c
4 //
5 //      Ethernet device driver for SMSC LAN91CXX compatible controllers
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 // Copyright (C) 2003 Nick Garnett 
13 // Copyright (C) 2004 Andrew Lunn
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //####BSDCOPYRIGHTBEGIN####
43 //
44 // -------------------------------------------
45 //
46 // Portions of this software may have been derived from OpenBSD or other sources,
47 // and are covered by the appropriate copyright disclaimers included herein.
48 //
49 // -------------------------------------------
50 //
51 //####BSDCOPYRIGHTEND####
52 //==========================================================================
53 //#####DESCRIPTIONBEGIN####
54 //
55 // Author(s):    hmt, based on lan900 (for LAN91C110) driver by jskov
56 //               jskov, based on CS8900 driver by Gary Thomas
57 // Contributors: gthomas, jskov, hmt, jco@ict.es, nickg
58 // Date:         2001-01-22
59 // Purpose:      
60 // Description:  hardware driver for LAN91CXX "LAN9000" ethernet
61 // Notes:        Pointer register is not saved/restored on receive interrupts.
62 //               The pointer is shared by both receive/transmit code.
63 //               But the net stack manages atomicity for you here.
64 //
65 //               The controller has an autorelease mode that allows TX packets
66 //               to be freed automatically on successful transmission - but
67 //               that is not used since we're only sending one packet at a
68 //               time anyway.
69 //               We may want to pingpong in future for throughput reasons.
70 //
71 //               <jco@ict.es> Added support for PCMCIA mode and shifted
72 //               address buses.
73 //
74 //####DESCRIPTIONEND####
75 //
76 //==========================================================================
77
78 // Based on LAN91C110 and LAN91C96
79
80 #include <pkgconf/system.h>
81 #include <pkgconf/devs_eth_smsc_lan91cxx.h>
82 #include <pkgconf/io_eth_drivers.h>
83
84 #include <cyg/infra/cyg_type.h>
85 #include <cyg/hal/hal_arch.h>
86 #include <cyg/hal/hal_intr.h>
87 #include <cyg/hal/hal_diag.h>
88 #include <cyg/infra/cyg_ass.h>
89 #include <cyg/infra/diag.h>
90 #include <cyg/hal/drv_api.h>
91 #include <cyg/io/eth/netdev.h>
92 #include <cyg/io/eth/eth_drv.h>
93 #ifdef CYGPKG_NET
94 #include <pkgconf/net.h>
95 #include <cyg/kernel/kapi.h>
96 #include <net/if.h>  /* Needed for struct ifnet */
97 #endif
98
99 #ifdef CYGPKG_INFRA_DEBUG
100 // Then we log, OOI, the number of times we get a bad packet number
101 // from the tx done fifo.
102 int lan91cxx_txfifo_good = 0;
103 int lan91cxx_txfifo_bad = 0;
104 #endif
105
106 // Set to perms of:
107 // 0 disables all debug output
108 // 1 for process debug output
109 // 2 for added data IO output: get_reg, put_reg
110 // 4 for packet allocation/free output
111 // 8 for only startup status, so we can tell we're installed OK
112 #define DEBUG 0
113
114
115 #if DEBUG
116 #if defined(CYGPKG_REDBOOT)
117 static void db_printf( char *fmt, ... )
118 {
119     extern int start_console(void);
120     extern void end_console(int);
121     va_list a;
122     int old_console;
123     va_start( a, fmt );
124     old_console = start_console();  
125     diag_vprintf( fmt, a );
126     end_console(old_console);
127     va_end( a );
128 }
129 #else
130 #define db_printf diag_printf
131 #endif
132 #else
133 #define db_printf( fmt, ... )
134 #endif
135
136
137 #if DEBUG & 1
138 #define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
139 #else
140 #define DEBUG_FUNCTION() do {} while(0)
141 #endif
142
143 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
144 #define KEEP_STATISTICS
145 #endif
146
147 #ifdef KEEP_STATISTICS
148 #define INCR_STAT( _x_ )        (cpd->stats. _x_ ++)
149 #else
150 #define INCR_STAT( _x_ )        CYG_EMPTY_STATEMENT
151 #endif
152
153 #include "smsc_lan91cxx.h"
154
155 #ifdef LAN91CXX_IS_LAN91C111
156 static void lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
157                                cyg_uint8 phyreg, cyg_uint16 value);
158 static cyg_uint16 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
159                                     cyg_uint8 phyreg);
160 #endif
161
162 static void lan91cxx_poll(struct eth_drv_sc *sc);
163
164
165 #ifdef LAN91CXX_IS_LAN91C111
166 // Revision A of the LAN91C111 has a bug in which it does not set the
167 // ODD bit in the status word and control byte of received packets. We
168 // work around this by assuming the bit is always set and tacking the
169 // extra odd byte onto the packet anyway. Higher protocol levels never
170 // believe the packet size reported by the driver and always use the
171 // values in the protocol headers. So this workaround is quite safe.
172 // In theory nobody should be using the RevA part now, but it appears
173 // that some people still have some in their parts bins.
174 #define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) \
175         (((__cpd)->c111_reva)?1:((__stat) & LAN91CXX_RX_STATUS_ODDFRM))
176 #define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) \
177         (((__cpd)->c111_reva)?1:((__val) & LAN91CXX_CONTROLBYTE_ODD))
178 #else
179 #define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) ((__stat) & LAN91CXX_RX_STATUS_ODDFRM)
180 #define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) ((__val) & LAN91CXX_CONTROLBYTE_ODD)
181 #endif
182
183 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
184 static cyg_interrupt lan91cxx_interrupt;
185 static cyg_handle_t  lan91cxx_interrupt_handle;
186
187 // This ISR is called when the ethernet interrupt occurs
188 static int lan91cxx_isr(cyg_vector_t vector, cyg_addrword_t data)
189              /* , HAL_SavedRegisters *regs */
190 {
191     struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
192     struct lan91cxx_priv_data *cpd =
193         (struct lan91cxx_priv_data *)sc->driver_private;
194
195     DEBUG_FUNCTION();
196
197     INCR_STAT( interrupts );
198
199     cyg_drv_interrupt_mask(cpd->interrupt);
200     cyg_drv_interrupt_acknowledge(cpd->interrupt);
201
202     return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
203 }
204 #endif
205
206 // The deliver function (ex-DSR)  handles the ethernet [logical] processing
207 static void
208 lan91cxx_deliver(struct eth_drv_sc *sc)
209 {
210     struct lan91cxx_priv_data *cpd =
211         (struct lan91cxx_priv_data *)sc->driver_private;
212
213     DEBUG_FUNCTION();
214
215     // Service the interrupt:
216     lan91cxx_poll(sc);
217     // Allow interrupts to happen again
218     cyg_drv_interrupt_unmask(cpd->interrupt);
219 }
220
221 static int
222 lan91cxx_int_vector(struct eth_drv_sc *sc)
223 {
224     struct lan91cxx_priv_data *cpd =
225         (struct lan91cxx_priv_data *)sc->driver_private;
226
227     return (cpd->interrupt);
228 }
229
230 static bool 
231 smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
232 {
233     struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
234     struct lan91cxx_priv_data *cpd =
235         (struct lan91cxx_priv_data *)sc->driver_private;
236     unsigned short val;
237     int i;
238 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
239     unsigned char ecor, ecsr;
240 #endif
241     cyg_bool esa_configured = false;
242
243     DEBUG_FUNCTION();
244
245     cpd->txbusy = cpd->within_send = 0;
246         
247 #ifdef CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR
248     cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR;
249 #else
250     cpd->addrsh = 0;
251 #endif
252
253 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
254
255     // If the chip is configured in PCMCIA mode, the internal
256     // registers mapped in the attribute memory should be
257     // initialized (i.e. to enable the I/O map)
258     
259     ecor = get_att(sc, LAN91CXX_ECOR);
260     
261     // pulse SRESET on ECOR
262     ecor |= LAN91CXX_ECOR_RESET;
263     put_att(sc, LAN91CXX_ECOR, ecor);
264     
265     HAL_DELAY_US(1);
266     
267     ecor &= ~LAN91CXX_ECOR_RESET;
268     put_att(sc, LAN91CXX_ECOR, ecor);
269
270     // then, enable I/O map
271     ecor |= LAN91CXX_ECOR_ENABLE;    
272     put_att(sc, LAN91CXX_ECOR, ecor);
273
274     // verify the register contents
275     if (ecor != get_att(sc, LAN91CXX_ECOR))
276         db_printf("LAN91CXX - Cannot access PCMCIA attribute registers\n");
277         
278     ecsr = get_att(sc, LAN91CXX_ECSR);
279 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_8_BIT
280 #error "91CXX 8-bit mode not yet supported."
281     ecsr |= LAN91CXX_ECSR_IOIS8;
282 #else
283     ecsr &= ~LAN91CXX_ECSR_IOIS8;
284 #endif
285     put_att(sc, LAN91CXX_ECSR, ecsr);
286         
287 #endif
288
289 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
290     // Initialize environment, setup interrupt handler
291     cyg_drv_interrupt_create(cpd->interrupt,
292                              CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
293                              (cyg_addrword_t)sc, //  Data item passed to interrupt handler
294                              (cyg_ISR_t *)lan91cxx_isr,
295                              (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
296                              &lan91cxx_interrupt_handle,
297                              &lan91cxx_interrupt);
298     cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
299 #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
300     cyg_drv_interrupt_acknowledge(cpd->interrupt);
301 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
302     cyg_drv_interrupt_unmask(cpd->interrupt);
303 #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
304     
305     // probe chip by reading the signature in BS register
306     val = get_banksel(sc);
307 #if DEBUG & 9
308     db_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
309                 cpd->base+LAN91CXX_BS, val );
310 #endif
311
312     if ((0xff00 & val) !=  0x3300) {
313         CYG_FAIL("No 91Cxx signature" );
314         diag_printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
315         return false;
316     }
317
318     val = get_reg(sc, LAN91CXX_REVISION);
319
320 #if DEBUG & 9
321     db_printf("LAN91CXX - type: %01x, rev: %01x\n",
322                 (val>>4)&0xf, val & 0xf);
323 #endif
324
325 #ifdef LAN91CXX_IS_LAN91C111
326     // Set RevA flag for LAN91C111 so we can cope with the odd-bit bug.
327     cpd->c111_reva = (val == 0x3390);
328 #endif
329     
330     // The controller may provide a function used to set up the ESA
331     if (cpd->config_enaddr)
332         (*cpd->config_enaddr)(cpd);
333
334     // Reset chip
335     put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
336     put_reg(sc, LAN91CXX_RCR, 0);
337
338     val = get_reg(sc, LAN91CXX_EPH_STATUS);
339 #ifndef LAN91CXX_IS_LAN91C111
340     // LINK_OK on 91C111 is just a general purpose input and may not
341     // have anything to do with the link.
342     if (!(val & LAN91CXX_STATUS_LINK_OK)) {
343  db_printf("no link\n");
344         return false;  // Link not connected
345     }
346 #endif
347
348
349 #if DEBUG & 9
350     db_printf("LAN91CXX - status: %04x\n", val);
351 #endif
352
353 #if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
354     // Use statically configured ESA from the private data
355 #if DEBUG & 9
356     db_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
357                 cpd->enaddr[0],
358                 cpd->enaddr[1],
359                 cpd->enaddr[2],
360                 cpd->enaddr[3],
361                 cpd->enaddr[4],
362                 cpd->enaddr[5] );
363 #endif // DEBUG
364     // Set up hardware address
365     for (i = 0;  i < sizeof(cpd->enaddr);  i += 2)
366         put_reg(sc, LAN91CXX_IA01+i/2,
367                 cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
368 #else // not CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
369     // Find ESA - check possible sources in sequence and stop when
370     // one provides the ESA:
371     //   RedBoot option (via provide_esa)
372     //   Compile-time configuration
373     //   EEPROM
374
375     if (NULL != cpd->provide_esa) {
376         esa_configured = cpd->provide_esa(cpd);
377 # if DEBUG & 8
378         if (esa_configured)
379             db_printf("Got ESA from RedBoot option\n");
380 # endif
381     }
382     if (!esa_configured && cpd->hardwired_esa) {
383         // ESA is already set in cpd->esa[]
384         esa_configured = true;
385 # if DEBUG & 8
386         db_printf("Got ESA from cpd\n");
387 # endif
388     }
389     if (esa_configured) {
390         // Set up hardware address
391         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2)
392             put_reg(sc, LAN91CXX_IA01+i/2,
393                     cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
394     } else {
395         // Use the address from the serial EEPROM
396         // Read out hardware address
397         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
398             unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
399             cpd->enaddr[i] =   (unsigned char)(0xff & z);
400             cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
401         }
402         esa_configured = true;
403 # if DEBUG & 8
404         db_printf("Got ESA from eeprom\n");
405 # endif
406     }
407 #if DEBUG & 9
408     db_printf("LAN91CXX - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
409                 cpd->enaddr[0],
410                 cpd->enaddr[1],
411                 cpd->enaddr[2],
412                 cpd->enaddr[3],
413                 cpd->enaddr[4],
414                 cpd->enaddr[5] );
415 #endif // DEBUG
416 #endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
417
418     // Initialize upper level driver
419     (sc->funs->eth_drv->init)(sc, cpd->enaddr);
420     return true;
421 }
422
423 static void
424 lan91cxx_stop(struct eth_drv_sc *sc)
425 {
426     struct lan91cxx_priv_data *cpd =
427         (struct lan91cxx_priv_data *)sc->driver_private;
428     DEBUG_FUNCTION();
429
430     CYG_ASSERT( cpd->within_send < 10, "stop: Excess send recursions" );
431     cpd->within_send++;
432     // Complete any outstanding activity:
433     if ( cpd->txbusy ) {
434         cpd->txbusy = 0;
435 #if DEBUG & 9
436         db_printf("LAN91CXX - Stopping, cleaning up pending TX\n" );
437 #endif
438         (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
439     }
440     // Reset chip
441     put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
442     put_reg(sc, LAN91CXX_RCR, 0);
443     cpd->txbusy = cpd->within_send = 0;
444 }
445
446 //
447 // This function is called to "start up" the interface.  It may be called
448 // multiple times, even when the hardware is already running.  It will be
449 // called whenever something "hardware oriented" changes and should leave
450 // the hardware ready to send/receive packets.
451 //
452 static void
453 lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
454 {
455     cyg_uint16 intr;
456 #ifdef LAN91CXX_IS_LAN91C111
457     int delay;
458 #endif
459 #ifdef CYGPKG_NET
460     struct ifnet *ifp = &sc->sc_arpcom.ac_if;
461 #endif
462     DEBUG_FUNCTION();
463
464 #ifdef LAN91CXX_IS_LAN91C111
465     // 91C111 Errata. Internal PHY comes up disabled. Must enable here.
466     lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_RST);
467     HAL_DELAY_US(500000);
468     lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_ANEG_EN |
469                                                  LAN91CXX_PHY_CTRL_SPEED);
470
471     // Start auto-negotiation
472     put_reg(sc, LAN91CXX_RPCR,
473             LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK | LAN91CXX_RPCR_ANEG);
474
475     // wait for auto-negotiation to finish.
476     // give it ~5 seconds before giving up (no cable?)
477     delay = 50;
478     while (!(lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_STAT) & 0x20)) {
479         if (--delay <= 0)
480             break;
481         HAL_DELAY_US(100000);
482     }
483 #if DEBUG & 1
484     if (delay <= 0)
485             diag_printf("auto-negotiation failed.\n");
486 #endif
487 #endif
488
489     put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
490
491     put_reg(sc, LAN91CXX_INTERRUPT, 0);   // disable interrupts
492     intr = get_reg(sc, LAN91CXX_INTERRUPT);
493     put_reg(sc, LAN91CXX_INTERRUPT, intr &      // ack old interrupts
494             (LAN91CXX_INTERRUPT_TX_INT | LAN91CXX_INTERRUPT_TX_EMPTY_INT | 
495             LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT));
496     put_reg(sc, LAN91CXX_RCR, 
497 #ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46.
498             LAN91CXX_RCR_ABORT_ENB |
499 #endif
500             LAN91CXX_RCR_STRIP_CRC |
501             LAN91CXX_RCR_RXEN | LAN91CXX_RCR_ALMUL);
502     put_reg(sc, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN);
503     put_reg(sc, LAN91CXX_CONTROL, 0);
504     put_reg(sc, LAN91CXX_INTERRUPT,       // enable interrupts
505             LAN91CXX_INTERRUPT_RCV_INT_M);
506
507 #ifdef CYGPKG_NET
508     if (( 0
509 #ifdef ETH_DRV_FLAGS_PROMISC_MODE
510          != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
511 #endif
512         ) || (ifp->if_flags & IFF_PROMISC)
513         ) {
514         // Then we select promiscuous mode.
515         unsigned short rcr;
516         rcr = get_reg(sc, LAN91CXX_RCR );
517         rcr |= LAN91CXX_RCR_PRMS;
518         put_reg(sc, LAN91CXX_RCR, rcr );
519     }
520 #endif
521 }
522
523 //
524 // This routine is called to perform special "control" opertions
525 //
526 static int
527 lan91cxx_control(struct eth_drv_sc *sc, unsigned long key,
528                void *data, int data_length)
529 {
530     unsigned char *esa = (unsigned char *)data;
531     int i;
532     unsigned short reg;
533     struct lan91cxx_priv_data *cpd =
534         (struct lan91cxx_priv_data *)sc->driver_private;
535
536     DEBUG_FUNCTION();
537
538     switch (key) {
539     case ETH_DRV_SET_MAC_ADDRESS:
540 #if 9 & DEBUG
541         db_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
542                 esa[0],
543                 esa[1],
544                 esa[2],
545                 esa[3],
546                 esa[4],
547                 esa[5] );
548 #ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
549         db_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
550 #endif
551 #endif // DEBUG
552
553 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
554         // Only now can we command the chip to perform EEPROM writes:
555
556         // select arbitrary writing to the EEPROM
557         reg = get_reg(sc, LAN91CXX_CONTROL);
558         reg |= LAN91CXX_CONTROL_EEPROM_SELECT;
559         put_reg(sc, LAN91CXX_CONTROL, reg );
560
561         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
562             int j;
563             // Set the address register
564             put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2);
565             // Poke the data
566             put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8));
567             // Command the store
568             reg = get_reg(sc, LAN91CXX_CONTROL);
569             reg |= LAN91CXX_CONTROL_STORE;
570             put_reg(sc, LAN91CXX_CONTROL, reg );
571             // and poll for completion
572             for ( j = 1024 * 1024; 0 < j ; j-- ) {
573                 reg = get_reg(sc, LAN91CXX_CONTROL);
574                 if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
575                     break;
576             }
577             CYG_ASSERT( 0 < j, "EEPROM write timout!" );
578         }
579
580         reg = get_reg(sc, LAN91CXX_CONTROL);
581         CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY),
582                     "EEPROM still busy!" );
583         // Clear the EEPROM selection bit
584         reg &=~LAN91CXX_CONTROL_EEPROM_SELECT;
585         put_reg(sc, LAN91CXX_CONTROL, reg );
586         // and check it "took"
587         reg = get_reg(sc, LAN91CXX_CONTROL);
588         CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_SELECT),
589                     "EEPROM still selected!" );
590         // and command a complete reload
591         reg |= LAN91CXX_CONTROL_RELOAD;
592         put_reg(sc, LAN91CXX_CONTROL, reg );
593         for ( i = 1024 * 1024; 0 < i ; i-- ) {
594             reg = get_reg(sc, LAN91CXX_CONTROL);
595             if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
596                 break;
597         }
598         CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
599         // Now extract the MAC address that is in the chip, and tell the
600         // system about it.
601         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
602             unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
603             cpd->enaddr[i] =   (unsigned char)(0xff & z);
604             cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
605         }
606 #if DEBUG & 9
607         db_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
608                     cpd->enaddr[0],
609                     cpd->enaddr[1],
610                     cpd->enaddr[2],
611                     cpd->enaddr[3],
612                     cpd->enaddr[4],
613                     cpd->enaddr[5] );
614 #endif // DEBUG
615         for (i = 0;  i < sizeof(cpd->enaddr);  i++ ) {
616             CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" );
617             if ( esa[i] != cpd->enaddr[i] )
618                 return 1; // the operation failed.
619         }
620 #else // not CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
621         // Whatever, we can write the MAC address into the interface info,
622         // and the chip registers no problem.
623         for ( i = 0; i < sizeof(cpd->enaddr);  i++ )
624             cpd->enaddr[i] = esa[i];
625         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
626             reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8);
627             put_reg(sc, LAN91CXX_IA01+i/2, reg );
628         }
629 #endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
630         return 0;
631
632 #ifdef ETH_DRV_GET_MAC_ADDRESS
633     case ETH_DRV_GET_MAC_ADDRESS:
634         // Extract the MAC address that is in the chip, and tell the
635         // system about it.
636         for (i = 0;  i < sizeof(cpd->enaddr);  i += 2) {
637             unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
638             esa[i] =   (unsigned char)(0xff & z);
639             esa[i+1] = (unsigned char)(0xff & (z >> 8));
640         }
641         return 0;
642 #endif
643
644 #ifdef ETH_DRV_GET_IF_STATS_UD
645     case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
646 #endif
647         // drop through
648 #ifdef ETH_DRV_GET_IF_STATS
649     case ETH_DRV_GET_IF_STATS:
650 #endif
651 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
652     {
653         struct ether_drv_stats *p = (struct ether_drv_stats *)data;
654         // Chipset entry is no longer supported; RFC1573.
655         for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
656             p->snmp_chipset[i] = 0;
657
658         // This perhaps should be a config opt, so you can make up your own
659         // description, or supply it from the instantiation.
660         strcpy( p->description, "SMSC LAN91Cxx" );
661         // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
662
663         reg = get_reg(sc, LAN91CXX_EPH_STATUS);
664         if ((reg & LAN91CXX_STATUS_LINK_OK) == 0) {
665             p->operational = 2;         // LINK DOWN
666             p->duplex = 1;              // UNKNOWN
667             p->speed = 0;
668         }
669         else {
670             p->operational = 3;         // LINK UP
671             p->duplex = 2;              // 2 = SIMPLEX, 3 = DUPLEX
672             p->speed = 10 * 1000000;    // it's only a 10Mbit device
673         }
674
675 #ifdef KEEP_STATISTICS
676         {
677             struct smsc_lan91cxx_stats *ps = &(cpd->stats);
678
679             // Admit to it...
680             p->supports_dot3        = true;
681
682             p->tx_good              = ps->tx_good             ;
683             p->tx_max_collisions    = ps->tx_max_collisions   ;
684             p->tx_late_collisions   = ps->tx_late_collisions  ;
685             p->tx_underrun          = ps->tx_underrun         ;
686             p->tx_carrier_loss      = ps->tx_carrier_loss     ;
687             p->tx_deferred          = ps->tx_deferred         ;
688             p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
689             p->tx_single_collisions = ps->tx_single_collisions;
690             p->tx_mult_collisions   = ps->tx_mult_collisions  ;
691             p->tx_total_collisions  = ps->tx_total_collisions ;
692             p->rx_good              = ps->rx_good             ;
693             p->rx_crc_errors        = ps->rx_crc_errors       ;
694             p->rx_align_errors      = ps->rx_align_errors     ;
695             p->rx_resource_errors   = ps->rx_resource_errors  ;
696             p->rx_overrun_errors    = ps->rx_overrun_errors   ;
697             p->rx_collisions        = ps->rx_collisions       ;
698             p->rx_short_frames      = ps->rx_short_frames     ;
699             p->rx_too_long_frames   = ps->rx_too_long_frames  ;
700             p->rx_symbol_errors     = ps->rx_symbol_errors    ;
701         
702             p->interrupts           = ps->interrupts          ;
703             p->rx_count             = ps->rx_count            ;
704             p->rx_deliver           = ps->rx_deliver          ;
705             p->rx_resource          = ps->rx_resource         ;
706             p->rx_restart           = ps->rx_restart          ;
707             p->tx_count             = ps->tx_count            ;
708             p->tx_complete          = ps->tx_complete         ;
709             p->tx_dropped           = ps->tx_dropped          ;
710         }
711 #endif // KEEP_STATISTICS
712
713         p->tx_queue_len = 1;
714
715         return 0; // OK
716     }
717 #endif
718     default:
719         break;
720     }
721     return 1;
722 }
723
724 //
725 // This routine is called to see if it is possible to send another packet.
726 // It will return non-zero if a transmit is possible, zero otherwise.
727 //
728 static int
729 lan91cxx_can_send(struct eth_drv_sc *sc)
730 {
731     struct lan91cxx_priv_data *cpd =
732         (struct lan91cxx_priv_data *)sc->driver_private;
733     int tcr;
734
735     DEBUG_FUNCTION();
736
737 #ifndef LAN91CXX_IS_LAN91C111
738     // LINK_OK on 91C111 is just a general purpose input and may not
739     // have anything to do with the link.
740     if ((get_reg(sc, LAN91CXX_EPH_STATUS) & LAN91CXX_STATUS_LINK_OK) == 0) {
741         db_printf("no link\n");
742         return false;  // Link not connected
743     }
744 #endif
745
746     CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
747     cpd->within_send++;
748
749     tcr = get_reg(sc, LAN91CXX_TCR);
750     if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
751 #if DEBUG & 1
752         db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
753 #endif
754         // Complete any outstanding activity:
755         if ( cpd->txbusy ) {
756             cpd->txbusy = 0;
757 #if DEBUG & 9
758             db_printf("LAN91CXX - can_send, cleaning up pending TX\n" );
759 #endif
760             (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
761         }
762         tcr |= LAN91CXX_TCR_TXENA;
763         put_reg(sc, LAN91CXX_TCR, tcr);
764     }
765
766     // This helps unstick deadly embraces.
767     lan91cxx_poll( sc ); // Deal with any outstanding rx state
768     cpd->within_send--;
769
770     return (cpd->txbusy == 0) && (0 == cpd->within_send);
771 }
772
773 //
774 // This routine is called to send data to the hardware.
775 static void 
776 lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len, 
777             int total_len, unsigned long key)
778 {
779     struct lan91cxx_priv_data *cpd = 
780         (struct lan91cxx_priv_data *)sc->driver_private;
781     int i, len, plen, tcr;
782
783     unsigned short *sdata = NULL;
784     unsigned short ints, control;
785     cyg_uint16 packet, status;
786
787     DEBUG_FUNCTION();
788
789     INCR_STAT( tx_count );
790
791     // Worry about the TX engine stopping.
792     tcr = get_reg(sc, LAN91CXX_TCR);
793     if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
794 #if DEBUG & 1
795         db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
796 #endif
797         tcr |= LAN91CXX_TCR_TXENA;
798         put_reg(sc, LAN91CXX_TCR, tcr);
799     }
800
801     // This helps unstick deadly embraces.
802     CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" );
803     cpd->within_send++;
804     lan91cxx_poll( sc ); // Deal with any outstanding rx state
805     cpd->within_send--;
806
807     cpd->txbusy = 1;
808     cpd->txkey = key;
809
810     // Find packet length
811     plen = 0;
812     for (i = 0;  i < sg_len;  i++)
813         plen += sg_list[i].len;
814
815     CYG_ASSERT( plen == total_len, "sg data length mismatch" );
816
817     // Alloc new TX packet
818     do {
819         put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_alloc_for_tx
820 #ifndef LAN91CXX_IS_LAN91C111
821                 | ((plen >> 8) & 0x07)
822 #endif
823             );
824
825         i = 1024 * 1024;
826         do {
827             status = get_reg(sc, LAN91CXX_INTERRUPT);
828         } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) );
829         if ( i )
830             packet = get_reg(sc, LAN91CXX_PNR);
831         else
832             packet = 0xffff;
833 #if DEBUG & 1
834         db_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
835 #endif
836         packet = packet >> 8;
837         if (packet & 0x80) {
838             // Hm.. Isn't this a dead end?
839 #if DEBUG & 1
840             db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
841 #endif
842             // Not if we can make progress with what's filling memory.
843             lan91cxx_poll( sc ); // Deal with any outstanding state
844             continue;
845         }
846     } while (0);
847
848 #if DEBUG & 4
849     db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
850                 packet, cpd->txpacket);
851 #endif
852     cpd->txpacket = packet;
853
854     put_reg(sc, LAN91CXX_PNR, packet);
855     // Note: Check FIFO state here before continuing?
856     put_reg(sc, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000);
857     // Pointer is now set, and the proper bank is selected for
858     // data writes.
859
860     // Prepare header:
861     put_data(sc, CYG_CPU_TO_LE16(0));        // reserve space for status word
862     // packet length (includes status, byte-count and control shorts)
863     put_data(sc, CYG_CPU_TO_LE16(0x7FE & (plen + 6)) ); // Always even, always < 15xx(dec)
864
865     // Put data into buffer
866     for (i = 0;  i < sg_len;  i++) {
867         sdata = (unsigned short *)sg_list[i].buf;
868         len = sg_list[i].len;
869
870         CYG_ASSERT(0 == (len & 1) || (i == (sg_len-1)), "odd length");
871         CYG_ASSERT( sdata, "No sg data pointer here" );
872         while(len >= sizeof(*sdata)) {
873             put_data(sc, *sdata++);
874             len -= sizeof(*sdata);
875         }
876     }
877     CYG_ASSERT( sdata, "No sg data pointer outside" );
878
879     // Lay down the control short unconditionally at the end.
880     // (or it might use random memory contents)
881     control = 0;
882     if ( 1 & plen ) {
883         // Need to set ODD flag and insert the data
884         unsigned char onebyte = *(unsigned char*)sdata;
885         control = onebyte;
886         control |= LAN91CXX_CONTROLBYTE_ODD;
887     }
888     control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case...
889     put_data(sc, CYG_CPU_TO_LE16(control));
890
891     // Enqueue the packet
892     put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
893
894     // Ack TX empty int and unmask it.
895     ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
896     put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_ACK);
897     put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_M);
898
899 #if DEBUG & 1
900     ints = get_reg(sc, LAN91CXX_INTERRUPT);
901     db_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
902 #endif
903 }
904
905 static void
906 lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat)
907 {
908     unsigned short packet, ints, tcr;
909     struct lan91cxx_priv_data *cpd =
910         (struct lan91cxx_priv_data *)sc->driver_private;
911     int success = 1;
912
913     DEBUG_FUNCTION();
914
915     INCR_STAT( tx_complete );
916
917     // Ack and mask TX interrupt set
918     ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
919     ints |= LAN91CXX_INTERRUPT_TX_SET_ACK;
920     ints &= ~LAN91CXX_INTERRUPT_TX_SET_M;
921     put_reg(sc, LAN91CXX_INTERRUPT, ints);
922
923     // Get number of completed packet and read the status word
924     packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
925 #if DEBUG & 1
926     db_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
927 #endif
928
929 #ifdef KEEP_STATISTICS
930     {
931         unsigned short reg;
932
933         reg = get_reg( sc, LAN91CXX_EPH_STATUS );
934         
935         // Covering each bit in turn...
936         if ( reg & LAN91CXX_STATUS_TX_UNRN   ) INCR_STAT( tx_underrun );
937         //if ( reg & LAN91CXX_STATUS_LINK_OK ) INCR_STAT(  );
938         //if ( reg & LAN91CXX_STATUS_CTR_ROL ) INCR_STAT(  );
939         //if ( reg & LAN91CXX_STATUS_EXC_DEF ) INCR_STAT(  );
940         if ( reg & LAN91CXX_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
941         if ( reg & LAN91CXX_STATUS_LATCOL    ) INCR_STAT( tx_late_collisions );
942         //if ( reg & LAN91CXX_STATUS_WAKEUP  ) INCR_STAT(  );
943         if ( reg & LAN91CXX_STATUS_TX_DEFR   ) INCR_STAT( tx_deferred );
944         //if ( reg & LAN91CXX_STATUS_LTX_BRD ) INCR_STAT(  );
945         if ( reg & LAN91CXX_STATUS_SQET      ) INCR_STAT( tx_sqetesterrors );
946         if ( reg & LAN91CXX_STATUS_16COL     ) INCR_STAT( tx_max_collisions );
947         //if ( reg & LAN91CXX_STATUS_LTX_MULT) INCR_STAT(  );
948         if ( reg & LAN91CXX_STATUS_MUL_COL   ) INCR_STAT( tx_mult_collisions );
949         if ( reg & LAN91CXX_STATUS_SNGL_COL  ) INCR_STAT( tx_single_collisions );
950         if ( reg & LAN91CXX_STATUS_TX_SUC    ) INCR_STAT( tx_good );
951
952         cpd->stats.tx_total_collisions = 
953             cpd->stats.tx_late_collisions + 
954             cpd->stats.tx_max_collisions + 
955             cpd->stats.tx_mult_collisions + 
956             cpd->stats.tx_single_collisions;
957
958         // We do not need to look in the Counter Register (LAN91CXX_COUNTER)
959         // because it just mimics the info we already have above.
960     }
961 #endif // KEEP_STATISTICS
962     // We do not really care about Tx failure.  Ethernet is not a reliable
963     // medium.  But we do care about the TX engine stopping.
964     tcr = get_reg(sc, LAN91CXX_TCR);
965     if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
966 #if DEBUG & 1
967         db_printf("%s: ENGINE RESTART: tcr 0x%04x ints %04x\n", __FUNCTION__, tcr, ints);
968 #endif
969         tcr |= LAN91CXX_TCR_TXENA;
970         put_reg(sc, LAN91CXX_TCR, tcr);
971         success = 0; // And treat this as an error...
972     }
973
974     packet &= 0xff;
975
976     // It certainly appears that occasionally the tx fifo tells lies; we
977     // get the wrong packet number.  Freeing the one we allocated seems to
978     // give correct operation.
979 #ifdef CYGPKG_INFRA_DEBUG
980     // Then we log, OOI, the number of times we get a bad packet number
981     // from the tx done fifo.
982     if (cpd->txpacket != packet )
983         lan91cxx_txfifo_bad++;
984     else
985         lan91cxx_txfifo_good++;
986 #endif
987 #if DEBUG & 4
988     db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
989 #endif
990     // and then free the packet
991     put_reg(sc, LAN91CXX_PNR, cpd->txpacket);
992     put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet);
993
994     // Ack the TX int which is supposed to clear the packet from the TX
995     // completion queue.
996     ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
997     ints |= LAN91CXX_INTERRUPT_TX_FIFO_ACK;
998     put_reg(sc, LAN91CXX_INTERRUPT, ints);
999
1000 #if DEBUG & 1
1001     // Hm... The free doesn't seem to have the desired effect?!?
1002     ints = get_reg(sc, LAN91CXX_INTERRUPT);
1003     packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
1004     db_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
1005 #endif
1006
1007     if ( cpd->txbusy ) {
1008         cpd->txbusy = 0;
1009         (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1010     }
1011 }
1012
1013
1014 //
1015 // This function is called when a packet has been received.  Its job is
1016 // to prepare to unload the packet from the hardware.  Once the length of
1017 // the packet is known, the upper layer of the driver can be told.  When
1018 // the upper layer is ready to unload the packet, the internal function
1019 // 'lan91cxx_recv' will be called to actually fetch it from the hardware.
1020 //
1021 static void
1022 lan91cxx_RxEvent(struct eth_drv_sc *sc)
1023 {
1024     struct lan91cxx_priv_data *cpd = 
1025         (struct lan91cxx_priv_data *)sc->driver_private;
1026     unsigned short stat, len;
1027 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1028     cyg_uint32 val;
1029 #endif
1030
1031     DEBUG_FUNCTION();
1032
1033     stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
1034 #if DEBUG & 1
1035     db_printf("RxEvent - FIFOs: 0x%04x\n", stat);
1036 #endif
1037     if ( 0x8000 & stat ) {
1038         // Then the Rx FIFO is empty
1039 #if DEBUG & 4
1040         db_printf("#####RxEvent with empty fifo\n");
1041 #endif
1042         return;
1043     }
1044
1045     INCR_STAT( rx_count );
1046
1047 #if DEBUG & 4
1048     db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
1049                 0xff & (stat >> 8), cpd->rxpacket );
1050 #endif
1051     // There is an Rx Packet ready
1052     cpd->rxpacket = 0xff & (stat >> 8);
1053
1054     // Read status and (word) length
1055     put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1056                                  LAN91CXX_POINTER_AUTO_INCR | 0x0000));
1057 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1058     val = get_data(sc);
1059     val = CYG_LE32_TO_CPU(val);
1060     stat = val & 0xffff;
1061     len = ((val >> 16) & 0xffff) - 6;   // minus header/footer words
1062 #else
1063     stat = get_data(sc);
1064     stat = CYG_LE16_TO_CPU(stat);
1065     len = get_data(sc);
1066     len = CYG_LE16_TO_CPU(len) - 6;     // minus header/footer words
1067 #endif
1068
1069 #ifdef KEEP_STATISTICS
1070     if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
1071     //if ( stat & LAN91CXX_RX_STATUS_BCAST    ) INCR_STAT(  );
1072     if ( stat & LAN91CXX_RX_STATUS_BADCRC   ) INCR_STAT( rx_crc_errors );
1073     if ( stat & LAN91CXX_RX_STATUS_TOOLONG  ) INCR_STAT( rx_too_long_frames );
1074     if ( stat & LAN91CXX_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames );
1075     //if ( stat & LAN91CXX_RX_STATUS_MCAST    ) INCR_STAT(  );
1076 #endif // KEEP_STATISTICS
1077
1078     if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
1079         INCR_STAT( rx_good );
1080         // Then it's OK
1081
1082         if( LAN91CXX_RX_STATUS_IS_ODD(cpd,stat) )
1083             len++;
1084
1085 #if DEBUG & 1
1086         db_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
1087 #endif
1088         // Check for bogusly short packets; can happen in promisc mode:
1089         // Asserted against and checked by upper layer driver.
1090 #ifdef CYGPKG_NET
1091         if ( len > sizeof( struct ether_header ) )
1092             // then it is acceptable; offer the data to the network stack
1093 #endif
1094         (sc->funs->eth_drv->recv)(sc, len);
1095
1096         return;
1097     }
1098
1099     // Not OK for one reason or another...
1100 #if DEBUG & 1
1101     db_printf("RxEvent - bad rx: stat: 0x%04x, len: 0x%04x\n", stat, len);
1102 #endif
1103
1104     // Free packet
1105     put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1106 }
1107
1108 //
1109 // This function is called as a result of the "eth_drv_recv()" call above.
1110 // Its job is to actually fetch data for a packet from the hardware once
1111 // memory buffers have been allocated for the packet.  Note that the buffers
1112 // may come in pieces, using a scatter-gather list.  This allows for more
1113 // efficient processing in the upper layers of the stack.
1114 //
1115 static void
1116 lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1117 {
1118 #if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || \
1119     defined(KEEP_STATISTICS) || defined(LAN91CXX_IS_LAN91C111)
1120     struct lan91cxx_priv_data *cpd = 
1121         (struct lan91cxx_priv_data *)sc->driver_private;
1122 #endif
1123     int i;
1124     short mlen=0, plen;
1125     cyg_uint16 *data=NULL;
1126     unsigned char *cp, cval, odd_even = 0;
1127 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1128     cyg_uint32 val;
1129 #else
1130     cyg_uint16 val;
1131 #endif
1132
1133     DEBUG_FUNCTION();
1134
1135     INCR_STAT( rx_deliver );
1136
1137     put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1138                                  LAN91CXX_POINTER_AUTO_INCR));
1139     val = get_data(sc);
1140
1141     // packet length (minus header/footer)
1142 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1143     val = CYG_LE32_TO_CPU(val);
1144     plen = (val >> 16) - 6;
1145 #else
1146     val = CYG_LE16_TO_CPU(val);
1147     plen = get_data(sc);
1148     plen = CYG_LE16_TO_CPU(plen) - 6;
1149 #endif
1150
1151     if( LAN91CXX_RX_STATUS_IS_ODD(cpd,val) )
1152         plen++;
1153
1154     for (i = 0;  i < sg_len;  i++) {
1155         data = (cyg_uint16 *)sg_list[i].buf;
1156         mlen = sg_list[i].len;
1157
1158         CYG_ASSERT(0 == (mlen & (sizeof(*data) - 1)) || (i == (sg_len-1)), "odd length");
1159
1160 #if DEBUG & 1
1161         db_printf("%s : mlen 0x%04x, plen 0x%04x\n", __FUNCTION__, mlen, plen);
1162 #endif
1163         if (data) {
1164             while (mlen >= sizeof(*data)) {
1165 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1166                 if (!(odd_even)) {        // because of the 32bit to 16bit conversion, read only every 2nd word
1167 #endif
1168                    val = get_data(sc);
1169 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1170                    odd_even = 1;
1171                }
1172                else {
1173                           val >>= 16;
1174                           odd_even = 0;
1175                }
1176 #endif
1177                 *data++ = val;
1178                 mlen -= sizeof(*data);
1179                 plen -= sizeof(*data);
1180             }
1181         }
1182         else { // must actively discard ie. read it from the chip anyway.
1183             while (mlen >= sizeof(*data)) {
1184 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1185                 if (!(odd_even)) {
1186 #endif
1187                     val = get_data(sc);
1188 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1189                     odd_even = 1;
1190                }
1191                else {
1192                    val >>= 16;
1193                    odd_even = 0;
1194                }
1195 #endif
1196                 mlen -= sizeof(*data);
1197                 plen -= sizeof(*data);
1198             }
1199         }
1200     }
1201     if (!(odd_even)) {      // read the control word only if we not already have it because of a 32bit access
1202     val = get_data(sc); // Read control word (and potential data) unconditionally
1203 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1204     val = CYG_LE32_TO_CPU(val);
1205     if (plen & 2) {
1206         if (data)
1207             *(cyg_uint16 *)data = val & 0xffff;
1208         cp = (unsigned char *)data + 2;
1209         val >>= 16;
1210         mlen -= 2;
1211         }
1212 #else
1213     val = CYG_LE16_TO_CPU(val);
1214 #endif
1215     }
1216         cp = (unsigned char *)data;
1217
1218     CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX, 
1219                "Controlbyte is not for Rx");
1220     CYG_ASSERT( (1 == mlen) == (0 != LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val)), 
1221                 "Controlbyte does not match");
1222     if (data && (1 == mlen) && LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val) ) {
1223         cval = val & 0x00ff;    // last byte contains data
1224         *cp = cval;
1225     }
1226
1227     val = get_reg(sc, LAN91CXX_FIFO_PORTS);
1228 #if DEBUG & 4
1229     if ( 0x8000 & val ) // Then the Rx FIFO is empty
1230         db_printf("#####Rx packet NOT freed, stat is 0x%04x (expected 0x%04x)\n",
1231                     val, cpd->rxpacket);
1232     else
1233         db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
1234                     0xff & (val >> 8), cpd->rxpacket );
1235 #endif
1236     CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
1237
1238     // Free packet
1239     put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1240 }
1241
1242 static void
1243 lan91cxx_poll(struct eth_drv_sc *sc)
1244 {
1245     unsigned short event;
1246     struct lan91cxx_priv_data *cpd = 
1247         (struct lan91cxx_priv_data *)sc->driver_private;
1248
1249 //    DEBUG_FUNCTION();
1250     while (1) {
1251         cyg_drv_interrupt_acknowledge(cpd->interrupt);
1252         // Get the (unmasked) requests
1253         event = get_reg(sc, LAN91CXX_INTERRUPT);
1254         event = event & (event >> 8) & 0xff;
1255         if (0 == event)
1256             break;
1257 #if 0
1258         if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
1259             // Early receive interrupt
1260         }
1261         else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
1262             // ethernet protocol handler failures
1263         }
1264         else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
1265             // receive overrun
1266         }
1267         else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
1268             // allocation interrupt
1269         }
1270         else
1271 #endif
1272         if (event & LAN91CXX_INTERRUPT_TX_SET) {
1273             lan91cxx_TxEvent(sc, event);
1274         }
1275         if (event & LAN91CXX_INTERRUPT_RCV_INT) {
1276             lan91cxx_RxEvent(sc);
1277         }
1278         if (event & ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
1279             db_printf("%s: Unknown interrupt: 0x%04x\n",
1280                         __FUNCTION__, event);
1281     }
1282 }
1283
1284 #ifdef LAN91CXX_IS_LAN91C111
1285
1286 static cyg_uint16
1287 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr, cyg_uint8 phyreg)
1288 {
1289     int i, mask, input_idx, clk_idx = 0;
1290     cyg_uint16 mii_reg, value;
1291     cyg_uint8 bits[64];
1292
1293     // 32 consecutive ones on MDO to establish sync
1294     for (i = 0; i < 32; ++i)
1295         bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1296
1297     // Start code <01>
1298     bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1299     bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1300
1301     // Read command <10>
1302     bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1303     bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1304
1305     // Output the PHY address, msb first
1306     for (mask = 0x10; mask; mask >>= 1) {
1307         if (phyaddr & mask)
1308             bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1309         else
1310             bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1311     }
1312
1313     // Output the phy register number, msb first
1314     for (mask = 0x10; mask; mask >>= 1) {
1315         if (phyreg & mask)
1316             bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1317         else
1318             bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1319     }
1320
1321     // Tristate and turnaround (1 bit times)
1322     bits[clk_idx++] = 0;
1323
1324     // Input starts at this bit time
1325     input_idx = clk_idx;
1326
1327     // Will input 16 bits
1328     for (i = 0; i < 16; ++i)
1329         bits[clk_idx++] = 0;
1330
1331     // Final clock bit
1332     bits[clk_idx++] = 0;
1333
1334     // Get the current MII register value
1335     mii_reg = get_reg(sc, LAN91CXX_MGMT);
1336
1337     // Turn off all MII Interface bits
1338     mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK | 
1339                  LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1340
1341     // Clock all 64 cycles
1342     for (i = 0; i < sizeof(bits); ++i) {
1343         // Clock Low - output data
1344         put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1345         HAL_DELAY_US(50);
1346
1347         // Clock Hi - input data
1348         put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1349         HAL_DELAY_US(50);
1350
1351         bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1352     }
1353
1354     // Return to idle state
1355     put_reg(sc, LAN91CXX_MGMT, mii_reg);
1356     HAL_DELAY_US(50);
1357
1358     // Recover input data
1359     for (value = 0, i = 0; i < 16; ++i) {
1360         value <<= 1;
1361         if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
1362             value |= 1;
1363     }
1364     return value;
1365 }
1366
1367 static void
1368 lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
1369                    cyg_uint8 phyreg, cyg_uint16 value)
1370 {
1371     int i, mask, clk_idx = 0;
1372     cyg_uint16 mii_reg;
1373     cyg_uint8 bits[65];
1374
1375     // 32 consecutive ones on MDO to establish sync
1376     for (i = 0; i < 32; ++i)
1377         bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1378
1379     // Start code <01>
1380     bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1381     bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1382
1383     // Write command <01>
1384     bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1385     bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1386
1387     // Output the PHY address, msb first
1388     for (mask = 0x10; mask; mask >>= 1) {
1389         if (phyaddr & mask)
1390             bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1391         else
1392             bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1393     }
1394
1395     // Output the phy register number, msb first
1396     for (mask = 0x10; mask; mask >>= 1) {
1397         if (phyreg & mask)
1398             bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1399         else
1400             bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1401     }
1402
1403     // Tristate and turnaround (2 bit times)
1404     bits[clk_idx++] = 0;
1405     bits[clk_idx++] = 0;
1406
1407     // Write out 16 bits of data, msb first
1408     for (mask = 0x8000; mask; mask >>= 1) {
1409         if (value & mask)
1410             bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1411         else
1412             bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1413     }
1414
1415     // Final clock bit (tristate)
1416     bits[clk_idx++] = 0;
1417
1418     // Get the current MII register value
1419     mii_reg = get_reg(sc, LAN91CXX_MGMT);
1420
1421     // Turn off all MII Interface bits
1422     mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK | 
1423                  LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1424
1425     // Clock all cycles
1426     for (i = 0; i < sizeof(bits); ++i) {
1427         // Clock Low - output data
1428         put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1429         HAL_DELAY_US(50);
1430
1431         // Clock Hi - input data
1432         put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1433         HAL_DELAY_US(50);
1434
1435 //      bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1436     }
1437
1438     // Return to idle state
1439     put_reg(sc, LAN91CXX_MGMT, mii_reg);
1440     HAL_DELAY_US(50);
1441 }
1442 #endif // LAN91CXX_IS_LAN91C111
1443
1444 // EOF if_lan91cxx.c