1 //==========================================================================
5 // Ethernet device driver for PowerPC QUICC (MPC8xx) boards
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) 2002, 2003 Gary Thomas
13 // Copyright (C) 2003 Nick Garnett <nickg@calivar.com>
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####
56 // Contributors: gthomas, nickg
59 // Description: hardware driver for MPC8xx QUICC
62 //####DESCRIPTIONEND####
64 //==========================================================================
66 // Ethernet device driver for MPC8xx QUICC
68 #include <pkgconf/system.h>
69 #include <pkgconf/devs_eth_powerpc_quicc.h>
70 #include <pkgconf/io_eth_drivers.h>
73 #include <pkgconf/net.h>
76 #include <cyg/infra/cyg_type.h>
77 #include <cyg/infra/diag.h>
79 #include <cyg/hal/hal_arch.h>
80 #include <cyg/hal/hal_cache.h>
81 #include <cyg/hal/hal_intr.h>
82 #include <cyg/hal/drv_api.h>
84 #include <cyg/io/eth/netdev.h>
85 #include <cyg/io/eth/eth_drv.h>
87 #include "quicc_eth.h"
89 static unsigned char quicc_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM]
90 [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
91 static unsigned char quicc_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM]
92 [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE] __attribute__((aligned(HAL_DCACHE_LINE_SIZE)));
94 static struct quicc_eth_info quicc_eth0_info;
95 static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x79, 0xB8};
96 static unsigned char enaddr[6];
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,
110 // For fetching the ESA from RedBoot
111 #include <cyg/hal/hal_if.h>
116 ETH_DRV_SC(quicc_eth0_sc,
117 &quicc_eth0_info, // Driver specific data
118 "eth0", // Name for this interface
127 quicc_eth_int_vector);
129 NETDEVTAB_ENTRY(quicc_netdev,
134 // LED activity [exclusive of hardware bits]
140 #define LED_TxACTIVE 7
141 #define LED_RxACTIVE 6
142 #define LED_IntACTIVE 5
148 _set_led(_get_led() | (1<<bit));
154 _set_led(_get_led() & ~(1<<bit));
157 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
158 static cyg_interrupt quicc_eth_interrupt;
159 static cyg_handle_t quicc_eth_interrupt_handle;
161 static void quicc_eth_int(struct eth_drv_sc *data);
162 static void quicc_eth_command(struct eth_drv_sc *sc, unsigned long cmd);
164 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
165 // This ISR is called when the ethernet interrupt occurs
167 quicc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs)
169 cyg_drv_interrupt_mask(QUICC_ETH_INT);
170 cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
171 return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR
175 // Deliver function (ex-DSR) handles the ethernet [logical] processing
177 quicc_eth_deliver(struct eth_drv_sc * sc)
180 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
181 // Allow interrupts to happen again
182 cyg_drv_interrupt_unmask(QUICC_ETH_INT);
187 // Initialize the interface - performed at system startup
188 // This function must set up the interface, including arranging to
189 // handle interrupts, etc, so that it may be "started" cheaply later.
192 quicc_eth_init(struct cyg_netdevtab_entry *tab)
194 struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
195 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
196 volatile EPPC *eppc = (volatile EPPC *)eppc_base();
197 struct cp_bufdesc *rxbd, *txbd;
198 unsigned char *RxBUF, *TxBUF, *ep, *ap;
199 volatile struct ethernet_pram *enet_pram;
200 volatile struct scc_regs *scc;
206 #ifdef QUICC_ETH_FETCH_ESA
207 QUICC_ETH_FETCH_ESA(esa_ok);
211 #if defined(CYGPKG_REDBOOT) && \
212 defined(CYGSEM_REDBOOT_FLASH_CONFIG)
213 esa_ok = flash_get_config("quicc_esa", enaddr, CONFIG_ESA);
215 esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,
216 "quicc_esa", enaddr, CONFIG_ESA);
219 // Can't figure out ESA
220 diag_printf("QUICC_ETH - Warning! ESA unknown\n");
221 memcpy(&enaddr, &_default_enaddr, sizeof(enaddr));
225 // Ensure consistent state between cache and what the QUICC sees
226 HAL_DCACHE_IS_ENABLED(cache_state);
229 HAL_DCACHE_DISABLE();
232 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
233 // Set up to handle interrupts
234 cyg_drv_interrupt_create(QUICC_ETH_INT,
235 CYGARC_SIU_PRIORITY_HIGH,
236 (cyg_addrword_t)sc, // Data item passed to interrupt handler
237 (cyg_ISR_t *)quicc_eth_isr,
238 (cyg_DSR_t *)eth_drv_dsr,
239 &quicc_eth_interrupt_handle,
240 &quicc_eth_interrupt);
241 cyg_drv_interrupt_attach(quicc_eth_interrupt_handle);
242 cyg_drv_interrupt_acknowledge(QUICC_ETH_INT);
243 cyg_drv_interrupt_unmask(QUICC_ETH_INT);
246 qi->pram = enet_pram = &eppc->pram[QUICC_ETH_SCC].enet_scc;
247 qi->ctl = scc = &eppc->scc_regs[QUICC_ETH_SCC]; // Use SCCx
249 // Shut down ethernet, in case it is already running
250 scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
252 memset((void *)enet_pram, 0, sizeof(*enet_pram));
254 TxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc));
255 RxBD = _mpc8xx_allocBd(CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM * sizeof(struct cp_bufdesc));
257 txbd = (struct cp_bufdesc *)((char *)eppc + TxBD);
258 rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD);
267 RxBUF = &quicc_eth_rxbufs[0][0];
268 TxBUF = &quicc_eth_txbufs[0][0];
270 // setup buffer descriptors
271 for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) {
273 rxbd->buffer = RxBUF;
274 rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
275 RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
279 rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
280 for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) {
282 txbd->buffer = TxBUF;
284 TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
288 txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer
290 // Set up parallel ports for connection to ethernet tranceiver
291 eppc->pio_papar |= (QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
292 eppc->pio_padir &= ~(QUICC_ETH_PA_RXD | QUICC_ETH_PA_TXD);
293 eppc->pio_paodr &= ~QUICC_ETH_PA_TXD;
295 eppc->pio_pcpar &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
296 eppc->pio_pcdir &= ~(QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
297 eppc->pio_pcso |= (QUICC_ETH_PC_COLLISION | QUICC_ETH_PC_Rx_ENABLE);
299 eppc->pio_papar |= (QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
300 eppc->pio_padir &= ~(QUICC_ETH_PA_Tx_CLOCK | QUICC_ETH_PA_Rx_CLOCK);
302 // Set up clock routing
303 eppc->si_sicr &= ~QUICC_ETH_SICR_MASK;
304 eppc->si_sicr |= QUICC_ETH_SICR_ENET;
305 eppc->si_sicr &= ~QUICC_ETH_SICR_ENABLE;
308 eppc->dma_sdcr = 0x0001;
310 // Initialize shared PRAM
311 enet_pram->rbase = RxBD;
312 enet_pram->tbase = TxBD;
314 // Set Big Endian mode
315 enet_pram->rfcr = QUICC_SCC_FCR_BE;
316 enet_pram->tfcr = QUICC_SCC_FCR_BE;
318 // Size of receive buffers
319 enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
321 // Initialize CRC calculations
322 enet_pram->c_pres = 0xFFFFFFFF;
323 enet_pram->c_mask = 0xDEBB20E3; // Actual CRC formula
324 enet_pram->crcec = 0;
326 enet_pram->disfc = 0;
329 enet_pram->pads = 0x8888;
330 enet_pram->pads = 0x0000;
333 enet_pram->ret_lim = 15;
334 enet_pram->ret_cnt = 0;
337 enet_pram->mflr = IEEE_8023_MAX_FRAME;
338 enet_pram->minflr = IEEE_8023_MIN_FRAME;
339 enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
340 enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE;
342 // Group address hash
343 enet_pram->gaddr1 = 0;
344 enet_pram->gaddr2 = 0;
345 enet_pram->gaddr3 = 0;
346 enet_pram->gaddr4 = 0;
348 // Device physical address
349 ep = &enaddr[sizeof(enaddr)];
350 ap = (unsigned char *)&enet_pram->paddr_h;
351 for (i = 0; i < sizeof(enaddr); i++) {
355 // Persistence counter
356 enet_pram->p_per = 0;
358 // Individual address filter
359 enet_pram->iaddr1 = 0;
360 enet_pram->iaddr2 = 0;
361 enet_pram->iaddr3 = 0;
362 enet_pram->iaddr4 = 0;
365 enet_pram->taddr_h = 0;
366 enet_pram->taddr_m = 0;
367 enet_pram->taddr_l = 0;
369 // Initialize the CPM (set up buffer pointers, etc).
370 quicc_eth_command(sc, QUICC_CPM_CR_INIT_TXRX);
372 // Clear any pending interrupt/exceptions
373 scc->scc_scce = 0xFFFF;
376 scc->scc_sccm = QUICC_SCCE_INTS | QUICC_SCCE_GRC | QUICC_SCCE_BSY;
378 // Set up SCCx to run in ethernet mode
380 scc->scc_gsmr_l = QUICC_SCC_GSML_TCI | QUICC_SCC_GSML_TPL_48 |
381 QUICC_SCC_GSML_TPP_01 | QUICC_SCC_GSML_MODE_ENET;
384 scc->scc_dsr = 0xD555;
386 // Protocol specifics (as if GSML wasn't enough)
387 scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 |
388 QUICC_PMSR_RCV_SHORT_FRAMES;
390 #ifdef QUICC_ETH_ENABLE
394 #ifdef QUICC_ETH_RESET_PHY
395 QUICC_ETH_RESET_PHY();
398 // Enable ethernet interface
399 #ifdef QUICC_ETH_PC_Tx_ENABLE
400 eppc->pio_pcpar |= QUICC_ETH_PC_Tx_ENABLE;
401 eppc->pio_pcdir &= ~QUICC_ETH_PC_Tx_ENABLE;
403 eppc->pip_pbpar |= QUICC_ETH_PB_Tx_ENABLE;
404 eppc->pip_pbdir |= QUICC_ETH_PB_Tx_ENABLE;
410 // Initialize upper level driver
411 (sc->funs->eth_drv->init)(sc, (unsigned char *)&enaddr);
414 clear_led(LED_TxACTIVE);
415 clear_led(LED_RxACTIVE);
421 // This function is called to shut down the interface.
424 quicc_eth_stop(struct eth_drv_sc *sc)
426 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
427 volatile struct scc_regs *scc = qi->ctl;
429 // Disable the device!
430 scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT);
434 // This function is called to "start up" the interface. It may be called
435 // multiple times, even when the hardware is already running. It will be
436 // called whenever something "hardware oriented" changes and should leave
437 // the hardware ready to send/receive packets.
440 quicc_eth_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
442 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
443 volatile struct scc_regs *scc = qi->ctl;
445 // Enable the device!
446 scc->scc_gsmr_l |= QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT;
450 // This function is called for low level "control" operations
453 quicc_eth_control(struct eth_drv_sc *sc, unsigned long key,
454 void *data, int length)
457 case ETH_DRV_SET_MAC_ADDRESS:
461 #ifdef ETH_DRV_GET_IF_STATS
462 case ETH_DRV_GET_IF_STATS:
464 struct ether_drv_stats *p = (struct ether_drv_stats *)data;
465 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
467 strcpy( p->description, "QUICC (MPC8xx) SCC Ethernet" );
468 CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
470 // Really need to determine the following values properly, for
471 // now just assume the link is up, full duplex, unknown speed.
473 p->operational = 3; // LINK UP
478 p->supports_dot3 = false;
480 // Those commented out are not available on this chip.
482 p->tx_good = qi->tx_good ;
483 //p->tx_max_collisions = qi->tx_max_collisions ;
484 p->tx_late_collisions = qi->tx_late_collisions ;
485 p->tx_underrun = qi->tx_underrun ;
486 p->tx_carrier_loss = qi->tx_carrier_loss ;
487 p->tx_deferred = qi->tx_deferred ;
488 //p->tx_sqetesterrors = qi->tx_sqetesterrors ;
489 //p->tx_single_collisions = qi->tx_single_collisions;
490 //p->tx_mult_collisions = qi->tx_mult_collisions ;
491 //p->tx_total_collisions = qi->tx_total_collisions ;
492 p->rx_good = qi->rx_good ;
493 p->rx_crc_errors = qi->rx_crc_errors ;
494 p->rx_align_errors = qi->rx_align_errors ;
495 p->rx_resource_errors = qi->rx_resource_errors ;
496 p->rx_overrun_errors = qi->rx_overrun_errors ;
497 p->rx_collisions = qi->rx_collisions ;
498 p->rx_short_frames = qi->rx_short_frames ;
499 p->rx_too_long_frames = qi->rx_long_frames ;
500 //p->rx_symbol_errors = qi->rx_symbol_errors ;
502 p->interrupts = qi->interrupts ;
503 p->rx_count = qi->rx_count ;
504 p->rx_deliver = qi->rx_deliver ;
505 p->rx_resource = qi->rx_resource ;
506 p->rx_restart = qi->rx_restart ;
507 p->tx_count = qi->tx_count ;
508 p->tx_complete = qi->tx_complete ;
509 p->tx_dropped = qi->tx_dropped ;
512 p->tx_queue_len = CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM;
526 // This function is called to see if another packet can be sent.
527 // It should return the number of packets which can be handled.
528 // Zero should be returned if the interface is busy and can not send any more.
531 quicc_eth_can_send(struct eth_drv_sc *sc)
533 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
535 return (qi->txactive < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM);
539 // This routine is called to send data to the hardware.
541 quicc_eth_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
542 int total_len, unsigned long key)
544 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
545 volatile struct cp_bufdesc *txbd, *txfirst;
547 int i, txindex, cache_state;
552 // Find a free buffer
553 txbd = txfirst = qi->txbd;
554 if ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int )))
556 panic ("No free xmit buffers");
558 diag_printf("QUICC Ethernet: No free xmit buffers\n");
561 // Remember the next buffer to try
562 if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
563 qi->txbd = qi->tbase;
567 txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
568 qi->txkey[txindex] = key;
570 txbd->length = total_len;
572 for (i = 0; i < sg_len; i++) {
573 memcpy((void *)bp, (void *)sg_list[i].buf, sg_list[i].len);
574 bp += sg_list[i].len;
576 // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
577 HAL_DCACHE_IS_ENABLED(cache_state);
579 HAL_DCACHE_FLUSH(txbd->buffer, txbd->length); // Make sure no stale data
581 // Send it on it's way
582 ctrl = txbd->ctrl & ~QUICC_BD_TX_PAD;
583 if (txbd->length < IEEE_8023_MIN_FRAME) {
584 ctrl |= QUICC_BD_TX_PAD;
586 txbd->ctrl = ctrl | QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int |
587 QUICC_BD_TX_LAST | QUICC_BD_TX_TC;
589 set_led(LED_TxACTIVE);
593 // This function is called when a packet has been received. It's job is
594 // to prepare to unload the packet from the hardware. Once the length of
595 // the packet is known, the upper layer of the driver can be told. When
596 // the upper layer is ready to unload the packet, the internal function
597 // 'quicc_eth_recv' will be called to actually fetch it from the hardware.
600 quicc_eth_RxEvent(struct eth_drv_sc *sc)
602 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
603 volatile struct cp_bufdesc *rxbd;
607 while ((rxbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
611 if( rxbd->ctrl & QUICC_BD_RX_MISS )
615 if( rxbd->ctrl & QUICC_BD_RX_LG )
617 qi->rx_long_frames++;
619 if( rxbd->ctrl & QUICC_BD_RX_NO )
621 qi->rx_align_errors++;
623 if( rxbd->ctrl & QUICC_BD_RX_SH )
625 qi->rx_short_frames++;
627 if( rxbd->ctrl & QUICC_BD_RX_CR )
631 if( rxbd->ctrl & QUICC_BD_RX_OV )
633 qi->rx_overrun_errors++;
636 if( rxbd->ctrl & QUICC_BD_RX_CL )
641 if( (rxbd->ctrl & QUICC_BD_RX_ERRORS) == 0 )
645 // OK frame - Prepare for callback
646 qi->rxbd = rxbd; // Save for callback
647 set_led(LED_RxACTIVE);
648 // Remove the CRC from the end
649 (sc->funs->eth_drv->recv)(sc, rxbd->length - 4);
651 clear_led(LED_RxACTIVE);
655 // Clear flags and wrap if needed else step up BD pointer
656 if (rxbd->ctrl & QUICC_BD_CTL_Wrap)
658 rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int | QUICC_BD_CTL_Wrap;
663 rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int;
668 // Remember where we left off
669 qi->rnext = (struct cp_bufdesc *)rxbd;
673 // This function is called as a result of the "eth_drv_recv()" call above.
674 // It's job is to actually fetch data for a packet from the hardware once
675 // memory buffers have been allocated for the packet. Note that the buffers
676 // may come in pieces, using a scatter-gather list. This allows for more
677 // efficient processing in the upper layers of the stack.
680 quicc_eth_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
682 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
685 int sg_list_null_buffer = 0;
687 bp = (unsigned char *)qi->rxbd->buffer;
688 // Note: the MPC8xx does not seem to snoop/invalidate the data cache properly!
689 HAL_DCACHE_IS_ENABLED(cache_state);
691 HAL_DCACHE_INVALIDATE(qi->rxbd->buffer, qi->rxbd->length); // Make sure no stale data
693 for (i = 0; i < sg_len; i++) {
694 if (sg_list[i].buf != 0) {
695 memcpy((void *)sg_list[i].buf, bp, sg_list[i].len);
696 bp += sg_list[i].len;
699 sg_list_null_buffer = 1;
702 // A NULL sg_list buffer usually means no mbufs, so we don't count
703 // it as a delivery, instead we count it as a resource error.
705 if (!sg_list_null_buffer)
713 quicc_eth_command( struct eth_drv_sc *sc, unsigned long cmd)
715 volatile EPPC *eppc = (volatile EPPC *)eppc_base();
717 eppc->cp_cr = QUICC_CPM_SCCx | cmd | QUICC_CPM_CR_BUSY;
718 while (eppc->cp_cr & QUICC_CPM_CR_BUSY )
723 quicc_eth_TxEvent(struct eth_drv_sc *sc, int stat)
725 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
726 volatile struct cp_bufdesc *txbd;
728 bool restart = false;
732 while ((txbd->ctrl & (QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int)) == QUICC_BD_CTL_Int) {
734 txindex = ((unsigned long)txbd - (unsigned long)qi->tbase) / sizeof(*txbd);
738 (sc->funs->eth_drv->tx_done)(sc, qi->txkey[txindex], 0);
739 txbd->ctrl &= ~QUICC_BD_CTL_Int; // Reset int pending bit
741 if (txbd->ctrl & QUICC_BD_TX_LC )
742 qi->tx_late_collisions++, restart = true;
743 if (txbd->ctrl & QUICC_BD_TX_RL )
744 qi->tx_retransmit_error++, restart = true;
745 if (txbd->ctrl & QUICC_BD_TX_UN )
746 qi->tx_underrun++, restart = true;
747 if (txbd->ctrl & QUICC_BD_TX_CSL )
748 qi->tx_carrier_loss++;
749 if (txbd->ctrl & QUICC_BD_TX_HB )
750 qi->tx_heartbeat_loss++;
751 if (txbd->ctrl & QUICC_BD_TX_DEF )
754 if( (txbd->ctrl & QUICC_BD_TX_ERRORS) == 0 )
758 if (txbd->ctrl & QUICC_BD_CTL_Wrap) {
759 txbd->ctrl = QUICC_BD_CTL_Wrap;
768 if (qi->txactive == 0) {
769 clear_led(LED_TxACTIVE);
772 // Remember where we left off
773 qi->tnext = (struct cp_bufdesc *)txbd;
777 quicc_eth_command(sc,QUICC_CPM_CR_RESTART_TX);
784 // Interrupt processing
787 quicc_eth_int(struct eth_drv_sc *sc)
789 struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private;
790 volatile struct scc_regs *scc = qi->ctl;
795 while ( (scce = scc->scc_scce) != 0 )
797 scc->scc_scce = scce;
799 if ( (scce & (QUICC_SCCE_TXE | QUICC_SCCE_TX)) != 0)
801 quicc_eth_TxEvent(sc, scce);
803 if ( (scce & ( QUICC_SCCE_RXF | QUICC_SCCE_RX )) != 0)
805 quicc_eth_RxEvent(sc);
807 if ( (scce & QUICC_SCCE_BSY) != 0)
809 qi->rx_resource_errors++;
811 if ( (scce & QUICC_SCCE_GRC) != 0 )
813 quicc_eth_command(sc, QUICC_CPM_CR_RESTART_TX);
815 quicc_eth_command(sc, QUICC_CPM_CR_HUNT_MODE);
825 quicc_eth_int_vector(struct eth_drv_sc *sc)
827 return (QUICC_ETH_INT);