From 031df3914990db0336a0d386fb53558b05de467e Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 23 Apr 2018 09:53:31 +0200 Subject: bsps: Move legacy network drivers to bsps This patch is a part of the BSP source reorganization. Update #3285. --- c/src/lib/libbsp/m68k/mvme167/Makefile.am | 2 +- c/src/lib/libbsp/m68k/mvme167/network/network.c | 3099 ----------------------- c/src/lib/libbsp/m68k/mvme167/network/uti596.h | 369 --- 3 files changed, 1 insertion(+), 3469 deletions(-) delete mode 100644 c/src/lib/libbsp/m68k/mvme167/network/network.c delete mode 100644 c/src/lib/libbsp/m68k/mvme167/network/uti596.h (limited to 'c/src/lib/libbsp/m68k/mvme167') diff --git a/c/src/lib/libbsp/m68k/mvme167/Makefile.am b/c/src/lib/libbsp/m68k/mvme167/Makefile.am index 665b65fcea..01899a9076 100644 --- a/c/src/lib/libbsp/m68k/mvme167/Makefile.am +++ b/c/src/lib/libbsp/m68k/mvme167/Makefile.am @@ -35,7 +35,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/btimer/btimer.c librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/btimer/timerisr.S if HAS_NETWORKING -librtemsbsp_a_SOURCES += network/network.c +librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/mvme167/net/network.c endif librtemsbsp_a_SOURCES += ../../../../../../bsps/m68k/shared/cache/cache.c diff --git a/c/src/lib/libbsp/m68k/mvme167/network/network.c b/c/src/lib/libbsp/m68k/mvme167/network/network.c deleted file mode 100644 index 06bcbfa84a..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/network/network.c +++ /dev/null @@ -1,3099 +0,0 @@ -/* network.c: An 82596 ethernet driver for rtems-bsd. - */ - -#define __INSIDE_RTEMS_BSD_TCPIP_STACK__ -#define KERNEL - -/* - * Selectively define to debug the network driver. If you define any of these - * you must run with polled console I/O. - */ - -/* -#define DBG_ADD_CMD -#define DBG_WAIT -#define DBG_SEND -#define DBG_MEM -#define DBG_SELFTEST_CMD -#define DBG_DUMP_CMD -#define DBG_RESET -#define DBG_ATTACH -#define DBG_START -#define DBG_INIT -#define DBG_STOP -#define DBG_RX -#define DBG_ISR -#define DBG_IOCTL -#define DBG_STAT -#define DBG_PACKETS -*/ - -#define IGNORE_SPURIOUS_IRQ -#define IGNORE_NO_RFA -#define IGNORE_MULTIPLE_RF - -/* - * Default number of buffer descriptors and buffer sizes. - */ -#define RX_BUF_COUNT 15 -#define TX_BUF_COUNT 4 -#define TX_BD_PER_BUF 4 - -#define RBUF_SIZE 1520 - -#define UTI_596_ETH_MIN_SIZE 60 - -#define INET_ADDR_MAX_BUF_SIZE (sizeof "255.255.255.255") - -/* - * RTEMS events - */ -#define INTERRUPT_EVENT RTEMS_EVENT_1 -#define START_TRANSMIT_EVENT RTEMS_EVENT_2 -#define NIC_RESET_EVENT RTEMS_EVENT_3 - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uti596.h" - -/* If we are running interrupt driven I/O no debug output is printed */ -#if CD2401_IO_MODE == 0 - #define printk(arglist) do { printk arglist; printk("\r"); } while (0); -#else - #define printk(arglist) -#endif - -#define UTI_596_ASSERT( condition, str ) if (!( condition ) ) { printk((str)) } - -/* Types of PORT commands */ -#define UTI596_RESET_PORT_FUNCTION 0 -#define UTI596_SELFTEST_PORT_FUNCTION 1 -#define UTI596_SCP_PORT_FUNCTION 2 -#define UTI596_DUMP_PORT_FUNCTION 3 - -/* Types of waiting for commands */ -#define UTI596_NO_WAIT 0 -#define UTI596_WAIT_FOR_CU_ACCEPT 1 -#define UTI596_WAIT_FOR_INITIALIZATION 2 -#define UTI596_WAIT_FOR_STAT_C 3 - -/* Device dependent data structure */ -static uti596_softc_ uti596_softc; - -/* Globals */ -int count_rx = 0; -static int scbStatus; -static rtems_status_code sc; -static i596_cmd *pIsrCmd; -static i596_rfd *pIsrRfd; - -/* - * Initial 596 configuration - */ -char uti596initSetup[] = { - 0x0E, /* Byte 0: length, prefetch off ( no RBD's ) */ - 0xC8, /* Byte 1: fifo to 8, monitor off */ - 0x40, /* Byte 2: don't save bad frames ( was save= 80, use intel's 40 )*/ - 0x2E, /* Byte 3: No source address insertion, 8 byte preamble */ - 0x00, /* Byte 4: priority and backoff defaults */ - 0x60, /* Byte 5: interframe spacing */ - 0x00, /* Byte 6: slot time LSB */ - 0xf2, /* Byte 7: slot time and retries */ - 0x0C, /* Byte 8: not promisc, enable bcast, tx no crs, crc inserted 32bit, 802.3 framing */ - 0x08, /* Byte 9: collision detect */ - 0x40, /* Byte 10: minimum frame length */ - 0xfb, /* Byte 11: tried C8 same as byte 1 in bits 6-7, else ignored*/ - 0x00, /* Byte 12: disable full duplex */ - 0x3f /* Byte 13: no multi IA, backoff enabled */ -}; - -/* Local Routines */ - -static unsigned long word_swap ( unsigned long ); -static void * malloc_16byte_aligned ( void **, void ** adjusted_pointer, size_t ); -RTEMS_INLINE_ROUTINE void uti596_writePortFunction ( volatile void *, unsigned long ); -/* currently unused by RTEMS */ -#if 0 -RTEMS_INLINE_ROUTINE void uti596_portReset( void ); -static unsigned long uti596_portSelfTest( i596_selftest * ); -static int uti596_portDump ( i596_dump_result * ); -static void uti596_CU_dump ( i596_dump_result * ); -#endif -static int uti596_wait ( uti596_softc_ *, uint8_t); -static int uti596_issueCA ( uti596_softc_ *, uint8_t); -static void uti596_addCmd ( i596_cmd * ); -static void uti596_addPolledCmd ( i596_cmd * ); -static int uti596_setScpAndScb ( uti596_softc_ * ); -static int uti596_diagnose ( void ); -static int uti596_configure ( uti596_softc_ * ); -static int uti596_IAsetup ( uti596_softc_ * ); -static int uti596_initTBD ( uti596_softc_ * ); -static int uti596_initRFA ( int ); -static void uti596_initMem ( uti596_softc_ * ); -static void uti596_initialize ( uti596_softc_ * ); -static void uti596_initialize_hardware ( uti596_softc_ * ); -static void uti596_reset_hardware ( uti596_softc_ *); -static void uti596_reset ( void ); -static void uti596_clearListStatus ( i596_rfd * ); -static i596_rfd * uti596_dequeue ( i596_rfd ** ); -static void uti596_append ( i596_rfd ** , i596_rfd * ); -static void uti596_supplyFD ( i596_rfd * ); -static void send_packet ( struct ifnet *, struct mbuf * ); - -/* Required RTEMS network driver functions and tasks (plus reset daemon) */ - -static void uti596_start ( struct ifnet * ); -void uti596_init ( void * ); -void uti596_stop ( uti596_softc_ * ); -void uti596_txDaemon ( void * ); -void uti596_rxDaemon ( void * ); -void uti596_resetDaemon( void * ); -rtems_isr uti596_DynamicInterruptHandler ( rtems_vector_number ); -static int uti596_ioctl ( struct ifnet *, u_long, caddr_t ); -void uti596_stats ( uti596_softc_ * ); - -#ifdef DBG_PACKETS -static void dumpQ( void ); -static void show_buffers( void ); -static void show_queues( void ); -static void print_eth ( unsigned char * ); -static void print_hdr ( unsigned char * ); -static void print_pkt ( unsigned char * ); -static void print_echo ( unsigned char * ); -#endif - -/* - * word_swap - * - * Return a 32 bit value, swapping the upper and lower words first. - * - * Input parameters: - * val - 32 bit value to swap - * - * Output parameters: NONE - * - * Return value: - * Input value with upper and lower 16-bit words swapped - */ -static unsigned long word_swap( - unsigned long val -) -{ - return (((val >> 16)&(0x0000ffff)) | ((val << 16)&(0xffff0000))); -} - -/* - * malloc_16byte_aligned - * - * Allocate a block of a least nbytes aligned on a 16-byte boundary. - * Clients are responsible to store both the real address and the adjusted - * address. The real address must be used to free the block. - * - * Input parameters: - * real_pointer - pointer to a void * pointer in which to store the starting - * address of the block. Required for free. - * adjusted_pointer - pointer to a void * pointer in which to store the - * starting address of the block rounded up to the next - * 16 byte boundary. - * nbytes - number of bytes of storage requested - * - * Output parameters: - * real_pointer - starting address of the block. - * adjusted_pointer - starting address of the block rounded up to the next - * 16 byte boundary. - * - * Return value: - * starting address of the block rounded up to the next 16 byte boundary. - * NULL if no storage was allocated. - */ -static void * malloc_16byte_aligned( - void ** real_pointer, - void ** adjusted_pointer, - size_t nbytes -) -{ - *real_pointer = malloc( nbytes + 0xF, 0, M_NOWAIT ); - *adjusted_pointer = (void *)(((unsigned long)*real_pointer + 0xF ) & 0xFFFFFFF0 ); - return *adjusted_pointer; -} - -/* - * uti596_scp_alloc - * - * Allocate a new scp, possibly freeing a previously allocated one. - * - * Input parameters: - * sc - pointer to the global uti596_softc in which to store pointers - * to the newly allocated block. - * - * Output parameters: NONE - * - * Return value: - * Pointer to the newly allocated, 16-byte aligned scp. - */ -static i596_scp * uti596_scp_alloc( - uti596_softc_ * sc -) -{ - if( sc->base_scp != NULL ) { - #ifdef DBG_MEM - printk(("uti596_scp_alloc: Already have an SCP at %p\n", sc->base_scp)) - #endif - return sc->pScp; - } - - /* allocate enough memory for the Scp block to be aligned on 16 byte boundary */ - malloc_16byte_aligned( (void *)&(sc->base_scp), (void *)&(sc->pScp), sizeof( i596_scp ) ); - - #ifdef DBG_MEM - printk(("uti596_scp_alloc: Scp base address is %p\n", sc->base_scp)) - printk(("uti596_scp_alloc: Scp aligned address is : %p\n",sc->pScp)) - #endif - - return sc->pScp; -} - -/* - * uti596_writePortFunction - * - * Write the command into the PORT. - * - * Input parameters: - * addr - 16-byte aligned address to write into the PORT. - * cmd - 4-bit cmd to write into the PORT - * - * Output parameters: NONE - * - * Return value: NONE - * - * The Motorola manual swapped the high and low registers. - */ -RTEMS_INLINE_ROUTINE void uti596_writePortFunction( - volatile void * addr, - unsigned long cmd -) -{ - i82596->port_lower = (unsigned short)(((unsigned long)addr & 0xFFF0) | cmd); - i82596->port_upper = (unsigned short)(((unsigned long)addr >> 16 ) & 0xFFFF); -} - -/* - * uti596_portReset - * - * Issue a port Reset to the uti596 - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return value: NONE - */ -RTEMS_INLINE_ROUTINE void uti596_portReset( void ) -{ - uti596_writePortFunction( NULL, UTI596_RESET_PORT_FUNCTION ); -} - -/* currently unused by RTEMS */ -#if 0 -/* - * uti596_portSelfTest - * - * Perform a self-test. Wait for up to 1 second for the test to - * complete. Normally, the test should complete in a very short time, - * so busy waiting is not an issue. - * - * Input parameters: - * stp - pointer to a 16-byte aligned uti596_selftest structure. - * - * Output parameters: NONE - * - * Return value: - * 32-bit result field if successful, -1 otherwise. - */ -static unsigned long uti596_portSelfTest( - i596_selftest * stp -) -{ - rtems_interval ticks_per_second, start_ticks, end_ticks; - - stp->results = 0xFFFFFFFF; - uti596_writePortFunction( stp, UTI596_SELFTEST_PORT_FUNCTION ); - - ticks_per_second = rtems_clock_get_ticks_per_second(); - - start_ticks = rtems_clock_get_ticks_since_boot(); - end_ticks = start_ticks + ticks_per_second; - - do { - if( stp->results != 0xFFFFFFFF ) - break; - else - start_ticks = rtems_clock_get_ticks_since_boot(); - } while (start_ticks <= end_ticks); - - if (start_ticks > end_ticks ) { - #ifdef DBG_SELFTEST_CMD - printk(("uti596_selftest: Timed out\n" )) - #endif - return -1; - } - else { - #ifdef DBG_SELFTEST_CMD - printk(("uti596_selftest: Succeeded with signature = 0x%08x, result = 0x%08x\n", - stp->signature, - stp->results)) - #endif - return stp->results; - } -} -#endif - -/* currently unused by RTEMS */ -#if 0 -/* - * uti596_portDump - * - * Perform a dump Wait for up to 1 second for the test to - * complete. Normally, the test should complete in a very short time, - * so busy waiting is not an issue. - * - * Input parameters: - * dp - pointer to a 16-byte aligned uti596_dump structure. - * - * Output parameters: NONE - * - * Return value: - * 16-bit dump_status field if successful, -1 otherwise. - */ -static int uti596_portDump( - i596_dump_result * dp -) -{ - rtems_interval ticks_per_second, start_ticks, end_ticks; - - dp->dump_status = 0; - uti596_writePortFunction( dp, UTI596_DUMP_PORT_FUNCTION ); - - ticks_per_second = rtems_clock_get_ticks_per_second(); - start_ticks = rtems_clock_get_ticks_since_boot(); - end_ticks = start_ticks + ticks_per_second; - - do { - if( dp->dump_status != 0xA006 ) - break; - else - start_ticks = rtems_clock_get_ticks_since_boot(); - } while (start_ticks <= end_ticks); - - if (start_ticks > end_ticks ) { - #ifdef DBG_DUMP_CMD - printk(("uti596_dump: Timed out with dump at 0x%08x\n", (unsigned long)dp )) - #endif - return -1; - } - else { - #ifdef DBG_DUMP_CMD - printk(("uti596_dump: Succeeded with dump at = 0x%08x\n", (unsigned long)dp )) - #endif - return dp->dump_status; - } -} -#endif - -/* - * uti596_wait - * - * Wait for a certain condition. - * - * Input parameters: - * sc - pointer to the uti596_softc struct - * wait_type - UTI596_NO_WAIT - * UTI596_WAIT - * UTI596_WAIT_FOR_CU_ACCEPT - * UTI596_WAIT_FOR_INITIALIZATION - * UTI596_WAIT_FOR_STAT_C - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise. - */ -static int uti596_wait( - uti596_softc_ *sc, - uint8_t waitType -) -{ - rtems_interval ticks_per_second, start_ticks, end_ticks; - - ticks_per_second = rtems_clock_get_ticks_per_second(); - start_ticks = rtems_clock_get_ticks_since_boot(); - end_ticks = start_ticks + ticks_per_second; - - switch( waitType ) { - - case UTI596_NO_WAIT: - return 0; - - case UTI596_WAIT_FOR_CU_ACCEPT: - do { - if (sc->scb.command == 0) - break; - else - - start_ticks = rtems_clock_get_ticks_since_boot(); - - } while (start_ticks <= end_ticks); - - if( (sc->scb.command != 0) || (start_ticks > end_ticks) ) { - printf("i82596 timed out with status %x, cmd %x.\n", - sc->scb.status, sc->scb.command); - return -1; - } - else - return 0; - - case UTI596_WAIT_FOR_INITIALIZATION: - do { - if( !sc->iscp.busy ) - break; - else - start_ticks = rtems_clock_get_ticks_since_boot(); - } while (start_ticks <= end_ticks); - - if (start_ticks > end_ticks ) { - #ifdef DBG_WAIT - printk(("uti596_setScpAndScb: Timed out\n" )) - #endif - return -1; - } - else { - #ifdef DBG_WAIT - printk(("uti596_setScpAndScb: Succeeded\n" )) - #endif - return 0; - } - - case UTI596_WAIT_FOR_STAT_C: - do { - if( *sc->pCurrent_command_status & STAT_C ) - break; - else - start_ticks = rtems_clock_get_ticks_since_boot(); - } while (start_ticks <= end_ticks); - - if (start_ticks > end_ticks ) { - #ifdef DBG_WAIT - printk(("uti596_initMem: timed out - STAT_C not obtained\n" )) - #endif - return -1; - } - else { - #ifdef DBG_WAIT - printk(("uti596_initMem: STAT_C obtained OK\n" )) - #endif - return 0; - } - } - return -1; -} - -/* - * uti596_issueCA - * - * Issue a Channel Attention command. Possibly wait for the - * command to start or complete. - * - * Input parameters: - * sc - pointer to the uti596_softc - * wait_type - UTI596_NO_WAIT - * UTI596_WAIT_BEGIN - * UTI596_WAIT_COMPLETION - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise. - */ -static int uti596_issueCA( - uti596_softc_ *sc, - uint8_t waitType -) -{ - /* Issue Channel Attention */ - i82596->chan_attn = 0x00000000; - - return (uti596_wait ( sc, waitType )); -} - -/* - * uti596_addCmd - * - * Add a uti596_cmd onto the end of the CBL command chain, - * or to the start if the chain is empty. - * - * Input parameters: - * pCmd - a pointer to the command to be added. - * - * Output parameters: NONE - * - * Return value: NONE - */ -static void uti596_addCmd( - i596_cmd *pCmd -) -{ - ISR_Level level; - - #ifdef DBG_ADD_CMD - printk(("uti596_addCmd: Adding command 0x%x\n", pCmd -> command )) - #endif - - /* Mark command as last in list, to return an interrupt */ - pCmd->command |= (CMD_EOL | CMD_INTR ); - pCmd->status = 0; - pCmd->next = I596_NULL; - - _ISR_Local_disable(level); - - if (uti596_softc.pCmdHead == I596_NULL) { - uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd; - uti596_softc.scb.cmd_pointer = word_swap ((unsigned long)pCmd); - - uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); - uti596_softc.scb.command = CUC_START; - uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT ); - - _ISR_Local_enable(level); - } - else { - uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd); - uti596_softc.pCmdTail = pCmd; - _ISR_Local_enable(level); - } - - #ifdef DBG_ADD_CMD - printk(("uti596_addCmd: Scb status & command 0x%x 0x%x\n", - uti596_softc.scb.status, - uti596_softc.scb.command )) - #endif -} - -/* - * uti596_addPolledCmd - * - * Add a single uti596_cmd to the end of the command block list - * for processing, send a CU_START and wait for its acceptance - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_addPolledCmd( - i596_cmd *pCmd -) -{ - - #ifdef DBG_ADD_CMD - printk(("uti596_addPolledCmd: Adding command 0x%x\n", pCmd -> command )) - #endif - - pCmd->status = 0; - pCmd->command |= CMD_EOL ; /* only command in list*/ - pCmd->next = I596_NULL; - - uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); - - uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd; - uti596_softc.scb.cmd_pointer = word_swap((unsigned long)pCmd); - uti596_softc.scb.command = CUC_START; - uti596_issueCA ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); - - uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL; - uti596_softc.scb.cmd_pointer = (unsigned long) I596_NULL; - - #ifdef DBG_ADD_CMD - printk(("uti596_addPolledCmd: Scb status & command 0x%x 0x%x\n", - uti596_softc.scb.status, - uti596_softc.scb.command )) - #endif -} - -/* currently unused by RTEMS */ -#if 0 -/* - * uti596_CU_dump - * - * Dump the LANC 82596 registers - * The outcome is the same as the portDump() but executed - * via the CU instead of via a PORT access. - * - * Input parameters: - * drp - a pointer to a i596_dump_result structure. - * - * Output parameters: NONE - * - * Return value: NONE - */ -static void uti596_CU_dump ( i596_dump_result * drp) -{ - i596_dump dumpCmd; - - dumpCmd.cmd.command = CmdDump; - dumpCmd.cmd.next = I596_NULL; - dumpCmd.pData = (char *) drp; - uti596_softc.cmdOk = 0; - uti596_addCmd ( (i596_cmd *) &dumpCmd ); - -} -#endif - -#if defined(DBG_STAT) || !defined(IGNORE_NO_RFA) -/* - * uti596_dump_scb - * - * Dump the system control block - * This function expands to nothing when using interrupt driven I/O - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return value: NONE - */ -static void uti596_dump_scb ( void ) -{ - printk(("status 0x%x\n",uti596_softc.scb.status)) - printk(("command 0x%x\n",uti596_softc.scb.command)) - printk(("cmd 0x%x\n",(int)uti596_softc.scb.pCmd)) - printk(("rfd 0x%x\n",(int)uti596_softc.scb.pRfd)) - printk(("crc_err 0x%" PRIx32 "\n",uti596_softc.scb.crc_err)) - printk(("align_err 0x%" PRIx32 "\n",uti596_softc.scb.align_err)) - printk(("resource_err 0x%" PRIx32 "\n",uti596_softc.scb.resource_err )) - printk(("over_err 0x%" PRIx32 "\n",uti596_softc.scb.over_err)) - printk(("rcvdt_err 0x%" PRIx32 "\n",uti596_softc.scb.rcvdt_err)) - printk(("short_err 0x%" PRIx32 "\n",uti596_softc.scb.short_err)) - printk(("t_on 0x%x\n",uti596_softc.scb.t_on)) - printk(("t_off 0x%x\n",uti596_softc.scb.t_off)) -} -#endif - -/* - * uti596_setScpAndScb - * - * Issue the first channel attention after reset and wait for the busy - * field to clear in the iscp. - * - * Input parameters: - * sc - pointer to the global uti596_softc - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise. - */ -static int uti596_setScpAndScb( - uti596_softc_ * sc -) -{ - /* set the busy flag in the iscp */ - sc->iscp.busy = 1; - - /* the command block list (CBL) is empty */ - sc->scb.command = 0; - sc->scb.cmd_pointer = (unsigned long) I596_NULL; /* all 1's */ - sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */ - - uti596_writePortFunction( sc->pScp, UTI596_SCP_PORT_FUNCTION ); - - /* Issue CA: pass the scb address to the 596 */ - return ( uti596_issueCA ( sc, UTI596_WAIT_FOR_INITIALIZATION ) ); -} - -/* - * uti596_diagnose - * - * Send a diagnose command to the CU - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise - */ -static int uti596_diagnose( void ) -{ - i596_cmd diagnose; - - diagnose.command = CmdDiagnose; - diagnose.status = 0; - uti596_softc.pCurrent_command_status = (unsigned short *)&diagnose.status; - uti596_addPolledCmd(&diagnose); - return (uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_STAT_C )); - - #ifdef DBG_INIT - printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status)) - #endif -} - -/* - * uti596_configure - * - * Send the CU a configure command with the desired - * configuration structure - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise - */ -static int uti596_configure ( - uti596_softc_ * sc -) -{ - sc->set_conf.cmd.command = CmdConfigure; - memcpy ( (void *)sc->set_conf.data, uti596initSetup, 14); - uti596_addPolledCmd( (i596_cmd *) &sc->set_conf); - - /* Poll for successful command completion */ - sc->pCurrent_command_status = (unsigned short *)&(sc->set_conf.cmd.status); - return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) ); -} - -/* - * uti596_IAsetup - * - * Send the CU an Individual Address setup command with - * the ethernet hardware address - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise - */ -static int uti596_IAsetup ( - uti596_softc_ * sc -) -{ - int i; - - sc->set_add.cmd.command = CmdSASetup; - for ( i=0; i<6; i++) { - sc->set_add.data[i]=sc->arpcom.ac_enaddr[i]; - } - sc->cmdOk = 0; - uti596_addPolledCmd((i596_cmd *)&sc->set_add); - - /* Poll for successful command completion */ - sc->pCurrent_command_status = (unsigned short *)&(sc->set_add.cmd.status); - return ( uti596_wait ( sc, UTI596_WAIT_FOR_STAT_C ) ); -} - -/* - * uti596_initTBD - * - * Initialize transmit buffer descriptors - * dynamically allocate mem for the number of tbd's required - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: - * 0 if successful, -1 otherwise - */ -static int uti596_initTBD ( uti596_softc_ * sc ) -{ - int i; - i596_tbd *pTbd, *pPrev; - - /* Set up a transmit command with a tbd ready */ - sc->pLastUnkRFD = I596_NULL; - sc->pTxCmd = (i596_tx *) calloc (1,sizeof (struct i596_tx) ); - sc->pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) ); - if ((sc->pTxCmd == NULL) || (sc->pTbd == NULL)) { - return -1; - } - sc->pTxCmd->pTbd = (i596_tbd *) word_swap ((unsigned long) sc->pTbd); - sc->pTxCmd->cmd.command = CMD_FLEX|CmdTx; - sc->pTxCmd->pad = 0; - sc->pTxCmd->count = 0; /* all bytes are in list of TBD's */ - - pPrev = pTbd = sc->pTbd; - - /* Allocate a linked list of tbd's each with it's 'next' field written - * with upper and lower words swapped (for big endian), and mark the end. - */ - for ( i=0; itxBdCount; i++) { - if ( (pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) )) == NULL ) { - return -1; - } - pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd); - pPrev = pTbd; - } - pTbd->next = I596_NULL; - return 0; -} - -/* - * uti596_initRFA - * - * Initialize the Receive Frame Area - * dynamically allocate mem for the number of rfd's required - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: - * # of buffer descriptors successfully allocated - */ -static int uti596_initRFA( int num ) -{ - i596_rfd *pRfd; - int i = 0; - - #ifdef DBG_INIT - printk(("uti596_initRFA: begins\n Requested frame descriptors ... %d.\n", num)) - #endif - - /* - * Create the first RFD in the RFA - */ - pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd)); - if ( !pRfd ) { - printk(("Can't allocate first buffer.\n")) - return 0; - } - else { - uti596_softc.countRFD = 1; - uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd; - } - - /* Create remaining RFDs */ - for (i = 1; i < num; i++) { - pRfd = (i596_rfd *) calloc (1, sizeof (struct i596_rfd) ); - if ( pRfd != NULL ) { - uti596_softc.countRFD++; /* update count */ - uti596_softc.pEndRFA->next = - (i596_rfd *) word_swap ((unsigned long) pRfd); /* write the link */ - uti596_softc.pEndRFA = pRfd; /* move the end */ - } - else { - printk(("Can't allocate all buffers: only %d allocated\n", i)) - break; - } - } /* end for */ - - uti596_softc.pEndRFA->next = I596_NULL; - UTI_596_ASSERT(uti596_softc.countRFD == num,"INIT:WRONG RFD COUNT\n" ) - - #ifdef DBG_INIT - printk (("uti596_initRFA: Head of RFA is buffer %p \n\ - uti596_initRFA: End of RFA is buffer %p \n", - uti596_softc.pBeginRFA, uti596_softc.pEndRFA )) - #endif - - /* Walk and initialize the RFD's */ - for ( pRfd = uti596_softc.pBeginRFA; - pRfd != I596_NULL; - pRfd = (i596_rfd *) word_swap ((unsigned long)pRfd->next) ) - { - pRfd->cmd = 0x0000; - pRfd->stat = 0x0000; - pRfd->pRbd = I596_NULL; - pRfd->count = 0; /* number of bytes in buffer: usually less than size */ - pRfd->size = 1532; /* was 1532; buffer size ( All RBD ) */ - } /* end for */ - - /* mark the last RFD as the last one in the RDL */ - uti596_softc.pEndRFA -> cmd = CMD_EOL; - uti596_softc.pSavedRfdQueue = - uti596_softc.pEndSavedQueue = I596_NULL; /* initially empty */ - - uti596_softc.savedCount = 0; - uti596_softc.nop.cmd.command = CmdNOp; /* initialize the nop command */ - - return (i); /* the number of allocated buffers */ -} - -/* - * uti596_initMem - * - * Initialize the 82596 memory structures for Tx and Rx - * dynamically allocate mem for the number of tbd's required - * - * Input parameters: - * sc - a pointer to the uti596_softc struct - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_initMem( - uti596_softc_ * sc -) -{ - int i; - - #ifdef DBG_INIT - printk(("uti596_initMem: begins\n")) - #endif - - sc->resetDone = 0; - - /* - * Set up receive frame area (RFA) - */ - i = uti596_initRFA( sc->rxBdCount ); - if ( i < sc->rxBdCount ) { - printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i)) - } - - /* - * Write the SCB with a pointer to the receive frame area - * and keep a pointer for our use. - */ - sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA); - sc->scb.pRfd = sc->pBeginRFA; - - /* - * Diagnose the health of the board - */ - uti596_diagnose(); - - /* - * Configure the 82596 - */ - uti596_configure( sc ); - - /* - * Set up the Individual (hardware) Address - */ - uti596_IAsetup ( sc ); - - /* - * Initialize the transmit buffer descriptors - */ - uti596_initTBD( sc ); - - /* Padding used to fill short tx frames */ - memset ( RTEMS_DEVOLATILE( char *, sc->zeroes ), 0, 64); - - /* now need ISR */ - sc->resetDone = 1; -} - -/* - * uti596_initialize - * - * Reset the 82596 and initialize it with a new SCP. - * - * Input parameters: - * sc - pointer to the uti596_softc - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_initialize( - uti596_softc_ *sc -) -{ - /* Reset the device. Stops it from doing whatever it might be doing. */ - uti596_portReset(); - - /* Get a new System Configuration Pointer */ - uti596_scp_alloc( sc ); - - /* write the SYSBUS: interrupt pin active high, LOCK disabled, - * internal triggering, linear mode - */ - sc->pScp->sysbus = 0x44; - - /* provide the iscp to the scp, keep a pointer for our use */ - sc->pScp->iscp_pointer = word_swap((unsigned long)&sc->iscp); - sc->pScp->iscp = &sc->iscp; - - /* provide the scb to the iscp, keep a pointer for our use */ - sc->iscp.scb_pointer = word_swap((unsigned long)&sc->scb); - sc->iscp.scb = &sc->scb; - - #ifdef DBG_INIT - printk(("uti596_initialize: Starting i82596.\n")) - #endif - - /* Set up the 82596 */ - uti596_setScpAndScb( sc ); - - /* clear the scb command word */ - sc->scb.command = 0; -} - -/* - * uti596_initialize_hardware - * - * Reset the 82596 and initialize it with a new SCP. Enable bus snooping. - * Install the interrupt handlers. - * - * Input parameters: - * sc - pointer to the uti596_softc - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_initialize_hardware( - uti596_softc_ *sc -) -{ - printk(("uti596_initialize_hardware: begins\n")) - - /* Get the PCCChip2 to assert bus snooping signals on behalf of the i82596 */ - pccchip2->LANC_berr_ctl = 0x40; - - uti596_initialize( sc ); - - /* - * Configure interrupt control in PCCchip2 - */ - pccchip2->LANC_error = 0xff; /* clear status register */ - pccchip2->LANC_int_ctl = 0x5d; /* lvl 5, enabled, edge-sensitive rising */ - pccchip2->LANC_berr_ctl = 0x5d; /* bus error: lvl 5, enabled, snoop control - * will supply dirty data and leave dirty data - * on read access and sink any data on write - */ - /* - * Install the interrupt handler - * calls rtems_interrupt_catch - */ - set_vector( uti596_DynamicInterruptHandler, 0x57, 1 ); - - /* Initialize the 82596 memory */ - uti596_initMem(sc); - - #ifdef DBG_INIT - printk(("uti596_initialize_hardware: After attach, status of board = 0x%x\n", sc->scb.status )) - #endif -} - -/* - * uti596_reset_hardware - * - * Reset the 82596 and initialize it with an SCP. - * - * Input parameters: - * sc - pointer to the uti596_softc - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_reset_hardware( - uti596_softc_ *sc -) -{ - rtems_status_code status_code; - i596_cmd *pCmd; - - pCmd = sc->pCmdHead; /* This is a tx command for sure (99.99999%) */ - - /* the command block list (CBL) is empty */ - sc->scb.cmd_pointer = (unsigned long) I596_NULL; /* all 1's */ - sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */ - - #ifdef DBG_RESET - printk(("uti596_reset_hardware\n")) - #endif - uti596_initialize( sc ); - - /* - * Wake the transmitter if needed. - */ - if ( sc->txDaemonTid && pCmd != I596_NULL ) { - printk(("****RESET: wakes transmitter!\n")) - status_code = rtems_bsdnet_event_send (sc->txDaemonTid, - INTERRUPT_EVENT); - - if ( status_code != RTEMS_SUCCESSFUL ) { - printk(("****ERROR:Could NOT send event to tid 0x%" PRIx32 " : %s\n", - sc->txDaemonTid, rtems_status_text (status_code) )) - } - } - - #ifdef DBG_RESET - printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status )) - #endif -} - -/* - * uti596_clearListStatus - * - * Clear the stat fields for all RFDs - * - * Input parameters: - * pRfd - a pointer to the head of the RFA - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_clearListStatus( - i596_rfd *pRfd -) -{ - while ( pRfd != I596_NULL ) { - pRfd -> stat = 0; - pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next); - } -} - -/* - * uti596_reset - * - * Reset the 82596 and reconfigure - * - * Input parameters: NONE - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_reset( void ) -{ - uti596_softc_ *sc = &uti596_softc; - - #ifdef DBG_RESET - printk(("uti596_reset: begin\n")) - #endif - - /* Wait for the CU to be available, then - * reset the ethernet hardware. Must re-config. - */ - sc->resetDone = 0; - uti596_wait ( sc, UTI596_WAIT_FOR_CU_ACCEPT ); - uti596_reset_hardware ( &uti596_softc ); - - #ifdef DBG_RESET - uti596_diagnose(); - #endif - - /* - * Configure the 82596 - */ - uti596_configure( sc ); - - /* - * Set up the Individual (hardware) Address - */ - uti596_IAsetup ( sc ); - - sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL; - - /* restore the RFA */ - - if ( sc->pLastUnkRFD != I596_NULL ) { - sc-> pEndRFA = sc->pLastUnkRFD; /* The end position can be updated */ - sc-> pLastUnkRFD = I596_NULL; - } - - sc->pEndRFA->next = (i596_rfd*)word_swap((uint32_t)sc->pSavedRfdQueue); - if ( sc->pSavedRfdQueue != I596_NULL ) { - sc->pEndRFA = sc->pEndSavedQueue; - sc->pSavedRfdQueue = sc->pEndSavedQueue = I596_NULL; - sc -> countRFD = sc->rxBdCount ; - } - - /* Re-address the head of the RFA in the SCB */ - sc->scb.pRfd = sc->pBeginRFA; - sc->scb.rfd_pointer = word_swap((unsigned long)sc->pBeginRFA); - - /* Clear the status of all RFDs */ - uti596_clearListStatus( sc->pBeginRFA ); - - printk(("uti596_reset: Starting NIC\n")) - - /* Start the receiver */ - sc->scb.command = RX_START; - sc->started = 1; /* assume that the start is accepted */ - sc->resetDone = 1; - uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT ); - - UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n") - - #ifdef DBG_RESET - printk(("uti596_reset: completed\n")) - #endif -} - -/* - * uti596_dequeue - * - * Remove an RFD from the received fram queue - * - * Input parameters: - * ppQ - a pointer to a i596_rfd pointer - * - * Output parameters: NONE - * - * Return value: - * pRfd - a pointer to the dequeued RFD - */ -i596_rfd * uti596_dequeue( - i596_rfd ** ppQ -) -{ - ISR_Level level; - i596_rfd * pRfd; - - _ISR_Local_disable(level); - - /* invalid address, or empty queue or emptied queue */ - if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) { - _ISR_Local_enable(level); - return I596_NULL; - } - - /* - * Point to the dequeued buffer, then - * adjust the queue pointer and detach the buffer - */ - pRfd = *ppQ; - *ppQ = (i596_rfd *) word_swap ((unsigned long) pRfd->next); - pRfd->next = I596_NULL; /* unlink the rfd being returned */ - - _ISR_Local_enable(level); - return pRfd; -} - -/* - * uti596_append - * - * Remove an RFD buffer from the RFA and tack it on to - * the received frame queue for processing. - * - * Input parameters: - * ppQ - a pointer to the queue pointer - * pRfd - a pointer to the buffer to be returned - * - * Output parameters: NONE - * - * Return value: NONE - */ - -void uti596_append( - i596_rfd ** ppQ, - i596_rfd * pRfd -) -{ - - i596_rfd *p; - - if ( pRfd != NULL && pRfd != I596_NULL) { - pRfd -> next = I596_NULL; - pRfd -> cmd |= CMD_EOL; /* set EL bit */ - - if ( *ppQ == NULL || *ppQ == I596_NULL ) { - /* empty list */ - *ppQ = pRfd; - } - else { - /* walk to the end of the list */ - for ( p=*ppQ; - p->next != I596_NULL; - p=(i596_rfd *) word_swap ((unsigned long)p->next) ); - - /* append the rfd */ - p->cmd &= ~CMD_EOL; /* Clear EL bit at end */ - p->next = (i596_rfd *) word_swap ((unsigned long)pRfd); - } - } - else { - printk(("Illegal attempt to append: %p\n", pRfd)) - } -} - -/* - * uti596_supplyFD - * - * Return a buffer (RFD) to the receive frame area (RFA). - * Call with interrupts disabled. - * - * Input parameters: - * pRfd - a pointer to the buffer to be returned - * - * Output parameters: NONE - * - * Return value: NONE - */ -void uti596_supplyFD ( - i596_rfd * pRfd -) -{ - i596_rfd *pLastRfd; - - UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD!\n") - - pRfd -> cmd = CMD_EOL; - pRfd -> pRbd = I596_NULL; - pRfd -> next = I596_NULL; - pRfd -> stat = 0x0000; /* clear STAT_C and STAT_B bits */ - - /* - * Check if the list is empty: - */ - if ( uti596_softc.pBeginRFA == I596_NULL ) { - - /* Start a list with one entry */ - uti596_softc.pBeginRFA = uti596_softc.pEndRFA = pRfd; - UTI_596_ASSERT(uti596_softc.countRFD == 0, "Null begin, but non-zero count\n") - if ( uti596_softc.pLastUnkRFD != I596_NULL ) { - printk(("LastUnkRFD is NOT NULL!!\n")) - } - uti596_softc.countRFD = 1; - return; - } - - /* - * Check if the last RFD is used/read by the 596. - */ - pLastRfd = uti596_softc.pEndRFA; - - /* C = complete, B = busy (prefetched) */ - if ( pLastRfd != I596_NULL && ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) { - - /* - * Not yet too late to add it - */ - pLastRfd -> next = (i596_rfd *) word_swap ((unsigned long)pRfd); - pLastRfd -> cmd &= ~CMD_EOL; /* RESET_EL : reset EL bit to 0 */ - uti596_softc.countRFD++; /* Lets assume we add it successfully - If not, the RFD may be used, and may - decrement countRFD < 0 !! */ - /* - * Check if the last RFD was used while appending. - */ - if ( pLastRfd -> stat & ( STAT_C | STAT_B ) ) { /* completed or was prefetched */ - /* - * Either the EL bit of the last rfd has been read by the 82596, - * and it will stop after reception,( true when RESET_EL not reached ) or - * the EL bit was NOT read by the 82596 and it will use the linked - * RFD for the next reception. ( true when RESET_EL was reached ) - * So, it is unknown whether or not the linked rfd will be used. - * Therefore, the end of list CANNOT be updated. - */ - UTI_596_ASSERT ( uti596_softc.pLastUnkRFD == I596_NULL, "Too many Unk RFD's\n" ) - uti596_softc.pLastUnkRFD = pRfd; - return; - } - else { - /* - * The RFD being added was not touched by the 82596 - */ - if (uti596_softc.pLastUnkRFD != I596_NULL ) { - - uti596_append((i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* Only here! saved Q */ - uti596_softc.pEndSavedQueue = pRfd; - uti596_softc.savedCount++; - uti596_softc.countRFD--; - - } - else { - - uti596_softc.pEndRFA = pRfd; /* the RFA has been extended */ - - if ( ( uti596_softc.scb.status & SCB_STAT_RNR || - uti596_softc.scb.status & RU_NO_RESOURCES ) && - uti596_softc.countRFD > 1 ) { - - /* Ensure that beginRFA is not EOL */ - uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL; - - UTI_596_ASSERT(uti596_softc.pEndRFA -> next == I596_NULL, "supply: List buggered\n") - UTI_596_ASSERT(uti596_softc.pEndRFA -> cmd & CMD_EOL, "supply: No EOL at end.\n") - UTI_596_ASSERT(uti596_softc.scb.command == 0, "Supply: scb command must be zero\n") - - #ifdef DBG_MEM - printk(("uti596_supplyFD: starting receiver")) - #endif - - /* start the receiver */ - UTI_596_ASSERT(uti596_softc.pBeginRFA != I596_NULL, "rx start w/ NULL begin! \n") - uti596_softc.scb.pRfd = uti596_softc.pBeginRFA; - uti596_softc.scb.rfd_pointer = word_swap ((unsigned long) uti596_softc.pBeginRFA); - - /* Don't ack RNR! The receiver should be stopped in this case */ - uti596_softc.scb.command = RX_START | SCB_STAT_RNR; - - UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n") - - /* send CA signal */ - uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT ); - } - } - return; - } - } - else { - /* - * too late , pLastRfd in use ( or NULL ), - * in either case, EL bit has been read, and RNR condition will occur - */ - uti596_append( (i596_rfd **)&uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */ - - uti596_softc.pEndSavedQueue = pRfd; /* reset end of saved queue */ - uti596_softc.savedCount++; - - return; - } -} - -/* - * send_packet - * - * Send a raw ethernet packet, add a - * transmit command to the CBL - * - * Input parameters: - * ifp - a pointer to the ifnet structure - * m - a pointer to the mbuf being sent - * - * Output parameters: NONE - * - * Return value: NONE - */ -void send_packet( - struct ifnet *ifp, struct mbuf *m -) -{ - i596_tbd *pPrev = I596_NULL; - i596_tbd *pRemainingTbdList; - i596_tbd *pTbd; - struct mbuf *n, *input_m = m; - uti596_softc_ *sc = ifp->if_softc; - struct mbuf *l = NULL; - unsigned int length = 0; - rtems_status_code status; - int bd_count = 0; - rtems_event_set events; - - /* - * For all mbufs in the chain, - * fill a transmit buffer descriptor for each - */ - pTbd = (i596_tbd*) word_swap ((unsigned long)sc->pTxCmd->pTbd); - - do { - if (m->m_len) { - /* - * Fill in the buffer descriptor - */ - length += m->m_len; - pTbd->data = (char *) word_swap ((unsigned long) mtod (m, void *)); - pTbd->size = m->m_len; - pPrev = pTbd; - pTbd = (i596_tbd *) word_swap ((unsigned long) pTbd->next); - l = m; - m = m->m_next; - } - else { - /* - * Just toss empty mbufs - */ - MFREE (m, n); - m = n; - if (l != NULL) - l->m_next = m; - } - } while( m != NULL && ++bd_count < 16 ); - - if ( length < UTI_596_ETH_MIN_SIZE ) { - pTbd->data = (char *) word_swap ((unsigned long) sc->zeroes); /* add padding to pTbd */ - pTbd->size = UTI_596_ETH_MIN_SIZE - length; /* zeroes have no effect on the CRC */ - } - else /* Don't use pTbd in the send routine */ - pTbd = pPrev; - - /* Disconnect the packet from the list of Tbd's */ - pRemainingTbdList = (i596_tbd *) word_swap ((unsigned long)pTbd->next); - pTbd->next = I596_NULL; - pTbd->size |= UTI_596_END_OF_FRAME; - - sc->rawsndcnt++; - - #ifdef DBG_SEND - printk(("send_packet: sending packet\n")) - #endif - - /* Sending Zero length packet: shouldn't happen */ - if (pTbd->size <= 0) return; - - #ifdef DBG_PACKETS - printk (("\nsend_packet: Transmitter adds packet\n")) - print_hdr ( sc->pTxCmd->pTbd->data ); /* print the first part */ - print_pkt ( sc->pTxCmd->pTbd->next->data ); /* print the first part */ - print_echo (sc->pTxCmd->pTbd->data); - #endif - - /* add the command to the output command queue */ - uti596_addCmd ( (i596_cmd *) sc->pTxCmd ); - - /* sleep until the command has been processed or Timeout encountered. */ - status= rtems_bsdnet_event_receive (INTERRUPT_EVENT, - RTEMS_WAIT|RTEMS_EVENT_ANY, - RTEMS_NO_TIMEOUT, - &events); - - if ( status != RTEMS_SUCCESSFUL ) { - printk(("Could not sleep %s\n", rtems_status_text(status))) - } - - #ifdef DBG_SEND - printk(("send_packet: RAW - wake\n")) - #endif - - sc->txInterrupts++; - - if ( sc->pTxCmd -> cmd.status & STAT_OK ) { - sc->stats.tx_packets++; - } - else { - - printk(("*** send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status )) - - sc->stats.tx_errors++; - if ( sc->pTxCmd->cmd.status & 0x0020 ) - sc->stats.tx_retries_exceeded++; - if (!(sc->pTxCmd->cmd.status & 0x0040)) - sc->stats.tx_heartbeat_errors++; - if ( sc->pTxCmd->cmd.status & 0x0400 ) - sc->stats.tx_carrier_errors++; - if ( sc->pTxCmd->cmd.status & 0x0800 ) - sc->stats.collisions++; - if ( sc->pTxCmd->cmd.status & 0x1000 ) - sc->stats.tx_aborted_errors++; - } /* end if stat_ok */ - - /* - * Restore the transmitted buffer descriptor chain. - */ - pTbd -> next = (i596_tbd *) word_swap ((unsigned long)pRemainingTbdList); - - /* - * Free the mbufs used by the sender. - */ - m = input_m; - while ( m != NULL ) { - MFREE(m,n); - m = n; - } -} - -/*********************************************************************** - * Function: uti596_attach - * - * Description: - * Configure the driver, and connect to the network stack - * - * Algorithm: - * - * Check parameters in the ifconfig structure, and - * set driver parameters accordingly. - * Initialize required rx and tx buffers. - * Link driver data structure onto device list. - * Return 1 on successful completion. - * - ***********************************************************************/ - -int uti596_attach( - struct rtems_bsdnet_ifconfig * pConfig, - int attaching -) -{ - uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */ - struct ifnet * ifp = (struct ifnet *)&sc->arpcom.ac_if; /* ifnet structure */ - int unitNumber; - char *unitName; -#if defined(mvme167) - unsigned char j1; /* State of J1 jumpers */ - char *pAddr; - int addr; -#endif - - #ifdef DBG_ATTACH - printk(("uti596_attach: begins\n")) - #endif - - /* The NIC is not started yet */ - sc->started = 0; - - /* Indicate to ULCS that this is initialized */ - ifp->if_softc = (void *)sc; - sc->pScp = NULL; - - /* Parse driver name */ - if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0) - return 0; - - ifp->if_name = unitName; - ifp->if_unit = unitNumber; - - /* Assign mtu */ - if ( pConfig -> mtu ) - ifp->if_mtu = pConfig -> mtu; - else - ifp->if_mtu = ETHERMTU; - - /* - * Check whether parameters should be obtained from NVRAM. If - * yes, and if an IP address, netmask, or ethernet address are - * provided in NVRAM, cheat, and stuff them into the ifconfig - * structure, OVERRIDING and existing or NULL values. - * - * Warning: If values are provided in NVRAM, the ifconfig entries - * must be NULL because buffer memory allocated to hold the - * structure values is unrecoverable and would be lost here. - */ - -#if defined(mvme167) - /* Read the J1 header */ - j1 = (unsigned char)(lcsr->vector_base & 0xFF); - - if ( !(j1 & 0x10) ) { - /* Jumper J1-4 is on, configure from NVRAM */ - - if ( (addr = nvram->ipaddr) ) { - /* We have a non-zero entry, copy the value */ - if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) ) - pConfig->ip_address = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 ); - else - rtems_panic("Can't allocate ip_address buffer!\n"); - } - - if ( (addr = nvram->netmask) ) { - /* We have a non-zero entry, copy the value */ - if ( (pAddr = malloc ( INET_ADDR_MAX_BUF_SIZE, 0, M_NOWAIT )) ) - pConfig->ip_netmask = (char *)inet_ntop(AF_INET, &addr, pAddr, INET_ADDR_MAX_BUF_SIZE -1 ); - else - rtems_panic("Can't allocate ip_netmask buffer!\n"); - } - - /* Ethernet address requires special handling -- it must be copied into - * the arpcom struct. The following if construct serves only to give the - * NVRAM parameter the highest priority if J1-4 indicates we are configuring - * from NVRAM. - * - * If the ethernet address is specified in NVRAM, go ahead and copy it. - * (ETHER_ADDR_LEN = 6 bytes). - */ - if ( nvram->enaddr[0] || nvram->enaddr[1] || nvram->enaddr[2] ) { - /* Anything in the first three bytes indicates a non-zero entry, copy value */ - memcpy ((void *)sc->arpcom.ac_enaddr, &nvram->enaddr, ETHER_ADDR_LEN); - } - else if ( pConfig->hardware_address) { - /* There is no entry in NVRAM, but there is in the ifconfig struct, so use it. */ - memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN); - } - else { - /* There is no ethernet address provided, so it will be read - * from BBRAM at $FFFC1F2C by default. [mvme167 manual p. 1-47] - */ - memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN); - } - } - else if ( pConfig->hardware_address) { - /* We are not configuring from NVRAM (J1-4 is off), and the ethernet address - * is given in the ifconfig structure. Copy it. - */ - memcpy ((void *)sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN); - } - else -#endif - { - /* We are not configuring from NVRAM (J1-4 is off), and there is no ethernet - * address provided in the ifconfig struct, so it will be read from BBRAM at - * $FFFC1F2C by default. [mvme167 manual p. 1-47] - */ - memcpy ((void *)sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN); - } - - /* Possibly override default acceptance of broadcast packets */ - if (pConfig->ignore_broadcast) - uti596initSetup[8] |= 0x02; - - /* Assign requested receive buffer descriptor count */ - if (pConfig->rbuf_count) - sc->rxBdCount = pConfig->rbuf_count; - else - sc->rxBdCount = RX_BUF_COUNT; - - /* Assign requested tx buffer descriptor count */ - if (pConfig->xbuf_count) - sc->txBdCount = pConfig->xbuf_count; - else - sc->txBdCount = TX_BUF_COUNT * TX_BD_PER_BUF; - - /* Set up fields in the ifnet structure*/ - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; - ifp->if_snd.ifq_maxlen = ifqmaxlen; - ifp->if_init = uti596_init; - ifp->if_ioctl = uti596_ioctl; - ifp->if_start = uti596_start; - ifp->if_output = ether_output; - - /* uti596_softc housekeeping */ - sc->started = 1; - sc->pInboundFrameQueue = I596_NULL; - sc->scb.command = 0; - - /* - * Attach the interface - */ - if_attach (ifp); - ether_ifattach (ifp); - return 1; -} - -/*********************************************************************** - * Function: uti596_start - * - * Description: - * start the driver - * - * Algorithm: - * send an event to the tx task - * set the if_flags - * - ***********************************************************************/ -static void uti596_start( - struct ifnet *ifp -) -{ - uti596_softc_ *sc = ifp->if_softc; - - #ifdef DBG_START - printk(("uti596_start: begins\n")) - #endif - - rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT); - ifp->if_flags |= IFF_OACTIVE; -} - -/*********************************************************************** - * Function: uti596_init - * - * Description: - * driver initialization - * - * Algorithm: - * initialize the 82596 - * start driver tx and rx tasks, and reset task - * send the RX_START command the the RU - * set if_flags - * - * - ***********************************************************************/ -void uti596_init( - void * arg -) -{ - uti596_softc_ *sc = arg; - struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if; - - if (sc->txDaemonTid == 0) { - - /* - * Initialize the 82596 - */ - #ifdef DBG_INIT - printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n")) - #endif - uti596_initialize_hardware(sc); - - /* - * Start driver tasks - */ - #ifdef DBG_INIT - printk(("uti596_init: starting driver tasks...\n")) - #endif - sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, (void *)sc); - sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, (void *)sc); - sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, (void *)sc); - - #ifdef DBG_INIT - printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status )) - #endif - } - - /* - * In case the ISR discovers there are no resources it reclaims - * them and restarts - */ - sc->started = 1; - - /* - * Enable receiver - */ - #ifdef DBG_INIT - printk(("uti596_init: enabling the reciever...\n" )) - #endif - sc->scb.command = RX_START; - uti596_issueCA ( sc, UTI596_WAIT_FOR_CU_ACCEPT ); - - /* - * Tell the world that we're running. - */ - ifp->if_flags |= IFF_RUNNING; - #ifdef DBG_INIT - printk(("uti596_init: completed.\n")) - #endif -} - -/*********************************************************************** - * Function: uti596stop - * - * Description: - * stop the driver - * - * Algorithm: - * mark driver as not started, - * mark transmitter as busy - * abort any transmissions/receptions - * clean-up all buffers ( RFD's et. al. ) - * - * - ***********************************************************************/ - -/* static */ void uti596_stop( - uti596_softc_ *sc -) -{ - struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if; - - ifp->if_flags &= ~IFF_RUNNING; - sc->started = 0; - - #ifdef DBG_STOP - printk(("uti596stop: %s: Shutting down ethercard, status was %4.4x.\n", - uti596_softc.arpcom.ac_if.if_name, uti596_softc.scb.status)) - #endif - - printk(("Stopping interface\n")) - sc->scb.command = CUC_ABORT | RX_ABORT; - i82596->chan_attn = 0x00000000; -} - -/*********************************************************************** - * Function: void uti596_txDaemon - * - * Description: Transmit task - * - * Algorithm: Get mbufs to be transmitted, stuff into RFDs, send - * - ***********************************************************************/ - -void uti596_txDaemon( - void *arg -) -{ - uti596_softc_ *sc = (uti596_softc_ *)arg; - struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if; - struct mbuf *m; - rtems_event_set events; - - for (;;) { - /* - * Wait for packet from stack - */ - rtems_bsdnet_event_receive (START_TRANSMIT_EVENT, - RTEMS_EVENT_ANY | RTEMS_WAIT, - RTEMS_NO_TIMEOUT, &events); - - /* - * Send packets till queue is empty. - * Ensure that irq is on before sending. - */ - for (;;) { - /* Get the next mbuf chain to transmit. */ - IF_DEQUEUE(&ifp->if_snd, m); - if (!m) - break; - - send_packet (ifp, m); /* blocks */ - } - ifp->if_flags &= ~IFF_OACTIVE; /* no more to send, mark output inactive */ - } -} - -/*********************************************************************** - * Function: uti596_rxDaemon - * - * Description: Receiver task - * - * Algorithm: Extract the packet from an RFD, and place into an - * mbuf chain. Place the mbuf chain in the network task - * queue. Assumes that the frame check sequence is removed - * by the 82596. - * - ***********************************************************************/ - -/* static */ void uti596_rxDaemon( - void *arg -) -{ - uti596_softc_ *sc = (uti596_softc_ *)arg; - struct ifnet *ifp = (struct ifnet *)&sc->arpcom.ac_if; - struct mbuf *m; - - i596_rfd *pRfd; - ISR_Level level; - rtems_id tid; - rtems_event_set events; - struct ether_header *eh; - - int frames = 0; - - #ifdef DBG_RX - printk(("uti596_rxDaemon: begin\n")) - printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd)) - #endif - - rtems_task_ident (0, 0, &tid); - - for(;;) { - /* - * Wait for packet. - */ - #ifdef DBG_RX - printk(("uti596_rxDaemon: Receiver sleeps\n")) - #endif - - rtems_bsdnet_event_receive (INTERRUPT_EVENT, - RTEMS_WAIT|RTEMS_EVENT_ANY, - RTEMS_NO_TIMEOUT, - &events); - - #ifdef DBG_RX - printk(("uti596_rxDaemon: Receiver wakes\n")) - #endif - /* - * While received frames are available. Note that the frame may be - * a fragment, so it is NOT a complete packet. - */ - pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue); - while ( pRfd && - pRfd != I596_NULL && - pRfd -> stat & STAT_C ) - { - - if ( pRfd->stat & STAT_OK) { /* a good frame */ - int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */ - - #ifdef DBG_RX - printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len)) - #endif - frames++; - - /* - * Allocate an mbuf to give to the stack - * The format of the data portion of the RFD is: - * . - * The FRAME CHECK SEQUENCE / CRC is stripped by the uti596. - * This is to be optimized later.... should not have to memcopy! - */ - MGETHDR(m, M_WAIT, MT_DATA); - MCLGET(m, M_WAIT); - - m->m_pkthdr.rcvif = ifp; - /* move everything into an mbuf */ - memcpy(m->m_data, (const char *)pRfd->data, pkt_len); - m->m_len = m->m_pkthdr.len = pkt_len - sizeof(struct ether_header) - 4; - - /* move the header to an mbuf */ - eh = mtod (m, struct ether_header *); - m->m_data += sizeof(struct ether_header); - - #ifdef DBG_PACKETS - { - int i; - printk(("uti596_rxDaemon: mbuf contains:\n")) - print_eth( (char *) (((int)m->m_data)-sizeof(struct ether_header))); - for ( i = 0; i<20; i++) { - printk((".")) - } - } - #endif - - ether_input (ifp, eh, m); - - } /* end if STAT_OK */ - - else { - /* - * A bad frame is present: Note that this could be the last RFD! - */ - #ifdef DBG_RX - printk(("uti596_rxDaemon: Bad frame\n")) - #endif - /* - * FIX ME: use the statistics from the SCB - */ - sc->stats.rx_errors++; - if ((sc->scb.pRfd->stat) & 0x0001) - sc->stats.collisions++; - if ((sc->scb.pRfd->stat) & 0x0080) - sc->stats.rx_length_errors++; - if ((sc->scb.pRfd->stat) & 0x0100) - sc->stats.rx_over_errors++; - if ((sc->scb.pRfd->stat) & 0x0200) - sc->stats.rx_fifo_errors++; - if ((sc->scb.pRfd->stat) & 0x0400) - sc->stats.rx_frame_errors++; - if ((sc->scb.pRfd->stat) & 0x0800) - sc->stats.rx_crc_errors++; - if ((sc->scb.pRfd->stat) & 0x1000) - sc->stats.rx_length_errors++; - } - - UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n") - - _ISR_Local_disable(level); - uti596_supplyFD ( pRfd ); /* Return RFD to RFA. */ - _ISR_Local_enable(level); - - pRfd = uti596_dequeue( (i596_rfd **)&sc->pInboundFrameQueue); /* grab next frame */ - - } /* end while */ - } /* end for() */ - - #ifdef DBG_RX - printk (("uti596_rxDaemon: frames ... %d\n", frames)) - #endif -} - -/*********************************************************************** - * Function: void uti596_resetDaemon - * - * Description: - ***********************************************************************/ -void uti596_resetDaemon( - void *arg -) -{ - uti596_softc_ *sc = (uti596_softc_ *)arg; - rtems_event_set events; - rtems_time_of_day tm_struct; - - /* struct ifnet *ifp = &sc->arpcom.ac_if; */ - - for (;;) { - /* Wait for reset event from ISR */ - rtems_bsdnet_event_receive (NIC_RESET_EVENT, - RTEMS_EVENT_ANY | RTEMS_WAIT, - RTEMS_NO_TIMEOUT, &events); - - rtems_clock_get_tod(&tm_struct); - printk(("reset daemon: Resetting NIC @ %" PRIu32 ":%" PRIu32 ":%" PRIu32 " \n", - tm_struct.hour, tm_struct.minute, tm_struct.second)) - - sc->stats.nic_reset_count++; - /* Reinitialize the LANC */ - rtems_bsdnet_semaphore_obtain (); - uti596_reset(); - rtems_bsdnet_semaphore_release (); - } -} - -/*********************************************************************** - * Function: uti596_DynamicInterruptHandler - * - * Description: - * This is the interrupt handler for the uti596 board - * - ***********************************************************************/ - -/* static */ rtems_isr uti596_DynamicInterruptHandler( - rtems_vector_number irq -) -{ -int fullStatus; - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: begins")) - #endif - - uti596_wait (&uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT); - - scbStatus = (fullStatus = uti596_softc.scb.status) & 0xf000; - - if ( scbStatus ) { - /* acknowledge interrupts */ - - /* Write to the ICLR bit in the PCCchip2 control registers to clear - * the INT status bit. Clearing INT here *before* sending the CA signal - * to the 82596 should ensure that interrupts won't be lost. - */ - pccchip2->LANC_int_ctl |=0x08; - pccchip2->LANC_berr_ctl |=0x08; - - /* printk(("***INFO: ACK %x\n", scbStatus))*/ - - /* Send the CA signal to acknowledge interrupt */ - uti596_softc.scb.command = scbStatus; - uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT ); - - if( uti596_softc.resetDone ) { - /* stack is attached */ - uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT ); - } - else { - printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus)) - return; - } - } - else { -#ifndef IGNORE_SPURIOUS_IRQ - printk(("\n***ERROR: Spurious interrupt (full status 0x%x). Resetting...\n", fullStatus)) - uti596_softc.nic_reset = 1; -#endif - } - - if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ) { - printk(("\n*****ERROR: Command Complete, and CNA available: 0x%x\nResetting...", scbStatus)) - uti596_softc.nic_reset = 1; - return; - } - - if ( !(scbStatus & SCB_STAT_CX) && (scbStatus & SCB_STAT_CNA) ) { - printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus)) - uti596_softc.nic_reset = 1; - return; - } - - if ( scbStatus & SCB_CUS_SUSPENDED ) { - printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus)) - uti596_softc.nic_reset = 1; - return; - } - - if ( scbStatus & RU_SUSPENDED ) { - printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus)) - uti596_softc.nic_reset = 1; - return; - } - - if ( scbStatus & SCB_STAT_RNR ) { - printk(("\n*****WARNING: RNR %x\n",scbStatus)) - if (uti596_softc.pBeginRFA != I596_NULL) { - printk(("*****INFO: RFD cmd: %x status:%x\n", uti596_softc.pBeginRFA->cmd, - uti596_softc.pBeginRFA->stat)) - } - else { - printk(("*****WARNING: RNR condition with NULL BeginRFA\n")) - } - } - - /* - * Receive Unit Control - * a frame is received - */ - if ( scbStatus & SCB_STAT_FR ) { - uti596_softc.rxInterrupts++; - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: Frame received\n")) - #endif - if ( uti596_softc.pBeginRFA == I596_NULL || - !( uti596_softc.pBeginRFA -> stat & STAT_C)) { -#ifndef IGNORE_NO_RFA - uti596_dump_scb(); - uti596_softc.nic_reset = 1; -#endif - } - else { - while ( uti596_softc.pBeginRFA != I596_NULL && - ( uti596_softc.pBeginRFA -> stat & STAT_C)) { - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n")) - #endif - count_rx ++; -#ifndef IGNORE_MULTIPLE_RF - if ( count_rx > 1) { - printk(("****WARNING: Received %i frames on 1 interrupt \n", count_rx)) - } -#endif - /* Give Received Frame to the ULCS */ - uti596_softc.countRFD--; - - if ( uti596_softc.countRFD < 0 ) { - printk(("ISR: Count < 0 !!! count == %d, beginRFA = %p\n", - uti596_softc.countRFD, uti596_softc.pBeginRFA)) - } - uti596_softc.stats.rx_packets++; - /* the rfd next link is stored with upper and lower words swapped so read it that way */ - pIsrRfd = (i596_rfd *) word_swap ((unsigned long)uti596_softc.pBeginRFA->next); - /* the append destroys the link */ - uti596_append( (i596_rfd **)&uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA ); - - /* - * if we have just received the a frame in the last unknown RFD, - * then it is certain that the RFA is empty. - */ - if ( uti596_softc.pLastUnkRFD == uti596_softc.pBeginRFA ) { - UTI_596_ASSERT(uti596_softc.pLastUnkRFD != I596_NULL,"****ERROR:LastUnk is NULL, begin ptr @ end!\n") - uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL; - } - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid)) - #endif - sc = rtems_bsdnet_event_send(uti596_softc.rxDaemonTid, INTERRUPT_EVENT); - if ( sc != RTEMS_SUCCESSFUL ) { - rtems_panic("Can't notify rxDaemon: %s\n", - rtems_status_text (sc)); - } - #ifdef DBG_ISR - else { - printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid)) - } - #endif - - uti596_softc.pBeginRFA = pIsrRfd; - } /* end while */ - } /* end if */ - - if ( uti596_softc.pBeginRFA == I596_NULL ) { - /* adjust the pEndRFA to reflect an empty list */ - if ( uti596_softc.pLastUnkRFD == I596_NULL && uti596_softc.countRFD != 0 ) { - printk(("Last Unk is NULL, BeginRFA is null, and count == %d\n", - uti596_softc.countRFD)) - } - uti596_softc.pEndRFA = I596_NULL; - if ( uti596_softc.countRFD != 0 ) { - printk(("****ERROR:Count is %d, but begin ptr is NULL\n", - uti596_softc.countRFD )) - } - } - } /* end if ( scbStatus & SCB_STAT_FR ) */ - - /* - * Command Unit Control - * a command is completed - */ - if ( scbStatus & SCB_STAT_CX ) { - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: CU\n")) - #endif - - pIsrCmd = uti596_softc.pCmdHead; - - /* For ALL completed commands */ - if ( pIsrCmd != I596_NULL && pIsrCmd->status & STAT_C ) { - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n")) - #endif - - /* Adjust the command block list */ - uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next); - - /* - * If there are MORE commands to process, - * the serialization in the raw routine has failed. - * ( Perhaps AddCmd is bad? ) - */ - UTI_596_ASSERT(uti596_softc.pCmdHead == I596_NULL, "****ERROR: command serialization failed\n") - - /* What if the command did not complete OK? */ - switch ( pIsrCmd->command & 0x7) { - case CmdConfigure: - - uti596_softc.cmdOk = 1; - break; - - case CmdDump: - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: dump!\n")) - #endif - uti596_softc.cmdOk = 1; - break; - - case CmdDiagnose: - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: diagnose!\n")) - #endif - uti596_softc.cmdOk = 1; - break; - - case CmdSASetup: - /* printk(("****INFO:Set address interrupt\n")) */ - if ( pIsrCmd -> status & STAT_OK ) { - uti596_softc.cmdOk = 1; - } - else { - printk(("****ERROR:SET ADD FAILED\n")) - } - break; - - case CmdTx: - UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n") - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid)) - #endif - if ( uti596_softc.txDaemonTid ) { - /* Ensure that the transmitter is present */ - sc = rtems_bsdnet_event_send (uti596_softc.txDaemonTid, - INTERRUPT_EVENT); - - if ( sc != RTEMS_SUCCESSFUL ) { - printk(("****ERROR:Could NOT send event to tid 0x%" PRIu32 " : %s\n", - uti596_softc.txDaemonTid, rtems_status_text (sc) )) - } - #ifdef DBG_ISR - else { - printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid)) - } - #endif - } - break; - - case CmdMulticastList: - printk(("***ERROR:Multicast?!\n")) - pIsrCmd->next = I596_NULL; - break; - - case CmdTDR: { - unsigned long status = *( (unsigned long *)pIsrCmd)+1; - printk(("****ERROR:TDR?!\n")) - - if (status & STAT_C) { - /* mark the TDR command successful */ - uti596_softc.cmdOk = 1; - } - else { - if (status & 0x4000) { - printk(("****WARNING:Transceiver problem.\n")) - } - if (status & 0x2000) { - printk(("****WARNING:Termination problem.\n")) - } - if (status & 0x1000) { - printk(("****WARNING:Short circuit.\n")) - /* printk(("****INFO:Time %ld.\n", status & 0x07ff)) */ - } - } - } - break; - - default: { - /* - * This should never be reached - */ - printk(("CX but NO known command\n")) - } - } /* end switch */ - - pIsrCmd = uti596_softc.pCmdHead; /* next command */ - if ( pIsrCmd != I596_NULL ) { - printk(("****WARNING: more commands in list, but no start to NIC\n")) - } - } /* end if pIsrCmd != NULL && pIsrCmd->stat & STAT_C */ - - else { - if ( pIsrCmd != I596_NULL ) { - /* The command MAY be NULL from a RESET */ - /* Reset the ethernet card, and wake the transmitter (if necessary) */ - printk(("****INFO: Request board reset ( tx )\n")) - uti596_softc.nic_reset = 1; - if ( uti596_softc.txDaemonTid) { - /* Ensure that a transmitter is present */ - sc = rtems_bsdnet_event_send (uti596_softc.txDaemonTid, - INTERRUPT_EVENT); - if ( sc != RTEMS_SUCCESSFUL ) { - printk(("****ERROR:Could NOT send event to tid 0x%" PRIu32 " : %s\n", - uti596_softc.txDaemonTid, rtems_status_text (sc) )) - } - #ifdef DBG_ISR - else { - printk(("uti596_DynamicInterruptHandler: ****INFO:Tx wake: %#x\n", - uti596_softc.txDaemonTid)) - } - #endif - } - } - } - } /* end if command complete */ - - /* - * If the receiver has stopped, - * check if this is a No Resources scenario, - * Try to add more RFD's ( no RBDs are used ) - */ - if ( uti596_softc.started ) { - if ( scbStatus & SCB_STAT_RNR ) { - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: INFO:RNR: status %#x \n", - uti596_softc.scb.status )) - #endif - /* - * THE RECEIVER IS OFF! - */ - if ( uti596_softc.pLastUnkRFD != I596_NULL ) { - /* We have an unknown RFD, it is not inbound */ - if ( uti596_softc.pLastUnkRFD -> stat & (STAT_C | STAT_B )) { /* in use */ - uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD; /* update end */ - } - else { - /* - * It is NOT in use, and since RNR, we know EL bit of pEndRFA was read! - * So, unlink it from the RFA and move it to the saved queue. - * But pBegin can equal LastUnk! - */ - - if ( uti596_softc.pEndRFA != I596_NULL ) { - /* check added feb24. */ - #ifdef DBG_ISR - if ((i596_rfd *)word_swap((unsigned long)uti596_softc.pEndRFA->next) != uti596_softc.pLastUnkRFD) { - printk(("***ERROR:UNK: %p not end->next: %p, end: %p\n", - uti596_softc.pLastUnkRFD, - uti596_softc.pEndRFA -> next, - uti596_softc.pEndRFA)) - printk(("***INFO:countRFD now %d\n", - uti596_softc.countRFD)) - printk(("\n\n")) - } - #endif - uti596_softc.pEndRFA -> next = I596_NULL; /* added feb 16 */ - } - uti596_append( (i596_rfd **)&uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD ); - uti596_softc.savedCount++; - uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD; - uti596_softc.countRFD--; /* It was not in the RFA */ - /* - * The Begin pointer CAN advance this far. We must resynch the CPU side - * with the chip. - */ - if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) { - #ifdef DBG_ISR - if ( uti596_softc.countRFD != 0 ) { - printk(("****INFO:About to set begin to NULL, with count == %d\n\n", - uti596_softc.countRFD )) - } - #endif - uti596_softc.pBeginRFA = I596_NULL; - UTI_596_ASSERT(uti596_softc.countRFD == 0, "****ERROR:Count must be zero here!\n") - } - } - uti596_softc.pLastUnkRFD = I596_NULL; - } /* end if exists UnkRFD */ - - /* - * Append the saved queue to the RFA. - * Any further RFD's being supplied will be added to - * this new list. - */ - if ( uti596_softc.pSavedRfdQueue != I596_NULL ) { - /* entries to add */ - if ( uti596_softc.pBeginRFA == I596_NULL ) { - /* add at beginning to list */ - #ifdef DBG_ISR - if(uti596_softc.countRFD != 0) { - printk(("****ERROR:Begin pointer is NULL, but count == %d\n", - uti596_softc.countRFD)) - } - #endif - uti596_softc.pBeginRFA = uti596_softc.pSavedRfdQueue; - uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue; - uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */ - } - else { - #ifdef DBG_ISR - if ( uti596_softc.countRFD <= 0) { - printk(("****ERROR:Begin pointer is not NULL, but count == %d\n", - uti596_softc.countRFD)) - } - #endif - UTI_596_ASSERT( uti596_softc.pEndRFA != I596_NULL, "****WARNING: END RFA IS NULL\n") - UTI_596_ASSERT( uti596_softc.pEndRFA->next == I596_NULL, "****ERROR:END RFA -> next must be NULL\n") - - uti596_softc.pEndRFA->next = (i596_rfd *)word_swap((unsigned long)uti596_softc.pSavedRfdQueue); - uti596_softc.pEndRFA->cmd &= ~CMD_EOL; /* clear the end of list */ - uti596_softc.pEndRFA = uti596_softc.pEndSavedQueue; - uti596_softc.pSavedRfdQueue = uti596_softc.pEndSavedQueue = I596_NULL; /* Reset the End */ - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: count... %d, saved ... %d \n", - uti596_softc.countRFD, - uti596_softc.savedCount)) - #endif - } - /* printk(("Isr: countRFD = %d\n",uti596_softc.countRFD)) */ - uti596_softc.countRFD += uti596_softc.savedCount; - /* printk(("Isr: after countRFD = %d\n",uti596_softc.countRFD)) */ - uti596_softc.savedCount = 0; - } - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: The list starts here %p\n",uti596_softc.pBeginRFA )) - #endif - - if ( uti596_softc.countRFD > 1) { - printk(("****INFO: pBeginRFA -> stat = 0x%x\n",uti596_softc.pBeginRFA -> stat)) - printk(("****INFO: pBeginRFA -> cmd = 0x%x\n",uti596_softc.pBeginRFA -> cmd)) - uti596_softc.pBeginRFA -> stat = 0; - UTI_596_ASSERT(uti596_softc.scb.command == 0, "****ERROR:scb command must be zero\n") - uti596_softc.scb.pRfd = uti596_softc.pBeginRFA; - uti596_softc.scb.rfd_pointer = word_swap((unsigned long)uti596_softc.pBeginRFA); - /* start RX here */ - printk(("****INFO: ISR Starting receiver\n")) - uti596_softc.scb.command = RX_START; /* should this also be CU start? */ - i82596->chan_attn = 0x00000000; - } - } /* end stat_rnr */ - } /* end if receiver started */ - - #ifdef DBG_ISR - printk(("uti596_DynamicInterruptHandler: X\n")) - #endif - count_rx=0; - - /* Do this last, to ensure that the reset is called at the right time. */ - if ( uti596_softc.nic_reset ) { - uti596_softc.nic_reset = 0; - sc = rtems_bsdnet_event_send(uti596_softc.resetDaemonTid, NIC_RESET_EVENT); - if ( sc != RTEMS_SUCCESSFUL ) - rtems_panic ("Can't notify resetDaemon: %s\n", rtems_status_text (sc)); - } - return; -} - -/*********************************************************************** - * Function: uti596_ioctl - * - * Description: - * driver ioctl function - * handles SIOCGIFADDR, SIOCSIFADDR, SIOCSIFFLAGS - * - ***********************************************************************/ - -static int uti596_ioctl( - struct ifnet *ifp, - u_long command, - caddr_t data -) -{ - uti596_softc_ *sc = ifp->if_softc; - int error = 0; - - #ifdef DBG_IOCTL - printk(("uti596_ioctl: begins\n", sc->pScp)) - #endif - - switch (command) { - case SIOCGIFADDR: - case SIOCSIFADDR: - printk(("SIOCSIFADDR\n")) - ether_ioctl (ifp, command, data); - break; - - case SIOCSIFFLAGS: - printk(("SIOCSIFFLAGS\n")) - switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { - case IFF_RUNNING: - printk(("IFF_RUNNING\n")) - uti596_stop (sc); - break; - - case IFF_UP: - printk(("IFF_UP\n")) - uti596_init ( (void *)sc); - break; - - case IFF_UP | IFF_RUNNING: - printk(("IFF_UP and RUNNING\n")) - uti596_stop (sc); - uti596_init ( (void *)sc); - break; - - default: - printk(("default\n")) - break; - } - break; - - case SIO_RTEMS_SHOW_STATS: - printk(("show stats\n")) - uti596_stats (sc); - break; - - /* FIXME: All sorts of multicast commands need to be added here! */ - default: - printk(("default: EINVAL\n")) - error = EINVAL; - break; - } - - return error; -} - -/*********************************************************************** - * Function: uti596_stats - * - * Description: - * print out the collected data - * - * Algorithm: - * use printf - * - ***********************************************************************/ - -void uti596_stats( - uti596_softc_ *sc -) -{ - printf ("CPU Reports:\n"); - printf (" Tx raw send count:%-8lu", sc->rawsndcnt); - printf (" Rx Interrupts:%-8lu", sc->rxInterrupts); - printf (" Tx Interrupts:%-8lu\n", sc->txInterrupts); - printf (" Rx Packets:%-8u", sc->stats.rx_packets); - printf (" Tx Attempts:%-u\n", sc->stats.tx_packets); - - printf (" Rx Dropped:%-8u", sc->stats.rx_dropped); - printf (" Rx IP Packets:%-8u", sc->stats.rx_packets); - printf (" Tx Errors:%-8u\n", sc->stats.tx_errors); - printf (" Tx aborted:%-8u", sc->stats.tx_aborted_errors); - printf (" Tx Dropped:%-8u\n", sc->stats.tx_dropped); - printf (" Tx IP packets:%-8u", sc->stats.tx_packets); - - printf (" Collisions Detected:%-8u\n", sc->stats.collisions); - printf (" Tx Heartbeat Errors:%-8u", sc->stats.tx_heartbeat_errors); - printf (" Tx Carrier Errors:%-8u\n", sc->stats.tx_carrier_errors); - printf (" Tx Aborted Errors:%-8u", sc->stats.tx_aborted_errors); - printf (" Rx Length Errors:%-8u\n", sc->stats.rx_length_errors); - printf (" Rx Overrun Errors:%-8u", sc->stats.rx_over_errors); - printf (" Rx Fifo Errors:%-8u\n", sc->stats.rx_fifo_errors); - printf (" Rx Framing Errors:%-8u", sc->stats.rx_frame_errors); - printf (" Rx crc errors:%-8u\n", sc->stats.rx_crc_errors); - - printf (" TX WAITS: %-8lu\n", sc->txRawWait); - - printf (" NIC resets: %-8u\n", sc->stats.nic_reset_count); - - printf (" NIC reports\n"); - - #ifdef DBG_STAT - uti596_dump_scb(); - #endif -} - -/************************ PACKET DEBUG ROUTINES ************************/ - -#ifdef DBG_PACKETS - -/* - * dumpQ - * - * Dumps frame queues for debugging - */ -static void dumpQ( void ) -{ - i596_rfd *pRfd; - - printk(("savedQ:\n")) - - for( pRfd = uti596_softc.pSavedRfdQueue; - pRfd != I596_NULL; - pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) { - printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd)) - } - - printk(("Inbound:\n")) - - for( pRfd = uti596_softc.pInboundFrameQueue; - pRfd != I596_NULL; - pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) { - printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd)) - } - - printk(("Last Unk: %p\n", uti596_softc.pLastUnkRFD )) - printk(("RFA:\n")) - - for( pRfd = uti596_softc.pBeginRFA; - pRfd != I596_NULL; - pRfd = (i596_rfd*)word_swap((uint32_t)pRfd -> next)) { - printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd)) - } -} - -/* - * show_buffers - * - * Print out the RFA and frame queues - */ -static void show_buffers (void) -{ - i596_rfd *pRfd; - - printk(("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n", - uti596_softc.scb.command, - uti596_softc.scb.status, - uti596_softc.countRFD)) - - printk(("\nRFA: \n")) - - for ( pRfd = uti596_softc.pBeginRFA; - pRfd != I596_NULL; - pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) { - printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n", - pRfd, pRfd->stat, pRfd->cmd)) - } - printk(("\nInbound: \n")) - - for ( pRfd = uti596_softc.pInboundFrameQueue; - pRfd != I596_NULL; - pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) { - printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n", - pRfd, pRfd->stat, pRfd->cmd)) - } - - printk(("\nSaved: \n")) - - for ( pRfd = uti596_softc.pSavedRfdQueue; - pRfd != I596_NULL; - pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) { - printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n", - pRfd, pRfd->stat, pRfd->cmd)) - } - - printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD)) -} - -/* - * show_queues - * - * Print out the saved frame queue and the RFA - */ -static void show_queues(void) -{ - i596_rfd *pRfd; - - printk(("CMD: 0x%x, Status: 0x%x\n", - uti596_softc.scb.command, - uti596_softc.scb.status)) - printk(("saved Q\n")) - - for ( pRfd = uti596_softc.pSavedRfdQueue; - pRfd != I596_NULL && - pRfd != NULL; - pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) { - printk(("0x%p\n", pRfd)) - } - - printk(("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue)) - - printk(("\nRFA:\n")) - - for ( pRfd = uti596_softc.pBeginRFA; - pRfd != I596_NULL && - pRfd != NULL; - pRfd = (i596_rfd *)word_swap((uint32_t)pRfd->next) ) { - printk(("0x%p\n", pRfd)) - } - - printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA)) -} - -/* - * print_eth - * - * Print the contents of an ethernet packet - * CANNOT BE CALLED FROM ISR - */ -static void print_eth( - unsigned char *add -) -{ - int i; - short int length; - - printk (("Packet Location %p\n", add)) - printk (("Dest ")) - - for (i = 0; i < 6; i++) { - printk ((" %2.2X", add[i])) - } - printk (("\n")) - printk (("Source")) - - for (i = 6; i < 12; i++) { - printk ((" %2.2X", add[i])) - } - - printk (("\n")) - printk (("frame type %2.2X%2.2X\n", add[12], add[13])) - - if ( add[12] == 0x08 && add[13] == 0x06 ) { - /* an ARP */ - printk (("Hardware type : %2.2X%2.2X\n", add[14],add[15])) - printk (("Protocol type : %2.2X%2.2X\n", add[16],add[17])) - printk (("Hardware size : %2.2X\n", add[18])) - printk (("Protocol size : %2.2X\n", add[19])) - printk (("op : %2.2X%2.2X\n", add[20],add[21])) - printk (("Sender Enet addr: ")) - - for ( i=0; i< 5 ; i++) { - printk (("%x:", add[22 + i])) - } - printk (("%x\n", add[27])) - printk (("Sender IP addr: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[28 + i])) - } - printk (("%u\n", add[31])) - printk (("Target Enet addr: ")) - - for ( i=0; i< 5 ; i++) { - printk (( "%x:", add[32 + i])) - } - printk (("%x\n", add[37])) - printk (("Target IP addr: ")) - - for ( i=0; i< 3 ; i++) { - printk (( "%u.", add[38 + i])) - } - printk (("%u\n", add[41])) - } - - if ( add[12] == 0x08 && add[13] == 0x00 ) { - /* an IP packet */ - printk (("*********************IP HEADER******************\n")) - printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15])) - printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ))) - printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n", - add[18],add[19], add[20], add[21])) - printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n", - add[22],add[23],add[24],add[25])) - printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35])) - printk (("Source IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[26 + i])) - } - printk (("%u\n", add[29])) - printk (("Destination IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[30 + i])) - } - printk (("%u\n", add[33])) - } -} - -/* - * print_hdr - * - * Print the contents of an ethernet packet header - * CANNOT BE CALLED FROM ISR - */ -static void print_hdr( - unsigned char *add -) -{ - int i; - - printk (("print_hdr: begins\n")) - printk (("Header Location %p\n", add)) - printk (("Dest ")) - - for (i = 0; i < 6; i++) { - printk ((" %2.2X", add[i])) - } - printk (("\nSource")) - - for (i = 6; i < 12; i++) { - printk ((" %2.2X", add[i])) - } - printk (("\nframe type %2.2X%2.2X\n", add[12], add[13])) - printk (("print_hdr: completed")) -} - -/* - * Function: print_pkt - * - * Print the contents of an ethernet packet & data - * CANNOT BE CALLED FROM ISR - */ -static void print_pkt( - unsigned char *add -) -{ - int i; - short int length; - - printk (("print_pkt: begins")) - printk (("Data Location %p\n", add)) - - if ( add[0] == 0x08 && add[1] == 0x06 ) { - /* an ARP */ - printk (("Hardware type : %2.2X%2.2X\n", add[14],add[15])) - printk (("Protocol type : %2.2X%2.2X\n", add[16],add[17])) - printk (("Hardware size : %2.2X\n", add[18])) - printk (("Protocol size : %2.2X\n", add[19])) - printk (("op : %2.2X%2.2X\n", add[20],add[21])) - printk (("Sender Enet addr: ")) - - for ( i=0; i< 5 ; i++) { - printk (( "%x:", add[22 + i])) - } - printk (("%x\n", add[27])) - printk (("Sender IP addr: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[28 + i])) - } - printk (("%u\n", add[31])) - printk (("Target Enet addr: ")) - - for ( i=0; i< 5 ; i++) { - printk (( "%x:", add[32 + i])) - } - printk (("%x\n", add[37])) - printk (("Target IP addr: ")) - - for ( i=0; i< 3 ; i++) { - printk (( "%u.", add[38 + i])) - } - printk (("%u\n", add[41])) - } - - if ( add[0] == 0x08 && add[1] == 0x00 ) { - /* an IP packet */ - printk (("*********************IP HEADER******************\n")) - printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15])) - printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ))) - printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n", - add[18],add[19], add[20], add[21])) - printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n", - add[22],add[23],add[24],add[25])) - printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35])) - printk (("Source IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk(( "%u.", add[26 + i])) - } - printk(("%u\n", add[29])) - printk(("Destination IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk(( "%u.", add[30 + i])) - } - printk(("%u\n", add[33])) - printk(("********************IP Packet Data*******************\n")) - length -=20; - - for ( i=0; i < length ; i++) { - printk(("0x%2.2x ", add[34+i])) - } - printk(("\n")) - printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37])) - printk(("ICMP identifier: %2.2x %2.2x\n", add[38], add[39])) - printk(("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41])) - printk(("print_pkt: completed")) - } -} - -/* - * print_echo - * - * Print the contents of an echo packet - * CANNOT BE CALLED FROM ISR - */ -static void print_echo( - unsigned char *add -) -{ - int i; - short int length; - - printk (("print_echo: begins")) - - if ( add[12] == 0x08 && add[13] == 0x00 ) { - /* an IP packet */ - printk (("Packet Location %p\n", add)) - printk (("Dest ")) - - for (i = 0; i < 6; i++) { - printk ((" %2.2X", add[i])) - } - printk (("\n")) - printk (("Source")) - - for (i = 6; i < 12; i++) { - printk ((" %2.2X", add[i])) - } - printk (("\n")) - printk (("frame type %2.2X%2.2X\n", add[12], add[13])) - - printk (("*********************IP HEADER******************\n")) - printk (("IP version/IPhdr length: %2.2X TOS: %2.2X\n", add[14] , add[15])) - printk (("IP total length: %2.2X %2.2X, decimal %d\n", add[16], add[17], length = (add[16]<<8 | add[17] ))) - printk (("IP identification: %2.2X %2.2X, 3-bit flags and offset %2.2X %2.2X\n", - add[18],add[19], add[20], add[21])) - printk (("IP TTL: %2.2X, protocol: %2.2X, checksum: %2.2X %2.2X \n", - add[22],add[23],add[24],add[25])) - printk (("IP packet type: %2.2X code %2.2X\n", add[34],add[35])) - printk (("Source IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[26 + i])) - } - printk (("%u\n", add[29])) - printk (("Destination IP address: ")) - - for ( i=0; i< 3 ; i++) { - printk (("%u.", add[30 + i])) - } - printk (("%u\n", add[33])) - printk(("********************IP Packet Data*******************\n")) - length -=20; - - for ( i=0; i < length ; i++) { - printk(("0x%2.2x ", add[34+i])) - } - printk(("\n")) - printk(("ICMP checksum: %2.2x %2.2x\n", add[36], add[37])) - printk(("ICMP identifier: %2.2x %2.2x\n", add[38], add[39])) - printk(("ICMP sequence nbr: %2.2x %2.2x\n", add[40], add[41])) - printk(("print_echo: completed")) - } -} - -#endif diff --git a/c/src/lib/libbsp/m68k/mvme167/network/uti596.h b/c/src/lib/libbsp/m68k/mvme167/network/uti596.h deleted file mode 100644 index 29e4fed299..0000000000 --- a/c/src/lib/libbsp/m68k/mvme167/network/uti596.h +++ /dev/null @@ -1,369 +0,0 @@ -/* uti596.h: Contains the defines and structures used by the uti596 driver */ - -/* - * EII: March 11: Created v. 0.0 - */ - -#ifndef UTI596_H -#define UTI596_H -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -/* Ethernet statistics */ - -struct enet_statistics{ - int rx_packets; /* total packets received */ - int tx_packets; /* total packets transmitted */ - int rx_errors; /* bad packets received */ - int tx_errors; /* packet transmit problems */ - int rx_dropped; /* no space in buffers */ - int tx_dropped; - int tx_retries_exceeded; /* excessive retries */ - int multicast; /* multicast packets received */ - int collisions; - - /* detailed rx_errors: */ - int rx_length_errors; - int rx_over_errors; /* receiver ring buff overflow */ - int rx_crc_errors; /* recved pkt with crc error */ - int rx_frame_errors; /* recv'd frame alignment error */ - int rx_fifo_errors; /* recv'r fifo overrun */ - int rx_missed_errors; /* receiver missed packet */ - - /* detailed tx_errors */ - int tx_aborted_errors; - int tx_carrier_errors; - int tx_fifo_errors; - int tx_heartbeat_errors; - int tx_window_errors; - - /* NIC reset errors */ - int nic_reset_count; /* The number of times uti596reset() has been called. */ -}; - -#define CMD_EOL 0x8000 /* The last command of the list, stop. */ -#define CMD_SUSP 0x4000 /* Suspend after doing cmd. */ -#define CMD_INTR 0x2000 /* Interrupt after doing cmd. */ - -#define CMD_FLEX 0x0008 /* Enable flexible memory model */ - -#define SCB_STAT_CX 0x8000 /* Cmd completes with 'I' bit set */ -#define SCB_STAT_FR 0x4000 /* Frame Received */ -#define SCB_STAT_CNA 0x2000 /* Cmd unit Not Active */ -#define SCB_STAT_RNR 0x1000 /* Receiver Not Ready */ - -#define SCB_CUS_SUSPENDED 0x0100 -#define SCB_CUS_ACTIVE 0x0200 - -#define STAT_C 0x8000 /* Set to 1 after execution */ -#define STAT_B 0x4000 /* 1 : Cmd being executed, 0 : Cmd done. */ -#define STAT_OK 0x2000 /* 1: Command executed ok 0 : Error */ -#define STAT_A 0x1000 /* command has been aborted */ - -#define STAT_S11 0x0800 -#define STAT_S10 0x0400 -#define STAT_S9 0x0200 -#define STAT_S8 0x0100 -#define STAT_S7 0x0080 -#define STAT_S6 0x0040 -#define STAT_S5 0x0020 -#define STAT_MAX_COLLS 0x000F - -#define RBD_STAT_P 0x4000 /* prefetch */ -#define RBD_STAT_F 0x4000 /* used */ - -#define CUC_START 0x0100 -#define CUC_RESUME 0x0200 -#define CUC_SUSPEND 0x0300 -#define CUC_ABORT 0x0400 -#define RX_START 0x0010 -#define RX_RESUME 0x0020 -#define RX_SUSPEND 0x0030 -#define RX_ABORT 0x0040 - -#define RU_SUSPENDED 0x0010 -#define RU_NO_RESOURCES 0x0020 -#define RU_READY 0x0040 - -#define I596_NULL ( ( void * ) 0xffffffff) -#define UTI_596_END_OF_FRAME 0x8000 - -struct i596_tbd; /* necessary forward declaration */ - -enum commands { - CmdNOp = 0, - CmdSASetup = 1, - CmdConfigure = 2, - CmdMulticastList = 3, - CmdTx = 4, - CmdTDR = 5, - CmdDump = 6, - CmdDiagnose = 7 -}; - -/* - * 82596 Dump Command Result - */ -typedef volatile struct i596_dump_result { - unsigned char bf; - unsigned char config_bytes[11]; - unsigned char reserved1[2]; - unsigned char ia_bytes[6]; - unsigned short last_tx_status; - unsigned short tx_crc_byte01; - unsigned short tx_crc_byte23; - unsigned short rx_crc_byte01; - unsigned short rx_crc_byte23; - unsigned short rx_temp_mem01; - unsigned short rx_temp_mem23; - unsigned short rx_temp_mem45; - unsigned short last_rx_status; - unsigned short hash_reg01; - unsigned short hash_reg23; - unsigned short hash_reg45; - unsigned short hash_reg67; - unsigned short slot_time_counter; - unsigned short wait_time_counter; - unsigned short rx_frame_length; - unsigned long reserved2; - unsigned long cb_in3; - unsigned long cb_in2; - unsigned long cb_in1; - unsigned long la_cb_addr; - unsigned long rdb_pointer; - unsigned long int_memory; - unsigned long rfd_size; - unsigned long tbd_pointer; - unsigned long base_addr; - unsigned long ru_temp_reg; - unsigned long tcb_count; - unsigned long next_rb_size; - unsigned long next_rb_addr; - unsigned long curr_rb_size; - unsigned long la_rbd_addr; - unsigned long next_rbd_addr; - unsigned long curr_rbd_addr; - unsigned long curr_rb_count; - unsigned long next_fd_addr; - unsigned long curr_fd_add; - unsigned long temp_cu_reg; - unsigned long next_tb_count; - unsigned long buffer_addr; - unsigned long la_tbd_addr; - unsigned long next_tbd_addr; - unsigned long cb_command; - unsigned long next_cb_addr; - unsigned long curr_cb_addr; - unsigned long scb_cmd_word; - unsigned long scb_pointer; - unsigned long cb_stat_word; - unsigned long mm_lfsr; - unsigned char micro_machine_bit_array[28]; - unsigned char cu_port[16]; - unsigned long mm_alu; - unsigned long reserved3; - unsigned long mm_temp_a_rr; - unsigned long mm_temp_a; - unsigned long tx_dma_b_cnt; - unsigned long mm_input_port_addr_reg; - unsigned long tx_dma_addr; - unsigned long mm_port_reg1; - unsigned long rx_dma_b_cnt; - unsigned long mm_port_reg2; - unsigned long rx_dma_addr; - unsigned long reserved4; - unsigned long bus_t_timers; - unsigned long diu_cntrl_reg; - unsigned long reserved5; - unsigned long sysbus; - unsigned long biu_cntrl_reg; - unsigned long mm_disp_reg; - unsigned long mm_status_reg; - unsigned short dump_status; -} i596_dump_result; - -typedef volatile struct i596_selftest { - unsigned long rom_signature; - unsigned long results; -} i596_selftest; - -/* - * Action commands - * (big endian, linear mode) - */ -typedef volatile struct i596_cmd { - unsigned short status; - unsigned short command; - volatile struct i596_cmd *next; -} i596_cmd; - -typedef volatile struct i596_nop { - i596_cmd cmd; -} i596_nop; - -typedef volatile struct i596_set_add { - i596_cmd cmd; - char data[8]; -} i596_set_add; - -typedef volatile struct i596_configure { - i596_cmd cmd; - char data[16]; -} i596_configure; - -typedef volatile struct i596_tx { - i596_cmd cmd; - volatile struct i596_tbd *pTbd; - unsigned short count; - unsigned short pad; - char data[6]; - unsigned short length; -} i596_tx; - -typedef volatile struct i596_tdr { - i596_cmd cmd; - unsigned long data; -} i596_tdr; - -typedef volatile struct i596_dump { - i596_cmd cmd; - char *pData; -} i596_dump; - -/* - * Transmit buffer descriptor - */ -typedef volatile struct i596_tbd { - unsigned short size; - unsigned short pad; - volatile struct i596_tbd *next; - char *data; -} i596_tbd; - -/* - * Receive buffer descriptor - * (flexible memory structure) - */ -typedef volatile struct i596_rbd { - unsigned short count; - unsigned short offset; - volatile struct i596_rbd *next; - char *data; - unsigned short size; - unsigned short pad; -} i596_rbd; - -/* - * Receive Frame Descriptor - */ -typedef volatile struct i596_rfd { - unsigned short stat; - unsigned short cmd; - volatile struct i596_rfd *next; - i596_rbd *pRbd; - unsigned short count; - unsigned short size; - char data [1532]; -} i596_rfd; - -/* - * System Control Block - */ -typedef volatile struct i596_scb { - unsigned short status; - unsigned short command; - unsigned long cmd_pointer; - unsigned long rfd_pointer; - unsigned long crc_err; - unsigned long align_err; - unsigned long resource_err; - unsigned long over_err; - unsigned long rcvdt_err; - unsigned long short_err; - unsigned short t_off; - unsigned short t_on; - i596_cmd *pCmd; - i596_rfd *pRfd; -} i596_scb; - -/* - * Intermediate System Configuration Pointer - */ -typedef volatile struct i596_iscp { - uint8_t null1; /* Always zero */ - uint8_t busy; /* Busy byte */ - unsigned short scb_offset; /* Not used in linear mode */ - unsigned long scb_pointer; /* Swapped pointer to scb */ - i596_scb *scb; /* Real pointer to scb */ -} i596_iscp; - -/* - * System Configuration Pointer - */ -typedef volatile struct i596_scp { - unsigned long sysbus; /* Only low 8 bits are used */ - unsigned long pad; /* Must be zero */ - unsigned long iscp_pointer; /* Swapped pointer to iscp */ - i596_iscp *iscp; /* Real pointer to iscp */ -} i596_scp; - -/* - * Device Dependent Data Structure - */ -typedef volatile struct uti596_softc { - struct arpcom arpcom; - i596_scp *pScp; /* Block aligned on 16 byte boundary */ - i596_scp *base_scp; /* Unaligned block. Need for free() */ - i596_iscp iscp; - i596_scb scb; - i596_set_add set_add; - i596_configure set_conf; - i596_tdr tdr; - i596_nop nop; - i596_tx *pTxCmd; - i596_tbd *pTbd; - - i596_rfd *pBeginRFA; - i596_rfd *pEndRFA; - i596_rfd *pLastUnkRFD; - i596_rbd *pLastUnkRBD; - i596_rfd *pEndSavedQueue; - i596_cmd *pCmdHead; - i596_cmd *pCmdTail; /* unneeded, as chaining not used, but implemented */ - - rtems_id rxDaemonTid; - rtems_id txDaemonTid; - rtems_id resetDaemonTid; - - struct enet_statistics stats; - int started; - unsigned long rxInterrupts; - unsigned long txInterrupts; - volatile int cmdOk; - unsigned short * pCurrent_command_status; - int resetDone; - unsigned long txRawWait; - i596_rfd *pInboundFrameQueue; - short int rxBdCount; - short int txBdCount; - short int countRFD; - short int savedCount; - i596_rfd *pSavedRfdQueue; - rtems_name semaphore_name; - rtems_id semaphore_id; - char zeroes[64]; - unsigned long rawsndcnt; - int nic_reset; /* flag for requesting that ISR issue a reset quest */ -} uti596_softc_; - -#endif /* UTI596_H */ -- cgit v1.2.3