1 //==========================================================================
5 // Ethernet device driver for MIPS Atlas using Philips SAA9730
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 <nickg@calivar.com>
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting the copyright
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####
55 // Contributors: msalter, nickg
58 // Description: hardware driver for SAA9730 ethernet
61 //####DESCRIPTIONEND####
63 //==========================================================================
65 // Ethernet device driver for MIPS Atlas
68 #include <pkgconf/system.h>
69 #include <pkgconf/devs_eth_mips_atlas.h>
70 #include <pkgconf/io_eth_drivers.h>
73 #include <pkgconf/net.h>
74 #include <cyg/kernel/kapi.h>
76 #include <cyg/infra/cyg_type.h>
77 #include <cyg/hal/hal_arch.h>
78 #include <cyg/hal/hal_endian.h>
79 #include <cyg/hal/hal_intr.h>
80 #include <cyg/hal/hal_cache.h>
81 #include <cyg/hal/hal_if.h>
82 #include <cyg/infra/diag.h>
83 #include <cyg/hal/drv_api.h>
84 #include <cyg/io/eth/netdev.h>
85 #include <cyg/io/eth/eth_drv.h>
88 #include <cyg/io/pci.h>
89 // So we can check the validity of the PCI window against the MLTs opinion,
90 // and thereby what the malloc heap consumes willy-nilly:
91 #include CYGHWR_MEMORY_LAYOUT_H
93 #error "Need PCI package here"
96 #ifndef CYGSEM_MIPS_ATLAS_SET_ESA
98 #include <pkgconf/redboot.h>
99 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
101 #include <flash_config.h>
102 RedBoot_config_option("Network hardware address [MAC]",
104 ALWAYS_ENABLED, true,
111 // SAA9730 LAN definitions
114 // Exported statistics and the like
115 #include <cyg/io/eth/eth_drv_stats.h>
117 #ifndef CYGPKG_REDBOOT
120 #define db_printf diag_printf
122 #define ETHER_ADDR_LEN 6
124 static unsigned poll_count = 0; // for bug workaround
125 static void __tx_poll(struct eth_drv_sc *sc);
127 struct saa9730_priv_data {
130 cyg_handle_t interrupt_handle;
131 cyg_interrupt interrupt_object;
132 cyg_uint32 devid; // PCI device id
133 cyg_uint32 base; // PCI memory map base
136 // index of next RX buffer
137 cyg_uint8 next_rx_bindex;
139 // index of next packet within RX buffer
140 cyg_uint8 next_rx_pindex;
142 // index of next TX buffer
143 cyg_uint8 next_tx_bindex;
145 // index of next packet within TX buffer
146 cyg_uint8 next_tx_pindex;
148 cyg_uint32 *tx_buffer[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
149 cyg_uint32 *rx_buffer[SAA9730_BUFFERS][SAA9730_RXPKTS_PER_BUFFER];
152 unsigned long tx_key[SAA9730_BUFFERS][SAA9730_TXPKTS_PER_BUFFER];
153 int tx_used[SAA9730_BUFFERS];
158 &saa9730_priv_data, // Driver specific data
159 "eth0", // Name for this interface
166 saa9730_deliver, // "pseudoDSR" called from fast net thread
170 NETDEVTAB_ENTRY(atlas_netdev,
175 #ifdef CYGSEM_MIPS_ATLAS_SET_ESA
176 static unsigned char enaddr[] = CYGDAT_MIPS_ATLAS_ESA;
178 static unsigned char enaddr[ETHER_ADDR_LEN];
181 static void saa9730_poll(struct eth_drv_sc *sc);
183 // This ISR is called when the ethernet interrupt occurs
185 saa9730_isr(cyg_vector_t vector, cyg_addrword_t data)
187 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
188 unsigned long __base = spd->base;
190 #ifndef CYGPKG_REDBOOT
191 SAA9730_EVM_IER_SW &= ~(SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
192 SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
193 cyg_drv_interrupt_mask(vector);
196 db_printf("saa9730_isr\n");
198 return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
201 #ifndef CYGPKG_REDBOOT
203 void saa9730_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
205 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
206 struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(spd->ndp);
207 struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
209 db_printf("saa9730_dsr\n");
212 eth_drv_dsr(vector, count, (cyg_addrword_t)sc);
217 saa9730_int_vector(struct eth_drv_sc *sc)
219 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
225 __init_buffers(struct saa9730_priv_data *spd)
227 extern char cyg_io_atlas_2kbuffers[];
228 cyg_uint32 *bufp = (cyg_uint32 *)CYGARC_UNCACHED_ADDRESS((unsigned)cyg_io_atlas_2kbuffers);
231 for (i = 0; i < SAA9730_BUFFERS; i++) {
232 for (j = 0; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
233 memset(bufp, 0, 2048);
234 spd->rx_buffer[i][j] = bufp;
235 bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
238 for (i = 0; i < SAA9730_BUFFERS; i++) {
239 for (j = 0; j < SAA9730_TXPKTS_PER_BUFFER; j++) {
240 memset(bufp, 0, 2048);
241 *bufp = CYG_CPU_TO_LE32(TX_EMPTY);
242 spd->tx_buffer[i][j] = bufp;
243 bufp += SAA9730_PACKET_SIZE/sizeof(*bufp);
247 spd->next_rx_pindex = 0;
248 spd->next_rx_bindex = 0;
249 spd->next_tx_pindex = 0;
250 spd->next_tx_bindex = 0;
254 __select_buffer(struct saa9730_priv_data *spd, int buf_nr)
256 unsigned long __base = spd->base;
261 for (i = 0; i < SAA9730_RXPKTS_PER_BUFFER; i++) {
262 p = spd->rx_buffer[buf_nr][i];
263 *p = CYG_CPU_TO_LE32(RX_READY);
267 SAA9730_OK2USE |= SAA9730_OK2USE_RXB;
269 SAA9730_OK2USE |= SAA9730_OK2USE_RXA;
274 __init_cam(struct saa9730_priv_data *spd)
276 unsigned long __base = spd->base;
277 cyg_uint32 abuf[3]; // room for 2 copies of mac address
280 // make 2 contiguous copies of mac addr
281 memcpy((char *)abuf, enaddr, 6);
282 memcpy((char *)abuf + 6, enaddr, 6);
284 // Setting up the address compare regs is weird because you have
285 // to access by word addresses even though addresses don't have
286 // an integral number of words.
288 for (i = 0; i < SAA9730_CAM_ENTRIES; i++) {
289 for (j = 0; j < 3; j++, cam_offset++) {
290 SAA9730_CAMADR = cam_offset;
291 SAA9730_CAMDAT = CYG_CPU_TO_BE32(abuf[j]);
297 __stop_dma(struct saa9730_priv_data *spd)
299 unsigned long __base = spd->base;
302 SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
305 SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
306 SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
308 // Set DMA and MAC reset bits
309 SAA9730_DMATST |= SAA9730_DMATST_RESET;
310 SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
315 __init_dma(struct saa9730_priv_data *spd)
317 unsigned long __base = spd->base;
322 SAA9730_DMATST |= SAA9730_DMATST_RESET;
325 SAA9730_TXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[0][0]);
326 SAA9730_TXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->tx_buffer[1][0]);
327 SAA9730_RXBUFA = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[0][0]);
328 SAA9730_RXBUFB = CYGARC_PHYSICAL_ADDRESS((unsigned long)spd->rx_buffer[1][0]);
330 SAA9730_PKTCNT = ((SAA9730_TXPKTS_PER_BUFFER << 24) |
331 (SAA9730_TXPKTS_PER_BUFFER << 16) |
332 (SAA9730_RXPKTS_PER_BUFFER << 8) |
333 (SAA9730_RXPKTS_PER_BUFFER << 0));
337 __select_buffer(spd, 0);
339 // initialize DMA control register
340 SAA9730_DMACTL = SAA9730_DMACTL_BLKINT |
341 SAA9730_DMACTL_MAXXFER_ANY |
342 SAA9730_DMACTL_ENDIAN_LITTLE;
344 SAA9730_DMACTL |= SAA9730_DMACTL_RXINT;
345 SAA9730_DMACTL |= (1<<SAA9730_DMACTL_RXINTCNT_SHIFT);
346 SAA9730_DMACTL &= ~SAA9730_DMACTL_BLKINT;
348 #ifndef CYGPKG_REDBOOT
349 SAA9730_DMACTL |= SAA9730_DMACTL_TXINT;
352 SAA9730_TIMOUT = 200;
354 // accept broadcast packets */
355 SAA9730_CAMCTL = SAA9730_CAMCTL_BROADCAST |
356 SAA9730_CAMCTL_COMPARE;
359 SAA9730_RXCTL |= SAA9730_RXCTL_STRIPCRC;
366 __check_mii(struct saa9730_priv_data *spd)
368 unsigned long __base = spd->base;
372 db_printf("__check_mii\n");
375 // spin till station is not busy
376 while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
379 // set PHY address = 'STATUS'
380 SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
381 (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) |
384 // spin till station is not busy
385 while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
390 // check the link status
391 if (SAA9730_MDDATA & PHY_STATUS_LINK_UP) {
393 SAA9730_MDCTL = SAA9730_MDCTL_BUSY |
394 (PHY_ADDRESS << SAA9730_MDCTL_PHY_SHIFT) |
397 // spin till station is not busy
398 while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
403 opmode = (SAA9730_MDDATA & PHY_REG31_OPMODE_MSK) >> PHY_REG31_OPMODE_SHIFT;
406 db_printf("MII mode %d\n", opmode);
409 if ((opmode == OPMODE_10BASET_FULLDUPLEX) ||
410 (opmode == OPMODE_100BASEX_FULLDUPLEX))
411 SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII | SAA9730_MACCTL_FULLDUP;
413 SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII;
417 db_printf("Link is down\n");
423 saa9730_reset(struct saa9730_priv_data *spd)
425 unsigned long __base = spd->base;
432 SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
435 SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
436 SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
438 // Set DMA and MAC reset bits
439 SAA9730_DMATST |= SAA9730_DMATST_RESET;
440 SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
451 atlas_saa9730_init(struct cyg_netdevtab_entry *tab)
453 static int initialized = 0; // only probe PCI et al *once*
454 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
455 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
458 db_printf("atlas_saa9730_init\n");
461 if (0 == initialized) {
462 cyg_pci_device_id devid;
463 cyg_pci_device dev_info;
467 devid = CYG_PCI_NULL_DEVID;
469 if (cyg_pci_find_device(CYG_PCI_VENDOR_PHILIPS, 0x9730, &devid) ) {
473 cyg_pci_get_device_info(devid, &dev_info);
475 if (!cyg_pci_configure_device(&dev_info)) {
477 db_printf("Failed to configure eth device\n");
482 // Philips SAA9730 implements only one function memory mapped
483 // into a single contigous memory region.
485 // According to spec. the BAR#1 is to be used for memory mapped IO.
486 spd->base = dev_info.base_map[1];
488 // FIXME! All IO units share an interrupt
489 spd->vector = CYGNUM_HAL_INTERRUPT_INTB;
491 // Setup timing stuff
492 cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
493 CYG_PCI_DEV_GET_DEVFN(devid),
494 CYG_PCI_CFG_LATENCY_TIMER, 0x20);
495 cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
496 CYG_PCI_DEV_GET_DEVFN(devid),
497 CYG_PCI_CFG_MIN_GNT, 9);
498 cyg_hal_plf_pci_cfg_write_byte(CYG_PCI_DEV_GET_BUS(devid),
499 CYG_PCI_DEV_GET_DEVFN(devid),
500 CYG_PCI_CFG_MAX_LAT, 24);
503 db_printf("eth0 found: bus[%d] dev[%d] base[%x] vector[%d]\n",
504 CYG_PCI_DEV_GET_BUS(devid),
505 CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
506 spd->base, spd->vector);
511 #ifndef CYGPKG_REDBOOT
512 cyg_drv_interrupt_create(
514 0, // Priority - unused
515 (CYG_ADDRWORD)spd, // Data item passed to ISR & DSR
518 &spd->interrupt_handle, // handle to intr obj
519 &spd->interrupt_object ); // space for int obj
521 cyg_drv_interrupt_attach(spd->interrupt_handle);
522 cyg_drv_interrupt_acknowledge(spd->vector);
523 cyg_drv_interrupt_unmask(spd->vector);
526 // When in Redboot we want to get RX interrupts. These
527 // will be picked up by the default interrupt handler and
529 unsigned long __base = spd->base;
530 SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
531 SAA9730_EVM_IER |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
532 SAA9730_EVM_ISR |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
536 db_printf(" **** Device enabled for I/O and Memory and Bus Master\n");
541 db_printf("eth0 not found\n");
552 // Fetch hardware address
553 #if defined(CYGPKG_REDBOOT) && \
554 defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \
555 !defined(CYGSEM_MIPS_ATLAS_SET_ESA)
556 flash_get_config("atlas_esa", enaddr, CONFIG_ESA);
559 CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
560 "atlas_esa", enaddr, CONFIG_ESA );
562 db_printf("ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
563 enaddr[0],enaddr[1],enaddr[2],enaddr[3],enaddr[4],enaddr[5]);
569 // Initialize upper level driver
570 (sc->funs->eth_drv->init)(sc, enaddr);
576 saa9730_stop(struct eth_drv_sc *sc)
578 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
579 unsigned long __base = spd->base;
582 SAA9730_DMACTL &= ~(SAA9730_DMACTL_ENRX | SAA9730_DMACTL_ENTX);
585 SAA9730_TXCTL &= ~SAA9730_TXCTL_ENTX;
586 SAA9730_RXCTL &= ~SAA9730_RXCTL_ENRX;
588 // Set DMA and MAC reset bits
589 SAA9730_DMATST |= SAA9730_DMATST_RESET;
590 SAA9730_MACCTL |= SAA9730_MACCTL_RESET;
596 __do_start(struct saa9730_priv_data *spd)
598 unsigned long __base = spd->base;
604 for (i = 0; i < SAA9730_BUFFERS; i++)
607 // for tx, turn on MAC first
608 SAA9730_TXCTL |= SAA9730_TXCTL_ENTX;
609 SAA9730_DMACTL |= SAA9730_DMACTL_ENTX;
611 // for rx, turn on DMA first
612 SAA9730_DMACTL |= SAA9730_DMACTL_ENRX;
613 SAA9730_RXCTL |= SAA9730_RXCTL_ENRX;
615 __select_buffer(spd, spd->next_rx_bindex);
619 // This function is called to "start up" the interface. It may be called
620 // multiple times, even when the hardware is already running. It will be
621 // called whenever something "hardware oriented" changes and should leave
622 // the hardware ready to send/receive packets.
625 saa9730_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
627 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
636 // This routine is called to perform special "control" opertions
639 saa9730_control(struct eth_drv_sc *sc, unsigned long key,
640 void *data, int data_length)
643 case ETH_DRV_SET_MAC_ADDRESS:
653 // This routine is called to see if it is possible to send another packet.
654 // It will return non-zero if a transmit is possible, zero otherwise.
657 saa9730_can_send(struct eth_drv_sc *sc)
659 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
660 unsigned long __base = spd->base;
664 if (spd->next_tx_bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
667 if (spd->next_tx_bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
674 static int tx_poll_count;
677 // This routine is called to send data to the hardware.
679 saa9730_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
680 int total_len, unsigned long key)
682 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
683 unsigned long __base = spd->base;
685 cyg_uint32 pktlen = total_len;
686 cyg_uint8 *pktdata, *to_p;
687 volatile cyg_uint32 *pktstat ;
688 struct eth_drv_sg *last_sg;
691 db_printf("saa9730_send: %d sg's, %d bytes, KEY %x\n",
692 sg_len, total_len, key );
698 bindex = spd->next_tx_bindex;
699 pindex = spd->next_tx_pindex;
701 spd->next_tx_pindex++;
702 if (spd->next_tx_pindex >= SAA9730_TXPKTS_PER_BUFFER) {
703 spd->next_tx_pindex = 0;
704 spd->next_tx_bindex ^= 1;
707 pktstat = spd->tx_buffer[bindex][pindex];
709 if (bindex == 0 && (SAA9730_OK2USE & SAA9730_OK2USE_TXA))
712 if (bindex == 1 && (SAA9730_OK2USE & SAA9730_OK2USE_TXB))
715 spd->tx_key[bindex][pindex] = key;
716 spd->tx_used[bindex] += 1;
718 pktdata = (cyg_uint8 *)((unsigned)pktstat + 4);
720 // Copy from the sglist into the tx buffer
723 for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
727 from_p = (cyg_uint8 *)(sg_list->buf);
733 memcpy((unsigned char *)to_p, from_p, l);
738 break; // Should exit via sg_last normally
741 // pad to minimum size
742 if (pktlen < SAA9730_MIN_PACKET_SIZE) {
743 memset(to_p, 0, SAA9730_MIN_PACKET_SIZE-pktlen);
744 pktlen = SAA9730_MIN_PACKET_SIZE;
747 // Set transmit status WORD for hardware (LAN-DMA-ENGINE)
748 *pktstat = CYG_CPU_TO_LE32(TX_READY | pktlen);
752 SAA9730_OK2USE |= SAA9730_OK2USE_TXA;
754 SAA9730_OK2USE |= SAA9730_OK2USE_TXB;
758 spd->tx_busy = bindex + 1;
764 __check_rxstate(struct saa9730_priv_data *spd)
766 unsigned long __base = spd->base;
767 cyg_uint32 status, flag, size;
772 db_printf("__check_rxstate\n");
775 #ifdef CYGPKG_REDBOOT
776 // Clear SAA9730 LAN interrupt and re-enable interrupts.
777 SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
778 SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
781 if ((SAA9730_DBGRXS & SAA9730_DBGRXS_RXDII_MASK) == SAA9730_DBGRXS_RXDII_ERROR) {
782 // re-init driver and controller
784 db_printf("DBGRXS: reset\n");
791 // Check RX packet status
792 for (i = 0; i < SAA9730_BUFFERS; i++) {
793 for (j = 1; j < SAA9730_RXPKTS_PER_BUFFER; j++) {
794 pkt = spd->rx_buffer[i][j];
795 status = CYG_LE32_TO_CPU(*pkt);
796 size = status & RXPACKET_STATUS_SIZE_MASK;
797 flag = status & RXPACKET_STATUS_FLAG_MASK;
798 if (flag == RX_INVALID_STAT || size > 1514 || *(pkt - 1)) {
799 // re-init driver and controller
801 db_printf("rxpkt: reset\n");
813 __tx_poll(struct eth_drv_sc *sc)
815 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
817 volatile cyg_uint32 *pktstat;
823 bindex = spd->tx_busy - 1;
824 pindex = spd->tx_used[bindex] - 1; // watch last pkt in buffer
826 pktstat = spd->tx_buffer[bindex][pindex];
828 status = CYG_LE32_TO_CPU(*pktstat);
829 if ((status & TXPACKET_STATUS_FLAG_MASK) != TX_HWDONE) {
833 if (++tx_poll_count > 1000) {
836 for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
837 (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
841 for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++)
842 (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1);
850 for (pindex = 0; pindex < spd->tx_used[bindex]; pindex++) {
851 /* Check for error. */
852 pktstat = spd->tx_buffer[bindex][pindex];
853 status = CYG_LE32_TO_CPU(*pktstat);
855 if (status & TXPACKET_STATUS_ERROR) {
856 if (status & TXPACKET_STATUS_EXDEFER)
857 db_printf("tx deferred\n");
859 if (status & TXPACKET_STATUS_LATECOLLERR)
860 db_printf("tx late collision\n");
862 if (status & TXPACKET_STATUS_LOSTCARRIER)
863 db_printf("tx no carrier\n");
865 if (status & TXPACKET_STATUS_UNDERRUN)
866 db_printf("tx underrun\n");
868 if (status & TXPACKET_STATUS_SQERR)
869 db_printf("tx sq\n");
872 *pktstat = CYG_CPU_TO_LE32(TX_EMPTY);
874 (sc->funs->eth_drv->tx_done)(sc, spd->tx_key[bindex][pindex], 1 /* status */);
878 spd->tx_used[bindex] = 0;
881 if (spd->tx_used[bindex])
882 spd->tx_busy = bindex + 1;
889 __rx_poll(struct eth_drv_sc *sc)
891 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
892 int bindex, pindex, done;
893 volatile cyg_uint32 *pkt;
894 cyg_uint32 status, pktlen;
897 db_printf("__rx_poll\n");
904 // index of next packet buffer
905 bindex = spd->next_rx_bindex;
907 // index of next packet within buffer
908 pindex = spd->next_rx_pindex;
910 pkt = spd->rx_buffer[bindex][pindex];
912 // stop now if no more packets
913 if (((status = CYG_LE32_TO_CPU(*pkt)) & RXPACKET_STATUS_FLAG_MASK) == RX_READY)
916 db_printf("__rx_poll pkt %08x status %08x\n",pkt,status);
918 // if this is the first packet in a buffer, switch the SAA9730 to
919 // use the next buffer for subsequent incoming packets.
921 __select_buffer(spd, bindex == 0);
923 // check for good packet
924 if (status & RXPACKET_STATUS_GOOD) {
926 pktlen = status & RXPACKET_STATUS_SIZE_MASK ;
929 (sc->funs->eth_drv->recv)(sc, pktlen);
935 db_printf("rx bad: %08x %08x\n",pkt,status);
938 /* go to next packet in sequence */
939 spd->next_rx_pindex++;
940 if (spd->next_rx_pindex >= SAA9730_RXPKTS_PER_BUFFER) {
941 spd->next_rx_pindex = 0;
942 spd->next_rx_bindex++;
943 if (spd->next_rx_bindex >= SAA9730_BUFFERS)
944 spd->next_rx_bindex = 0;
948 if (((poll_count++) % 100) == 0)
949 __check_rxstate(spd);
954 saa9730_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
956 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
957 volatile cyg_uint32 *pkt;
958 cyg_uint32 pktlen, status;
959 struct eth_drv_sg *last_sg;
964 pkt = spd->rx_buffer[spd->next_rx_bindex][spd->next_rx_pindex];
966 status = CYG_LE32_TO_CPU(*pkt);
967 if (status & RXPACKET_STATUS_GOOD) {
969 pktlen = status & RXPACKET_STATUS_SIZE_MASK;
975 // check we have memory to copy into; we would be called even if
976 // caller was out of memory in order to maintain our state.
977 if (0 == sg_len || 0 == sg_list)
978 return; // caller was out of mbufs
981 from_p = (cyg_uint8 *)((unsigned)pkt + 4);
983 for (last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++) {
987 to_p = (cyg_uint8 *)(sg_list->buf);
990 if (0 >= l || 0 == to_p)
991 return; // caller was out of mbufs
996 memcpy(to_p, (unsigned char *)from_p, l);
1005 __do_deliver(struct eth_drv_sc *sc)
1007 // First pass any rx data up the stack
1010 // Then scan for completed Txen and inform the stack
1015 saa9730_poll(struct eth_drv_sc *sc)
1017 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
1019 #ifndef CYGPKG_REDBOOT
1020 cyg_drv_interrupt_mask(spd->vector);
1023 (void)saa9730_isr(spd->vector, (cyg_addrword_t)spd);
1027 cyg_drv_interrupt_acknowledge(spd->vector);
1029 #ifndef CYGPKG_REDBOOT
1030 cyg_drv_interrupt_unmask(spd->vector);
1035 // The deliver function (ex-DSR) handles the ethernet [logical] processing
1037 saa9730_deliver(struct eth_drv_sc *sc)
1039 struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
1040 unsigned long __base = spd->base;
1045 cyg_drv_interrupt_acknowledge(spd->vector);
1047 #ifndef CYGPKG_REDBOOT
1048 // Clear SAA9730 LAN interrupt and re-enable interrupts.
1049 SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
1050 cyg_drv_interrupt_unmask(spd->vector);