1 //==========================================================================
5 // Davicom DM9000 ethernet driver
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 2003, 2004 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //#####DESCRIPTIONBEGIN####
43 // Contributors: msalter
46 // Description: hardware driver for Davicom DM9000 NIC
49 //####DESCRIPTIONEND####
51 //==========================================================================
53 #include <pkgconf/system.h>
54 #include <pkgconf/io_eth_drivers.h>
55 #include <pkgconf/devs_eth_davicom_dm9000.h>
57 #include <cyg/infra/cyg_type.h>
58 #include <cyg/infra/cyg_ass.h>
59 #include <cyg/hal/hal_arch.h>
60 #include <cyg/hal/hal_cache.h>
61 #include <cyg/hal/hal_intr.h>
62 #include <cyg/hal/hal_endian.h>
63 #include <cyg/infra/diag.h>
64 #include <cyg/hal/hal_if.h>
65 #include <cyg/hal/drv_api.h>
66 #include <cyg/io/eth/netdev.h>
67 #include <cyg/io/eth/eth_drv.h>
69 #include <dm9000_info.h>
72 #include <pkgconf/redboot.h>
74 #include <flash_config.h>
77 #include CYGDAT_DEVS_ETH_DAVICOM_DM9000_INL
79 #define DM9000_PKT_MAX 1536
85 // Control and Status register offsets
100 #define DM_EPDRL 0x0d
101 #define DM_EPDRH 0x0e
107 #define DM_TRPAL 0x22
108 #define DM_TRPAH 0x23
109 #define DM_RWPAL 0x24
110 #define DM_RWPAH 0x25
115 #define DM_CHIPR 0x2c
117 #define DM_MRCMDX 0xf0
118 #define DM_MRCMD 0xf2
119 #define DM_MDRAL 0xf4
120 #define DM_MDRAH 0xf5
121 #define DM_MWCMDX 0xf6
122 #define DM_MWCMD 0xf8
123 #define DM_MDWAL 0xfa
124 #define DM_MDWAH 0xfb
125 #define DM_TXPLL 0xfc
126 #define DM_TXPLH 0xfd
130 // NCR (Network Control Register)
131 #define NCR_EXT_PHY (1 << 7) // 1 ==> external PHY, 0 ==> internal
132 #define NCR_WAKEEN (1 << 6) // enable wakeup events
133 #define NCR_FCOL (1 << 4) // force collision mode (test)
134 #define NCR_FDX (1 << 3) // full duplex (read-only for internal phy)
135 #define NCR_LBK_NOR (0 << 1) // loopback off
136 #define NCR_LBK_MAC (1 << 1) // MAC loopback
137 #define NCR_LBK_PHY (2 << 1) // PHY loopback
138 #define NCR_RST (1 << 0) // Reset (auto-clears after 10us)
140 // NSR (Network Status Register)
141 #define NSR_SPEED (1 << 7) // 0 = 100Mbps, 1 = 10Mbps
142 #define NSR_LINKST (1 << 6) // link status (1 = okay)
143 #define NSR_WAKEST (1 << 5) // wake status (clear by read)
144 #define NSR_TX2END (1 << 3) // TX packet 2 complete
145 #define NSR_TX1END (1 << 2) // TX packet 1 complete
146 #define NSR_RXOV (1 << 1) // RX overflow
148 // TCR (TX Control Register)
149 #define TCR_TJDIS (1 << 6) // TX jabber disable
150 #define TCR_EXCECM (1 << 5) // 0 = abort after 15 collisions
151 #define TCR_PAD_DIS2 (1 << 4)
152 #define TCR_CRC_DIS2 (1 << 3)
153 #define TCR_PAD_DIS1 (1 << 2)
154 #define TCR_CRC_DIS1 (1 << 1)
155 #define TCR_TXREQ (1 << 0)
157 // TSR (TX Status Register)
158 #define TSR_TJTO (1 << 7)
159 #define TSR_LC (1 << 6)
160 #define TSR_NC (1 << 5)
161 #define TSR_LCOL (1 << 4)
162 #define TSR_COL (1 << 3)
163 #define TSR_EC (1 << 2)
165 // RCR (RX Control Register)
166 #define RCR_WTDIS (1 << 6)
167 #define RCR_DIS_LONG (1 << 5)
168 #define RCR_DIS_CRC (1 << 4)
169 #define RCR_ALL (1 << 3)
170 #define RCR_RUNT (1 << 2)
171 #define RCR_PRMSC (1 << 1)
172 #define RCR_RXEN (1 << 0)
174 // RSR (RX Status Register)
175 #define RSR_RF (1 << 7)
176 #define RSR_MF (1 << 6)
177 #define RSR_LCS (1 << 5)
178 #define RSR_RWTO (1 << 4)
179 #define RSR_PLE (1 << 3)
180 #define RSR_AE (1 << 2)
181 #define RSR_CE (1 << 1)
182 #define RSR_FOE (1 << 0)
184 // FCR (Flow Control Register)
185 #define FCR_TXPO (1 << 7)
186 #define FCR_TXPF (1 << 6)
187 #define FCR_TXPEN (1 << 5)
188 #define FCR_BKPA (1 << 4)
189 #define FCR_BKPM (1 << 3)
190 #define FCR_RXPS (1 << 2)
191 #define FCR_RXPCS (1 << 1)
192 #define FCR_FLCE (1 << 0)
194 // EPCR (EEPROM & PHY Control Register)
195 #define EPCR_REEP (1 << 5)
196 #define EPCR_WEP (1 << 4)
197 #define EPCR_EPOS (1 << 3)
198 #define EPCR_ERPRR (1 << 2)
199 #define EPCR_ERPRW (1 << 1)
200 #define EPCR_ERRE (1 << 0)
202 // WCR (Wakeup Control Register)
203 #define WCR_LINKEN (1 << 5)
204 #define WCR_SAMPLEEN (1 << 4)
205 #define WCR_MAGICEN (1 << 3)
206 #define WCR_LINKST (1 << 2)
207 #define WCR_SAMPLEST (1 << 1)
208 #define WCR_MAGIGST (1 << 0)
210 // SMCR (Special Mode Control Register)
211 #define SMCR_SM_EN (1 << 7)
212 #define SMCR_FLC (1 << 2)
213 #define SMCR_FB1 (1 << 1)
214 #define SMCR_FB0 (1 << 0)
216 // ISR (Interrupt Status Register)
217 #define ISR_IOMODE_16 (0 << 6)
218 #define ISR_IOMODE_32 (1 << 6)
219 #define ISR_IOMODE_8 (2 << 6)
220 #define ISR_ROOS (1 << 3)
221 #define ISR_ROS (1 << 2)
222 #define ISR_PTS (1 << 1)
223 #define ISR_PRS (1 << 0)
225 // IMR (Interrupt Mask Register)
226 #define IMR_PAR (1 << 7)
227 #define IMR_ROOM (1 << 3)
228 #define IMR_ROM (1 << 2)
229 #define IMR_PTM (1 << 1)
230 #define IMR_PRM (1 << 0)
233 #define PHY_BMCR 0x00
234 #define PHY_BMSR 0x01
235 #define PHY_ANAR 0x04
237 /* PHY BMCR (Basic Mode Control Register) */
238 #define PHY_BMCR_AUTO_NEG_EN (1 << 12)
239 #define PHY_BMCR_AUTO_NEG_START (1 << 12)
241 /* PHY BMSR (Basic Mode Status Register) */
242 #define PHY_BMSR_AUTO_NEG_COMPLETE (1 << 5)
244 // Read one datum from 8-bit bus
245 static int read_data_8(struct dm9000 *p, cyg_uint8 *dest)
247 HAL_READ_UINT8(p->io_data, *dest);
251 // Read one datum from 16-bit bus
252 static int read_data_16(struct dm9000 *p, cyg_uint8 *dest)
256 HAL_READ_UINT16(p->io_data, val);
257 memcpy(dest, &val, 2);
261 // Read one datum from 32-bit bus
262 static int read_data_32(struct dm9000 *p, cyg_uint8 *dest)
266 HAL_READ_UINT32(p->io_data, val);
267 memcpy(dest, &val, 4);
272 // Write one datum to 8-bit bus
273 static int write_data_8(struct dm9000 *p, cyg_uint8 *src)
275 HAL_WRITE_UINT8(p->io_data, *src);
279 // Write one datum to 16-bit bus
280 static int write_data_16(struct dm9000 *p, cyg_uint8 *src)
284 memcpy(&val, src, 2);
285 HAL_WRITE_UINT16(p->io_data, val);
289 // Write one datum to 32-bit bus
290 static int write_data_32(struct dm9000 *p, cyg_uint8 *src)
294 memcpy(&val, src, 4);
295 HAL_WRITE_UINT32(p->io_data, val);
301 // Return one byte from DM9000 register
302 static cyg_uint8 getreg(struct dm9000 *p, cyg_uint8 reg)
305 HAL_WRITE_UINT8(p->io_addr, reg);
306 HAL_READ_UINT8(p->io_data, val);
310 // Write one byte to DM9000 register
311 static void putreg(struct dm9000 *p, cyg_uint8 reg, cyg_uint8 val)
313 HAL_WRITE_UINT8(p->io_addr, reg);
314 HAL_WRITE_UINT8(p->io_data, val);
317 // Read a word from EEPROM
318 static cyg_uint16 eeprom_read(struct dm9000 *p, int offset)
320 putreg(p, DM_EPAR, offset);
321 putreg(p, DM_EPCR, EPCR_ERPRR);
322 while (getreg(p, DM_EPCR) & EPCR_ERRE)
324 CYGACC_CALL_IF_DELAY_US(8000);
325 putreg(p, DM_EPCR, 0);
326 return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
329 // Write a word to EEPROM
330 static void eeprom_write(struct dm9000 *p, int offset, cyg_uint16 val)
332 putreg(p, DM_EPAR, offset);
333 putreg(p, DM_EPDRH, val >> 8);
334 putreg(p, DM_EPDRL, val);
335 putreg(p, DM_EPCR, EPCR_WEP | EPCR_ERPRW);
336 while (getreg(p, DM_EPCR) & EPCR_ERRE)
338 CYGACC_CALL_IF_DELAY_US(8000);
339 putreg(p, DM_EPCR, 0);
342 // Reload info from EEPROM
343 static void eeprom_reload(struct dm9000 *p)
345 putreg(p, DM_EPCR, EPCR_REEP);
346 while (getreg(p, DM_EPCR) & EPCR_ERRE)
348 CYGACC_CALL_IF_DELAY_US(8000);
349 putreg(p, DM_EPCR, 0);
353 // Read a word from PHY
354 static cyg_uint16 phy_read(struct dm9000 *p, int offset)
356 putreg(p, DM_EPAR, 0x40 + offset);
357 putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRR);
358 CYGACC_CALL_IF_DELAY_US(200);
359 putreg(p, DM_EPCR, 0);
360 return getreg(p, DM_EPDRL) | (getreg(p, DM_EPDRH) << 8);
363 // Write a word to PHY
364 static void phy_write(struct dm9000 *p, int offset, cyg_uint16 val)
366 putreg(p, DM_EPAR, 0x40 + offset);
367 putreg(p, DM_EPDRL, val);
368 putreg(p, DM_EPDRH, val >> 8);
369 putreg(p, DM_EPCR, EPCR_EPOS | EPCR_ERPRW);
370 CYGACC_CALL_IF_DELAY_US(500);
371 putreg(p, DM_EPCR, 0);
375 static void init_phy(struct dm9000 *p)
381 putreg(p, DM_GPCR, 0x01);
382 putreg(p, DM_GPR, 0x00);
384 phy_write(p, PHY_ANAR, 0x1e1); // Advertise 10/100 half/full duplex w/CSMA
385 phy_write(p, PHY_BMCR, PHY_BMCR_AUTO_NEG_EN | PHY_BMCR_AUTO_NEG_START);
387 /* wait for autonegotiation to complete */
389 CYGACC_CALL_IF_DELAY_US(1000);
390 r = phy_read(p, PHY_BMSR);
391 } while (!(r & PHY_BMSR_AUTO_NEG_COMPLETE) && t++ < 2000);
395 static inline void dm9000_reset(struct dm9000 *p)
397 putreg(p, DM_NCR, NCR_RST);
398 CYGACC_CALL_IF_DELAY_US(100);
401 static int initialize_nic(struct dm9000 *priv)
407 switch (getreg(priv, DM_ISR) >> 6) {
409 priv->read_data = read_data_16;
410 priv->write_data = write_data_16;
414 priv->read_data = read_data_32;
415 priv->write_data = write_data_32;
419 priv->read_data = read_data_8;
420 priv->write_data = write_data_8;
424 diag_printf("Unknown DM9000 bus i/f.\n");
430 putreg(priv, DM_TCR, 0);
431 putreg(priv, DM_BPTR, 0x3f);
432 putreg(priv, DM_FCTR, 0x38);
433 putreg(priv, DM_FCR, 0xff);
434 putreg(priv, DM_SMCR, 0);
435 putreg(priv, DM_NSR, NSR_WAKEST | NSR_TX1END | NSR_TX2END);
436 putreg(priv, DM_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
439 for (i = 0; i < 6; i++)
440 putreg(priv, DM_PAR + i, priv->mac_address[i]);
442 // clear multicast table except for broadcast address
443 for (i = 0; i < 6; i++)
444 putreg(priv, DM_MAR + i, 0x00);
445 putreg(priv, DM_MAR + 6, 0x00);
446 putreg(priv, DM_MAR + 7, 0x80);
451 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
452 static cyg_uint32 dm9000_isr(cyg_vector_t vector, cyg_addrword_t data)
454 struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
455 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
457 cyg_drv_interrupt_mask(priv->interrupt);
458 cyg_drv_interrupt_acknowledge(priv->interrupt);
460 return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;
465 // ------------------------------------------------------------------------
467 // API Function : dm9000_init
469 // ------------------------------------------------------------------------
471 dm9000_init(struct cyg_netdevtab_entry * ndp)
473 struct eth_drv_sc *sc;
477 unsigned short u16tab[64];
479 sc = (struct eth_drv_sc *)ndp->device_instance;
480 priv = (struct dm9000 *)sc->driver_private;
484 #ifdef CYG_HAL_DM9000_PRESENT
485 if (!CYG_HAL_DM9000_PRESENT())
489 id = getreg(priv, DM_VIDL);
490 id |= getreg(priv, DM_VIDH) << 8;
491 id |= getreg(priv, DM_PIDL) << 16;
492 id |= getreg(priv, DM_PIDH) << 24;
494 if (id != 0x90000A46)
497 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
498 cyg_drv_interrupt_create(priv->interrupt,
503 &priv->interrupt_handle,
504 &priv->interrupt_object);
505 cyg_drv_interrupt_attach(priv->interrupt_handle);
506 cyg_drv_interrupt_acknowledge(priv->interrupt);
507 cyg_drv_interrupt_unmask(priv->interrupt);
508 #endif // !CYGPKG_IO_ETH_DRIVERS_STAND_ALONE
510 for (i = 0; i < 64; i++)
511 u16tab[i] = eeprom_read(priv, i);
519 eeprom_write(priv, 6, u16tab[6]);
520 eeprom_write(priv, 3, u16tab[3]);
526 for (i = 0; i < 64; i++)
527 u16tab[i] = eeprom_read(priv, i);
528 } while ((u16tab[0] | u16tab[1] | u16tab[2]) == 0);
530 priv->mac_address[0] = u16tab[0];
531 priv->mac_address[1] = u16tab[0] >> 8;
532 priv->mac_address[2] = u16tab[1];
533 priv->mac_address[3] = u16tab[1] >> 8;
534 priv->mac_address[4] = u16tab[2];
535 priv->mac_address[5] = u16tab[2] >> 8;
537 if (!initialize_nic(priv))
540 // Initialize upper level driver
541 (sc->funs->eth_drv->init)(sc, &(priv->mac_address[0]) );
545 // ------------------------------------------------------------------------
547 // API Function : dm9000_start
549 // ------------------------------------------------------------------------
551 dm9000_start( struct eth_drv_sc *sc, unsigned char *enaddr, int flags )
553 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
556 putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
559 putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
564 // ------------------------------------------------------------------------
566 // API Function : dm9000_stop
568 // ------------------------------------------------------------------------
570 dm9000_stop( struct eth_drv_sc *sc )
572 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
575 putreg(priv, DM_RCR, 0);
578 putreg(priv, DM_IMR, IMR_PAR);
584 // ------------------------------------------------------------------------
586 // API Function : dm9000_recv
588 // ------------------------------------------------------------------------
590 dm9000_recv( struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len )
592 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
593 struct eth_drv_sg *sg = sg_list;
596 int len, total_len, nread, n, leftover;
598 total_len = priv->rxlen;
599 nread = leftover = 0;
601 // diag_printf("dm9000_recv: total_len=%d\n", total_len);
607 // diag_printf("recv: buf=%p len=%d to_read=%d, leftover=%d\n", p, len, total_len - nread, leftover);
609 if ((nread + len) > total_len)
610 len = total_len - nread;
613 if (leftover <= len) {
614 memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), leftover);
620 memcpy(p, tmpbuf + (sizeof(tmpbuf) - leftover), len);
628 while (len >= sizeof(tmpbuf)) {
629 n = priv->read_data(priv, p);
636 n = priv->read_data(priv, tmpbuf);
638 memcpy(p, tmpbuf, n);
643 memcpy(p, tmpbuf, len);
651 } while (nread < total_len);
654 for (sg = sg_list; sg < (sg_list + sg_len); sg++) {
656 diag_dump_buf(sg->buf, sg->len);
661 // ------------------------------------------------------------------------
663 // API Function : dm9000_can_send
665 // ------------------------------------------------------------------------
667 dm9000_can_send(struct eth_drv_sc *sc)
669 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
671 if (!priv->active || priv->txbusy || priv->reset_pending)
678 // ------------------------------------------------------------------------
680 // API Function : dm9000_send
682 // ------------------------------------------------------------------------
684 dm9000_send(struct eth_drv_sc *sc,
685 struct eth_drv_sg *sg_list, int sg_len,
686 int total_len, unsigned long key)
688 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
689 struct eth_drv_sg *sg;
691 int i, len, n, save_len, tail_extra;
695 diag_printf("dm9000_send: NCR[%02x] NSR[%02x] TRPA[%04x]\n",
696 getreg(priv, DM_NCR), getreg(priv, DM_NSR),
697 getreg(priv, DM_TRPAL) | (getreg(priv, DM_TRPAH) << 8)
701 for (sg = sg_list; sg < (sg_list + sg_len); sg++) {
703 diag_dump_buf(sg->buf, sg->len);
710 save_len = total_len;
713 /* Disable all interrupts */
714 putreg(priv, DM_IMR, IMR_PAR);
716 HAL_WRITE_UINT8(priv->io_addr, DM_MWCMD);
718 while (total_len > 0) {
724 /* write any left over partial words by combining them with the start
725 * of this sg block */
727 int head_extra = sizeof(tmpbuf) - tail_extra;
728 memcpy(tmpbuf + tail_extra, p, head_extra);
731 for (i = 0; i < sizeof(tmpbuf) && total_len > 0; i += n) {
732 n = priv->write_data(priv, tmpbuf + i);
738 /* write out whole words */
739 while (len >= priv->buswidth) {
740 n = priv->write_data(priv, p);
746 /* if we have some left over partial words... */
748 /* combine them with the next sg block if available */
749 if (total_len > len ) {
751 memcpy(tmpbuf, p, tail_extra);
753 /* otherwise just write this last partial word */
754 n = priv->write_data(priv, p);
763 putreg(priv, DM_TXPLL, save_len);
764 putreg(priv, DM_TXPLH, save_len >> 8);
766 putreg(priv, DM_TCR, TCR_TXREQ);
768 /* Re-enable interrupt */
769 putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
772 // ------------------------------------------------------------------------
774 // API Function : dm9000_poll
776 // ------------------------------------------------------------------------
778 dm9000_poll(struct eth_drv_sc *sc)
780 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
781 cyg_uint8 status, rxstat;
782 cyg_uint16 pkt_stat, pkt_len;
786 putreg(priv, DM_IMR, IMR_PAR);
788 // get and clear staus
789 status = getreg(priv, DM_ISR);
790 putreg(priv, DM_ISR, status);
793 if (1 /*status & ISR_PRS*/) {
794 cyg_uint8 hdr[4]; /* 4 byte Rx pkt hdr */
796 getreg(priv, DM_MRCMDX); /* dummy read */
798 HAL_READ_UINT8(priv->io_data, rxstat);
800 // check for packet ready
802 HAL_WRITE_UINT8(priv->io_addr, DM_MRCMD);
804 i += priv->read_data(priv, hdr + i);
806 pkt_stat = hdr[0] | (hdr[1] << 8);
807 pkt_len = hdr[2] | (hdr[3] << 8);
810 diag_printf("pkt_stat=%04x pkt_len=%04x\n", pkt_stat, pkt_len);
813 if (pkt_len < 0x40) {
814 diag_printf("packet too short: %d (0x%04x)\n", pkt_len, pkt_len);
817 i += priv->read_data(priv, hdr);
818 } else if (pkt_len > 1536) {
819 priv->reset_pending = 1;
820 diag_printf("packet too long: %d (0x%04x)\n", pkt_len, pkt_len);
821 } else if (pkt_stat & 0xbf00) {
822 diag_printf("bad packet status: 0x%04x\n", pkt_stat);
825 i += priv->read_data(priv, hdr);
828 priv->rxlen = pkt_len;
829 (sc->funs->eth_drv->recv)(sc, pkt_len);
832 } else if (rxstat > 1) {
833 // this should never happen.
834 diag_printf("unknown rxstat byte: %d\n", rxstat);
835 priv->reset_pending = 1;
840 // check transmit status
841 if (status & ISR_PTS) {
844 txstat = getreg(priv, DM_NSR);
846 if (txstat & (NSR_TX1END | NSR_TX2END)) {
847 if (txstat & NSR_TX1END)
848 txstat = getreg(priv, DM_TSRI);
850 txstat = getreg(priv, DM_TSRII);
852 if (txstat & TSR_COL) {
856 if (getreg(priv, DM_TRPAL) & 3) {
857 // NIC bug detected. Need to reset.
858 priv->reset_pending = 1;
859 diag_printf("NIC collision bug detected!\n");
862 (sc->funs->eth_drv->tx_done)(sc, priv->txkey, 0);
867 if (priv->reset_pending && !priv->txbusy) {
868 initialize_nic(priv);
871 putreg(priv, DM_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
873 priv->reset_pending = 0;
877 putreg(priv, DM_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
881 // ------------------------------------------------------------------------
883 // API Function : dm9000_deliver
885 // ------------------------------------------------------------------------
887 dm9000_deliver(struct eth_drv_sc *sc)
889 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
893 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
894 cyg_drv_interrupt_unmask(priv->interrupt);
898 // ------------------------------------------------------------------------
900 // API Function : dm9000_int_vector
902 // ------------------------------------------------------------------------
904 dm9000_int_vector(struct eth_drv_sc *sc)
906 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
908 return priv->interrupt;
912 // ------------------------------------------------------------------------
914 // API Function : dm9000_ioctl
916 // ------------------------------------------------------------------------
918 dm9000_ioctl(struct eth_drv_sc *sc, unsigned long key,
919 void *data, int data_length)
921 struct dm9000 *priv = (struct dm9000 *)sc->driver_private;
922 cyg_uint8 *esa = (cyg_uint8 *)data;
926 #ifdef ETH_DRV_GET_MAC_ADDRESS
927 case ETH_DRV_GET_MAC_ADDRESS:
928 memcpy(esa, priv->mac_address, sizeof(priv->mac_address));
931 #ifdef ETH_DRV_SET_MAC_ADDRESS
932 case ETH_DRV_SET_MAC_ADDRESS:
933 for (i = 0; i < sizeof(priv->mac_address); i++) {
934 priv->mac_address[i] = esa[i];
935 putreg(priv, DM_PAR + i, priv->mac_address[i]);
937 #if defined(CYGSEM_DEVS_ETH_DAVICOM_DM9000_WRITE_EEPROM)
938 for (i = 0; i < sizeof(priv->mac_address) / 2; i++)
939 eeprom_write(priv, i, priv->mac_address[2*i] | (priv->mac_address[2*i+1] << 8));
941 diag_printf("dm9000: eeprom write disabled\n");
950 // ------------------------------------------------------------------------