1 //==========================================================================
5 // Ethernet device driver for SMSC LAN91CXX compatible controllers
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.
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.
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
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.
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.
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.
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //####BSDCOPYRIGHTBEGIN####
43 // -------------------------------------------
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.
48 // -------------------------------------------
50 //####BSDCOPYRIGHTEND####
51 //==========================================================================
52 //#####DESCRIPTIONBEGIN####
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
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.
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
68 // We may want to pingpong in future for throughput reasons.
70 // <jco@ict.es> Added support for PCMCIA mode and shifted
73 //####DESCRIPTIONEND####
75 //==========================================================================
77 // Based on LAN91C110 and LAN91C96
79 #include <pkgconf/system.h>
80 #include <pkgconf/devs_eth_smsc_lan91cxx.h>
81 #include <pkgconf/io_eth_drivers.h>
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>
93 #include <pkgconf/net.h>
94 #include <cyg/kernel/kapi.h>
95 #include <net/if.h> /* Needed for struct ifnet */
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;
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
115 #if defined(CYGPKG_REDBOOT)
116 static void db_printf( char *fmt, ... )
118 extern int start_console(void);
119 extern void end_console(int);
123 old_console = start_console();
124 diag_vprintf( fmt, a );
125 end_console(old_console);
130 static void db_printf( char *fmt, ... )
133 int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
135 CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
136 diag_vprintf( fmt, a );
137 CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
141 #define db_printf diag_printf
146 static void db_printf( char *fmt, ... )
149 int old_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
151 CYGACC_CALL_IF_SET_CONSOLE_COMM( 0 );
152 diag_vprintf( fmt, a );
153 CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
157 #define db_printf( fmt, ... )
163 #define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
165 #define DEBUG_FUNCTION() do {} while(0)
168 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
169 #define KEEP_STATISTICS
172 #ifdef KEEP_STATISTICS
173 #define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
175 #define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
178 #include "smsc_lan91cxx.h"
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,
187 static void lan91cxx_poll(struct eth_drv_sc *sc);
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))
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)
208 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
209 static cyg_interrupt lan91cxx_interrupt;
210 static cyg_handle_t lan91cxx_interrupt_handle;
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 */
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;
222 INCR_STAT( interrupts );
224 cyg_drv_interrupt_mask(cpd->interrupt);
225 cyg_drv_interrupt_acknowledge(cpd->interrupt);
227 return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
231 // The deliver function (ex-DSR) handles the ethernet [logical] processing
233 lan91cxx_deliver(struct eth_drv_sc *sc)
235 struct lan91cxx_priv_data *cpd =
236 (struct lan91cxx_priv_data *)sc->driver_private;
240 // Service the interrupt:
242 // Allow interrupts to happen again
243 cyg_drv_interrupt_unmask(cpd->interrupt);
247 lan91cxx_int_vector(struct eth_drv_sc *sc)
249 struct lan91cxx_priv_data *cpd =
250 (struct lan91cxx_priv_data *)sc->driver_private;
252 return (cpd->interrupt);
256 smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
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;
263 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
264 unsigned char ecor, ecsr;
266 cyg_bool esa_configured = false;
270 cpd->txbusy = cpd->within_send = 0;
272 #ifdef CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR
273 cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR;
278 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
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)
284 ecor = get_att(sc, LAN91CXX_ECOR);
286 // pulse SRESET on ECOR
287 ecor |= LAN91CXX_ECOR_RESET;
288 put_att(sc, LAN91CXX_ECOR, ecor);
290 CYGACC_CALL_IF_DELAY_US(1);
292 ecor &= ~LAN91CXX_ECOR_RESET;
293 put_att(sc, LAN91CXX_ECOR, ecor);
295 // then, enable I/O map
296 ecor |= LAN91CXX_ECOR_ENABLE;
297 put_att(sc, LAN91CXX_ECOR, ecor);
299 // verify the register contents
300 if (ecor != get_att(sc, LAN91CXX_ECOR))
301 db_printf("LAN91CXX - Cannot access PCMCIA attribute registers\n");
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;
308 ecsr &= ~LAN91CXX_ECSR_IOIS8;
310 put_att(sc, LAN91CXX_ECSR, ecsr);
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);
328 // probe chip by reading the signature in BS register
329 val = get_banksel(sc);
331 db_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
332 cpd->base+LAN91CXX_BS, val );
335 if ((0xff00 & val) != 0x3300) {
336 CYG_FAIL("No 91Cxx signature" );
337 diag_printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
341 val = get_reg(sc, LAN91CXX_REVISION);
344 db_printf("LAN91CXX - type: %01x, rev: %01x\n",
345 (val>>4)&0xf, val & 0xf);
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);
353 // The controller may provide a function used to set up the ESA
354 if (cpd->config_enaddr)
355 (*cpd->config_enaddr)(cpd);
358 put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
359 put_reg(sc, LAN91CXX_RCR, 0);
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
373 db_printf("LAN91CXX - status: %04x\n", val);
376 #if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
377 // Use statically configured ESA from the private data
379 db_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
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
398 if (NULL != cpd->provide_esa) {
399 esa_configured = cpd->provide_esa(cpd);
402 db_printf("Got ESA from RedBoot option\n");
405 if (!esa_configured && cpd->hardwired_esa) {
406 // ESA is already set in cpd->esa[]
407 esa_configured = true;
409 db_printf("Got ESA from cpd\n");
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));
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));
425 esa_configured = true;
427 db_printf("Got ESA from eeprom\n");
431 db_printf("LAN91CXX - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
439 #endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
441 // Initialize upper level driver
442 (sc->funs->eth_drv->init)(sc, cpd->enaddr);
447 lan91cxx_stop(struct eth_drv_sc *sc)
449 struct lan91cxx_priv_data *cpd =
450 (struct lan91cxx_priv_data *)sc->driver_private;
453 CYG_ASSERT( cpd->within_send < 10, "stop: Excess send recursions" );
455 // Complete any outstanding activity:
459 db_printf("LAN91CXX - Stopping, cleaning up pending TX\n" );
461 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
464 put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
465 put_reg(sc, LAN91CXX_RCR, 0);
466 cpd->txbusy = cpd->within_send = 0;
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.
476 lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
479 #ifdef LAN91CXX_IS_LAN91C111
483 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
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);
494 #ifdef LAN91CXX_FORCE_10MHZ
495 lan91cxx_write_phy( sc, 0, LAN91CXX_PHY_AUTO_AD, 0x0061);
498 // Start auto-negotiation
499 put_reg(sc, LAN91CXX_RPCR,
500 LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK | LAN91CXX_RPCR_ANEG);
502 // wait for auto-negotiation to finish.
503 // give it ~5 seconds before giving up (no cable?)
505 while (!(lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_STAT) & 0x20)) {
508 CYGACC_CALL_IF_DELAY_US(100000);
512 diag_printf("auto-negotiation failed.\n");
516 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
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 |
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);
536 #ifdef ETH_DRV_FLAGS_PROMISC_MODE
537 != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
539 ) || (ifp->if_flags & IFF_PROMISC)
541 // Then we select promiscuous mode.
543 rcr = get_reg(sc, LAN91CXX_RCR );
544 rcr |= LAN91CXX_RCR_PRMS;
545 put_reg(sc, LAN91CXX_RCR, rcr );
551 // This routine is called to perform special "control" opertions
554 lan91cxx_control(struct eth_drv_sc *sc, unsigned long key,
555 void *data, int data_length)
557 unsigned char *esa = (unsigned char *)data;
560 struct lan91cxx_priv_data *cpd =
561 (struct lan91cxx_priv_data *)sc->driver_private;
566 case ETH_DRV_SET_MAC_ADDRESS:
568 db_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
575 #ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
576 db_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
580 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
581 // Only now can we command the chip to perform EEPROM writes:
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 );
588 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
590 // Set the address register
591 put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2);
593 put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8));
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) )
604 CYG_ASSERT( 0 < j, "EEPROM write timout!" );
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) )
625 CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
626 // Now extract the MAC address that is in the chip, and tell the
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));
634 db_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
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.
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 );
656 #endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
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
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));
671 #ifdef ETH_DRV_GET_IF_STATS_UD
672 case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
675 #ifdef ETH_DRV_GET_IF_STATS
676 case ETH_DRV_GET_IF_STATS:
678 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
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;
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" );
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
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
702 #ifdef KEEP_STATISTICS
704 struct smsc_lan91cxx_stats *ps = &(cpd->stats);
707 p->supports_dot3 = true;
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 ;
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 ;
738 #endif // KEEP_STATISTICS
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.
756 lan91cxx_can_send(struct eth_drv_sc *sc)
758 struct lan91cxx_priv_data *cpd =
759 (struct lan91cxx_priv_data *)sc->driver_private;
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
773 CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
776 tcr = get_reg(sc, LAN91CXX_TCR);
777 if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
779 db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
781 // Complete any outstanding activity:
785 db_printf("LAN91CXX - can_send, cleaning up pending TX\n" );
787 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
789 tcr |= LAN91CXX_TCR_TXENA;
790 put_reg(sc, LAN91CXX_TCR, tcr);
793 // This helps unstick deadly embraces.
794 lan91cxx_poll( sc ); // Deal with any outstanding rx state
797 return (cpd->txbusy == 0) && (0 == cpd->within_send);
801 // This routine is called to send data to the hardware.
803 lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
804 int total_len, unsigned long key)
806 struct lan91cxx_priv_data *cpd =
807 (struct lan91cxx_priv_data *)sc->driver_private;
808 int i, len, plen, tcr;
813 unsigned short ints, control;
814 cyg_uint16 packet, status;
818 INCR_STAT( tx_count );
821 ints = get_reg(sc, LAN91CXX_INTERRUPT);
822 db_printf("%s:START: ints: %04x\n", __FUNCTION__, ints);
825 // Worry about the TX engine stopping.
826 tcr = get_reg(sc, LAN91CXX_TCR);
827 if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
829 db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
831 tcr |= LAN91CXX_TCR_TXENA;
832 put_reg(sc, LAN91CXX_TCR, tcr);
835 // This helps unstick deadly embraces.
836 CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" );
838 lan91cxx_poll( sc ); // Deal with any outstanding rx state
844 // Find packet length
846 for (i = 0; i < sg_len; i++)
847 plen += sg_list[i].len;
849 CYG_ASSERT( plen == total_len, "sg data length mismatch" );
851 // Alloc new TX packet
853 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_alloc_for_tx
854 #ifndef LAN91CXX_IS_LAN91C111
855 | ((plen >> 8) & 0x07)
861 status = get_reg(sc, LAN91CXX_INTERRUPT);
862 } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) );
864 packet = get_reg(sc, LAN91CXX_PNR);
868 db_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
870 packet = packet >> 8;
872 // Hm.. Isn't this a dead end?
874 db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
876 // Not if we can make progress with what's filling memory.
877 lan91cxx_poll( sc ); // Deal with any outstanding state
883 db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
884 packet, cpd->txpacket);
886 cpd->txpacket = packet;
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
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)
899 for (i = 0; i < sg_len; i++) {
900 sdata = (cyg_uint8 *)sg_list[i].buf;
901 len = sg_list[i].len;
904 data |= *sdata<<((dpos&1)*8);
905 dpos++, len--, sdata++;
906 if( (dpos & 1) == 0 )
908 put_data(sc, CYG_CPU_TO_LE16(data));
914 // Lay down the control short unconditionally at the end.
915 // (or it might use random memory contents)
918 // Need to set ODD flag and insert the data
920 control |= LAN91CXX_CONTROLBYTE_ODD;
922 control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case...
923 put_data(sc, CYG_CPU_TO_LE16(control));
925 // Enqueue the packet
926 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
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);
934 ints = get_reg(sc, LAN91CXX_INTERRUPT);
935 db_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
940 lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat)
942 unsigned short packet, ints, tcr;
943 struct lan91cxx_priv_data *cpd =
944 (struct lan91cxx_priv_data *)sc->driver_private;
949 INCR_STAT( tx_complete );
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);
957 // Get number of completed packet and read the status word
958 packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
960 db_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
963 #ifdef KEEP_STATISTICS
967 reg = get_reg( sc, LAN91CXX_EPH_STATUS );
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 );
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;
992 // We do not need to look in the Counter Register (LAN91CXX_COUNTER)
993 // because it just mimics the info we already have above.
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) ) {
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);
1003 tcr |= LAN91CXX_TCR_TXENA;
1004 put_reg(sc, LAN91CXX_TCR, tcr);
1005 success = 0; // And treat this as an error...
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++;
1019 lan91cxx_txfifo_good++;
1022 db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
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);
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);
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);
1041 if ( cpd->txbusy ) {
1043 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1047 void get_data_init(struct eth_drv_sc *sc)
1049 struct lan91cxx_priv_data *cpd =
1050 (struct lan91cxx_priv_data *)sc->driver_private;
1052 cpd->data_buf = 0xa5a5a5a5;
1053 cpd->data_pos = sizeof(rxd_t);
1056 cyg_uint8 get_data_byte(struct eth_drv_sc *sc)
1059 struct lan91cxx_priv_data *cpd =
1060 (struct lan91cxx_priv_data *)sc->driver_private;
1062 if( cpd->data_pos == sizeof(rxd_t) )
1064 cpd->data_buf = get_data(sc);
1068 c = (cpd->data_buf>>(cpd->data_pos*8))&0xFF;
1075 cyg_uint16 get_data_short(struct eth_drv_sc *sc)
1079 val = get_data_byte(sc);
1080 val |= get_data_byte(sc)<<8;
1082 return CYG_LE16_TO_CPU(val);
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.
1093 lan91cxx_RxEvent(struct eth_drv_sc *sc)
1095 struct lan91cxx_priv_data *cpd =
1096 (struct lan91cxx_priv_data *)sc->driver_private;
1097 unsigned short stat, len;
1101 stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
1103 db_printf("RxEvent - FIFOs: 0x%04x\n", stat);
1105 if ( 0x8000 & stat ) {
1106 // Then the Rx FIFO is empty
1108 db_printf("#####RxEvent with empty fifo\n");
1113 INCR_STAT( rx_count );
1116 db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
1117 0xff & (stat >> 8), cpd->rxpacket );
1119 // There is an Rx Packet ready
1120 cpd->rxpacket = 0xff & (stat >> 8);
1122 // Read status and (word) length
1123 put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1124 LAN91CXX_POINTER_AUTO_INCR | 0x0000));
1127 stat = get_data_short(sc);
1128 len = get_data_short(sc);
1129 len = len - 6; // minus header/footer words
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
1140 if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
1141 INCR_STAT( rx_good );
1144 if( LAN91CXX_RX_STATUS_IS_ODD(cpd,stat) )
1148 db_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
1150 // Check for bogusly short packets; can happen in promisc mode:
1151 // Asserted against and checked by upper layer driver.
1153 if ( len > sizeof( struct ether_header ) )
1154 // then it is acceptable; offer the data to the network stack
1156 (sc->funs->eth_drv->recv)(sc, len);
1161 // Not OK for one reason or another...
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));
1178 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
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.
1190 lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
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;
1199 cyg_uint8 *data=NULL;
1201 unsigned char *cp, cval;
1205 INCR_STAT( rx_deliver );
1207 put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1208 LAN91CXX_POINTER_AUTO_INCR));
1211 val = get_data_short(sc);
1212 plen = get_data_short(sc);
1215 for (i = 0; i < sg_len; i++) {
1217 data = (cyg_uint8 *)sg_list[i].buf;
1218 mlen = sg_list[i].len;
1225 db_printf("%s : mlen 0x%04x plen 0x%04x clen 0x%04x\n", __FUNCTION__, mlen, plen, clen);
1232 *data++ = get_data_byte(sc);
1236 else { // must actively discard ie. read it from the chip anyway.
1238 db_printf("lan91cxx_recv: No data!!!!!\n");
1241 (void)get_data_byte(sc);
1246 diag_dump_buf( sg_list[i].buf, sg_list[i].len > 64 ? 64 : sg_list[i].len );
1249 val = get_data_short(sc); // Read control word (and potential data) unconditionally
1251 cp = (unsigned char *)data;
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
1262 val = get_reg(sc, LAN91CXX_FIFO_PORTS);
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);
1268 db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
1269 0xff & (val >> 8), cpd->rxpacket );
1271 CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
1274 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1279 lan91cxx_poll(struct eth_drv_sc *sc)
1281 unsigned short event;
1282 struct lan91cxx_priv_data *cpd =
1283 (struct lan91cxx_priv_data *)sc->driver_private;
1285 // DEBUG_FUNCTION();
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;
1295 if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
1296 // Early receive interrupt
1297 db_printf("Early receive interrupt\n");
1299 else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
1300 // ethernet protocol handler failures
1301 db_printf("Ethernet protocol handler failures\n");
1303 else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
1305 db_printf("Receive overrun\n");
1307 else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
1308 // allocation interrupt
1309 db_printf("Allocation interrupt\n");
1313 if (event & LAN91CXX_INTERRUPT_TX_SET) {
1314 lan91cxx_TxEvent(sc, event);
1316 if (event & LAN91CXX_INTERRUPT_RCV_INT) {
1317 lan91cxx_RxEvent(sc);
1319 if (event & ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
1320 db_printf("%s: Unknown interrupt: 0x%04x\n",
1321 __FUNCTION__, event);
1325 #ifdef LAN91CXX_IS_LAN91C111
1328 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr, cyg_uint8 phyreg)
1330 int i, mask, input_idx, clk_idx = 0;
1331 cyg_uint16 mii_reg, value;
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;
1339 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1340 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1342 // Read command <10>
1343 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1344 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1346 // Output the PHY address, msb first
1347 for (mask = 0x10; mask; mask >>= 1) {
1349 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1351 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1354 // Output the phy register number, msb first
1355 for (mask = 0x10; mask; mask >>= 1) {
1357 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1359 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1362 // Tristate and turnaround (1 bit times)
1363 bits[clk_idx++] = 0;
1365 // Input starts at this bit time
1366 input_idx = clk_idx;
1368 // Will input 16 bits
1369 for (i = 0; i < 16; ++i)
1370 bits[clk_idx++] = 0;
1373 bits[clk_idx++] = 0;
1375 // Get the current MII register value
1376 mii_reg = get_reg(sc, LAN91CXX_MGMT);
1378 // Turn off all MII Interface bits
1379 mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1380 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
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);
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);
1392 bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1395 // Return to idle state
1396 put_reg(sc, LAN91CXX_MGMT, mii_reg);
1397 CYGACC_CALL_IF_DELAY_US(50);
1399 // Recover input data
1400 for (value = 0, i = 0; i < 16; ++i) {
1402 if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
1409 lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
1410 cyg_uint8 phyreg, cyg_uint16 value)
1412 int i, mask, clk_idx = 0;
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;
1421 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1422 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1424 // Write command <01>
1425 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1426 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1428 // Output the PHY address, msb first
1429 for (mask = 0x10; mask; mask >>= 1) {
1431 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1433 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1436 // Output the phy register number, msb first
1437 for (mask = 0x10; mask; mask >>= 1) {
1439 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1441 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1444 // Tristate and turnaround (2 bit times)
1445 bits[clk_idx++] = 0;
1446 bits[clk_idx++] = 0;
1448 // Write out 16 bits of data, msb first
1449 for (mask = 0x8000; mask; mask >>= 1) {
1451 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1453 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1456 // Final clock bit (tristate)
1457 bits[clk_idx++] = 0;
1459 // Get the current MII register value
1460 mii_reg = get_reg(sc, LAN91CXX_MGMT);
1462 // Turn off all MII Interface bits
1463 mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1464 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
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);
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);
1476 // bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1479 // Return to idle state
1480 put_reg(sc, LAN91CXX_MGMT, mii_reg);
1481 CYGACC_CALL_IF_DELAY_US(50);
1483 #endif // LAN91CXX_IS_LAN91C111
1485 // EOF if_lan91cxx.c