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