Index: devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/eth/powerpc/quicc/current/cdl/quicc_eth_drivers.cdl,v retrieving revision 1.3 diff -u -r1.3 quicc_eth_drivers.cdl --- quicc_eth_drivers.cdl 2000/08/25 17:32:45 1.3 +++ quicc_eth_drivers.cdl 2001/10/16 03:22:56 @@ -56,33 +56,98 @@ description "Ethernet driver for PowerPC MPC8xx boards." compile -library=libextras.a if_quicc.c - cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE { - display "Buffer size" - flavor data - default_value 1520 - description " - This option specifies the size of the internal buffers used - for the PowerPC QUICC/ethernet device." - } + cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC1 { + display "PowerPC QUICC/SCC ethernet port 1 driver" + flavor bool + default_value CYGPKG_HAL_POWERPC_MPC860 + description " + This option includes the ethernet driver for the PowerPC QUICC/SCC + port 1." + + cdl_option CYGDAT_DEVS_ETH_POWERPC_QUICC_SCC1_NAME { + display "Interface name for PowerPC QUICC/SCC ethernet port 1" + flavor data + default_value {"\"eth0\""} + description " + This option specifies the ethernet interface name for the + PowerPC QUICC/SCC port 1." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_BUFSIZE { + display "Buffer size" + flavor data + default_value 1520 + description " + This option specifies the size of the internal buffers used + for the PowerPC QUICC/ethernet device." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_TxNUM { + display "Number of output buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of output buffer packets + to be used for the PowerPC QUICC/ethernet device." + } - cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM { - display "Number of output buffers" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of output buffer packets - to be used for the PowerPC QUICC/ethernet device." + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_RxNUM { + display "Number of input buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of input buffer packets + to be used for the PowerPC QUICC/ethernet device." + } } + + cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC2 { + display "PowerPC QUICC/SCC ethernet port 2 driver" + flavor bool + default_value CYGPKG_HAL_POWERPC_MPC850 + description " + This option includes the ethernet driver for the PowerPC QUICC/SCC + port 2." + + cdl_option CYGDAT_DEVS_ETH_POWERPC_QUICC_SCC2_NAME { + display "Interface name for PowerPC QUICC/SCC ethernet port 2" + flavor data + default_value {"\"eth0\""} + description " + This option specifies the ethernet interface name for the + PowerPC QUICC/SCC port 2." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_BUFSIZE { + display "Buffer size" + flavor data + default_value 1520 + description " + This option specifies the size of the internal buffers used + for the PowerPC QUICC/ethernet device." + } + + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_TxNUM { + display "Number of output buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of output buffer packets + to be used for the PowerPC QUICC/ethernet device." + } - cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM { - display "Number of input buffers" - flavor data - legal_values 2 to 16 - default_value 4 - description " - This option specifies the number of input buffer packets - to be used for the PowerPC QUICC/ethernet device." + cdl_option CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_RxNUM { + display "Number of input buffers" + flavor data + legal_values 2 to 16 + default_value 4 + description " + This option specifies the number of input buffer packets + to be used for the PowerPC QUICC/ethernet device." + } } cdl_component CYGPKG_DEVS_ETH_POWERPC_QUICC_OPTIONS { Index: devs/eth/powerpc/quicc/current/src/if_quicc.c =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/eth/powerpc/quicc/current/src/if_quicc.c,v retrieving revision 1.9 diff -u -r1.9 if_quicc.c --- if_quicc.c 2001/09/12 00:59:19 1.9 +++ if_quicc.c 2001/10/16 03:22:56 @@ -74,12 +74,6 @@ #include "quicc_eth.h" -static unsigned char quicc_eth_rxbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM] - [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE]; -static unsigned char quicc_eth_txbufs[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM] - [CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE]; - -static struct quicc_eth_info quicc_eth0_info; static unsigned char _default_enaddr[] = { 0x08, 0x00, 0x3E, 0x28, 0x79, 0xB8}; static unsigned char enaddr[6]; #ifdef CYGPKG_REDBOOT @@ -100,10 +94,30 @@ #ifndef CONFIG_ESA #define CONFIG_ESA 6 #endif + +#ifdef CYGPKG_HAL_POWERPC_MBX +#define VPD_ETHERNET_ADDRESS 0x08 +extern int _mbx_fetch_VPD(int, void *, int); +#endif -ETH_DRV_SC(quicc_eth0_sc, - &quicc_eth0_info, // Driver specific data - "eth0", // Name for this interface +#ifdef CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC1 +static struct quicc_eth_info quicc_scc1_info = { + QUICC_CPM_SCC1, + CYGNUM_HAL_INTERRUPT_CPM_SCC1, +}; + +static unsigned char quicc_scc1_rxbufs + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_RxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_BUFSIZE]; +static unsigned char quicc_scc1_txbufs + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_TxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_BUFSIZE]; +static unsigned long quicc_scc1_txkeys + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_TxNUM]; + +ETH_DRV_SC(quicc_scc1_sc, + &quicc_scc1_info, // Driver specific data + CYGDAT_DEVS_ETH_POWERPC_QUICC_SCC1_NAME, quicc_eth_start, quicc_eth_stop, quicc_eth_control, @@ -117,14 +131,43 @@ NETDEVTAB_ENTRY(quicc_netdev, "quicc_eth", quicc_eth_init, - &quicc_eth0_sc); + &quicc_scc1_sc); +#endif -extern int _mbx_fetch_VPD(int, void *, int); +#ifdef CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC2 +static struct quicc_eth_info quicc_scc2_info = { + QUICC_CPM_SCC2, + CYGNUM_HAL_INTERRUPT_CPM_SCC2, +}; + +static unsigned char quicc_scc2_rxbufs + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_RxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_BUFSIZE]; +static unsigned char quicc_scc2_txbufs + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_TxNUM] + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_BUFSIZE]; +static unsigned long quicc_scc2_txkeys + [CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_TxNUM]; + +ETH_DRV_SC(quicc_scc2_sc, + &quicc_scc2_info, // Driver specific data + CYGDAT_DEVS_ETH_POWERPC_QUICC_SCC2_NAME, + quicc_eth_start, + quicc_eth_stop, + quicc_eth_control, + quicc_eth_can_send, + quicc_eth_send, + quicc_eth_recv, + quicc_eth_deliver, + quicc_eth_int, + quicc_eth_int_vector); -#ifdef CYGPKG_NET -static cyg_interrupt quicc_eth_interrupt; -static cyg_handle_t quicc_eth_interrupt_handle; +NETDEVTAB_ENTRY(quicc_netdev, + "quicc_eth", + quicc_eth_init, + &quicc_scc2_sc); #endif + static void quicc_eth_int(struct eth_drv_sc *data); #ifdef CYGPKG_NET @@ -132,8 +175,10 @@ static int quicc_eth_isr(cyg_vector_t vector, cyg_addrword_t data, HAL_SavedRegisters *regs) { - cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); - cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + struct eth_drv_sc *sc = (struct eth_drv_sc *)data; + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + cyg_drv_interrupt_mask(qi->int_num); + cyg_drv_interrupt_acknowledge(qi->int_num); return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR); // Run the DSR } #endif @@ -142,10 +187,13 @@ static void quicc_eth_deliver(struct eth_drv_sc * sc) { +#ifdef CYGPKG_NET + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; +#endif quicc_eth_int(sc); #ifdef CYGPKG_NET // Allow interrupts to happen again - cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + cyg_drv_interrupt_unmask(qi->int_num); #endif } @@ -164,26 +212,28 @@ unsigned char *RxBUF, *TxBUF, *ep, *ap; volatile struct ethernet_pram *enet_pram; volatile struct scc_regs *scc; - int TxBD, RxBD; + int TxBD, RxBD, txnum, rxnum, bufsize, channel; int cache_state; int i; - bool esa_ok; + bool esa_ok = false; +#ifdef CYGPKG_HAL_POWERPC_MBX // Fetch the board address from the VPD -#define VPD_ETHERNET_ADDRESS 0x08 - if (_mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr)) == 0) { + esa_ok = _mbx_fetch_VPD(VPD_ETHERNET_ADDRESS, enaddr, sizeof(enaddr)) != 0; +#endif #if defined(CYGPKG_REDBOOT) && \ defined(CYGSEM_REDBOOT_FLASH_CONFIG) + if (!esa_ok) esa_ok = flash_get_config("quicc_esa", enaddr, CONFIG_ESA); #else - esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, - "quicc_esa", enaddr, CONFIG_ESA); + if (!esa_ok) + esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET, + "quicc_esa", enaddr, CONFIG_ESA); #endif - if (!esa_ok) { - // Can't figure out ESA - diag_printf("QUICC_ETH - Warning! ESA unknown\n"); - memcpy(&enaddr, &_default_enaddr, sizeof(enaddr)); - } + if (!esa_ok) { + // Can't figure out ESA + diag_printf("QUICC_ETH - Warning! ESA unknown\n"); + memcpy(&enaddr, &_default_enaddr, sizeof(enaddr)); } // Ensure consistent state between cache and what the QUICC sees @@ -193,28 +243,58 @@ #ifdef CYGPKG_NET // Set up to handle interrupts - cyg_drv_interrupt_create(CYGNUM_HAL_INTERRUPT_CPM_SCC1, + cyg_drv_interrupt_create(qi->int_num, CYGARC_SIU_PRIORITY_HIGH, (cyg_addrword_t)sc, // Data item passed to interrupt handler (cyg_ISR_t *)quicc_eth_isr, (cyg_DSR_t *)eth_drv_dsr, - &quicc_eth_interrupt_handle, - &quicc_eth_interrupt); - cyg_drv_interrupt_attach(quicc_eth_interrupt_handle); - cyg_drv_interrupt_acknowledge(CYGNUM_HAL_INTERRUPT_CPM_SCC1); - cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_CPM_SCC1); + &qi->interrupt_handle, + &qi->interrupt); + cyg_drv_interrupt_attach(qi->interrupt_handle); + cyg_drv_interrupt_acknowledge(qi->int_num); + cyg_drv_interrupt_unmask(qi->int_num); #endif - qi->pram = enet_pram = &eppc->pram[0].enet_scc; - qi->ctl = scc = &eppc->scc_regs[0]; // Use SCC1 + switch (qi->channel) { +#ifdef CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC1 + case QUICC_CPM_SCC1: + channel = 0; + TxBD = 0x2C00; // FIXME + txnum = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_TxNUM; + rxnum = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_RxNUM; + bufsize = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC1_BUFSIZE; + RxBUF = &quicc_scc1_rxbufs[0][0]; + TxBUF = &quicc_scc1_txbufs[0][0]; + qi->txkey = &quicc_scc1_txkeys[0]; + break; +#endif +#ifdef CYGPKG_DEVS_ETH_POWERPC_QUICC_SCC2 + case QUICC_CPM_SCC2: + channel = 1; + TxBD = 0x2D00; // FIXME + txnum = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_TxNUM; + rxnum = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_RxNUM; + bufsize = CYGNUM_DEVS_ETH_POWERPC_QUICC_SCC2_BUFSIZE; + RxBUF = &quicc_scc2_rxbufs[0][0]; + TxBUF = &quicc_scc2_txbufs[0][0]; + qi->txkey = &quicc_scc2_txkeys[0]; + break; +#endif + + default: + return false; + } + + qi->pram = enet_pram = &eppc->pram[channel].enet_scc; + qi->ctl = scc = &eppc->scc_regs[channel]; + // Shut down ethernet, in case it is already running scc->scc_gsmr_l &= ~(QUICC_SCC_GSML_ENR | QUICC_SCC_GSML_ENT); memset((void *)enet_pram, 0, sizeof(*enet_pram)); - TxBD = 0x2C00; // FIXME - RxBD = TxBD + CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM * sizeof(struct cp_bufdesc); + RxBD = TxBD + txnum * sizeof(struct cp_bufdesc); txbd = (struct cp_bufdesc *)((char *)eppc + TxBD); rxbd = (struct cp_bufdesc *)((char *)eppc + RxBD); @@ -225,29 +305,27 @@ qi->rxbd = rxbd; qi->rnext = rxbd; - RxBUF = &quicc_eth_rxbufs[0][0]; - TxBUF = &quicc_eth_txbufs[0][0]; - // setup buffer descriptors - for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_RxNUM; i++) { + for (i = 0; i < rxnum; i++) { rxbd->length = 0; rxbd->buffer = RxBUF; rxbd->ctrl = QUICC_BD_CTL_Ready | QUICC_BD_CTL_Int; - RxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + RxBUF += bufsize; rxbd++; } rxbd--; rxbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer - for (i = 0; i < CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM; i++) { + for (i = 0; i < txnum; i++) { txbd->length = 0; txbd->buffer = TxBUF; txbd->ctrl = 0; - TxBUF += CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + TxBUF += bufsize; txbd++; } txbd--; txbd->ctrl |= QUICC_BD_CTL_Wrap; // Last buffer +#ifdef CYGPKG_HAL_POWERPC_MBX // Set up parallel ports for connection to MC68160 ethernet tranceiver eppc->pio_papar |= (QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); eppc->pio_padir &= ~(QUICC_MBX_PA_RXD | QUICC_MBX_PA_TXD); @@ -264,6 +342,7 @@ eppc->si_sicr &= ~QUICC_MBX_SICR_MASK; eppc->si_sicr |= QUICC_MBX_SICR_ENET; eppc->si_sicr &= ~QUICC_MBX_SICR_SCC1_ENABLE; +#endif // Set up DMA mode eppc->dma_sdcr = 0x0001; @@ -277,7 +356,7 @@ enet_pram->tfcr = QUICC_SCC_FCR_BE; // Size of receive buffers - enet_pram->mrblr = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + enet_pram->mrblr = bufsize; // Initialize CRC calculations enet_pram->c_pres = 0xFFFFFFFF; @@ -297,8 +376,8 @@ // Frame sizes enet_pram->mflr = IEEE_8023_MAX_FRAME; enet_pram->minflr = IEEE_8023_MIN_FRAME; - enet_pram->maxd1 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; - enet_pram->maxd2 = CYGNUM_DEVS_ETH_POWERPC_QUICC_BUFSIZE; + enet_pram->maxd1 = bufsize; + enet_pram->maxd2 = bufsize; // Group address hash enet_pram->gaddr1 = 0; @@ -328,7 +407,7 @@ enet_pram->taddr_l = 0; // Initialize the CPM (set up buffer pointers, etc). - eppc->cp_cr = QUICC_CPM_SCC1 | QUICC_CPM_CR_INIT_TXRX | QUICC_CPM_CR_BUSY; + eppc->cp_cr = qi->channel | QUICC_CPM_CR_INIT_TXRX | QUICC_CPM_CR_BUSY; while (eppc->cp_cr & QUICC_CPM_CR_BUSY) ; // Clear any pending interrupt/exceptions @@ -349,12 +428,26 @@ scc->scc_psmr = QUICC_PMSR_ENET_CRC | QUICC_PMSR_SEARCH_AFTER_22 | QUICC_PMSR_RCV_SHORT_FRAMES; +#ifdef CYGPKG_HAL_POWERPC_MBX // Configure board interface *MBX_CTL1 = MBX_CTL1_ETEN | MBX_CTL1_TPEN; // Enable ethernet, TP mode // Enable ethernet interface eppc->pio_pcpar |= QUICC_MBX_PC_Tx_ENABLE; eppc->pio_pcdir &= ~QUICC_MBX_PC_Tx_ENABLE; +#else + if (channel == 0) { + // RTS1 + eppc->pip_pbpar |= 0x1000; + eppc->pip_pbdir |= 0x1000; + eppc->pip_pbodr &= ~0x1000; + } else { + // RTS2 + eppc->pip_pbpar |= 0x2000; + eppc->pip_pbdir |= 0x2000; + eppc->pip_pbodr &= ~0x2000; + } +#endif if (cache_state) HAL_DCACHE_ENABLE(); @@ -588,5 +681,6 @@ static int quicc_eth_int_vector(struct eth_drv_sc *sc) { - return (CYGNUM_HAL_INTERRUPT_CPM_SCC1); + struct quicc_eth_info *qi = (struct quicc_eth_info *)sc->driver_private; + return (qi->int_num); } Index: devs/eth/powerpc/quicc/current/src/quicc_eth.h =================================================================== RCS file: /cvs/ecos/ecos/packages/devs/eth/powerpc/quicc/current/src/quicc_eth.h,v retrieving revision 1.1 diff -u -r1.1 quicc_eth.h --- quicc_eth.h 2000/04/18 21:52:01 1.1 +++ quicc_eth.h 2001/10/16 03:22:56 @@ -57,13 +57,21 @@ #include // QUICC structure definitions struct quicc_eth_info { + CYG_ADDRWORD channel; // Which channel SCC1/SCC2 + CYG_WORD int_num; // Interrupt number + volatile struct ethernet_pram *pram; // Parameter RAM pointer volatile struct scc_regs *ctl; // SCC control registers volatile struct cp_bufdesc *txbd, *rxbd; // Next Tx,Rx descriptor to use struct cp_bufdesc *tbase, *rbase; // First Tx,Rx descriptor struct cp_bufdesc *tnext, *rnext; // Next descriptor to check for interrupt int txsize, rxsize; // Length of individual buffers - unsigned long txkey[CYGNUM_DEVS_ETH_POWERPC_QUICC_TxNUM]; + unsigned long *txkey; + +#ifdef CYGPKG_NET + cyg_interrupt interrupt; + cyg_handle_t interrupt_handle; +#endif }; // SCC registers - ethernet mode