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
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //####BSDCOPYRIGHTBEGIN####
44 // -------------------------------------------
46 // Portions of this software may have been derived from OpenBSD or other sources,
47 // and are covered by the appropriate copyright disclaimers included herein.
49 // -------------------------------------------
51 //####BSDCOPYRIGHTEND####
52 //==========================================================================
53 //#####DESCRIPTIONBEGIN####
55 // Author(s): hmt, based on lan900 (for LAN91C110) driver by jskov
56 // jskov, based on CS8900 driver by Gary Thomas
57 // Contributors: gthomas, jskov, hmt, jco@ict.es, nickg
60 // Description: hardware driver for LAN91CXX "LAN9000" ethernet
61 // Notes: Pointer register is not saved/restored on receive interrupts.
62 // The pointer is shared by both receive/transmit code.
63 // But the net stack manages atomicity for you here.
65 // The controller has an autorelease mode that allows TX packets
66 // to be freed automatically on successful transmission - but
67 // that is not used since we're only sending one packet at a
69 // We may want to pingpong in future for throughput reasons.
71 // <jco@ict.es> Added support for PCMCIA mode and shifted
74 //####DESCRIPTIONEND####
76 //==========================================================================
78 // Based on LAN91C110 and LAN91C96
80 #include <pkgconf/system.h>
81 #include <pkgconf/devs_eth_smsc_lan91cxx.h>
82 #include <pkgconf/io_eth_drivers.h>
84 #include <cyg/infra/cyg_type.h>
85 #include <cyg/hal/hal_arch.h>
86 #include <cyg/hal/hal_intr.h>
87 #include <cyg/hal/hal_diag.h>
88 #include <cyg/infra/cyg_ass.h>
89 #include <cyg/infra/diag.h>
90 #include <cyg/hal/drv_api.h>
91 #include <cyg/io/eth/netdev.h>
92 #include <cyg/io/eth/eth_drv.h>
94 #include <pkgconf/net.h>
95 #include <cyg/kernel/kapi.h>
96 #include <net/if.h> /* Needed for struct ifnet */
99 #ifdef CYGPKG_INFRA_DEBUG
100 // Then we log, OOI, the number of times we get a bad packet number
101 // from the tx done fifo.
102 int lan91cxx_txfifo_good = 0;
103 int lan91cxx_txfifo_bad = 0;
107 // 0 disables all debug output
108 // 1 for process debug output
109 // 2 for added data IO output: get_reg, put_reg
110 // 4 for packet allocation/free output
111 // 8 for only startup status, so we can tell we're installed OK
116 #if defined(CYGPKG_REDBOOT)
117 static void db_printf( char *fmt, ... )
119 extern int start_console(void);
120 extern void end_console(int);
124 old_console = start_console();
125 diag_vprintf( fmt, a );
126 end_console(old_console);
130 #define db_printf diag_printf
133 #define db_printf( fmt, ... )
138 #define DEBUG_FUNCTION() do { db_printf("%s\n", __FUNCTION__); } while (0)
140 #define DEBUG_FUNCTION() do {} while(0)
143 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
144 #define KEEP_STATISTICS
147 #ifdef KEEP_STATISTICS
148 #define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
150 #define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
153 #include "smsc_lan91cxx.h"
155 #ifdef LAN91CXX_IS_LAN91C111
156 static void lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
157 cyg_uint8 phyreg, cyg_uint16 value);
158 static cyg_uint16 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
162 static void lan91cxx_poll(struct eth_drv_sc *sc);
165 #ifdef LAN91CXX_IS_LAN91C111
166 // Revision A of the LAN91C111 has a bug in which it does not set the
167 // ODD bit in the status word and control byte of received packets. We
168 // work around this by assuming the bit is always set and tacking the
169 // extra odd byte onto the packet anyway. Higher protocol levels never
170 // believe the packet size reported by the driver and always use the
171 // values in the protocol headers. So this workaround is quite safe.
172 // In theory nobody should be using the RevA part now, but it appears
173 // that some people still have some in their parts bins.
174 #define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) \
175 (((__cpd)->c111_reva)?1:((__stat) & LAN91CXX_RX_STATUS_ODDFRM))
176 #define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) \
177 (((__cpd)->c111_reva)?1:((__val) & LAN91CXX_CONTROLBYTE_ODD))
179 #define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) ((__stat) & LAN91CXX_RX_STATUS_ODDFRM)
180 #define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) ((__val) & LAN91CXX_CONTROLBYTE_ODD)
183 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
184 static cyg_interrupt lan91cxx_interrupt;
185 static cyg_handle_t lan91cxx_interrupt_handle;
187 // This ISR is called when the ethernet interrupt occurs
188 static int lan91cxx_isr(cyg_vector_t vector, cyg_addrword_t data)
189 /* , HAL_SavedRegisters *regs */
191 struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
192 struct lan91cxx_priv_data *cpd =
193 (struct lan91cxx_priv_data *)sc->driver_private;
197 INCR_STAT( interrupts );
199 cyg_drv_interrupt_mask(cpd->interrupt);
200 cyg_drv_interrupt_acknowledge(cpd->interrupt);
202 return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
206 // The deliver function (ex-DSR) handles the ethernet [logical] processing
208 lan91cxx_deliver(struct eth_drv_sc *sc)
210 struct lan91cxx_priv_data *cpd =
211 (struct lan91cxx_priv_data *)sc->driver_private;
215 // Service the interrupt:
217 // Allow interrupts to happen again
218 cyg_drv_interrupt_unmask(cpd->interrupt);
222 lan91cxx_int_vector(struct eth_drv_sc *sc)
224 struct lan91cxx_priv_data *cpd =
225 (struct lan91cxx_priv_data *)sc->driver_private;
227 return (cpd->interrupt);
231 smsc_lan91cxx_init(struct cyg_netdevtab_entry *tab)
233 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
234 struct lan91cxx_priv_data *cpd =
235 (struct lan91cxx_priv_data *)sc->driver_private;
238 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
239 unsigned char ecor, ecsr;
241 cyg_bool esa_configured = false;
245 cpd->txbusy = cpd->within_send = 0;
247 #ifdef CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR
248 cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91CXX_SHIFT_ADDR;
253 #if CYGINT_DEVS_ETH_SMSC_LAN91CXX_PCMCIA_MODE
255 // If the chip is configured in PCMCIA mode, the internal
256 // registers mapped in the attribute memory should be
257 // initialized (i.e. to enable the I/O map)
259 ecor = get_att(sc, LAN91CXX_ECOR);
261 // pulse SRESET on ECOR
262 ecor |= LAN91CXX_ECOR_RESET;
263 put_att(sc, LAN91CXX_ECOR, ecor);
267 ecor &= ~LAN91CXX_ECOR_RESET;
268 put_att(sc, LAN91CXX_ECOR, ecor);
270 // then, enable I/O map
271 ecor |= LAN91CXX_ECOR_ENABLE;
272 put_att(sc, LAN91CXX_ECOR, ecor);
274 // verify the register contents
275 if (ecor != get_att(sc, LAN91CXX_ECOR))
276 db_printf("LAN91CXX - Cannot access PCMCIA attribute registers\n");
278 ecsr = get_att(sc, LAN91CXX_ECSR);
279 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_8_BIT
280 #error "91CXX 8-bit mode not yet supported."
281 ecsr |= LAN91CXX_ECSR_IOIS8;
283 ecsr &= ~LAN91CXX_ECSR_IOIS8;
285 put_att(sc, LAN91CXX_ECSR, ecsr);
289 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
290 // Initialize environment, setup interrupt handler
291 cyg_drv_interrupt_create(cpd->interrupt,
292 CYGNUM_DEVS_ETH_SMSC_LAN91CXX_INT_PRIO,
293 (cyg_addrword_t)sc, // Data item passed to interrupt handler
294 (cyg_ISR_t *)lan91cxx_isr,
295 (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
296 &lan91cxx_interrupt_handle,
297 &lan91cxx_interrupt);
298 cyg_drv_interrupt_attach(lan91cxx_interrupt_handle);
299 #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
300 cyg_drv_interrupt_acknowledge(cpd->interrupt);
301 #ifndef CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
302 cyg_drv_interrupt_unmask(cpd->interrupt);
303 #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
305 // probe chip by reading the signature in BS register
306 val = get_banksel(sc);
308 db_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
309 cpd->base+LAN91CXX_BS, val );
312 if ((0xff00 & val) != 0x3300) {
313 CYG_FAIL("No 91Cxx signature" );
314 diag_printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
318 val = get_reg(sc, LAN91CXX_REVISION);
321 db_printf("LAN91CXX - type: %01x, rev: %01x\n",
322 (val>>4)&0xf, val & 0xf);
325 #ifdef LAN91CXX_IS_LAN91C111
326 // Set RevA flag for LAN91C111 so we can cope with the odd-bit bug.
327 cpd->c111_reva = (val == 0x3390);
330 // The controller may provide a function used to set up the ESA
331 if (cpd->config_enaddr)
332 (*cpd->config_enaddr)(cpd);
335 put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
336 put_reg(sc, LAN91CXX_RCR, 0);
338 val = get_reg(sc, LAN91CXX_EPH_STATUS);
339 #ifndef LAN91CXX_IS_LAN91C111
340 // LINK_OK on 91C111 is just a general purpose input and may not
341 // have anything to do with the link.
342 if (!(val & LAN91CXX_STATUS_LINK_OK)) {
343 db_printf("no link\n");
344 return false; // Link not connected
350 db_printf("LAN91CXX - status: %04x\n", val);
353 #if 0 < CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
354 // Use statically configured ESA from the private data
356 db_printf("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
364 // Set up hardware address
365 for (i = 0; i < sizeof(cpd->enaddr); i += 2)
366 put_reg(sc, LAN91CXX_IA01+i/2,
367 cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
368 #else // not CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
369 // Find ESA - check possible sources in sequence and stop when
370 // one provides the ESA:
371 // RedBoot option (via provide_esa)
372 // Compile-time configuration
375 if (NULL != cpd->provide_esa) {
376 esa_configured = cpd->provide_esa(cpd);
379 db_printf("Got ESA from RedBoot option\n");
382 if (!esa_configured && cpd->hardwired_esa) {
383 // ESA is already set in cpd->esa[]
384 esa_configured = true;
386 db_printf("Got ESA from cpd\n");
389 if (esa_configured) {
390 // Set up hardware address
391 for (i = 0; i < sizeof(cpd->enaddr); i += 2)
392 put_reg(sc, LAN91CXX_IA01+i/2,
393 cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
395 // Use the address from the serial EEPROM
396 // Read out hardware address
397 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
398 unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
399 cpd->enaddr[i] = (unsigned char)(0xff & z);
400 cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
402 esa_configured = true;
404 db_printf("Got ESA from eeprom\n");
408 db_printf("LAN91CXX - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
416 #endif // !CYGINT_DEVS_ETH_SMSC_LAN91CXX_STATIC_ESA
418 // Initialize upper level driver
419 (sc->funs->eth_drv->init)(sc, cpd->enaddr);
424 lan91cxx_stop(struct eth_drv_sc *sc)
426 struct lan91cxx_priv_data *cpd =
427 (struct lan91cxx_priv_data *)sc->driver_private;
430 CYG_ASSERT( cpd->within_send < 10, "stop: Excess send recursions" );
432 // Complete any outstanding activity:
436 db_printf("LAN91CXX - Stopping, cleaning up pending TX\n" );
438 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
441 put_reg(sc, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
442 put_reg(sc, LAN91CXX_RCR, 0);
443 cpd->txbusy = cpd->within_send = 0;
447 // This function is called to "start up" the interface. It may be called
448 // multiple times, even when the hardware is already running. It will be
449 // called whenever something "hardware oriented" changes and should leave
450 // the hardware ready to send/receive packets.
453 lan91cxx_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
456 #ifdef LAN91CXX_IS_LAN91C111
460 struct ifnet *ifp = &sc->sc_arpcom.ac_if;
464 #ifdef LAN91CXX_IS_LAN91C111
465 // 91C111 Errata. Internal PHY comes up disabled. Must enable here.
466 lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_RST);
467 HAL_DELAY_US(500000);
468 lan91cxx_write_phy(sc, 0, LAN91CXX_PHY_CTRL, LAN91CXX_PHY_CTRL_ANEG_EN |
469 LAN91CXX_PHY_CTRL_SPEED);
471 // Start auto-negotiation
472 put_reg(sc, LAN91CXX_RPCR,
473 LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK | LAN91CXX_RPCR_ANEG);
475 // wait for auto-negotiation to finish.
476 // give it ~5 seconds before giving up (no cable?)
478 while (!(lan91cxx_read_phy(sc, 0, LAN91CXX_PHY_STAT) & 0x20)) {
481 HAL_DELAY_US(100000);
485 diag_printf("auto-negotiation failed.\n");
489 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
491 put_reg(sc, LAN91CXX_INTERRUPT, 0); // disable interrupts
492 intr = get_reg(sc, LAN91CXX_INTERRUPT);
493 put_reg(sc, LAN91CXX_INTERRUPT, intr & // ack old interrupts
494 (LAN91CXX_INTERRUPT_TX_INT | LAN91CXX_INTERRUPT_TX_EMPTY_INT |
495 LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT));
496 put_reg(sc, LAN91CXX_RCR,
497 #ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46.
498 LAN91CXX_RCR_ABORT_ENB |
500 LAN91CXX_RCR_STRIP_CRC |
501 LAN91CXX_RCR_RXEN | LAN91CXX_RCR_ALMUL);
502 put_reg(sc, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN);
503 put_reg(sc, LAN91CXX_CONTROL, 0);
504 put_reg(sc, LAN91CXX_INTERRUPT, // enable interrupts
505 LAN91CXX_INTERRUPT_RCV_INT_M);
509 #ifdef ETH_DRV_FLAGS_PROMISC_MODE
510 != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
512 ) || (ifp->if_flags & IFF_PROMISC)
514 // Then we select promiscuous mode.
516 rcr = get_reg(sc, LAN91CXX_RCR );
517 rcr |= LAN91CXX_RCR_PRMS;
518 put_reg(sc, LAN91CXX_RCR, rcr );
524 // This routine is called to perform special "control" opertions
527 lan91cxx_control(struct eth_drv_sc *sc, unsigned long key,
528 void *data, int data_length)
530 unsigned char *esa = (unsigned char *)data;
533 struct lan91cxx_priv_data *cpd =
534 (struct lan91cxx_priv_data *)sc->driver_private;
539 case ETH_DRV_SET_MAC_ADDRESS:
541 db_printf("LAN91CXX - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
548 #ifndef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
549 db_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
553 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
554 // Only now can we command the chip to perform EEPROM writes:
556 // select arbitrary writing to the EEPROM
557 reg = get_reg(sc, LAN91CXX_CONTROL);
558 reg |= LAN91CXX_CONTROL_EEPROM_SELECT;
559 put_reg(sc, LAN91CXX_CONTROL, reg );
561 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
563 // Set the address register
564 put_reg(sc, LAN91CXX_POINTER, LAN91CXX_ESA_EEPROM_OFFSET + i/2);
566 put_reg(sc, LAN91CXX_GENERAL, esa[i] | (esa[i+1] << 8));
568 reg = get_reg(sc, LAN91CXX_CONTROL);
569 reg |= LAN91CXX_CONTROL_STORE;
570 put_reg(sc, LAN91CXX_CONTROL, reg );
571 // and poll for completion
572 for ( j = 1024 * 1024; 0 < j ; j-- ) {
573 reg = get_reg(sc, LAN91CXX_CONTROL);
574 if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
577 CYG_ASSERT( 0 < j, "EEPROM write timout!" );
580 reg = get_reg(sc, LAN91CXX_CONTROL);
581 CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY),
582 "EEPROM still busy!" );
583 // Clear the EEPROM selection bit
584 reg &=~LAN91CXX_CONTROL_EEPROM_SELECT;
585 put_reg(sc, LAN91CXX_CONTROL, reg );
586 // and check it "took"
587 reg = get_reg(sc, LAN91CXX_CONTROL);
588 CYG_ASSERT( 0 == (reg & LAN91CXX_CONTROL_EEPROM_SELECT),
589 "EEPROM still selected!" );
590 // and command a complete reload
591 reg |= LAN91CXX_CONTROL_RELOAD;
592 put_reg(sc, LAN91CXX_CONTROL, reg );
593 for ( i = 1024 * 1024; 0 < i ; i-- ) {
594 reg = get_reg(sc, LAN91CXX_CONTROL);
595 if ( 0 == (reg & LAN91CXX_CONTROL_EEPROM_BUSY) )
598 CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
599 // Now extract the MAC address that is in the chip, and tell the
601 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
602 unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
603 cpd->enaddr[i] = (unsigned char)(0xff & z);
604 cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
607 db_printf("LAN91CXX - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
615 for (i = 0; i < sizeof(cpd->enaddr); i++ ) {
616 CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" );
617 if ( esa[i] != cpd->enaddr[i] )
618 return 1; // the operation failed.
620 #else // not CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
621 // Whatever, we can write the MAC address into the interface info,
622 // and the chip registers no problem.
623 for ( i = 0; i < sizeof(cpd->enaddr); i++ )
624 cpd->enaddr[i] = esa[i];
625 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
626 reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8);
627 put_reg(sc, LAN91CXX_IA01+i/2, reg );
629 #endif // !CYGSEM_DEVS_ETH_SMSC_LAN91CXX_WRITE_EEPROM
632 #ifdef ETH_DRV_GET_MAC_ADDRESS
633 case ETH_DRV_GET_MAC_ADDRESS:
634 // Extract the MAC address that is in the chip, and tell the
636 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
637 unsigned short z = get_reg(sc, LAN91CXX_IA01+i/2 );
638 esa[i] = (unsigned char)(0xff & z);
639 esa[i+1] = (unsigned char)(0xff & (z >> 8));
644 #ifdef ETH_DRV_GET_IF_STATS_UD
645 case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
648 #ifdef ETH_DRV_GET_IF_STATS
649 case ETH_DRV_GET_IF_STATS:
651 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
653 struct ether_drv_stats *p = (struct ether_drv_stats *)data;
654 // Chipset entry is no longer supported; RFC1573.
655 for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
656 p->snmp_chipset[i] = 0;
658 // This perhaps should be a config opt, so you can make up your own
659 // description, or supply it from the instantiation.
660 strcpy( p->description, "SMSC LAN91Cxx" );
661 // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
663 reg = get_reg(sc, LAN91CXX_EPH_STATUS);
664 if ((reg & LAN91CXX_STATUS_LINK_OK) == 0) {
665 p->operational = 2; // LINK DOWN
666 p->duplex = 1; // UNKNOWN
670 p->operational = 3; // LINK UP
671 p->duplex = 2; // 2 = SIMPLEX, 3 = DUPLEX
672 p->speed = 10 * 1000000; // it's only a 10Mbit device
675 #ifdef KEEP_STATISTICS
677 struct smsc_lan91cxx_stats *ps = &(cpd->stats);
680 p->supports_dot3 = true;
682 p->tx_good = ps->tx_good ;
683 p->tx_max_collisions = ps->tx_max_collisions ;
684 p->tx_late_collisions = ps->tx_late_collisions ;
685 p->tx_underrun = ps->tx_underrun ;
686 p->tx_carrier_loss = ps->tx_carrier_loss ;
687 p->tx_deferred = ps->tx_deferred ;
688 p->tx_sqetesterrors = ps->tx_sqetesterrors ;
689 p->tx_single_collisions = ps->tx_single_collisions;
690 p->tx_mult_collisions = ps->tx_mult_collisions ;
691 p->tx_total_collisions = ps->tx_total_collisions ;
692 p->rx_good = ps->rx_good ;
693 p->rx_crc_errors = ps->rx_crc_errors ;
694 p->rx_align_errors = ps->rx_align_errors ;
695 p->rx_resource_errors = ps->rx_resource_errors ;
696 p->rx_overrun_errors = ps->rx_overrun_errors ;
697 p->rx_collisions = ps->rx_collisions ;
698 p->rx_short_frames = ps->rx_short_frames ;
699 p->rx_too_long_frames = ps->rx_too_long_frames ;
700 p->rx_symbol_errors = ps->rx_symbol_errors ;
702 p->interrupts = ps->interrupts ;
703 p->rx_count = ps->rx_count ;
704 p->rx_deliver = ps->rx_deliver ;
705 p->rx_resource = ps->rx_resource ;
706 p->rx_restart = ps->rx_restart ;
707 p->tx_count = ps->tx_count ;
708 p->tx_complete = ps->tx_complete ;
709 p->tx_dropped = ps->tx_dropped ;
711 #endif // KEEP_STATISTICS
725 // This routine is called to see if it is possible to send another packet.
726 // It will return non-zero if a transmit is possible, zero otherwise.
729 lan91cxx_can_send(struct eth_drv_sc *sc)
731 struct lan91cxx_priv_data *cpd =
732 (struct lan91cxx_priv_data *)sc->driver_private;
737 #ifndef LAN91CXX_IS_LAN91C111
738 // LINK_OK on 91C111 is just a general purpose input and may not
739 // have anything to do with the link.
740 if ((get_reg(sc, LAN91CXX_EPH_STATUS) & LAN91CXX_STATUS_LINK_OK) == 0) {
741 db_printf("no link\n");
742 return false; // Link not connected
746 CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
749 tcr = get_reg(sc, LAN91CXX_TCR);
750 if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
752 db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
754 // Complete any outstanding activity:
758 db_printf("LAN91CXX - can_send, cleaning up pending TX\n" );
760 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, 0);
762 tcr |= LAN91CXX_TCR_TXENA;
763 put_reg(sc, LAN91CXX_TCR, tcr);
766 // This helps unstick deadly embraces.
767 lan91cxx_poll( sc ); // Deal with any outstanding rx state
770 return (cpd->txbusy == 0) && (0 == cpd->within_send);
774 // This routine is called to send data to the hardware.
776 lan91cxx_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
777 int total_len, unsigned long key)
779 struct lan91cxx_priv_data *cpd =
780 (struct lan91cxx_priv_data *)sc->driver_private;
781 int i, len, plen, tcr;
783 unsigned short *sdata = NULL;
784 unsigned short ints, control;
785 cyg_uint16 packet, status;
789 INCR_STAT( tx_count );
791 // Worry about the TX engine stopping.
792 tcr = get_reg(sc, LAN91CXX_TCR);
793 if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
795 db_printf("%s: ENGINE RESTART: tcr 0x%04x\n", __FUNCTION__, tcr );
797 tcr |= LAN91CXX_TCR_TXENA;
798 put_reg(sc, LAN91CXX_TCR, tcr);
801 // This helps unstick deadly embraces.
802 CYG_ASSERT( cpd->within_send < 10, "send: Excess send recursions" );
804 lan91cxx_poll( sc ); // Deal with any outstanding rx state
810 // Find packet length
812 for (i = 0; i < sg_len; i++)
813 plen += sg_list[i].len;
815 CYG_ASSERT( plen == total_len, "sg data length mismatch" );
817 // Alloc new TX packet
819 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_alloc_for_tx
820 #ifndef LAN91CXX_IS_LAN91C111
821 | ((plen >> 8) & 0x07)
827 status = get_reg(sc, LAN91CXX_INTERRUPT);
828 } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT) && (--i > 0) );
830 packet = get_reg(sc, LAN91CXX_PNR);
834 db_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
836 packet = packet >> 8;
838 // Hm.. Isn't this a dead end?
840 db_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
842 // Not if we can make progress with what's filling memory.
843 lan91cxx_poll( sc ); // Deal with any outstanding state
849 db_printf("#####Tx packet allocated 0x%04x (previous 0x%04x)\n",
850 packet, cpd->txpacket);
852 cpd->txpacket = packet;
854 put_reg(sc, LAN91CXX_PNR, packet);
855 // Note: Check FIFO state here before continuing?
856 put_reg(sc, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000);
857 // Pointer is now set, and the proper bank is selected for
861 put_data(sc, CYG_CPU_TO_LE16(0)); // reserve space for status word
862 // packet length (includes status, byte-count and control shorts)
863 put_data(sc, CYG_CPU_TO_LE16(0x7FE & (plen + 6)) ); // Always even, always < 15xx(dec)
865 // Put data into buffer
866 for (i = 0; i < sg_len; i++) {
867 sdata = (unsigned short *)sg_list[i].buf;
868 len = sg_list[i].len;
870 CYG_ASSERT(0 == (len & 1) || (i == (sg_len-1)), "odd length");
871 CYG_ASSERT( sdata, "No sg data pointer here" );
872 while(len >= sizeof(*sdata)) {
873 put_data(sc, *sdata++);
874 len -= sizeof(*sdata);
877 CYG_ASSERT( sdata, "No sg data pointer outside" );
879 // Lay down the control short unconditionally at the end.
880 // (or it might use random memory contents)
883 // Need to set ODD flag and insert the data
884 unsigned char onebyte = *(unsigned char*)sdata;
886 control |= LAN91CXX_CONTROLBYTE_ODD;
888 control |= LAN91CXX_CONTROLBYTE_CRC; // Just in case...
889 put_data(sc, CYG_CPU_TO_LE16(control));
891 // Enqueue the packet
892 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
894 // Ack TX empty int and unmask it.
895 ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
896 put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_ACK);
897 put_reg(sc, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_SET_M);
900 ints = get_reg(sc, LAN91CXX_INTERRUPT);
901 db_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
906 lan91cxx_TxEvent(struct eth_drv_sc *sc, int stat)
908 unsigned short packet, ints, tcr;
909 struct lan91cxx_priv_data *cpd =
910 (struct lan91cxx_priv_data *)sc->driver_private;
915 INCR_STAT( tx_complete );
917 // Ack and mask TX interrupt set
918 ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
919 ints |= LAN91CXX_INTERRUPT_TX_SET_ACK;
920 ints &= ~LAN91CXX_INTERRUPT_TX_SET_M;
921 put_reg(sc, LAN91CXX_INTERRUPT, ints);
923 // Get number of completed packet and read the status word
924 packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
926 db_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
929 #ifdef KEEP_STATISTICS
933 reg = get_reg( sc, LAN91CXX_EPH_STATUS );
935 // Covering each bit in turn...
936 if ( reg & LAN91CXX_STATUS_TX_UNRN ) INCR_STAT( tx_underrun );
937 //if ( reg & LAN91CXX_STATUS_LINK_OK ) INCR_STAT( );
938 //if ( reg & LAN91CXX_STATUS_CTR_ROL ) INCR_STAT( );
939 //if ( reg & LAN91CXX_STATUS_EXC_DEF ) INCR_STAT( );
940 if ( reg & LAN91CXX_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
941 if ( reg & LAN91CXX_STATUS_LATCOL ) INCR_STAT( tx_late_collisions );
942 //if ( reg & LAN91CXX_STATUS_WAKEUP ) INCR_STAT( );
943 if ( reg & LAN91CXX_STATUS_TX_DEFR ) INCR_STAT( tx_deferred );
944 //if ( reg & LAN91CXX_STATUS_LTX_BRD ) INCR_STAT( );
945 if ( reg & LAN91CXX_STATUS_SQET ) INCR_STAT( tx_sqetesterrors );
946 if ( reg & LAN91CXX_STATUS_16COL ) INCR_STAT( tx_max_collisions );
947 //if ( reg & LAN91CXX_STATUS_LTX_MULT) INCR_STAT( );
948 if ( reg & LAN91CXX_STATUS_MUL_COL ) INCR_STAT( tx_mult_collisions );
949 if ( reg & LAN91CXX_STATUS_SNGL_COL ) INCR_STAT( tx_single_collisions );
950 if ( reg & LAN91CXX_STATUS_TX_SUC ) INCR_STAT( tx_good );
952 cpd->stats.tx_total_collisions =
953 cpd->stats.tx_late_collisions +
954 cpd->stats.tx_max_collisions +
955 cpd->stats.tx_mult_collisions +
956 cpd->stats.tx_single_collisions;
958 // We do not need to look in the Counter Register (LAN91CXX_COUNTER)
959 // because it just mimics the info we already have above.
961 #endif // KEEP_STATISTICS
962 // We do not really care about Tx failure. Ethernet is not a reliable
963 // medium. But we do care about the TX engine stopping.
964 tcr = get_reg(sc, LAN91CXX_TCR);
965 if ( 0 == (LAN91CXX_TCR_TXENA & tcr) ) {
967 db_printf("%s: ENGINE RESTART: tcr 0x%04x ints %04x\n", __FUNCTION__, tcr, ints);
969 tcr |= LAN91CXX_TCR_TXENA;
970 put_reg(sc, LAN91CXX_TCR, tcr);
971 success = 0; // And treat this as an error...
976 // It certainly appears that occasionally the tx fifo tells lies; we
977 // get the wrong packet number. Freeing the one we allocated seems to
978 // give correct operation.
979 #ifdef CYGPKG_INFRA_DEBUG
980 // Then we log, OOI, the number of times we get a bad packet number
981 // from the tx done fifo.
982 if (cpd->txpacket != packet )
983 lan91cxx_txfifo_bad++;
985 lan91cxx_txfifo_good++;
988 db_printf("#####Tx packet freed 0x%04x (expected 0x%04x)\n", packet, cpd->txpacket );
990 // and then free the packet
991 put_reg(sc, LAN91CXX_PNR, cpd->txpacket);
992 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet);
994 // Ack the TX int which is supposed to clear the packet from the TX
996 ints = get_reg(sc, LAN91CXX_INTERRUPT) & 0xff00;
997 ints |= LAN91CXX_INTERRUPT_TX_FIFO_ACK;
998 put_reg(sc, LAN91CXX_INTERRUPT, ints);
1001 // Hm... The free doesn't seem to have the desired effect?!?
1002 ints = get_reg(sc, LAN91CXX_INTERRUPT);
1003 packet = get_reg(sc, LAN91CXX_FIFO_PORTS);
1004 db_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
1007 if ( cpd->txbusy ) {
1009 (sc->funs->eth_drv->tx_done)(sc, cpd->txkey, success);
1015 // This function is called when a packet has been received. Its job is
1016 // to prepare to unload the packet from the hardware. Once the length of
1017 // the packet is known, the upper layer of the driver can be told. When
1018 // the upper layer is ready to unload the packet, the internal function
1019 // 'lan91cxx_recv' will be called to actually fetch it from the hardware.
1022 lan91cxx_RxEvent(struct eth_drv_sc *sc)
1024 struct lan91cxx_priv_data *cpd =
1025 (struct lan91cxx_priv_data *)sc->driver_private;
1026 unsigned short stat, len;
1027 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1033 stat = get_reg(sc, LAN91CXX_FIFO_PORTS);
1035 db_printf("RxEvent - FIFOs: 0x%04x\n", stat);
1037 if ( 0x8000 & stat ) {
1038 // Then the Rx FIFO is empty
1040 db_printf("#####RxEvent with empty fifo\n");
1045 INCR_STAT( rx_count );
1048 db_printf("#####Rx packet allocated 0x%04x (previous 0x%04x)\n",
1049 0xff & (stat >> 8), cpd->rxpacket );
1051 // There is an Rx Packet ready
1052 cpd->rxpacket = 0xff & (stat >> 8);
1054 // Read status and (word) length
1055 put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1056 LAN91CXX_POINTER_AUTO_INCR | 0x0000));
1057 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1059 val = CYG_LE32_TO_CPU(val);
1060 stat = val & 0xffff;
1061 len = ((val >> 16) & 0xffff) - 6; // minus header/footer words
1063 stat = get_data(sc);
1064 stat = CYG_LE16_TO_CPU(stat);
1066 len = CYG_LE16_TO_CPU(len) - 6; // minus header/footer words
1069 #ifdef KEEP_STATISTICS
1070 if ( stat & LAN91CXX_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
1071 //if ( stat & LAN91CXX_RX_STATUS_BCAST ) INCR_STAT( );
1072 if ( stat & LAN91CXX_RX_STATUS_BADCRC ) INCR_STAT( rx_crc_errors );
1073 if ( stat & LAN91CXX_RX_STATUS_TOOLONG ) INCR_STAT( rx_too_long_frames );
1074 if ( stat & LAN91CXX_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames );
1075 //if ( stat & LAN91CXX_RX_STATUS_MCAST ) INCR_STAT( );
1076 #endif // KEEP_STATISTICS
1078 if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
1079 INCR_STAT( rx_good );
1082 if( LAN91CXX_RX_STATUS_IS_ODD(cpd,stat) )
1086 db_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
1088 // Check for bogusly short packets; can happen in promisc mode:
1089 // Asserted against and checked by upper layer driver.
1091 if ( len > sizeof( struct ether_header ) )
1092 // then it is acceptable; offer the data to the network stack
1094 (sc->funs->eth_drv->recv)(sc, len);
1099 // Not OK for one reason or another...
1101 db_printf("RxEvent - bad rx: stat: 0x%04x, len: 0x%04x\n", stat, len);
1105 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1109 // This function is called as a result of the "eth_drv_recv()" call above.
1110 // Its job is to actually fetch data for a packet from the hardware once
1111 // memory buffers have been allocated for the packet. Note that the buffers
1112 // may come in pieces, using a scatter-gather list. This allows for more
1113 // efficient processing in the upper layers of the stack.
1116 lan91cxx_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1118 #if (4 & DEBUG) || defined(CYGPKG_INFRA_DEBUG) || \
1119 defined(KEEP_STATISTICS) || defined(LAN91CXX_IS_LAN91C111)
1120 struct lan91cxx_priv_data *cpd =
1121 (struct lan91cxx_priv_data *)sc->driver_private;
1125 cyg_uint16 *data=NULL;
1126 unsigned char *cp, cval, odd_even = 0;
1127 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1135 INCR_STAT( rx_deliver );
1137 put_reg(sc, LAN91CXX_POINTER, (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
1138 LAN91CXX_POINTER_AUTO_INCR));
1141 // packet length (minus header/footer)
1142 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1143 val = CYG_LE32_TO_CPU(val);
1144 plen = (val >> 16) - 6;
1146 val = CYG_LE16_TO_CPU(val);
1147 plen = get_data(sc);
1148 plen = CYG_LE16_TO_CPU(plen) - 6;
1151 if( LAN91CXX_RX_STATUS_IS_ODD(cpd,val) )
1154 for (i = 0; i < sg_len; i++) {
1155 data = (cyg_uint16 *)sg_list[i].buf;
1156 mlen = sg_list[i].len;
1158 CYG_ASSERT(0 == (mlen & (sizeof(*data) - 1)) || (i == (sg_len-1)), "odd length");
1161 db_printf("%s : mlen 0x%04x, plen 0x%04x\n", __FUNCTION__, mlen, plen);
1164 while (mlen >= sizeof(*data)) {
1165 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1166 if (!(odd_even)) { // because of the 32bit to 16bit conversion, read only every 2nd word
1169 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1178 mlen -= sizeof(*data);
1179 plen -= sizeof(*data);
1182 else { // must actively discard ie. read it from the chip anyway.
1183 while (mlen >= sizeof(*data)) {
1184 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1188 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1196 mlen -= sizeof(*data);
1197 plen -= sizeof(*data);
1201 if (!(odd_even)) { // read the control word only if we not already have it because of a 32bit access
1202 val = get_data(sc); // Read control word (and potential data) unconditionally
1203 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91CXX_USE_32BIT
1204 val = CYG_LE32_TO_CPU(val);
1207 *(cyg_uint16 *)data = val & 0xffff;
1208 cp = (unsigned char *)data + 2;
1213 val = CYG_LE16_TO_CPU(val);
1216 cp = (unsigned char *)data;
1218 CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX,
1219 "Controlbyte is not for Rx");
1220 CYG_ASSERT( (1 == mlen) == (0 != LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val)),
1221 "Controlbyte does not match");
1222 if (data && (1 == mlen) && LAN91CXX_CONTROLBYTE_IS_ODD(cpd,val) ) {
1223 cval = val & 0x00ff; // last byte contains data
1227 val = get_reg(sc, LAN91CXX_FIFO_PORTS);
1229 if ( 0x8000 & val ) // Then the Rx FIFO is empty
1230 db_printf("#####Rx packet NOT freed, stat is 0x%04x (expected 0x%04x)\n",
1231 val, cpd->rxpacket);
1233 db_printf("#####Rx packet freed 0x%04x (expected 0x%04x)\n",
1234 0xff & (val >> 8), cpd->rxpacket );
1236 CYG_ASSERT( (0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet" );
1239 put_reg(sc, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
1243 lan91cxx_poll(struct eth_drv_sc *sc)
1245 unsigned short event;
1246 struct lan91cxx_priv_data *cpd =
1247 (struct lan91cxx_priv_data *)sc->driver_private;
1249 // DEBUG_FUNCTION();
1251 cyg_drv_interrupt_acknowledge(cpd->interrupt);
1252 // Get the (unmasked) requests
1253 event = get_reg(sc, LAN91CXX_INTERRUPT);
1254 event = event & (event >> 8) & 0xff;
1258 if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
1259 // Early receive interrupt
1261 else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
1262 // ethernet protocol handler failures
1264 else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
1267 else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
1268 // allocation interrupt
1272 if (event & LAN91CXX_INTERRUPT_TX_SET) {
1273 lan91cxx_TxEvent(sc, event);
1275 if (event & LAN91CXX_INTERRUPT_RCV_INT) {
1276 lan91cxx_RxEvent(sc);
1278 if (event & ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
1279 db_printf("%s: Unknown interrupt: 0x%04x\n",
1280 __FUNCTION__, event);
1284 #ifdef LAN91CXX_IS_LAN91C111
1287 lan91cxx_read_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr, cyg_uint8 phyreg)
1289 int i, mask, input_idx, clk_idx = 0;
1290 cyg_uint16 mii_reg, value;
1293 // 32 consecutive ones on MDO to establish sync
1294 for (i = 0; i < 32; ++i)
1295 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1298 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1299 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1301 // Read command <10>
1302 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1303 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1305 // Output the PHY address, msb first
1306 for (mask = 0x10; mask; mask >>= 1) {
1308 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1310 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1313 // Output the phy register number, msb first
1314 for (mask = 0x10; mask; mask >>= 1) {
1316 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1318 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1321 // Tristate and turnaround (1 bit times)
1322 bits[clk_idx++] = 0;
1324 // Input starts at this bit time
1325 input_idx = clk_idx;
1327 // Will input 16 bits
1328 for (i = 0; i < 16; ++i)
1329 bits[clk_idx++] = 0;
1332 bits[clk_idx++] = 0;
1334 // Get the current MII register value
1335 mii_reg = get_reg(sc, LAN91CXX_MGMT);
1337 // Turn off all MII Interface bits
1338 mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1339 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1341 // Clock all 64 cycles
1342 for (i = 0; i < sizeof(bits); ++i) {
1343 // Clock Low - output data
1344 put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1347 // Clock Hi - input data
1348 put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1351 bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1354 // Return to idle state
1355 put_reg(sc, LAN91CXX_MGMT, mii_reg);
1358 // Recover input data
1359 for (value = 0, i = 0; i < 16; ++i) {
1361 if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
1368 lan91cxx_write_phy(struct eth_drv_sc *sc, cyg_uint8 phyaddr,
1369 cyg_uint8 phyreg, cyg_uint16 value)
1371 int i, mask, clk_idx = 0;
1375 // 32 consecutive ones on MDO to establish sync
1376 for (i = 0; i < 32; ++i)
1377 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1380 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1381 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1383 // Write command <01>
1384 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1385 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1387 // Output the PHY address, msb first
1388 for (mask = 0x10; mask; mask >>= 1) {
1390 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1392 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1395 // Output the phy register number, msb first
1396 for (mask = 0x10; mask; mask >>= 1) {
1398 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1400 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1403 // Tristate and turnaround (2 bit times)
1404 bits[clk_idx++] = 0;
1405 bits[clk_idx++] = 0;
1407 // Write out 16 bits of data, msb first
1408 for (mask = 0x8000; mask; mask >>= 1) {
1410 bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
1412 bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
1415 // Final clock bit (tristate)
1416 bits[clk_idx++] = 0;
1418 // Get the current MII register value
1419 mii_reg = get_reg(sc, LAN91CXX_MGMT);
1421 // Turn off all MII Interface bits
1422 mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
1423 LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
1426 for (i = 0; i < sizeof(bits); ++i) {
1427 // Clock Low - output data
1428 put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i]);
1431 // Clock Hi - input data
1432 put_reg(sc, LAN91CXX_MGMT, mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
1435 // bits[i] |= get_reg(sc, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
1438 // Return to idle state
1439 put_reg(sc, LAN91CXX_MGMT, mii_reg);
1442 #endif // LAN91CXX_IS_LAN91C111
1444 // EOF if_lan91cxx.c