summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/m68k/mvme167/network/network.c
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/m68k/mvme167/network/network.c')
-rw-r--r--c/src/lib/libbsp/m68k/mvme167/network/network.c3753
1 files changed, 1960 insertions, 1793 deletions
diff --git a/c/src/lib/libbsp/m68k/mvme167/network/network.c b/c/src/lib/libbsp/m68k/mvme167/network/network.c
index bcfc07ef00..c8a2e71734 100644
--- a/c/src/lib/libbsp/m68k/mvme167/network/network.c
+++ b/c/src/lib/libbsp/m68k/mvme167/network/network.c
@@ -1,4 +1,4 @@
-/* uti596.c: An 82596 ethernet driver for rtems-bsd.
+/* network.c: An 82596 ethernet driver for rtems-bsd.
*
* $Id$
*/
@@ -9,36 +9,36 @@
* Selectively define to debug the network driver. If you define any of these
* you must run with polled console I/O.
*/
-
-#define DBG_596
-#define DBG_596_RFA
+
+/*
+#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_INIT_2
-/*#define DBG_INIT_3*/
-#define DBG_RESET
-#define DBG_VERSION
+#define DBG_STOP
+#define DBG_RX
#define DBG_ISR
-#define DBG_RAW_ISR
-#define DBG_596_RFD
-#define DBG_FR
-#define DBG_RAW
-#define DBG_ATTACH
-#define DBG_POLLED_CMD
-#define DBG_ADD
-#define DBG_SUPPLY_FD
-
+#define DBG_IOCTL
+#define DBG_STAT
+#define DBG_PACKETS
+*/
/*
* 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 RX_BUF_COUNT 15
+#define TX_BUF_COUNT 4
+#define TX_BD_PER_BUF 4
-#define RBUF_SIZE 1520
+#define RBUF_SIZE 1520
-#define UTI_596_ETH_MIN_SIZE 60
+#define UTI_596_ETH_MIN_SIZE 60
/*
* RTEMS events
@@ -62,21 +62,33 @@
#include <netinet/if_ether.h>
#include "uti596.h"
-#include "netexterns.h"
+/* If we are running interrupt driven I/O no debug output is printed */
#if CD2401_POLLED_IO == 1
- #define printk(arglist) printk arglist;
+ #define printk(arglist) printk arglist;
#else
- #define printk(arglist)
+ #define printk(arglist)
#endif
-#define UTI_596_ASSERT( condition, str ) if (!( condition ) ) { printk((str)) }
+#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
-int count_rx = 0;
-i596_rfd *pISR_Rfd;
+/* 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;
@@ -86,131 +98,1576 @@ 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 */
- 0x0E, /* Byte 8: not promisc, disable 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 */
+ 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 */
};
-/* Required RTEMS network driver functions and tasks (reset daemon extra) */
-
-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 *, int, caddr_t );
-void uti596_stats( uti596_softc_ * );
-
/* Local Routines */
-void uti596_initialize_hardware( uti596_softc_ * );
-void uti596_initMem( uti596_softc_ * );
-int uti596_initRFA( int );
-void uti596addPolledCmd( i596_cmd * );
-void uti596Diagnose( int );
-i596_rfd * uti596dequeue( i596_rfd ** );
-void uti596reset( void );
-void uti596_reset_hardware( uti596_softc_ *);
-void uti596clearListStatus( i596_rfd * );
-void send_packet( struct ifnet *, struct mbuf * );
-void uti596addCmd( i596_cmd *pCmd );
-void uti596supplyFD( i596_rfd * );
-void uti596append( i596_rfd ** , i596_rfd * );
-
-void printk_time( void );
-void dump_scb( void );
-
-#ifdef DBG_INIT_3
+static unsigned long word_swap ( unsigned long );
+static void * malloc_16byte_aligned ( void **, void ** adjusted_pointer, size_t );
+RTEMS_INLINE_ROUTINE void uti596_writePortFunction ( void *, unsigned long );
+RTEMS_INLINE_ROUTINE void uti596_portReset( void );
+static unsigned long uti596_portSelfTest( i596_selftest * );
+static int uti596_portDump ( i596_dump_result * );
+static int uti596_wait ( uti596_softc_ *, unsigned8 );
+static int uti596_issueCA ( uti596_softc_ *, unsigned8 );
+static void uti596_addCmd ( i596_cmd * );
+static void uti596_addPolledCmd ( i596_cmd * );
+static void uti596_CU_dump ( i596_dump_result * );
+static void uti596_dump_scb ( void );
+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 *, int, 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
-int uti596dump( char * );
-void dumpQ( void );
-void show_buffers( void );
-void show_queues( void );
-/* Helper function for reading/writing big endian memory structures */
-unsigned long word_swap(unsigned long);
+
+/*
+ * 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(
+ 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 );
+}
+
+
+/*
+ * 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 );
+
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
+ do {
+ if( stp->results != 0xFFFFFFFF )
+ break;
+ else
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ } 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;
+ }
+}
+
+
+/*
+ * 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 );
+
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
+ do {
+ if( dp->dump_status != 0xA006 )
+ break;
+ else
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ } 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;
+ }
+}
+
+
+/*
+ * uti596_wait
+ *
+ * Wait for a certain condition.
+ *
+ * Input parameters:
+ * sc - pointer to the uti596_softc struct
+ * wait_type - UTI596_NO_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,
+ unsigned8 waitType
+)
+{
+ rtems_interval ticks_per_second, start_ticks, end_ticks;
+
+ switch( waitType ) {
+ case UTI596_NO_WAIT:
+ return 0;
+
+ case UTI596_WAIT_FOR_CU_ACCEPT:
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
+ do {
+ if (sc->scb.command == 0)
+ break;
+ else
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+
+ } 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:
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
+ do {
+ if( !sc->iscp.busy )
+ break;
+ else
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ } 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:
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second);
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ end_ticks = start_ticks + ticks_per_second;
+
+ do {
+ if( *sc->pCurrent_command_status & STAT_C )
+ break;
+ else
+ rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks);
+ } 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,
+ unsigned8 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_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_Enable(level);
+ }
+ else {
+ uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd);
+ uti596_softc.pCmdTail = pCmd;
+ _ISR_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
+}
+
+
+/*
+ * 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 );
+
+}
+
+
+/*
+ * 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%x\n",uti596_softc.scb.crc_err))
+ printk(("align_err 0x%x\n",uti596_softc.scb.align_err))
+ printk(("resource_err 0x%x\n",uti596_softc.scb.resource_err ))
+ printk(("over_err 0x%x\n",uti596_softc.scb.over_err))
+ printk(("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err))
+ printk(("short_err 0x%x\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))
+}
+
+
+/*
+ * 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 = &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 (sc->set_conf.data, uti596initSetup, 14);
+ uti596_addPolledCmd( (i596_cmd *) &sc->set_conf);
+
+ /* Poll for successful command completion */
+ sc->pCurrent_command_status = &(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 = &(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; i<sc->txBdCount; 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 == RX_BUF_COUNT,"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 ( &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 = 0x54;
+
+ /* 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
+)
+{
+ rtems_isr_entry dummy;
+
+ 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
+ */
+ dummy = (rtems_isr_entry) 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_event_send (sc->txDaemonTid,
+ INTERRUPT_EVENT);
+
+ if ( status_code != RTEMS_SUCCESSFUL ) {
+ printk(("****ERROR:Could NOT send event to tid 0x%x : %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 = 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_Disable(level);
+
+ /* invalid address, or empty queue or emptied queue */
+ if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
+ _ISR_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_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))
+ }
+}
-/* Waits for the command word to clear. The command word is cleared AFTER the interrupt is
- * generated. This allows the CPU to issue the next command
+/*
+ * 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
*/
-#define UTI_WAIT_COMMAND_ACCEPTED(duration,function) \
-{ rtems_interval ticks_per_second, start_ticks, end_ticks; \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second); \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks); \
- end_ticks = start_ticks + ticks_per_second; \
- do { \
- if (uti596_softc.scb.command == 0) \
- break; \
- else { \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks); \
- } \
- } while (start_ticks <= end_ticks); \
- if ((uti596_softc.scb.command != 0) || (start_ticks > end_ticks)) \
- printf("%s: i82596 timed out with status %x, cmd %x.\n", function, \
- uti596_softc.scb.status, uti596_softc.scb.command); \
+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(&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( &uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
+
+ uti596_softc.pEndSavedQueue = pRfd; /* reset end of saved queue */
+ uti596_softc.savedCount++;
+
+ return;
+ }
}
-#define UTI_WAIT_TICKS \
-{ rtems_interval ticks_per_second, start_ticks, end_ticks; \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second); \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks); \
- end_ticks = start_ticks + ticks_per_second; \
- do { \
- rtems_clock_get(RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &start_ticks); \
- } while (start_ticks <= end_ticks); \
+
+/*
+ * 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 );
+
+ /* This should never happen */
+ if ( bd_count == 16 ) {
+ printk(("TX ERROR:Too many mbufs in the packet!!!\n"))
+ printk(("Must coalesce!\n"))
+ }
+
+ 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
- *
- ***********************************************************************/
+
+
+/***********************************************************************
+ * 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
)
{
- uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */
- struct ifnet * ifp = &sc->arpcom.ac_if; /* ifnet structure */
+ uti596_softc_ *sc = &uti596_softc; /* device dependent data structure */
+ struct ifnet * ifp = &sc->arpcom.ac_if; /* ifnet structure */
- int unitNumber;
- char *unitName;
+ int unitNumber;
+ char *unitName;
-#ifdef DBG_ATTACH
+ #ifdef DBG_ATTACH
printk(("uti596_attach: begins\n"))
-#endif
+ #endif
/* The NIC is not started yet */
sc->started = 0;
@@ -219,9 +1676,9 @@ int uti596_attach(
ifp->if_softc = sc;
sc->pScp = NULL;
- /* Parse driver name */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)
- return 0;
+ /* Parse driver name */
+ if ((unitNumber = rtems_bsdnet_parse_driver_name (pConfig, &unitName)) < 0)
+ return 0;
ifp->if_name = unitName;
ifp->if_unit = unitNumber;
@@ -232,13 +1689,16 @@ int uti596_attach(
else
ifp->if_mtu = ETHERMTU;
- /* For now the ethernet address must be specified in the ifconfig structure,
- * else FIXME so it can be read in from BBRAM at $FFFC1F2C (6 bytes)
+ /* Ethernet address can be specified in the ifconfig structure or
+ * it can be read in from BBRAM at $FFFC1F2C (6 bytes)
* mvme167 manual p. 1-47
*/
if ( pConfig->hardware_address) {
memcpy (sc->arpcom.ac_enaddr, pConfig->hardware_address, ETHER_ADDR_LEN);
}
+ else {
+ memcpy (sc->arpcom.ac_enaddr, (char *)0xFFFC1F2C, ETHER_ADDR_LEN);
+ }
/* Assign requested receive buffer descriptor count */
if (pConfig->rbuf_count)
@@ -253,9 +1713,9 @@ int uti596_attach(
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_flags = IFF_BROADCAST | IFF_SIMPLEX;
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_init = uti596_init;
+ ifp->if_init = uti596_init;
ifp->if_ioctl = uti596_ioctl;
ifp->if_start = uti596_start;
ifp->if_output = ether_output;
@@ -280,7 +1740,7 @@ int uti596_attach(
* start the driver
*
* Algorithm:
- * send an event to the tx task
+ * send an event to the tx task
* set the if_flags
*
***********************************************************************/
@@ -289,9 +1749,11 @@ static void uti596_start(
)
{
uti596_softc_ *sc = ifp->if_softc;
-#ifdef DBG_INIT
+
+ #ifdef DBG_START
printk(("uti596_start: begins\n"))
-#endif
+ #endif
+
rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
ifp->if_flags |= IFF_OACTIVE;
}
@@ -322,43 +1784,42 @@ void uti596_init(
/*
* Initialize the 82596
*/
-#ifdef DBG_INIT
+ #ifdef DBG_INIT
printk(("uti596_init: begins\nuti596_init: initializing the 82596...\n"))
-#endif
+ #endif
uti596_initialize_hardware(sc);
/*
* Start driver tasks
*/
-#ifdef DBG_INIT
+ #ifdef DBG_INIT
printk(("uti596_init: starting driver tasks...\n"))
-#endif
+ #endif
sc->txDaemonTid = rtems_bsdnet_newproc ("UTtx", 2*4096, uti596_txDaemon, sc);
sc->rxDaemonTid = rtems_bsdnet_newproc ("UTrx", 2*4096, uti596_rxDaemon, sc);
sc->resetDaemonTid = rtems_bsdnet_newproc ("UTrt", 2*4096, uti596_resetDaemon, sc);
-#ifdef DBG_INIT
+ #ifdef DBG_INIT
printk(("uti596_init: After attach, status of board = 0x%x\n", sc->scb.status ))
-#endif
+ #endif
}
/*
* Enable receiver
*/
-#ifdef DBG_INIT
+ #ifdef DBG_INIT
printk(("uti596_init: enabling the reciever...\n" ))
-#endif
+ #endif
sc->scb.command = RX_START;
- i82596->chan_attn = 0x00000000;
- UTI_WAIT_COMMAND_ACCEPTED(4000,"uti596_init: 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
+ #ifdef DBG_INIT
printk(("uti596_init: completed.\n"))
-#endif
+ #endif
}
/***********************************************************************
@@ -374,23 +1835,21 @@ void uti596_init(
* clean-up all buffers ( RFD's et. al. )
*
*
- *
- *
***********************************************************************/
/* static */ void uti596_stop(
uti596_softc_ *sc
)
{
- struct ifnet *ifp = &sc->arpcom.ac_if;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
- ifp->if_flags &= ~IFF_RUNNING;
+ ifp->if_flags &= ~IFF_RUNNING;
sc->started = 0;
-#ifdef DBG_596
+ #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
+ #endif
printk(("Stopping interface\n"))
sc->scb.command = CUC_ABORT | RX_ABORT;
@@ -468,144 +1927,126 @@ void uti596_txDaemon(
struct ether_header *eh;
int frames = 0;
-#ifdef DBG_INIT_3
- int i;
-#endif
-#ifdef DBG_596
+ #ifdef DBG_RX
printk(("uti596_rxDaemon: begin\n"))
printk(("&scb = %p, pRfd = %p\n", &sc->scb,sc->scb.pRfd))
-#endif
+ #endif
rtems_task_ident (0, 0, &tid);
-#ifdef DBG_596
- printk(("uti596_rxDaemon: RX tid = 0x%x\n", tid))
-#endif
+ 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( &sc->pInboundFrameQueue);
+ while ( pRfd &&
+ pRfd != I596_NULL &&
+ pRfd -> stat & STAT_C )
+ {
- for(;;) {
- /*
- * Wait for packet.
- */
-#ifdef DBG_596
- printk(("uti596_rxDaemon: Receiver sleeps\n"))
-#endif
+ if ( pRfd->stat & STAT_OK) { /* a good frame */
+ int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
+ #ifdef DBG_RX
+ printk(("uti596_rxDaemon: Good frame, @%p, data @%p length %d\n", pRfd, pRfd -> data , pkt_len))
+ #endif
+ frames++;
-#ifdef DBG_596
- 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 = uti596dequeue( &sc->pInboundFrameQueue);
- while ( pRfd &&
- pRfd != I596_NULL &&
- pRfd -> stat & STAT_C )
- {
-
-#ifdef DBG_INIT_3
- printk(("\nuti596_rxDaemon: Received packet:\n"))
- print_eth( pRfd->data);
-#endif
- if ( pRfd->stat & STAT_OK) { /* a good frame */
- int pkt_len = pRfd->count & 0x3fff; /* the actual # of bytes received */
-
-#ifdef DBG_596
- 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:
- * <ethernet header, payload>.
- * 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,
- 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_596
- printk(("uti596_rxDaemon: m->m_ext: %p pRfd -> data: %p\n",
- m->m_ext, pRfd->data))
-#endif
-#ifdef DBG_INIT_3
- 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 */
+ /*
+ * Allocate an mbuf to give to the stack
+ * The format of the data portion of the RFD is:
+ * <ethernet header, payload>.
+ * 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, 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++;
+ }
- else {
- /*
- * A bad frame is present: Note that this could be the last RFD!
- */
-#ifdef DBG_596
- 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")
- UTI_596_ASSERT(pRfd != I596_NULL, "Supplying NULL RFD\n")
+ _ISR_Disable(level);
+ uti596_supplyFD ( pRfd ); /* Return RFD to RFA. */
+ _ISR_Enable(level);
-#ifdef DBG_SUPPLY_FD
- printk(("uti596_rxDaemon: Supply FD Starting\n"))
-#endif
- _ISR_Disable(level);
- uti596supplyFD ( pRfd ); /* Return RFD to RFA. */
- _ISR_Enable(level);
-#ifdef DBG_SUPPLY_FD
- printk(("uti596_rxDaemon: Supply FD Complete\n"))
-#endif
- pRfd = uti596dequeue( &sc->pInboundFrameQueue); /* grab next frame */
+ pRfd = uti596_dequeue( &sc->pInboundFrameQueue); /* grab next frame */
- } /* end while */
- } /* end for(;;) */
+ } /* end while */
+ } /* end for() */
-#ifdef DBG_596
- printk (("uti596_rxDaemon: frames ... %d\n", frames))
-#endif
+ #ifdef DBG_RX
+ printk (("uti596_rxDaemon: frames ... %d\n", frames))
+ #endif
}
+
/***********************************************************************
* Function: void uti596_resetDaemon
*
@@ -634,31 +2075,29 @@ void uti596_resetDaemon(
sc->stats.nic_reset_count++;
/* Reinitialize the LANC */
rtems_bsdnet_semaphore_obtain ();
- uti596reset();
+ uti596_reset();
rtems_bsdnet_semaphore_release ();
}
}
- /***********************************************************************
- * Function: uti596_DynamicInterruptHandler
- *
- * Description:
- * This is the interrupt handler for the uti596 board
- *
- * Algorithm:
- *
- ***********************************************************************/
+/***********************************************************************
+ * Function: uti596_DynamicInterruptHandler
+ *
+ * Description:
+ * This is the interrupt handler for the uti596 board
+ *
+ ***********************************************************************/
/* static */ rtems_isr uti596_DynamicInterruptHandler(
rtems_vector_number irq
)
{
-#ifdef DEBUG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: begins"))
-#endif
+ #endif
- UTI_WAIT_COMMAND_ACCEPTED(20000,"****ERROR:on ISR entry");
+ uti596_wait (&uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT);
scbStatus = uti596_softc.scb.status & 0xf000;
@@ -676,14 +2115,14 @@ void uti596_resetDaemon(
/* Send the CA signal to acknowledge interrupt */
uti596_softc.scb.command = scbStatus;
- i82596->chan_attn = 0x00000000;
+ uti596_issueCA ( &uti596_softc, UTI596_NO_WAIT );
if( uti596_softc.resetDone ) {
/* stack is attached */
- UTI_WAIT_COMMAND_ACCEPTED(20000,"****ERROR:ACK");
+ uti596_wait ( &uti596_softc, UTI596_WAIT_FOR_CU_ACCEPT );
}
else {
- /* printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus)) */
+ printk(("***INFO: ACK'd w/o processing. status = %x\n", scbStatus))
return;
}
}
@@ -693,43 +2132,38 @@ void uti596_resetDaemon(
}
- if ( (scbStatus & SCB_STAT_CX) && !(scbStatus & SCB_STAT_CNA) ){
- printk_time();
+ 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_time();
printk(("\n*****ERROR: CNA, NO CX:0x%x\nResetting...",scbStatus))
uti596_softc.nic_reset = 1;
return;
}
if ( scbStatus & SCB_CUS_SUSPENDED ) {
- printk_time();
printk(("\n*****ERROR: Command unit suspended!:0x%x\nResetting...",scbStatus))
uti596_softc.nic_reset = 1;
return;
}
if ( scbStatus & RU_SUSPENDED ) {
- printk_time();
printk(("\n*****ERROR: Receive unit suspended!:0x%x\nResetting...",scbStatus))
uti596_softc.nic_reset = 1;
return;
}
if ( scbStatus & SCB_STAT_RNR ) {
- printk_time();
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))
+ 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"))
+ printk(("*****WARNING: RNR condition with NULL BeginRFA\n"))
}
}
@@ -740,37 +2174,37 @@ void uti596_resetDaemon(
if ( scbStatus & SCB_STAT_FR ) {
uti596_softc.rxInterrupts++;
-#ifdef DBG_FR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: Frame received\n"))
-#endif
+ #endif
if ( uti596_softc.pBeginRFA == I596_NULL ||
- !( uti596_softc.pBeginRFA -> stat & STAT_C)) {
- dump_scb();
- uti596_softc.nic_reset = 1;
+ !( uti596_softc.pBeginRFA -> stat & STAT_C)) {
+ uti596_dump_scb();
+ uti596_softc.nic_reset = 1;
}
else {
while ( uti596_softc.pBeginRFA != I596_NULL &&
( uti596_softc.pBeginRFA -> stat & STAT_C)) {
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: pBeginRFA != NULL\n"))
-#endif
+ #endif
count_rx ++;
if ( count_rx > 1) {
printk(("****WARNING: Received 2 frames on 1 interrupt \n"))
- }
+ }
/* 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 */
- uti596append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
+ uti596_append( &uti596_softc.pInboundFrameQueue , uti596_softc.pBeginRFA );
/*
* if we have just received the a frame in the last unknown RFD,
@@ -781,19 +2215,19 @@ void uti596_resetDaemon(
uti596_softc.pEndRFA = uti596_softc.pLastUnkRFD = I596_NULL;
}
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: Wake %#x\n",uti596_softc.rxDaemonTid))
-#endif
+ #endif
sc = rtems_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_RAW_ISR
+ #ifdef DBG_ISR
else {
printk(("uti596_DynamicInterruptHandler: Rx Wake: %#x\n",uti596_softc.rxDaemonTid))
- }
-#endif
+ }
+ #endif
uti596_softc.pBeginRFA = pIsrRfd;
} /* end while */
@@ -804,7 +2238,7 @@ void uti596_resetDaemon(
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",
@@ -819,18 +2253,18 @@ void uti596_resetDaemon(
* a command is completed
*/
if ( scbStatus & SCB_STAT_CX ) {
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: CU\n"))
-#endif
+ #endif
pIsrCmd = uti596_softc.pCmdHead;
/* For ALL completed commands */
if ( pIsrCmd != I596_NULL && pIsrCmd->status & STAT_C ) {
-#ifdef DBG_RAW_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: pIsrCmd != NULL\n"))
-#endif
+ #endif
/* Adjust the command block list */
uti596_softc.pCmdHead = (i596_cmd *) word_swap ((unsigned long)pIsrCmd->next);
@@ -846,21 +2280,20 @@ void uti596_resetDaemon(
switch ( pIsrCmd->command & 0x7) {
case CmdConfigure:
- /* printk(("****INFO:Configure OK\n")) */
uti596_softc.cmdOk = 1;
break;
case CmdDump:
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: dump!\n"))
-#endif
+ #endif
uti596_softc.cmdOk = 1;
break;
case CmdDiagnose:
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: diagnose!\n"))
-#endif
+ #endif
uti596_softc.cmdOk = 1;
break;
@@ -871,14 +2304,14 @@ void uti596_resetDaemon(
}
else {
printk(("****ERROR:SET ADD FAILED\n"))
- }
+ }
break;
case CmdTx:
UTI_596_ASSERT(uti596_softc.txDaemonTid, "****ERROR:Null txDaemonTid\n")
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: wake TX:0x%x\n",uti596_softc.txDaemonTid))
-#endif
+ #endif
if ( uti596_softc.txDaemonTid ) {
/* Ensure that the transmitter is present */
sc = rtems_event_send (uti596_softc.txDaemonTid,
@@ -888,11 +2321,11 @@ void uti596_resetDaemon(
printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
uti596_softc.txDaemonTid, rtems_status_text (sc) ))
}
-#ifdef DBG_RAW_ISR
+ #ifdef DBG_ISR
else {
printk(("****INFO:Tx wake: %#x\n",uti596_softc.txDaemonTid))
}
-#endif
+ #endif
}
break;
@@ -902,25 +2335,25 @@ void uti596_resetDaemon(
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)) */
- }
- }
+ 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;
@@ -942,7 +2375,6 @@ void uti596_resetDaemon(
if ( pIsrCmd != I596_NULL ) {
/* The command MAY be NULL from a RESET */
/* Reset the ethernet card, and wake the transmitter (if necessary) */
- printk_time();
printk(("****INFO: Request board reset ( tx )\n"))
uti596_softc.nic_reset = 1;
if ( uti596_softc.txDaemonTid) {
@@ -950,13 +2382,15 @@ void uti596_resetDaemon(
sc = rtems_event_send (uti596_softc.txDaemonTid,
INTERRUPT_EVENT);
if ( sc != RTEMS_SUCCESSFUL ) {
- printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",uti596_softc.txDaemonTid, rtems_status_text (sc) ))
- }
-#ifdef DBG_RAW_ISR
+ printk(("****ERROR:Could NOT send event to tid 0x%x : %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
+ printk(("uti596_DynamicInterruptHandler: ****INFO:Tx wake: %#x\n",
+ uti596_softc.txDaemonTid))
+ }
+ #endif
}
}
}
@@ -970,9 +2404,10 @@ void uti596_resetDaemon(
*/
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
+ #ifdef DBG_ISR
+ printk(("uti596_DynamicInterruptHandler: INFO:RNR: status %#x \n",
+ uti596_softc.scb.status ))
+ #endif
/*
* THE RECEIVER IS OFF!
*/
@@ -990,7 +2425,7 @@ void uti596_resetDaemon(
if ( uti596_softc.pEndRFA != I596_NULL ) {
/* check added feb24. */
-#ifdef DEBUG_RFA
+ #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,
@@ -1000,10 +2435,10 @@ void uti596_resetDaemon(
uti596_softc.countRFD))
printk(("\n\n"))
}
-#endif
+ #endif
uti596_softc.pEndRFA -> next = I596_NULL; /* added feb 16 */
}
- uti596append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
+ uti596_append( &uti596_softc.pSavedRfdQueue, uti596_softc.pLastUnkRFD );
uti596_softc.savedCount++;
uti596_softc.pEndSavedQueue = uti596_softc.pLastUnkRFD;
uti596_softc.countRFD--; /* It was not in the RFA */
@@ -1012,12 +2447,12 @@ void uti596_resetDaemon(
* with the chip.
*/
if ( uti596_softc.pBeginRFA == uti596_softc.pLastUnkRFD ) {
-#ifdef DEBUG_RFA
+ #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
+ #endif
uti596_softc.pBeginRFA = I596_NULL;
UTI_596_ASSERT(uti596_softc.countRFD == 0, "****ERROR:Count must be zero here!\n")
}
@@ -1034,23 +2469,23 @@ void uti596_resetDaemon(
/* entries to add */
if ( uti596_softc.pBeginRFA == I596_NULL ) {
/* add at beginning to list */
-#ifdef DEBUG_RFA
+ #ifdef DBG_ISR
if(uti596_softc.countRFD != 0) {
printk(("****ERROR:Begin pointer is NULL, but count == %d\n",
uti596_softc.countRFD))
}
-#endif
+ #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 DEBUG_RFA
+ #ifdef DBG_ISR
if ( uti596_softc.countRFD <= 0) {
printk(("****ERROR:Begin pointer is not NULL, but count == %d\n",
uti596_softc.countRFD))
}
-#endif
+ #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")
@@ -1058,11 +2493,11 @@ void uti596_resetDaemon(
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 DEBUG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: count... %d, saved ... %d \n",
uti596_softc.countRFD,
uti596_softc.savedCount))
-#endif
+ #endif
}
/* printk(("Isr: countRFD = %d\n",uti596_softc.countRFD)) */
uti596_softc.countRFD += uti596_softc.savedCount;
@@ -1070,18 +2505,17 @@ void uti596_resetDaemon(
uti596_softc.savedCount = 0;
}
-#ifdef DBG_596_RFD
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: The list starts here %p\n",uti596_softc.pBeginRFA ))
-#endif
+ #endif
if ( uti596_softc.countRFD > 1) {
- printk_time();
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_val = word_swap((unsigned long)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? */
@@ -1090,9 +2524,9 @@ void uti596_resetDaemon(
} /* end stat_rnr */
} /* end if receiver started */
-#ifdef DBG_ISR
+ #ifdef DBG_ISR
printk(("uti596_DynamicInterruptHandler: X\n"))
-#endif
+ #endif
count_rx=0;
@@ -1106,6 +2540,7 @@ void uti596_resetDaemon(
return;
}
+
/***********************************************************************
* Function: uti596_ioctl
*
@@ -1113,8 +2548,6 @@ void uti596_resetDaemon(
* driver ioctl function
* handles SIOCGIFADDR, SIOCSIFADDR, SIOCSIFFLAGS
*
- * Algorithm:
- *
***********************************************************************/
static int uti596_ioctl(
@@ -1125,9 +2558,9 @@ static int uti596_ioctl(
uti596_softc_ *sc = ifp->if_softc;
int error = 0;
-#ifdef DBG_INIT
+ #ifdef DBG_IOCTL
printk(("uti596_ioctl: begins\n", sc->pScp))
-#endif
+ #endif
switch (command) {
case SIOCGIFADDR:
@@ -1176,6 +2609,7 @@ static int uti596_ioctl(
return error;
}
+
/***********************************************************************
* Function: uti596_stats
*
@@ -1191,7 +2625,7 @@ void uti596_stats(
uti596_softc_ *sc
)
{
- printf("CPU Reports:\n");
+ 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);
@@ -1219,1221 +2653,143 @@ void uti596_stats(
printf (" NIC resets: %-8u\n", sc->stats.nic_reset_count);
- printf(" NIC reports\n");
+ printf (" NIC reports\n");
- dump_scb();
+ #ifdef DBG_STAT
+ uti596_dump_scb();
+ #endif
}
-/***********************************************************************
- *************************** LOCAL ROUTINES ****************************
- ***********************************************************************/
-/***********************************************************************
- * Function: void uti596_initialize_hardware
- *
- * Description:
- ***********************************************************************/
-void uti596_initialize_hardware(
- uti596_softc_ *sc
-)
-{
- int boguscnt = 1000;
- rtems_isr_entry dummy;
+/************************ PACKET DEBUG ROUTINES ************************/
- printk(("uti596_initialize_hardware: begins\n"))
-
- pccchip2->LANC_berr_ctl = 0x40; /* Enable snooping */
-
- /* reset the board */
- i82596->port_lower = 0x0000; /* Each Port access must consist of two 16-bit writes */
- i82596->port_upper = 0x0000;
-
- /* allocate enough memory for the Scp block to be aligned on 16 bit boundary */
- uti596_softc.pScp = (i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
-
-#ifdef DBG_INIT
- printk(("uti596_initialize_hardware: Scp address initially %p\n", sc->pScp))
-#endif
-
- /* align the block */
- sc->pScp = (i596_scp *)
- ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
-
-#ifdef DBG_INIT
- printk(("uti596_initialize_hardware: change scp address to : %p\n",sc->pScp))
-#endif
-
- /* change the scp address */
-#ifdef DBG_INIT
- printk(("uti596_initialize_hardware: Change the SCP address\n"))
-#endif
-
- /* reset the board */
- i82596->port_lower = 0x0000;
- i82596->port_upper = 0x0000;
-
- /* supply the Scp address
- * Lower Command Word D31-D16; Upper Command Word D15-D0
- */
- i82596->port_lower = (((int)sc->pScp) & 0xfff0) | 0x0002;
- i82596->port_upper = (((int)sc->pScp) >> 16 ) & 0xffff;
-
-
- /* write the SYSBUS: interrupt pin active high, LOCK disabled,
- * internal triggering, linear mode
- */
- sc->pScp->sysbus = word_swap(0x00540000);
-
- /* provide the iscp to the scp, keep a pointer for our use */
- sc->pScp->iscp_val = 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_val = word_swap((unsigned long)&sc->scb);
- sc->iscp.scb = &sc->scb;
-
- /* set the busy flag in the iscp */
- sc->iscp.stat = word_swap(0x00000001);
-
- /* the command block list (CBL) is empty */
- sc->scb.Cmd_val = (unsigned long) I596_NULL; /* all 1's */
- sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */
-
-#ifdef DBG_596
- printk(("uti596_initialize_hardware: Starting i82596.\n"))
-#endif
-
- /* Issue CA: pass the scb address to the 596 */
- i82596->chan_attn = 0x00000000;
-
- UTI_WAIT_TICKS
-
- /* Wait for the 596 to read the SCB address and clear 'stat' */
- while (sc->iscp.stat) {
- if (--boguscnt == 0) {
- printk(("initialize_hardware: timed out with status %4.4lx\n",
- sc->iscp.stat ))
- break;
- }
- } /* end while */
-
- /* clear the scb command word */
- sc->scb.command = 0;
-
- /*
- * 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
- */
- dummy = (rtems_isr_entry) 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
-}
-
-/***********************************************************************
- * Function: uti596_initMem
- *
- * Description:
- * creates the necessary descriptors for the
- * uti596 board, hooks the interrupt, and starts the board.
- * Assumes that interrupts are hooked.
- *
- * Algorithm:
- *
- ***********************************************************************/
-
-void uti596_initMem(
- uti596_softc_ * sc
-)
-{
- int i,count;
- i596_tbd *pTbd, *pPrev;
-
-#ifdef DBG_INIT
- printk(("uti596_initMem: begins\n"))
-#endif
-
- sc->resetDone = 0;
-
- /*
- * Set up receive frame area (RFA)
- */
-#ifdef DBG_INIT
- printk(("uti596_initMem: Initializing the RFA...\n"))
-#endif
- i = uti596_initRFA( sc->rxBdCount );
- if ( i < sc->rxBdCount ) {
- printk(("init_rfd: only able to allocate %d receive frame descriptors\n", i))
- }
-
- sc->scb.Rfd_val = word_swap((unsigned long)sc->pBeginRFA);
- sc->scb.pRfd = sc->pBeginRFA;
-
- /*
- * Diagnose the health of the board
- * send the CU a diagnostic command
- */
-#ifdef DBG_INIT
- printk(("uti596_initMem: Running diagnostics...\n"))
-#endif
- uti596Diagnose(1);
-
- /*
- * Configure the 82596
- * send the CU a configure command with our initial setup
- */
-#ifdef DBG_INIT
- printk(("uti596_initMem: Configuring...\n"))
-#endif
- sc->set_conf.cmd.command = CmdConfigure;
- memcpy (sc->set_conf.data, uti596initSetup, 14);
- uti596addPolledCmd( (i596_cmd *) &sc->set_conf);
-
- /* Poll for successful command completion */
- count = 2000;
- while( !( sc->set_conf.cmd.status & STAT_C ) && --count ) {
- printk(("."))
- }
-
- if ( count ) {
- printk(("Configure OK, count = %d\n",count))
- }
- else {
- printk(("***Configure failed\n"))
- }
- /*
- * Set up the Internet Address
- * send the CU an IA-setup command
- */
-#ifdef DBG_INIT
- printk(("uti596_initMem: Setting Address...\n"))
-#endif
- sc->set_add.cmd.command = CmdSASetup;
- for ( i=0; i<6; i++) {
- sc->set_add.data[i]=sc->arpcom.ac_enaddr[i];
-#ifdef DBG_INIT
- printk(("uti596_initMem: copying byte %d: 0x%x\n", i, sc->set_add.data[i]))
-#endif
- }
- sc->cmdOk = 0;
- uti596addPolledCmd((i596_cmd *)&sc->set_add);
-
- /* Poll for successful command completion */
- count = 2000;
- while( !(sc->set_add.cmd.status & STAT_C ) && --count) {
- printk(("."))
- }
-
- if ( count ) {
- printk(("Set Address OK, count= %d\n",count))
- }
- else {
- printk(("Set Address Failed\n"))
- }
-#ifdef DBG_INIT
- printk(( "uti596_initMem: After initialization, status and command: 0x%x, 0x%x\n",
- sc->scb.status, sc->scb.status))
-#endif
+#ifdef DBG_PACKETS
- /*
- *Initialize transmit buffer descriptors
- */
-#ifdef DBG_INIT
- printk(( "uti596_initMem:Initializing TBDs...\n"))
-#endif
- sc->pLastUnkRFD = I596_NULL;
- sc->pTxCmd = (i596_tx *) calloc (1,sizeof (struct i596_tx) );
- sc->pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
- 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; i<sc->txBdCount; i++) {
- pTbd = (i596_tbd *) calloc (1,sizeof (struct i596_tbd) );
- pPrev->next = (i596_tbd *) word_swap ((unsigned long) pTbd);
- pPrev = pTbd;
- }
- pTbd->next = I596_NULL;
-
- /* Padding used to fill short tx frames */
- memset ( &sc->zeroes, 0, 64);
-
-#ifdef DBG_596
- printk(( "uti596_initMem: After receiver start, status and command: 0x%x, 0x%x\n",
- sc->scb.status, sc->scb.status))
-#endif
-
-#ifdef DBG_596
- printk(("uti596_initMem allows ISR's\n"))
-#endif
- sc->resetDone = 1; /* now need ISR */
-}
-
-/***********************************************************************
- * Function: uti596initRFA(int num)
- *
- * Description:
- * attempts to allocate and initialize ( chain together )
- * the requested number of FD's
- *
- * Algorithm:
- *
- ***********************************************************************/
-
-int uti596_initRFA( int num )
-{
- i596_rfd *pRfd;
- int i = 0;
-
-#ifdef DBG_596
- 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;
- printk(("First Rfd allocated @: %p\n",
- uti596_softc.pBeginRFA))
- }
-
- /* Create remaining RFAs */
- 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 */
-#ifdef DBG_596_RFA
- printk(("uti596_initRFA: Allocated RFD @ %p\n", pRfd))
-#endif
- }
- 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 == RX_BUF_COUNT,"INIT:WRONG RFD COUNT\n" )
-
-#ifdef DBG_596_RFA
- 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
- /* 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 ) */
- if ( pRfd -> data == NULL ) {
- printk(("Can't allocate the RFD data buffer\n"))
- }
- }
-
- /* 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 */
-}
-
- /***********************************************************************
- * Function: uti596addPolledCmd
- *
- * Description:
- * This routine issues a single command then polls for it's
- * completion.
- *
- * Algorithm:
- * Give the command to the driver. ( CUC_START is ALWAYS required )
- * Poll for completion.
- *
- ***********************************************************************/
-
-void uti596addPolledCmd(
- i596_cmd *pCmd
-)
-{
-
- #ifdef DBG_596
- printk(("uti596addPolledCmd: Adding command 0x%x\n", pCmd -> command ))
- #endif
-
-#ifdef DBG_POLLED_CMD
-
- switch ( pCmd -> command & 0x7 ) { /* check bottom 3 bits */
- case CmdConfigure:
- printk(("uti596addPolledCmd: Configure Command 0x%x\n", pCmd->command))
- break;
- case CmdSASetup:
- printk(("uti596addPolledCmd: Set CMDress Command 0x%x\n", pCmd->command))
- break;
- case CmdMulticastList:
- printk(("uti596addPolledCmd: Multi-cast list 0x%x\n", pCmd->command))
- break;
- case CmdNOp:
- printk(("uti596addPolledCmd: NO op 0x%x\n", pCmd->command))
- break;
- case CmdTDR:
- printk(("uti596addPolledCmd: TDR 0x%x\n", pCmd->command))
- break;
- case CmdDump:
- printk(("uti596addPolledCmd: Dump 0x%x\n", pCmd->command))
- break;
- case CmdDiagnose:
- printk(("uti596addPolledCmd: Diagnose 0x%x\n", pCmd->command))
- break;
- case CmdTx:
- break;
- default:
- printk(("PolledCMD: ****Unknown Command encountered 0x%x\n", pCmd->command))
- break;
- } /* end switch */
-
-#endif
-
- pCmd->status = 0;
- pCmd->command |= CMD_EOL ; /* only command in list*/
-
- pCmd->next = I596_NULL;
-
- UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: wait prev");
-
- uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = pCmd;
- uti596_softc.scb.Cmd_val = word_swap((unsigned long)pCmd);
- uti596_softc.scb.command = CUC_START;
- i82596->chan_attn = 0x00000000;
-
- UTI_WAIT_COMMAND_ACCEPTED(10000,"Add Polled command: start");
- uti596_softc.pCmdHead = uti596_softc.pCmdTail = uti596_softc.scb.pCmd = I596_NULL;
- uti596_softc.scb.Cmd_val = (unsigned long) I596_NULL;
-
-#ifdef DBG_POLLED_CMD
- printk(("uti596addPolledCmd: Scb status & command 0x%x 0x%x\n",
- uti596_softc.scb.status,
- uti596_softc.scb.command ))
-#endif
-}
-
-
-/***********************************************************************
- * Function: void uti596Diagnose
- *
- * Description:
- *
- ***********************************************************************/
-void uti596Diagnose(
- int verbose
-)
-{
- i596_cmd diagnose;
- int count=10000;
-
- diagnose.command = CmdDiagnose;
- diagnose.status = 0;
- uti596addPolledCmd(&diagnose);
- while( !( diagnose.status & STAT_C ) && count ) {
- if(verbose) {
- printk(("."))
- }
- count --;
- }
- if(verbose) {
- printk(("Status diagnostic: 0xa000 is a success ... 0x%2.2x\n", diagnose.status))
- }
-}
-
-/***********************************************************************
- * Function: void uti596dequeue
- *
- * Description:
- * removes an RFD from the received frame queue,
- *
- * Algorithm:
- *
- ***********************************************************************/
-i596_rfd * uti596dequeue(
- i596_rfd ** ppQ
-)
-{
- ISR_Level level;
-
- i596_rfd * pRfd;
- _ISR_Disable(level);
-
- /* invalid address, or empty queue or emptied queue */
- if( ppQ == NULL || *ppQ == NULL || *ppQ == I596_NULL) {
- _ISR_Enable(level);
- return I596_NULL;
- }
-
- pRfd = *ppQ; /* The dequeued buffer */
- *ppQ = (i596_rfd *) \
- word_swap ((unsigned long) pRfd->next); /* advance the queue pointer */
- pRfd->next = I596_NULL; /* unlink the rfd being returned */
-
- _ISR_Enable(level);
- return pRfd;
-}
-
-/***********************************************************************
- * Function: void uti596reset
+/*
+ * dumpQ
*
- * Description:
- ***********************************************************************/
-void uti596reset( void )
+ * Dumps frame queues for debugging
+ */
+static void dumpQ( void )
{
- int i,count;
- uti596_softc_ *sc = &uti596_softc;
- /* i596_rfd * pRfd; */
-
-#ifdef DBG_RESET
- printk(("uti596reset: begin\n"))
-#endif
-
- sc->resetDone = 0;
- UTI_WAIT_COMMAND_ACCEPTED(10000, "reset: wait for previous command complete");
- uti596_reset_hardware(&uti596_softc); /* reset the ethernet hardware. must re-config */
-
-#ifdef DBG_RESET
- uti596Diagnose(1);
-#endif
-
- sc->set_conf.cmd.command = CmdConfigure;
- memcpy (sc->set_conf.data, uti596initSetup, 14);
- uti596addPolledCmd( (i596_cmd *) &sc->set_conf);
-
- /* POLL */
- count = 2000;
- while( !( sc->set_conf.cmd.status & STAT_C ) && --count ) {
- printk(("."))
- }
-
- if ( count ) {
- printk(("Configure OK, count = %d\n",count))
- }
- else {
- printk(("reset: Configure failed\n"))
- }
-
- /*
- * Create the IA setup command
- */
-
-#ifdef DBG_RESET
- printk(("uti596reset: Setting Address\n"))
-#endif
- 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;
- uti596addPolledCmd((i596_cmd *)&sc->set_add);
+ i596_rfd *pRfd;
- count = 2000;
- while( !(sc->set_add.cmd.status & STAT_C ) && --count) {
- printk(("."))
- }
- if ( count ) {
- printk(("Reset Set Address OK, count= %d\n",count))
- }
- else {
- printk(("Reset Set Address Failed\n"))
+ printk(("savedQ:\n"))
+
+ for( pRfd = uti596_softc.pSavedRfdQueue;
+ pRfd != I596_NULL;
+ pRfd = pRfd -> next) {
+ printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
}
-
- sc->pCmdHead = sc->pCmdTail = sc->scb.pCmd = I596_NULL;
-
-#ifdef DBG_RESET
- printk(( "uti596reset: After reset, status and command: 0x%x, 0x%x\n",
- sc->scb.status, sc->scb.status))
-#endif
-
- /* restore the RFA */
-
- /* dumpQ(); */
-
- if ( sc->pLastUnkRFD != I596_NULL ) {
- sc-> pEndRFA = sc->pLastUnkRFD; /* The end position can be updated */
- sc-> pLastUnkRFD = I596_NULL;
+
+ printk(("Inbound:\n"))
+
+ for( pRfd = uti596_softc.pInboundFrameQueue;
+ pRfd != I596_NULL;
+ pRfd = pRfd -> next) {
+ printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
}
-
- sc->pEndRFA->next = sc->pSavedRfdQueue;
- if ( sc->pSavedRfdQueue != I596_NULL ) {
- sc->pEndRFA = sc->pEndSavedQueue;
- sc->pSavedRfdQueue = sc->pEndSavedQueue = I596_NULL;
- sc -> countRFD = sc->rxBdCount ;
+
+ printk(("Last Unk: %p\n", uti596_softc.pLastUnkRFD ))
+ printk(("RFA:\n"))
+
+ for( pRfd = uti596_softc.pBeginRFA;
+ pRfd != I596_NULL;
+ pRfd = pRfd -> next) {
+ printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
}
-
- sc->scb.pRfd = sc->pBeginRFA; /* readdress the head of the RFA in the SCB */
- sc->scb.Rfd_val = word_swap((unsigned long)sc->pBeginRFA);
-
- uti596clearListStatus(sc->pBeginRFA );
-
- /* dumpQ(); */
-
- printk(("Reset:Starting NIC\n"))
- sc->scb.command = RX_START;
- sc->started = 1; /* we assume that the start works */
- sc->resetDone = 1;
- i82596->chan_attn = 0x00000000;
- UTI_WAIT_COMMAND_ACCEPTED(4000, "reset");
- printk(("Reset:Start complete \n"))
- UTI_596_ASSERT(sc->pCmdHead == I596_NULL, "Reset: CMD not cleared\n")
-
-#ifdef DBG_RESET
- printk(("uti596reset: completed\n"))
-#endif
}
-/***********************************************************************
- * Function: void uti596_reset_hardware
- *
- * Description:
- ***********************************************************************/
-void uti596_reset_hardware(
- uti596_softc_ *sc
-)
+/*
+ * show_buffers
+ *
+ * Print out the RFA and frame queues
+ */
+static void show_buffers (void)
{
- int boguscnt = 1000;
- rtems_status_code status_code;
- i596_cmd *pCmd;
-
-
- printk(("uti596_reset_hardware\n"))
- pCmd = sc->pCmdHead; /* This is a tx command for sure (99.99999%) */
-
- /* reset the board */
- i82596->port_lower = 0x0000;
- i82596->port_upper = 0x0000;
-
- if ( sc->pScp == NULL ) {
- printk(("Calloc scp\n"))
- uti596_softc.pScp = (i596_scp *) calloc(1,sizeof(struct i596_scp) + 0xf);
- }
-
-#ifdef DBG_RESET
- printk(("uti596_reset_hardware: Scp address %p\n", sc->pScp))
-#endif
-
- /* align the block */
- sc->pScp = (i596_scp *)
- ((((int)uti596_softc.pScp) + 0xf) & 0xfffffff0);
-
-#ifdef DBG_RESET
- printk(("uti596_reset_hardware: change scp address to : %p\n",sc->pScp))
-#endif
+ i596_rfd *pRfd;
- /* change the scp address */
-#ifdef DBG_RESET
- printk(("uti596_reset_hardware: Change the SCP address\n"))
-#endif
+ printk(("82596 cmd: 0x%x, status: 0x%x RFA len: %d\n",
+ uti596_softc.scb.command,
+ uti596_softc.scb.status,
+ uti596_softc.countRFD))
- /* reset the board */
- i82596->port_lower = 0x0000;
- i82596->port_upper = 0x0000;
+ printk(("\nRFA: \n"))
- /* supply the Scp address
- * Lower Command Word D31-D16; Upper Command Word D15-D0
- */
- i82596->port_lower = (((int)sc->pScp) & 0xfff0) | 0x0002;
- i82596->port_upper = (((int)sc->pScp) >> 16 ) & 0xffff;
-
- /* write the SYSBUS: interrupt pin active high, LOCK disabled,
- * internal triggering, linear mode
- */
- sc->pScp->sysbus = word_swap(0x00540000);
+ for ( pRfd = uti596_softc.pBeginRFA;
+ pRfd != I596_NULL;
+ pRfd = pRfd->next) {
+ printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
+ pRfd, pRfd->stat, pRfd->cmd))
+ }
+ printk(("\nInbound: \n"))
- /* provide the iscp to the scp, keep a pointer for our use */
- sc->pScp->iscp_val = 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_val = word_swap((unsigned long)&sc->scb);
- sc->iscp.scb = &sc->scb;
-
- /* set the busy flag in the iscp */
- sc->iscp.stat = word_swap(0x00000001);
-
- /* the command block list (CBL) is empty */
- sc->scb.Cmd_val = (unsigned long) I596_NULL; /* all 1's */
- sc->pCmdHead = sc->scb.pCmd = I596_NULL; /* all 1's */
-
- /*
- * Wake the transmitter if needed.
- */
- if ( uti596_softc.txDaemonTid && pCmd != I596_NULL ) {
- printk(("****RESET: wakes transmitter!\n"))
- status_code = rtems_event_send (uti596_softc.txDaemonTid,
- INTERRUPT_EVENT);
-
- if ( status_code != RTEMS_SUCCESSFUL ) {
- printk(("****ERROR:Could NOT send event to tid 0x%x : %s\n",
- uti596_softc.txDaemonTid, rtems_status_text (status_code) ))
- }
- }
-
-#ifdef DBG_596
- printk(("uti596_reset_hardware: starting i82596.\n"))
-#endif
-
- /* Pass the scb address to the 596 */
- i82596->chan_attn = 0x00000000;
-
- while (sc->iscp.stat)
- if (--boguscnt == 0)
- {
- printk(("reset_hardware: timed out with status %4.4lx\n",
- sc->iscp.stat ))
- break;
- }
-
- /* clear the command word */
- sc->scb.command = 0;
-
-#ifdef DBG_RESET
- printk(("uti596_reset_hardware: After reset_hardware, status of board = 0x%x\n", sc->scb.status ))
-#endif
-}
-
- /***********************************************************************
- * Function: uti596clearListStatus
- *
- * Description:
- * Clear the stat fields for all rfd's
- * Algorithm:
- *
- ***********************************************************************/
+ for ( pRfd = uti596_softc.pInboundFrameQueue;
+ pRfd != I596_NULL;
+ pRfd = pRfd->next) {
+ printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
+ pRfd, pRfd->stat, pRfd->cmd))
+ }
-void uti596clearListStatus(
- i596_rfd *pRfd
-)
-{
- while ( pRfd != I596_NULL ) {
- pRfd -> stat = 0;
- pRfd = (i596_rfd *) word_swap((unsigned long)pRfd-> next);
+ printk(("\nSaved: \n"))
+
+ for ( pRfd = uti596_softc.pSavedRfdQueue;
+ pRfd != I596_NULL;
+ pRfd = pRfd->next) {
+ printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
+ pRfd, pRfd->stat, pRfd->cmd))
}
+
+ printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD))
}
- /***********************************************************************
- * Function: send_packet
- *
- * Description: Send a raw ethernet packet
- *
- * Algorithm:
- * increment some stats counters,
- * create the transmit command,
- * add the command to the CBL,
- * wait for event
- *
- ***********************************************************************/
-void send_packet(
- struct ifnet *ifp, struct mbuf *m
-)
+/*
+ * show_queues
+ *
+ * Print out the saved frame queue and the RFA
+ */
+static void show_queues(void)
{
- 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 );
-
- /* This should never happen */
- if ( bd_count == 16 ) {
- printk(("TX ERROR:Too many mbufs in the packet!!!\n"))
- printk(("Must coalesce!\n"))
- }
-
- 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
- pTbd = pPrev; /* Don't use pTbd in the send routine */
-
- /* 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;
-
-#ifdef DBG_RAW
- printk(("send_packet: RAW - Add cmd and sleep\n"))
-#endif
-
- sc->rawsndcnt++;
-
-#ifdef DBG_RAW
- printk(("send_packet: RAW - sending packet\n"))
-#endif
-
- /* Sending Zero length packet: shouldn't happen */
- if (pTbd->size <= 0) return ;
-
-#ifdef DBG_INIT_3
- 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 */
- uti596addCmd ( (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_RAW
- printk(("send_packet: RAW - wake\n"))
-#endif
-
- sc->txInterrupts++;
+ i596_rfd *pRfd;
-#ifdef DBG_INIT_3
- printk(("\nsend_packet: Transmitter issued packet\n"))
- print_hdr ( sc->pTxCmd->pTbd -> data ); /* print the first part */
- print_pkt ( sc->pTxCmd->pTbd ->next-> data ); /* print the first part */
-#endif
+ printk(("CMD: 0x%x, Status: 0x%x\n",
+ uti596_softc.scb.command,
+ uti596_softc.scb.status))
+ printk(("saved Q\n"))
- if ( sc->pTxCmd -> cmd.status & STAT_OK ) {
- sc->stats.tx_packets++;
+ for ( pRfd = uti596_softc.pSavedRfdQueue;
+ pRfd != I596_NULL &&
+ pRfd != NULL;
+ pRfd = pRfd->next) {
+ printk(("0x%p\n", pRfd))
}
- else {
-#ifdef DBG_RAW
- printk(("******send_packet: Driver Error 0x%x\n", sc->pTxCmd -> cmd.status ))
-#endif
- 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 transmited buffer descriptor chain.
- */
- pTbd -> next = (i596_tbd *) word_swap ((unsigned long)pRemainingTbdList);
+ printk(("End saved Q 0x%p\n", uti596_softc.pEndSavedQueue))
- /*
- * Free the mbufs used by the sender.
- */
- m = input_m;
- while ( m != NULL ) {
- MFREE(m,n);
- m = n;
+ printk(("\nRFA:\n"))
+
+ for ( pRfd = uti596_softc.pBeginRFA;
+ pRfd != I596_NULL &&
+ pRfd != NULL;
+ pRfd = pRfd->next) {
+ printk(("0x%p\n", pRfd))
}
-}
-
- /***********************************************************************
- * Function: uti596addCmd
- *
- * Description:
- * This routine adds a command onto the end of the
- * command chain
- *
- * Algorithm:
- * Add the command to the end of an existing chain,
- * or start the chain and issue a CUC_START
- *
- *
- ***********************************************************************/
-
-/* static */ void uti596addCmd(
- i596_cmd *pCmd
-)
-{
- ISR_Level level;
-
- #ifdef DBG_596
- printk(("uti596addCmd: Adding command 0x%x\n", pCmd -> command ))
- #endif
-
-#ifdef DBG_ADD
-
- switch ( pCmd -> command & 0x7 ){ /* check bottom 3 bits */
- case CmdConfigure:
- printk(("uti596addCmd: Configure Command 0x%x\n", pCmd->command))
- break;
- case CmdSASetup:
- printk(("uti596addCmd: Set Address Command 0x%x\n", pCmd->command))
- break;
- case CmdMulticastList:
- printk(("uti596addCmd: Multi-cast list 0x%x\n", pCmd->command))
- break;
- case CmdNOp:
- printk(("uti596addCmd: NO op 0x%x\n", pCmd->command))
- break;
- case CmdTDR:
- printk(("uti596addCmd: TDR 0x%x\n", pCmd->command))
- break;
- case CmdDump:
- printk(("uti596addCmd: Dump 0x%x\n", pCmd->command))
- break;
- case CmdDiagnose:
- printk(("uti596addCmd: Diagnose 0x%x\n", pCmd->command))
- break;
- case CmdTx:
- break;
- default:
- printk(("****Unknown Command encountered 0x%x\n", pCmd->command))
- break;
- } /* end switch */
-#endif
-
- pCmd->status = 0;
- pCmd->command |= (CMD_EOL | CMD_INTR ); /* all commands last in list & return an interrupt */
-
- pCmd->next = I596_NULL;
-
- _ISR_Disable(level);
- if (uti596_softc.pCmdHead == I596_NULL)
- {
- uti596_softc.pCmdHead =
- uti596_softc.pCmdTail =
- uti596_softc.scb.pCmd = pCmd;
- uti596_softc.scb.Cmd_val = word_swap ((unsigned long)pCmd);
-#ifdef DBG_596
- printk(("uti596addCmd: First Cmd\n"))
-#endif
- UTI_WAIT_COMMAND_ACCEPTED(10000,"add command"); /* wait for acceptance of previous command */
- uti596_softc.scb.command = CUC_START;
- i82596->chan_attn = 0x00000000;
- _ISR_Enable(level);
- }
- else
- {
-#ifdef DBG_596
- printk(("uti596addCmd: Chained Cmd\n"))
-#endif
- uti596_softc.pCmdTail->next = (i596_cmd *) word_swap ((unsigned long)pCmd);
- uti596_softc.pCmdTail = pCmd;
- _ISR_Enable(level);
- }
-
-#ifdef DBG_596
- printk(("uti596addCmd: Scb status & command 0x%x 0x%x\n",
- uti596_softc.scb.status,
- uti596_softc.scb.command ))
-#endif
-}
-
-
-/***********************************************************************
- * Function: uti596supplyFD
- *
- * Description: returns a buffer to the receive frame pool.
- * call this with Inetrrupts disabled!
- *
- * Algorithm:
- *
- ***********************************************************************/
-
-void uti596supplyFD(
- 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 ) {
- /* Init a list w/ 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;
-
- if ( pLastRfd != I596_NULL &&
- ! (pLastRfd -> stat & ( STAT_C | STAT_B ) )) { /* C = complete, B = busy (prefetched) */
-
- /*
- * 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 is 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 ) {
-
- uti596append(&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 ) {
- uti596_softc.pBeginRFA -> cmd &= ~CMD_EOL; /* Ensure that beginRFA is not 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_START
- printk(("uti596supplyFD: 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_val = word_swap ((unsigned long) uti596_softc.pBeginRFA);
- uti596_softc.scb.command = RX_START | SCB_STAT_RNR; /* Don't ack RNR! The receiver
- * should be stopped in this case */
- UTI_596_ASSERT( !(uti596_softc.scb.status & SCB_STAT_FR),"FRAME RECEIVED INT COMING!\n")
- i82596->chan_attn = 0x00000000; /* send CA signal */
- }
- }
- return;
-
- }
- }
- else {
- /*
- * too late , pLastRfd in use ( or NULL ),
- * in either case, EL bit has been read, and RNR condition will occur
- */
- uti596append( &uti596_softc.pSavedRfdQueue, pRfd); /* save it for RNR */
-
- uti596_softc.pEndSavedQueue = pRfd; /* reset end of saved queue */
- uti596_softc.savedCount++;
-
- return;
- }
-}
-/***********************************************************************
- * Function: void uti596append
- *
- * Description:
- * adds an RFD to the end of the received frame queue,
- * for processing by the rxproc.
- * Also removes this RFD from the RFA
- *
- * Algorithm:
- *
- ***********************************************************************/
-void uti596append(
- 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))
- }
+ printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA))
}
-/***********************************************************************
- * Function: void printk_time
- *
- * Description:
- ***********************************************************************/
-void printk_time( void )
-{
- rtems_time_of_day tm_struct;
- rtems_clock_get(RTEMS_CLOCK_GET_TOD, &tm_struct);
- printk(("Current time: %d:%d:%d \n",
- tm_struct.hour,
- tm_struct.minute,
- tm_struct.second))
-}
-
-/***********************************************************************
- * Function: void dump_scb
+/*
+ * print_eth
*
- * Description:
- ***********************************************************************/
-void 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%x\n",uti596_softc.scb.crc_err))
- printk(("align_err 0x%x\n",uti596_softc.scb.align_err))
- printk(("resource_err 0x%x\n",uti596_softc.scb.resource_err ))
- printk(("over_err 0x%x\n",uti596_softc.scb.over_err))
- printk(("rcvdt_err 0x%x\n",uti596_softc.scb.rcvdt_err))
- printk(("short_err 0x%x\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))
-}
-
-
-#ifdef DBG_INIT_3
-
- /***********************************************************************
- **
- ** Debugging Functions
- **
- ***********************************************************************/
-
-
- /***********************************************************************
- * Function: print_eth
- *
- * Description:
- * Print the contents of an ethernet packet header
- * CANNOT BE CALLED FROM ISR
- *
- * Algorithm:
- * Print Destination, Src, and type of packet
- *
- ***********************************************************************/
-
-/* static */ void print_eth(
+ * Print the contents of an ethernet packet
+ * CANNOT BE CALLED FROM ISR
+ */
+static void print_eth(
unsigned char *add
)
{
@@ -2445,12 +2801,12 @@ void dump_scb( void )
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 ((" %2.2X", add[i]))
}
printk (("\n"))
@@ -2467,19 +2823,19 @@ void dump_scb( void )
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: "))
@@ -2489,7 +2845,9 @@ void dump_scb( void )
printk (("%u\n", add[41]))
}
- if ( add[12] == 0x08 && add[13] == 0x00 ) { /* an IP packet */
+
+ 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] )))
@@ -2502,41 +2860,25 @@ void dump_scb( void )
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 (("%u\n", add[33]))
}
}
- /***********************************************************************
- * Function: print_hdr
- *
- * Description:
- * Print the contents of an ethernet packet header
- * CANNOT BE CALLED FROM ISR
- *
- * Algorithm:
- * Print Destination, Src, and type of packet
- *
- ***********************************************************************/
-
-/* static */ void print_hdr(
+
+/*
+ * print_hdr
+ *
+ * Print the contents of an ethernet packet header
+ * CANNOT BE CALLED FROM ISR
+ */
+static void print_hdr(
unsigned char *add
)
{
@@ -2548,29 +2890,24 @@ void dump_scb( void )
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
- *
- * Description:
- * Print the contents of an ethernet packet header
- * CANNOT BE CALLED FROM ISR
- *
- * Algorithm:
- * Print Destination, Src, and type of packet
- *
- ***********************************************************************/
-
-/* static */ void print_pkt(
+
+/*
+ * Function: print_pkt
+ *
+ * Print the contents of an ethernet packet & data
+ * CANNOT BE CALLED FROM ISR
+ */
+static void print_pkt(
unsigned char *add
)
{
@@ -2591,18 +2928,18 @@ void dump_scb( void )
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:", add[32 + i]))
}
printk (("%x\n", add[37]))
printk (("Target IP addr: "))
@@ -2627,7 +2964,7 @@ void dump_scb( void )
for ( i=0; i< 3 ; i++) {
printk(( "%u.", add[26 + i]))
- }
+ }
printk(("%u\n", add[29]))
printk(("Destination IP address: "))
@@ -2649,19 +2986,14 @@ void dump_scb( void )
}
}
- /***********************************************************************
- * Function: print_echo
- *
- * Description:
- * Print the contents of an ethernet packet header
- * CANNOT BE CALLED FROM ISR
- *
- * Algorithm:
- * Prints only echo packets
- *
- ***********************************************************************/
-
-/* static */ void print_echo(
+
+/*
+ * print_echo
+ *
+ * Print the contents of an echo packet
+ * CANNOT BE CALLED FROM ISR
+ */
+static void print_echo(
unsigned char *add
)
{
@@ -2677,13 +3009,13 @@ void dump_scb( void )
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]))
@@ -2699,7 +3031,7 @@ void dump_scb( void )
for ( i=0; i< 3 ; i++) {
printk (("%u.", add[26 + i]))
- }
+ }
printk (("%u\n", add[29]))
printk (("Destination IP address: "))
@@ -2712,7 +3044,7 @@ void dump_scb( void )
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]))
@@ -2721,169 +3053,4 @@ void dump_scb( void )
}
}
-#endif
-
-/***********************************************************************
- * Function: uti596dump
- *
- * Description: Dump 596 registers
- *
- * Algorithm:
- ***********************************************************************/
-/* static */ int uti596dump(
- char * pDumpArea
-)
-{
- i596_dump dumpCmd;
- int boguscnt = 25000000; /* over a second! */
-
-#ifdef DBG_596
- printk(("uti596dump: begin\n"))
-#endif
-
- dumpCmd.cmd.command = CmdDump;
- dumpCmd.cmd.next = I596_NULL;
- dumpCmd.pData = pDumpArea;
- uti596_softc.cmdOk = 0;
- uti596addCmd ( (i596_cmd *)&dumpCmd);
- while (1) {
- if ( --boguscnt == 0) {
- printk(("Dump command was not processed within spin loop delay\n"))
- return 0;
- }
- else {
- if ( uti596_softc.cmdOk ) {
- return 1; /* successful completion */
- }
- }
- }
-}
-
-/***********************************************************************
- * Function: void dumpQ
- *
- * Description:
- ***********************************************************************/
-void dumpQ( void )
-{
- i596_rfd *pRfd;
-
- printk(("savedQ:\n"))
-
- for( pRfd = uti596_softc.pSavedRfdQueue;
- pRfd != I596_NULL;
- pRfd = 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 = 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 = pRfd -> next) {
- printk(("pRfd: %p, stat: 0x%x cmd: 0x%x\n",pRfd,pRfd -> stat,pRfd -> cmd))
- }
-}
-
-
-/***********************************************************************
- * Function: void show_buffers
- *
- * Description:
- ***********************************************************************/
-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 = 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 = 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 = pRfd->next) {
- printk(("Frame @ %p, status: %2.2x, cmd: %2.2x\n",
- pRfd, pRfd->stat, pRfd->cmd))
- }
-
- printk(("\nUnknown: %p\n",uti596_softc.pLastUnkRFD))
-}
-
-/***********************************************************************
- * Function: void show_queues
- *
- * Description:
- ***********************************************************************/
-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 = 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 = pRfd->next) {
- printk(("0x%p\n", pRfd))
- }
-
- printk(("uti596_softc.pEndRFA: %p\n",uti596_softc.pEndRFA))
-}
-
- /***********************************************************************
- * Function: word_swap
- *
- * Description:
- * Return a 32 bit value, swapping the upper
- * and lower words first.
- *
- ***********************************************************************/
-unsigned long word_swap (unsigned long val)
-{
- return (((val >> 16)&(0x0000ffff)) | ((val << 16)&(0xffff0000)));
-}
-
-
+#endif \ No newline at end of file