diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-12-04 22:55:13 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2008-12-04 22:55:13 +0000 |
commit | b17830622a32cbbeaac014e8e6bb56d99184876a (patch) | |
tree | 4a622766310aceed0bdbabc8b79d5f5cebaf1241 /c/src/lib/libbsp/lm32/shared | |
parent | 2008-12-04 Jukka Pietarinen <jukka.pietarinen@mrf.fi> (diff) | |
download | rtems-b17830622a32cbbeaac014e8e6bb56d99184876a.tar.bz2 |
2008-12-04 Jukka Pietarinen <jukka.pietarinen@mrf.fi>
* ChangeLog, Makefile.am, README, acinclude.m4, configure.ac,
shared/clock/ckinit.c, shared/clock/clock.h,
shared/console/console.c, shared/console/uart.c,
shared/console/uart.h, shared/start/start.S,
shared/startup/bspstart.c, shared/startup/setvec.c,
shared/timer/timer.c, shared/tsmac/dp83848phy.h,
shared/tsmac/tsmac.c, shared/tsmac/tsmac.h: New files.
Diffstat (limited to 'c/src/lib/libbsp/lm32/shared')
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/clock/ckinit.c | 179 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/clock/clock.h | 42 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/console/console.c | 226 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/console/uart.c | 72 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/console/uart.h | 89 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/start/start.S | 156 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/startup/bspstart.c | 49 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/startup/setvec.c | 43 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/timer/timer.c | 107 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/tsmac/dp83848phy.h | 182 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/tsmac/tsmac.c | 824 | ||||
-rw-r--r-- | c/src/lib/libbsp/lm32/shared/tsmac/tsmac.h | 160 |
12 files changed, 2129 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/lm32/shared/clock/ckinit.c b/c/src/lib/libbsp/lm32/shared/clock/ckinit.c new file mode 100644 index 0000000000..433d3d5d72 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/clock/ckinit.c @@ -0,0 +1,179 @@ +/* ckinit.c + * + * Clock device driver for Lattice Mico32 (lm32). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#include <stdlib.h> + +#include <rtems.h> +#include <bsp.h> +#include "../include/system_conf.h" +#include "clock.h" + +static inline int clockread(unsigned int reg) +{ + return *((int*)(TIMER0_BASE_ADDRESS + reg)); +} + +static inline void clockwrite(unsigned int reg, int value) +{ + *((int*)(TIMER0_BASE_ADDRESS + reg)) = value; +} + +void Clock_exit( void ); +rtems_isr Clock_isr( rtems_vector_number vector ); +extern lm32_isr_entry set_vector(rtems_isr_entry handler, + rtems_vector_number vector, int type); + +/* + * The interrupt vector number associated with the clock tick device + * driver. + */ + +#define CLOCK_VECTOR ( TIMER0_IRQ ) +#define CLOCK_IRQMASK ( 1 << CLOCK_VECTOR ) + +/* + * Clock_driver_ticks is a monotonically increasing counter of the + * number of clock ticks since the driver was initialized. + */ + +volatile uint32_t Clock_driver_ticks; + +/* + * These are set by clock driver during its init + */ + +rtems_device_major_number rtems_clock_major = ~0; +rtems_device_minor_number rtems_clock_minor; + +/* + * The previous ISR on this clock tick interrupt vector. + */ + +rtems_isr_entry Old_ticker; + +void Clock_exit( void ); + +/* + * Isr Handler + */ + +rtems_isr Clock_isr( + rtems_vector_number vector +) +{ +/* + * bump the number of clock driver ticks since initialization + * + * determine if it is time to announce the passing of tick as configured + * to RTEMS through the rtems_clock_tick directive + * + * perform any timer dependent tasks + */ + + /* Clear overflow flag */ + clockwrite(LM32_CLOCK_SR, 0); + lm32_interrupt_ack(CLOCK_IRQMASK); + + /* Increment clock ticks */ + Clock_driver_ticks += 1; + + rtems_clock_tick(); +} + +/* + * Install_clock + * + * Install a clock tick handler and reprograms the chip. This + * is used to initially establish the clock tick. + */ + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + /* + * Initialize the clock tick device driver variables + */ + + Clock_driver_ticks = 0; + + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, CLOCK_VECTOR, 1 ); + /* + * Hardware specific initialize goes here + */ + + printk("rtems_configuration_get_microseconds_per_tick() %d\n", + rtems_configuration_get_microseconds_per_tick()); + printk("PERIOD %d\n", + (CPU_FREQUENCY / (1000000 / rtems_configuration_get_microseconds_per_tick()))); + + /* Set clock period */ + clockwrite(LM32_CLOCK_PERIOD, + (CPU_FREQUENCY / + (1000000 / rtems_configuration_get_microseconds_per_tick()))); + + /* Enable clock interrupts and start in continuous mode */ + clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_ITO | + LM32_CLOCK_CR_CONT | + LM32_CLOCK_CR_START); + + lm32_interrupt_unmask(CLOCK_IRQMASK); + + /* + * Schedule the clock cleanup routine to execute if the application exits. + */ + + atexit( Clock_exit ); +} + +/* + * Clean up before the application exits + */ + +void Clock_exit( void ) +{ + /* Disable clock interrupts and stop */ + + lm32_interrupt_unmask(CLOCK_IRQMASK); + clockwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP); +} + +/* + * Clock_initialize + * + * Device driver entry point for clock tick driver initialization. + */ + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp +) +{ + printk("Clock initialize %d %d\n", major, minor); + + Install_clock( Clock_isr ); + + /* + * make major/minor avail to others such as shared memory driver + */ + + rtems_clock_major = major; + rtems_clock_minor = minor; + + return RTEMS_SUCCESSFUL; +} diff --git a/c/src/lib/libbsp/lm32/shared/clock/clock.h b/c/src/lib/libbsp/lm32/shared/clock/clock.h new file mode 100644 index 0000000000..d8f86175f9 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/clock/clock.h @@ -0,0 +1,42 @@ +/* + * This file contains definitions for LatticeMico32 Timer (Clock) + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#ifndef _BSPCLOCK_H +#define _BSPCLOCK_H + +/* Status Register */ + +#define LM32_CLOCK_SR (0x0000) +#define LM32_CLOCK_SR_TO (0x0001) +#define LM32_CLOCK_SR_RUN (0x0002) + +/* Control Register */ + +#define LM32_CLOCK_CR (0x0004) +#define LM32_CLOCK_CR_ITO (0x0001) +#define LM32_CLOCK_CR_CONT (0x0002) +#define LM32_CLOCK_CR_START (0x0004) +#define LM32_CLOCK_CR_STOP (0x0008) + +/* Period Register */ + +#define LM32_CLOCK_PERIOD (0x0008) + +/* Snapshot Register */ + +#define LM32_CLOCK_SNAPSHOT (0x000C) + +#endif /* _BSPCLOCK_H */ diff --git a/c/src/lib/libbsp/lm32/shared/console/console.c b/c/src/lib/libbsp/lm32/shared/console/console.c new file mode 100644 index 0000000000..63fa79de0d --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/console/console.c @@ -0,0 +1,226 @@ +/* + * Console driver for Lattice Mico32 (lm32). + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#define NO_BSP_INIT + +#include <rtems.h> +#include <bsp.h> +#include <rtems/libio.h> + +void BSP_uart_polled_write(char ch); +char BSP_uart_polled_read( void ); +char BSP_uart_is_character_ready(char *ch); + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg +) +{ + rtems_status_code status; + + printk("console_initialize\n"); + + status = rtems_io_register_name( + "/dev/console", + major, + (rtems_device_minor_number) 0 + ); + + if (status != RTEMS_SUCCESSFUL) + rtems_fatal_error_occurred(status); + + return RTEMS_SUCCESSFUL; +} + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +bool is_character_ready( + char *ch +) +{ + return BSP_uart_is_character_ready(ch); +} + +/* inbyte + * + * This routine reads a character from the SOURCE. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from SOURCE + */ + +char inbyte( void ) +{ + /* + * If polling, wait until a character is available. + */ + + return (char) BSP_uart_polled_read(); +} + +/* outbyte + * + * This routine transmits a character out the SOURCE. It may support + * XON/XOFF flow control. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( + char ch +) +{ + /* + * If polling, wait for the transmitter to be ready. + * Check for flow control requests and process. + * Then output the character. + */ + + BSP_uart_polled_write(ch); +} + +/* + * Open entry point + */ + +rtems_device_driver console_open( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * Close entry point + */ + +rtems_device_driver console_close( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +/* + * read bytes from the serial port. We only have stdin. + */ + +rtems_device_driver console_read( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + rtems_libio_rw_args_t *rw_args; + char *buffer; + int maximum; + int count = 0; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + buffer[ count ] = inbyte(); + if (buffer[ count ] == '\n' || buffer[ count ] == '\r') { + buffer[ count++ ] = '\n'; + break; + } + } + + rw_args->bytes_moved = count; + return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED; +} + +/* + * write bytes to the serial port. Stdout and stderr are the same. + */ + +rtems_device_driver console_write( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + int count; + int maximum; + rtems_libio_rw_args_t *rw_args; + char *buffer; + + rw_args = (rtems_libio_rw_args_t *) arg; + + buffer = rw_args->buffer; + maximum = rw_args->count; + + for (count = 0; count < maximum; count++) { + if ( buffer[ count ] == '\n') { + outbyte('\r'); + } + outbyte( buffer[ count ] ); + } + + rw_args->bytes_moved = maximum; + return 0; +} + +/* + * IO Control entry point + */ + +rtems_device_driver console_control( + rtems_device_major_number major, + rtems_device_minor_number minor, + void * arg +) +{ + return RTEMS_SUCCESSFUL; +} + +BSP_output_char_function_type BSP_output_char = BSP_uart_polled_write; +BSP_polling_getchar_function_type BSP_poll_char = BSP_uart_polled_read; diff --git a/c/src/lib/libbsp/lm32/shared/console/uart.c b/c/src/lib/libbsp/lm32/shared/console/uart.c new file mode 100644 index 0000000000..a67f8092aa --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/console/uart.c @@ -0,0 +1,72 @@ +/* + * Uart driver for Lattice Mico32 (lm32) UART + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#include "../include/system_conf.h" +#include "uart.h" +#include <rtems/libio.h> + +static inline int uartread(unsigned int reg) +{ + return *((int*)(UART_BASE_ADDRESS + reg)); +} + +static inline void uartwrite(unsigned int reg, int value) +{ + *((int*)(UART_BASE_ADDRESS + reg)) = value; +} + +void BSP_uart_init(int baud) +{ + /* Disable UART interrupts */ + uartwrite(LM32_UART_IER, 0); + + /* Line control 8 bit, 1 stop, no parity */ + uartwrite(LM32_UART_LCR, LM32_UART_LCR_8BIT); + + /* Modem control, DTR = 1, RTS = 1 */ + uartwrite(LM32_UART_MCR, LM32_UART_MCR_DTR | LM32_UART_MCR_RTS); + + /* Set baud rate */ + uartwrite(LM32_UART_DIV, CPU_FREQUENCY/baud); +} + +void BSP_uart_polled_write(char ch) +{ + /* Insert CR before LF */ + if (ch == '\n') + BSP_uart_polled_write('\r'); + /* Wait until THR is empty. */ + while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_THRE)); + uartwrite(LM32_UART_RBR, ch); +} + +char BSP_uart_polled_read( void ) +{ + /* Wait until there is a byte in RBR */ + while (!(uartread(LM32_UART_LSR) & LM32_UART_LSR_DR)); + return (char) uartread(LM32_UART_RBR); +} + +char BSP_uart_is_character_ready(char *ch) +{ + if (uartread(LM32_UART_LSR) & LM32_UART_LSR_DR) + { + *ch = (char) uartread(LM32_UART_RBR); + return true; + } + *ch = '0'; + return false; +} diff --git a/c/src/lib/libbsp/lm32/shared/console/uart.h b/c/src/lib/libbsp/lm32/shared/console/uart.h new file mode 100644 index 0000000000..7c64646fdc --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/console/uart.h @@ -0,0 +1,89 @@ +/* + * This file contains definitions for LatticeMico32 UART + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#ifndef _BSPUART_H +#define _BSPUART_H + +void BSP_uart_init(int baud); + +/* Receive buffer register / transmit holding register */ + +#define LM32_UART_RBR (0x0000) + +/* Interrupt enable register */ + +#define LM32_UART_IER (0x0004) +#define LM32_UART_IER_RBRI (0x0001) +#define LM32_UART_IER_THRI (0x0002) +#define LM32_UART_IER_RLSI (0x0004) +#define LM32_UART_IER_MSI (0x0008) + +/* Interrupt identification register */ + +#define LM32_UART_IIR (0x0008) +#define LM32_UART_IIR_STAT (0x0001) +#define LM32_UART_IIR_ID0 (0x0002) +#define LM32_UART_IIR_ID1 (0x0004) + +/* Line control register */ + +#define LM32_UART_LCR (0x000C) +#define LM32_UART_LCR_WLS0 (0x0001) +#define LM32_UART_LCR_WLS1 (0x0002) +#define LM32_UART_LCR_STB (0x0004) +#define LM32_UART_LCR_PEN (0x0008) +#define LM32_UART_LCR_EPS (0x0010) +#define LM32_UART_LCR_SP (0x0020) +#define LM32_UART_LCR_SB (0x0040) +#define LM32_UART_LCR_5BIT (0) +#define LM32_UART_LCR_6BIT (LM32_UART_LCR_WLS0) +#define LM32_UART_LCR_7BIT (LM32_UART_LCR_WLS1) +#define LM32_UART_LCR_8BIT (LM32_UART_LCR_WLS1 | LM32_UART_LCR_WLS0) + +/* Modem control register */ + +#define LM32_UART_MCR (0x0010) +#define LM32_UART_MCR_DTR (0x0001) +#define LM32_UART_MCR_RTS (0x0002) + +/* Line status register */ + +#define LM32_UART_LSR (0x0014) +#define LM32_UART_LSR_DR (0x0001) +#define LM32_UART_LSR_OE (0x0002) +#define LM32_UART_LSR_PE (0x0004) +#define LM32_UART_LSR_FE (0x0008) +#define LM32_UART_LSR_BI (0x0010) +#define LM32_UART_LSR_THRE (0x0020) +#define LM32_UART_LSR_TEMT (0x0040) + +/* Modem status register */ + +#define LM32_UART_MSR (0x0018) +#define LM32_UART_MSR_DCTS (0x0001) +#define LM32_UART_MSR_DDSR (0x0002) +#define LM32_UART_MSR_TERI (0x0004) +#define LM32_UART_MSR_DDCD (0x0008) +#define LM32_UART_MSR_CTS (0x0010) +#define LM32_UART_MSR_DSR (0x0020) +#define LM32_UART_MSR_RI (0x0040) +#define LM32_UART_MSR_DCD (0x0000) + +/* Baud-rate divisor register */ + +#define LM32_UART_DIV (0x001C) + +#endif /* _BSPUART_H */ diff --git a/c/src/lib/libbsp/lm32/shared/start/start.S b/c/src/lib/libbsp/lm32/shared/start/start.S new file mode 100644 index 0000000000..6cfa9268f1 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/start/start.S @@ -0,0 +1,156 @@ +/* LM32 startup code + * + * This is the entry point on reset and when loading the + * executive from a bootloader. + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + + .section .boot,"a",@progbits + .align 4 + + .globl start + .type start,@function + .globl _start + .type _start,@function + .globl __start + .type __start,@function + .globl LatticeDDInit + .type LatticeDDInit,@function + +LatticeDDInit: +__start: +_start: +start: + /* Clear r0 */ + xor r0,r0,r0 + /* Disable interrupts */ + wcsr IE, r0 + /* Mask all interrupts */ + wcsr IM,r0 + /* Set exception base address */ + mvhi r1, hi(start) + ori r1, r1, lo(start) + wcsr EBA, r1 + bi crt0 + nop +/* + * Unused handlers call debug handlers + */ +breakpoint_handler: + rcsr r7, DEBA + addi r7, r7, 32 + b r7 + nop + nop + nop + nop + nop +instruction_bus_error_handler: + rcsr r7, DEBA + addi r7, r7, 64 + b r7 + nop + nop + nop + nop + nop +watchpoint_handler: + rcsr r7, DEBA + addi r7, r7, 96 + b r7 + nop + nop + nop + nop + nop +data_bus_error_handler: + rcsr r7, DEBA + addi r7, r7, 128 + b r7 + nop + nop + nop + nop + nop +divide_by_zero_handler: + rcsr r7, DEBA + addi r7, r7, 160 + b r7 + nop + nop + nop + nop + nop +interrupt_handler: + .extern _ISR_Handler + bi _ISR_Handler + nop + nop + nop + nop + nop + nop + nop +system_call_handler: + rcsr r7, DEBA + addi r7, r7, 224 + b r7 + nop + nop + nop + nop + nop + + .text +crt0: + /* Flush data cache */ + addi r1, r0, 1 + wcsr DCC, r1 + nop + nop + nop + nop + /* Flush Instruction Cache */ + wcsr ICC, r1 + nop + nop + nop + nop + /* Initialize stack pointer */ + mvhi sp, hi(_fstack-4) + ori sp, sp, lo(_fstack-4) + /* Initialize global pointer */ + mvhi gp, hi(_edata) + ori gp, gp, lo(_edata) + /* Clear bss */ + mvhi r1, hi(_clear_start) + ori r1, r1, lo(_clear_start) + mvhi r3, hi(_clear_end) + ori r3, r3, lo(_clear_end) +.clear_bss: + be r1, r3, .end_clear_bss + sw (r1+0), r0 + addi r1, r1, 4 + bi .clear_bss +.end_clear_bss: + mvi r1, 0 + mvi r2, 0 + mvi r3, 0 + calli boot_card +.dead_end: + bi .dead_end + + calli boot_card +# boot_card should never return +_stuck_in_start: + bi _stuck_in_start + + diff --git a/c/src/lib/libbsp/lm32/shared/startup/bspstart.c b/c/src/lib/libbsp/lm32/shared/startup/bspstart.c new file mode 100644 index 0000000000..770d8d81b4 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/startup/bspstart.c @@ -0,0 +1,49 @@ +/* + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#include <string.h> + +#include <bsp.h> +#include "../include/system_conf.h" +#include "../console/uart.h" +#include <rtems/score/heap.h> + +#include <rtems/system.h> +#include <rtems/score/isr.h> +#include <rtems/score/timespec.h> +#include <rtems/score/tod.h> + +/* + * bsp_start + * + * This routine does the bulk of the system initialization. + */ + +void bsp_start( void ) +{ + /* Setup console baud rate which we derive from + Mico System Builder (MSB) generated system_conf.h */ + BSP_uart_init(UART_BAUD_RATE); +} + +void bsp_predriver_hook(void) +{ +} + + diff --git a/c/src/lib/libbsp/lm32/shared/startup/setvec.c b/c/src/lib/libbsp/lm32/shared/startup/setvec.c new file mode 100644 index 0000000000..b7818d3699 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/startup/setvec.c @@ -0,0 +1,43 @@ +/* set_vector + * + * This routine installs an interrupt vector on the target Board/CPU. + * This routine is allowed to be as board dependent as necessary. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + */ + +#include <rtems.h> +#include <bsp.h> + +lm32_isr_entry set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + lm32_isr_entry previous_isr; + + if ( type ) + rtems_interrupt_catch( handler, vector, (rtems_isr_entry *) &previous_isr ); + else { + /* XXX: install non-RTEMS ISR as "raw" interupt */ + } + return previous_isr; +} diff --git a/c/src/lib/libbsp/lm32/shared/timer/timer.c b/c/src/lib/libbsp/lm32/shared/timer/timer.c new file mode 100644 index 0000000000..4fef00ce37 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/timer/timer.c @@ -0,0 +1,107 @@ +/* timer.c + * + * This file manages the benchmark timer used by the RTEMS Timing + * Test Suite. Each measured time period is demarcated by calls to + * benchmark_timer_initialize() and benchmark_timer_read(). + * benchmark_timer_read() usually returns the number of microseconds + * since benchmark_timer_initialize() exitted. + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#include <rtems.h> +#include <bsp.h> +#include "../include/system_conf.h" +#include "../../shared/clock/clock.h" + +static inline int timerread(unsigned int reg) +{ +#ifdef TIMER1_BASE_ADDRESS + return *((int*)(TIMER1_BASE_ADDRESS + reg)); +#else +#warning "Benchmarking timer TIMER1 not available!" + return 0; +#endif +} + +static inline void timerwrite(unsigned int reg, int value) +{ +#ifdef TIMER1_BASE_ADDRESS + *((int*)(TIMER1_BASE_ADDRESS + reg)) = value; +#endif +} + +bool benchmark_timer_find_average_overhead; + +void benchmark_timer_initialize( void ) +{ + /* Set timer period */ + timerwrite(LM32_CLOCK_PERIOD, 0xffffffff); + /* Stop timer */ + timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_STOP); + /* Clear status register */ + timerwrite(LM32_CLOCK_SR, 0); + /* Start timer */ + timerwrite(LM32_CLOCK_CR, LM32_CLOCK_CR_START); +} + +/* + * The following controls the behavior of benchmark_timer_read(). + * + * AVG_OVEREHAD is the overhead for starting and stopping the timer. It + * is usually deducted from the number returned. + * + * LEAST_VALID is the lowest number this routine should trust. Numbers + * below this are "noise" and zero is returned. + */ + +#define AVG_OVERHEAD 4 /* It typically takes X.X microseconds */ + /* (Y countdowns) to start/stop the timer. */ + /* This value is in microseconds. */ +#define LEAST_VALID 4 /* Don't trust a clicks value lower than this */ + +int benchmark_timer_read( void ) +{ + uint32_t ticks; + uint32_t total; + uint32_t status; + + ticks = 0xffffffff - timerread(LM32_CLOCK_SNAPSHOT); + status = timerread(LM32_CLOCK_SR); + if (status & LM32_CLOCK_SR_TO) + printk("Timer overflow!\n"); + + total = ticks / (CPU_FREQUENCY / 1000000); + + if ( benchmark_timer_find_average_overhead == true ) + return total; /* in XXX microsecond units */ + else + { + if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + /* + * Somehow convert total into microseconds + */ + return (total - AVG_OVERHEAD); + } +} + +void benchmark_timer_disable_subtracting_average_overhead( + bool find_flag +) +{ + benchmark_timer_find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/lm32/shared/tsmac/dp83848phy.h b/c/src/lib/libbsp/lm32/shared/tsmac/dp83848phy.h new file mode 100644 index 0000000000..792130943f --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/tsmac/dp83848phy.h @@ -0,0 +1,182 @@ +/* + * This file contains definitions for LatticeMico32 TSMAC (Tri-Speed MAC) + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#ifndef _DP83848PHY_H +#define _DP83848PHY_H + +#define DEFAULT_PHY_ADDRESS (0x01) + +#define PHY_BMCR (0x00) +#define PHY_BMCR_RESET (1<<15) +#define PHY_BMCR_LOOPBACK (1<<14) +#define PHY_BMCR_SPEEDSEL (1<<13) +#define PHY_BMCR_AN_ENA (1<<12) +#define PHY_BMCR_PWRDWN (1<<11) +#define PHY_BMCR_ISOLATE (1<<10) +#define PHY_BMCR_RESTART_AN (1<<9) +#define PHY_BMCR_DUPLEX_MODE (1<<8) +#define PHY_BMCR_COLL_TEST (1<<7) +#define PHY_BMSR (0x01) +#define PHY_BMSR_100_T4 (1<<15) +#define PHY_BMSR_100_TX_FD (1<<14) +#define PHY_BMSR_100_TX_HD (1<<13) +#define PHY_BMSR_10_T_FD (1<<12) +#define PHY_BMSR_10_T_HD (1<<11) +#define PHY_BMSR_PRESUP (1<<6) +#define PHY_BMSR_AN_CMPL (1<<5) +#define PHY_BMSR_REM_FLT (1<<4) +#define PHY_BMSR_AN_AB (1<<3) +#define PHY_BMSR_LINK_STAT (1<<2) +#define PHY_BMSR_JABBDET (1<<1) +#define PHY_BMSR_EXT_CAP (1<<0) +#define PHY_PHYIDR1 (0x02) +#define DEFAULT_PHYIDR1 (0x2000) +#define PHY_PHYIDR2 (0x03) +#define DEFAULT_PHYIDR2 (0x5C90) +#define PHY_ANAR (0x04) +#define PHY_ANAR_NP (1<<15) +#define PHY_ANAR_RF (1<<13) +#define PHY_ANAR_ASM_DIR (1<<11) +#define PHY_ANAR_PAUSE (1<<10) +#define PHY_ANAR_T4 (1<<9) +#define PHY_ANAR_TX_FD (1<<8) +#define PHY_ANAR_TX (1<<7) +#define PHY_ANAR_10_FD (1<<6) +#define PHY_ANAR_10 (1<<5) +#define PHY_ANAR_SEL_MASK (0x0f) +#define PHY_ANAR_SEL_SHIFT (0) +#define PHY_ANAR_SEL_DEF (1) +#define PHY_ANLPAR (0x05) +#define PHY_ANLPAR_NP (1<<15) +#define PHY_ANLPAR_ACK (1<<14) +#define PHY_ANLPAR_RF (1<<13) +#define PHY_ANLPAR_ASM_DIR (1<<11) +#define PHY_ANLPAR_PAUSE (1<<10) +#define PHY_ANLPAR_T4 (1<<9) +#define PHY_ANLPAR_TX_FD (1<<8) +#define PHY_ANLPAR_TX (1<<7) +#define PHY_ANLPAR_10_FD (1<<6) +#define PHY_ANLPAR_10 (1<<5) +#define PHY_ANLPAR_SEL_MASK (0x0f) +#define PHY_ANLPAR_SEL_SHIFT (0) +#define PHY_ANLPARNP (0x05) +#define PHY_ANLPARNP_NP (1<<15) +#define PHY_ANLPARNP_ACK (1<<14) +#define PHY_ANLPARNP_MP (1<<13) +#define PHY_ANLPARNP_ACK2 (1<<12) +#define PHY_ANLPARNP_TOGGLE (1<<11) +#define PHY_ANLPARNP_CDE_MASK (0x03ff) +#define PHY_ANER (0x06) +#define PHY_ANER_PDF (1<<4) +#define PHY_ANER_LP_NP_ABLE (1<<3) +#define PHY_ANER_NP_ABLE (1<<2) +#define PHY_ANER_PAGE_RX (1<<1) +#define PHY_ANER_LP_AN_ABLE (1<<0) +#define PHY_ANNPTR (0x07) +#define PHY_ANNPTR_NP (1<<15) +#define PHY_ANNPTR_MP (1<<13) +#define PHY_ANNPTR_ACK2 (1<<12) +#define PHY_ANNPTR_TOG_TX (1<<11) +#define PHY_ANNPTR_CDE_MASK (0x03ff) +#define PHY_PHYSTS (0x10) +#define PHY_PHYSTS_MDIX_MDE (1<<14) +#define PHY_PHYSTS_RCV_ERRL (1<<13) +#define PHY_PHYSTS_POLSTAT (1<<12) +#define PHY_PHYSTS_FCSL (1<<11) +#define PHY_PHYSTS_SD (1<<10) +#define PHY_PHYSTS_DESCL (1<<9) +#define PHY_PHYSTS_PGREC (1<<8) +#define PHY_PHYSTS_MIIIRQ (1<<7) +#define PHY_PHYSTS_REM_FLT (1<<6) +#define PHY_PHYSTS_JABBDET (1<<5) +#define PHY_PHYSTS_AN_CMP (1<<4) +#define PHY_PHYSTS_LOOPBACK (1<<3) +#define PHY_PHYSTS_DUPLEX (1<<2) +#define PHY_PHYSTS_SPEED (1<<1) +#define PHY_PHYSTS_LINK (1<<0) +#define PHY_MICR (0x11) +#define PHY_MICR_TINT (1<<2) +#define PHY_MICR_INTEN (1<<1) +#define PHY_MICR_INT_OE (1<<0) +#define PHY_MISR (0x12) +#define PHY_MISR_ED_INT (1<<14) +#define PHY_MISR_LINK_INT (1<<13) +#define PHY_MISR_SPD_INT (1<<12) +#define PHY_MISR_DUP_INT (1<<11) +#define PHY_MISR_ANC_INT (1<<10) +#define PHY_MISR_FHF_INT (1<<9) +#define PHY_MISR_RHF_INT (1<<8) +#define PHY_MISR_ED_INT_EN (1<<6) +#define PHY_MISR_LINK_INT_EN (1<<5) +#define PHY_MISR_SPD_INT_EN (1<<4) +#define PHY_MISR_DUP_INT_EN (1<<3) +#define PHY_MISR_ANC_INT_EN (1<<2) +#define PHY_MISR_FHF_INT_EN (1<<1) +#define PHY_MISR_RHF_INT_EN (1<<0) +#define PHY_FCSCR (0x14) +#define PHY_RECR (0x15) +#define PHY_PCSR (0x16) +#define PHY_PCSR_TQ_EN (1<<10) +#define PHY_PCSR_SDFPMA (1<<9) +#define PHY_PCSR_SD_OPT (1<<8) +#define PHY_PCSR_DESC_TIME (1<<7) +#define PHY_PCSR_F_100_OK (1<<5) +#define PHY_PCSR_NRZI_BYPASS (1<<2) +#define PHY_RBR (0x17) +#define PHY_RBR_RMII_MODE (1<<5) +#define PHY_RBR_RMII_REV1_0 (1<<4) +#define PHY_RBR_RX_OVF_STS (1<<3) +#define PHY_RBR_RX_UNF_STS (1<<2) +#define PHY_RBR_ELAST_BUF1 (1<<1) +#define PHY_RBR_ELAST_BUF0 (1<<0) +#define PHY_LEDCR (0x18) +#define PHY_LEDCR_DRV_SPDLED (1<<5) +#define PHY_LEDCR_DRV_LNKLED (1<<4) +#define PHY_LEDCR_DRV_ACTLED (1<<3) +#define PHY_LEDCR_SPDLED (1<<2) +#define PHY_LEDCR_LNKLED (1<<1) +#define PHY_LEDCR_ACTLED (1<<0) +#define PHY_PHYCR (0x19) +#define PHY_PHYCR_MDIX_EN (1<<15) +#define PHY_PHYCR_FORCE_MDIX (1<<14) +#define PHY_PHYCR_PAUSE_RX (1<<13) +#define PHY_PHYCR_PAUSE_TX (1<<12) +#define PHY_PHYCR_BIST_FE (1<<11) +#define PHY_PHYCR_PSR_15 (1<<10) +#define PHY_PHYCR_BIST_STATUS (1<<9) +#define PHY_PHYCR_BIST_START (1<<8) +#define PHY_PHYCR_BP_STRETCH (1<<7) +#define PHY_PHYCR_LED_CNFG1 (1<<6) +#define PHY_PHYCR_LED_CNFG0 (1<<5) +#define PHY_PHYCR_ADDR4 (1<<4) +#define PHY_PHYCR_ADDR3 (1<<3) +#define PHY_PHYCR_ADDR2 (1<<2) +#define PHY_PHYCR_ADDR1 (1<<1) +#define PHY_PHYCR_ADDR0 (1<<0) +#define PHY_10BTSCR (0x1A) +#define PHY_10BTSCR_SERIAL (1<<15) +#define PHY_10BTSCR_SQ_MASK (0x07) +#define PHY_10BTSCR_SQ_SHIFT (9) +#define PHY_10BTSCR_LP_10_DIS (1<<8) +#define PHY_10BTSCR_LP_DIS (1<<7) +#define PHY_10BTSCR_FLINK_10 (1<<1) +#define PHY_10BTSCR_POL (1<<4) +#define PHY_10BTSCR_HB_DIS (1<<1) +#define PHY_10BTSCR_JAB_DIS (1<<0) +#define PHY_CDCTRL1 (0x1B) +#define PHY_EDCR (0x1D) + +#endif /* _DP83848PHY_H */ diff --git a/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.c b/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.c new file mode 100644 index 0000000000..a0eb06116e --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.c @@ -0,0 +1,824 @@ +/* + * This file contains definitions for LatticeMico32 TSMAC (Tri-Speed MAC) + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#define _KERNEL + +#include <rtems.h> +#include <bsp.h> +#include <stdio.h> +#include <errno.h> +#include <rtems/error.h> +#include <rtems/rtems_bsdnet.h> + +#include <sys/param.h> +#include <sys/mbuf.h> +#include <sys/socket.h> +#include <sys/sockio.h> + +#include <net/if.h> + +#include <netinet/in.h> +#include <netinet/if_ether.h> + +#include "../include/system_conf.h" +#include "tsmac.h" +#include "dp83848phy.h" + +struct tsmac_softc { + struct arpcom arpcom; + void *ioaddr; + rtems_id rxDaemonTid; + rtems_id txDaemonTid; + + /* + * Statistics + */ + int rxInterrupts; + int rxPktIgnore; + int rxLenCheckError; + int rxLongFrame; + int rxShortFrame; + int rxIPGViolation; + int rxCRCError; + int rxOKPackets; + int rxControlFrame; + int rxPauseFrame; + int rxMulticast; + int rxBroadcast; + int rxVLANTag; + int rxPreShrink; + int rxDribNib; + int rxUnsupOPCD; + int rxByteCnt; + int rxFifoFull; + + int txInterrupts; + int txUnicast; + int txPauseFrame; + int txMulticast; + int txBroadcast; + int txVLANTag; + int txBadFCS; + int txJumboCnt; + int txByteCnt; + int txLostCarrier; + int txFifoFull; +}; + +/* + * Macros to access tsmac wrapper registers. + */ + +static inline uint32_t tsmacread(unsigned int reg) +{ + return *((uint32_t *)(TS_MAC_CORE_BASE_ADDRESS + reg)); +} + +static inline void tsmacwrite(unsigned int reg, uint32_t value) +{ + *((uint32_t *)(TS_MAC_CORE_BASE_ADDRESS + reg)) = value; +} + +/* + * tsmac is a wishbone to MAC wrapper. + * The macros below access to MAC registers. + */ + +static inline uint16_t tsmacregread(unsigned int reg) +{ + tsmacwrite(LM32_TSMAC_MAC_REGS_ADDR_RW, reg); + return *((uint16_t *)(TS_MAC_CORE_BASE_ADDRESS + LM32_TSMAC_MAC_REGS_DATA + 2)); +} + +static inline void tsmacregwrite(unsigned int reg, uint16_t value) +{ + *((uint16_t *)(TS_MAC_CORE_BASE_ADDRESS + LM32_TSMAC_MAC_REGS_DATA + 2)) = value; + tsmacwrite(LM32_TSMAC_MAC_REGS_ADDR_RW, REGS_ADDR_WRITE | reg); +} + +/* +#define DEBUG 1 +*/ + +/* We support one interface */ + +#define TSMAC_NUM 1 +#define TSMAC_NAME "TSMAC" +#define TSMAC_MAC0 0x00 +#define TSMAC_MAC1 0x0E +#define TSMAC_MAC2 0xB2 +#define TSMAC_MAC3 0x00 +#define TSMAC_MAC4 0x00 +#define TSMAC_MAC5 0x01 + +/* + * The interrupt vector number associated with the tsmac device + * driver. + */ + +#define TSMAC_VECTOR ( TS_MAC_CORE_IRQ ) +#define TSMAC_IRQMASK ( 1 << TSMAC_VECTOR ) + +rtems_isr tsmac_interrupt_handler(rtems_vector_number vector); + +extern lm32_isr_entry set_vector(rtems_isr_entry handler, + rtems_vector_number vector, int type); + +/* + * Macros to access PHY registers through the (G)MII + */ + +uint16_t tsmacphyread(unsigned int reg) +{ + tsmacregwrite(LM32_TSMAC_GMII_MNG_CTL_BYTE0, + ((DEFAULT_PHY_ADDRESS & GMII_MNG_CTL_PHY_ADD_MASK) << + GMII_MNG_CTL_PHY_ADD_SHIFT) | + ((reg & GMII_MNG_CTL_REG_ADD_MASK) << + GMII_MNG_CTL_REG_ADD_SHIFT) | + GMII_MNG_CTL_READ_PHYREG); + + /* Wait for management interface to be ready */ + while(!(tsmacregread(LM32_TSMAC_GMII_MNG_CTL_BYTE0) & GMII_MNG_CTL_CMD_FIN)); + + return tsmacregread(LM32_TSMAC_GMII_MNG_DAT_BYTE0); +} + +void tsmacphywrite(unsigned int reg, uint16_t value) +{ + tsmacregwrite(LM32_TSMAC_GMII_MNG_DAT_BYTE0, value); + tsmacregwrite(LM32_TSMAC_GMII_MNG_CTL_BYTE0, + ((DEFAULT_PHY_ADDRESS & GMII_MNG_CTL_PHY_ADD_MASK) << + GMII_MNG_CTL_PHY_ADD_SHIFT) | + ((reg & GMII_MNG_CTL_REG_ADD_MASK) << + GMII_MNG_CTL_REG_ADD_SHIFT) | + GMII_MNG_CTL_WRITE_PHYREG); + + /* Wait for management interface to be ready */ + while(!(tsmacregread(LM32_TSMAC_GMII_MNG_CTL_BYTE0) & GMII_MNG_CTL_CMD_FIN)); +} + +/* + * Event definitions + */ +#define INTERRUPT_EVENT RTEMS_EVENT_1 +#define START_TRANSMIT_EVENT RTEMS_EVENT_2 + +static struct tsmac_softc tsmac_softc[TSMAC_NUM]; + +#ifdef CPU_U32_FIX + +/* + * Routine to align the received packet so that the ip header + * is on a 32-bit boundary. Necessary for cpu's that do not + * allow unaligned loads and stores and when the 32-bit DMA + * mode is used. + * + * Transfers are done on word basis to avoid possibly slow byte + * and half-word writes. + * + * Copied over from sonic.c driver + */ + +void ipalign(struct mbuf *m) +{ + unsigned int *first, *last, data; + unsigned int tmp = 0; + + if ((((int) m->m_data) & 2) && (m->m_len)) { + last = (unsigned int *) ((((int) m->m_data) + m->m_len + 8) & ~3); + first = (unsigned int *) (((int) m->m_data) & ~3); + tmp = *first << 16; + first++; + do { + data = *first; + *first = tmp | (data >> 16); + tmp = data << 16; + first++; + } while (first <= last); + + m->m_data = (caddr_t)(((int) m->m_data) + 2); + } +} +#endif + +/* + * Receive task + */ +static void tsmac_rxDaemon(void *arg) +{ + struct tsmac_softc *tsmac = (struct tsmac_softc *) arg; + struct ifnet *ifp = &tsmac->arpcom.ac_if; + rtems_event_set events; + int rxq, count, len, data; + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_rxDaemon\n"); +#endif + + for(;;) + { + rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS, + RTEMS_WAIT | RTEMS_EVENT_ANY, + RTEMS_NO_TIMEOUT, + &events); + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_rxDaemon wakeup\n"); +#endif + + for (;;) + { + struct mbuf* m; + struct ether_header* eh; + uint32_t *buf; + + /* Get number of RX frames in RX FIFO */ + rxq = tsmacread(LM32_TSMAC_RX_FRAMES_CNT); + + if (rxq == 0) + break; + + /* Get lenght of frame */ + len = tsmacread(LM32_TSMAC_RX_LEN_FIFO); +#ifdef DEBUG + printk(TSMAC_NAME ": Frames %d, len 0x%04x (%d)\n", + rxq, len, len); +#endif + + /* + * Get memory for packet + */ + MGETHDR(m, M_WAIT, MT_DATA); + MCLGET(m, M_WAIT); + + m->m_pkthdr.rcvif = ifp; + + buf = (uint32_t *) mtod(m, uint32_t*); + for (count = 0; count < len; count += 4) + { + data = tsmacread(LM32_TSMAC_RX_DATA_FIFO); + *buf++ = data; +#ifdef DEBUG + printk("%08x ", data); +#endif + } +#ifdef DEBUG + printk("\n"); +#endif + + m->m_len = m->m_pkthdr.len = + len - sizeof(uint32_t) - sizeof(struct ether_header); + eh = mtod(m, struct ether_header*); + m->m_data += sizeof(struct ether_header); + +#ifdef CPU_U32_FIX + ipalign(m); /* Align packet on 32-bit boundary */ +#endif + + /* Notify the ip stack that there is a new packet */ + ether_input(ifp, eh, m); + + /* + * Release RX frame + */ + } + } +} + +static unsigned char tsmac_txbuf[2048]; + +static void tsmac_sendpacket(struct ifnet *ifp, struct mbuf *m) +{ + struct mbuf *nm = m; + int len = 0, i; + uint32_t *buf; + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_sendpacket\n"); +#endif + + do + { +#ifdef DEBUG + printk("mbuf: 0x%08x len %03x: ", nm->m_data, nm->m_len); + for (i = 0; i < nm->m_len; i++) + { + printk("%02x", mtod(nm, unsigned char*)[i]); + if (i & 1) + printk(" "); + } + printk("\n"); +#endif + + if (nm->m_len > 0) + { + memcpy(&tsmac_txbuf[len], (char *)nm->m_data, nm->m_len); + len += nm->m_len; + } + } + while ((nm = nm->m_next) != 0); + + buf = (uint32_t *) tsmac_txbuf; + for (i = 0; i < len; i += 4) + { +#ifdef DEBUG + printk("%08x", *buf); +#endif + tsmacwrite(LM32_TSMAC_TX_DATA_FIFO, *buf++); + } +#ifdef DEBUG + printk("\n"); +#endif + + /* + * Enqueue TX frame + */ + tsmacwrite(LM32_TSMAC_TX_LEN_FIFO, len); +} + +/* + * Transmit task + */ +static void tsmac_txDaemon(void *arg) +{ + struct tsmac_softc *tsmac = (struct tsmac_softc *) arg; + struct ifnet *ifp = &tsmac->arpcom.ac_if; + struct mbuf *m; + rtems_event_set events; + int txq; + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_txDaemon\n"); +#endif + + for (;;) + { + /* + * Wait for packet + */ + rtems_bsdnet_event_receive (START_TRANSMIT_EVENT | INTERRUPT_EVENT, + RTEMS_EVENT_ANY | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, &events); +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_txDaemon event\n"); +#endif + for (;;) + { + /* + * Here we should read amount of transmit memory available + */ + + txq = 2048; + + if (txq < ifp->if_mtu) + { + /* + * Here we need to enable transmit done IRQ + */ +#ifdef DEBUG + printk(TSMAC_NAME ": TXMA %d < MTU + CW%d\n", txq, + ifp->if_mtu); +#endif + break; + } + + /* + * Get the next mbuf chain to transmit. + */ + IF_DEQUEUE(&ifp->if_snd, m); +#ifdef DEBUG + printk(TSMAC_NAME ": mbuf %08x\n", (int) m); +#endif + if (!m) + break; + tsmac_sendpacket(ifp, m); + + m_freem(m); + } + ifp->if_flags &= ~IFF_OACTIVE; + } +} + +/* + * Initialize TSMAC hardware + */ +void tsmac_init_hardware(struct tsmac_softc *tsmac) +{ + unsigned char *mac_addr; + int version_id, phyid, stat; + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_init_hardware\n"); +#endif + + version_id = tsmacread(LM32_TSMAC_VERID); +#ifdef DEBUG + printk(TSMAC_NAME ": Version ID %08x\n", version_id); +#endif + +#ifdef DEBUG + printk(TSMAC_NAME ": MAC MODE %04x\n", tsmacregread(LM32_TSMAC_MODE_BYTE0)); + printk(TSMAC_NAME ": MAC TX_RX_CTL %04x\n", tsmacregread(LM32_TSMAC_TX_RX_CTL_BYTE0)); + printk(TSMAC_NAME ": MAC MAX_PKT_SIZE %04x\n", tsmacregread(LM32_TSMAC_MAX_PKT_SIZE_BYTE0)); + printk(TSMAC_NAME ": MAC IPG_VAL %04x\n", tsmacregread(LM32_TSMAC_IPG_VAL_BYTE0)); + printk(TSMAC_NAME ": MAC MAC_ADDR0 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_0_BYTE0)); + printk(TSMAC_NAME ": MAC MAC_ADDR1 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_1_BYTE0)); + printk(TSMAC_NAME ": MAC MAC_ADDR2 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_2_BYTE0)); + printk(TSMAC_NAME ": MAC TX_RX_STS %04x\n", + tsmacregread(LM32_TSMAC_TX_RX_STS_BYTE0)); +#endif + + /* + * Set our physical address + */ + mac_addr = tsmac->arpcom.ac_enaddr; + tsmacregwrite(LM32_TSMAC_MAC_ADDR_0_BYTE0, (mac_addr[0] << 8) | mac_addr[1]); + tsmacregwrite(LM32_TSMAC_MAC_ADDR_1_BYTE0, (mac_addr[2] << 8) | mac_addr[3]); + tsmacregwrite(LM32_TSMAC_MAC_ADDR_2_BYTE0, (mac_addr[4] << 8) | mac_addr[5]); + +#ifdef DEBUG + printk(TSMAC_NAME ": After setting MAC address.\n"); + printk(TSMAC_NAME ": MAC MAC_ADDR0 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_0_BYTE0)); + printk(TSMAC_NAME ": MAC MAC_ADDR1 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_1_BYTE0)); + printk(TSMAC_NAME ": MAC MAC_ADDR2 %04x\n", + tsmacregread(LM32_TSMAC_MAC_ADDR_2_BYTE0)); +#endif + + /* + * Configure PHY + */ + + phyid = tsmacphyread(PHY_PHYIDR1); +#ifdef DEBUG + printk(TSMAC_NAME ": PHYIDR1 %08x\n", phyid); +#endif + phyid = tsmacphyread(PHY_PHYIDR2); +#ifdef DEBUG + printk(TSMAC_NAME ": PHYIDR2 %08x\n", phyid); +#endif + +#ifdef TSMAC_FORCE_10BASET + /* Force 10baseT mode, no AN, full duplex */ + tsmacphywrite(PHY_BMCR, PHY_BMCR_DUPLEX_MODE); + stat = tsmacphyread(PHY_BMCR); +#ifdef DEBUG + printk(TSMAC_NAME ": PHY BMCR %04x, wrote %04x\n", stat, + PHY_BMCR_DUPLEX_MODE); +#endif + stat = tsmacphyread(PHY_BMSR); +#ifdef DEBUG + printk(TSMAC_NAME ": PHY BMSR %04x\n", stat); +#endif + /* Support for 10baseT modes only */ + tsmacphywrite(PHY_ANAR, PHY_ANAR_10_FD | PHY_ANAR_10 | PHY_ANAR_SEL_DEF); + stat = tsmacphyread(PHY_ANAR); +#ifdef DEBUG + printk(TSMAC_NAME ": PHY ANAR %04x, wrote %04x\n", stat, + PHY_ANAR_10_FD | PHY_ANAR_10 | PHY_ANAR_SEL_DEF); +#endif +#endif /* TSMAC_FORCE_10BASET */ + stat = tsmacphyread(PHY_PHYSTS); +#ifdef DEBUG + printk(TSMAC_NAME ": PHY PHYSTS %04x\n", stat); +#endif + + /* Enable receive and transmit interrupts */ + tsmacwrite(LM32_TSMAC_INTR_ENB, INTR_ENB | + INTR_RX_SMRY | INTR_TX_SMRY | + INTR_RX_PKT_RDY | INTR_TX_PKT_SENT); +} + +/* + * Initialize and start the device + */ +void tsmac_init(void *arg) +{ + struct tsmac_softc *tsmac = &tsmac_softc[0]; + struct ifnet *ifp = &tsmac->arpcom.ac_if; + +#ifdef DEBUG + printk(TSMAC_NAME ": tsmac_init, tsmac->txDaemonTid = 0x%x\n", + tsmac->txDaemonTid); +#endif + + if (tsmac->txDaemonTid == 0) + { + /* + * Initialize hardware + */ + tsmac_init_hardware(tsmac); + + /* + * Start driver tasks + */ + tsmac->txDaemonTid = rtems_bsdnet_newproc ("TSMACtx", 4096, + tsmac_txDaemon, tsmac); + tsmac->rxDaemonTid = rtems_bsdnet_newproc ("TSMACrx", 4096, + tsmac_rxDaemon, tsmac); + /* + * Setup interrupt handler + */ + set_vector( tsmac_interrupt_handler, TSMAC_VECTOR, 1 ); + + /* Interrupt line for TSMAC */ + lm32_interrupt_unmask(TSMAC_IRQMASK); + } + + ifp->if_flags |= IFF_RUNNING; + + /* + * Receive broadcast + */ + + tsmacregwrite(LM32_TSMAC_TX_RX_CTL_BYTE0, TX_RX_CTL_RECEIVE_BRDCST | + TX_RX_CTL_RECEIVE_PAUSE); + + /* + * Enable transmitter + * Flow control enable + * Enable receiver + */ + + tsmacregwrite(LM32_TSMAC_MODE_BYTE0, MODE_TX_EN | MODE_RX_EN | MODE_FC_EN); + + /* + * Wake up receive task to receive packets in queue + */ + rtems_event_send(tsmac->rxDaemonTid, INTERRUPT_EVENT); +} + +void tsmac_stop(struct ifnet *ifp) +{ + struct tsmac_softc *tsmac = ifp->if_softc; + + /* + * Mask tsmac interrupts + */ + lm32_interrupt_mask(TSMAC_IRQMASK); + + ifp->if_flags &= ~IFF_RUNNING; + + /* + * Disable transmitter and receiver + */ + tsmacregwrite(LM32_TSMAC_MODE_BYTE0, 0); +} + +/* + * Send packet + */ +void tsmac_start(struct ifnet *ifp) +{ + struct tsmac_softc *tsmac = ifp->if_softc; + + rtems_event_send (tsmac->txDaemonTid, START_TRANSMIT_EVENT); + ifp->if_flags |= IFF_OACTIVE; +} + +void tsmac_stats(struct tsmac_softc *tsmac) +{ + uint32_t data; + int stat; + + /* + * Update counters from TSMAC MIB counters + */ + + tsmac->rxPktIgnore = tsmacread(LM32_TSMAC_RX_PKT_IGNR_CNT); + tsmac->rxLenCheckError = tsmacread(LM32_TSMAC_RX_LEN_CHK_ERR_CNT); + tsmac->rxLongFrame = tsmacread(LM32_TSMAC_RX_LNG_FRM_CNT); + tsmac->rxShortFrame = tsmacread(LM32_TSMAC_RX_SHRT_FRM_CNT); + tsmac->rxIPGViolation = tsmacread(LM32_TSMAC_RX_IPG_VIOL_CNT); + tsmac->rxCRCError = tsmacread(LM32_TSMAC_RX_CRC_ERR_CNT); + tsmac->rxOKPackets = tsmacread(LM32_TSMAC_RX_OK_PKT_CNT); + tsmac->rxControlFrame = tsmacread(LM32_TSMAC_RX_CTL_FRM_CNT); + tsmac->rxPauseFrame = tsmacread(LM32_TSMAC_RX_PAUSE_FRM_CNT); + tsmac->rxMulticast = tsmacread(LM32_TSMAC_RX_MULTICAST_CNT); + tsmac->rxBroadcast = tsmacread(LM32_TSMAC_RX_BRDCAST_CNT); + tsmac->rxVLANTag = tsmacread(LM32_TSMAC_RX_VLAN_TAG_CNT); + tsmac->rxPreShrink = tsmacread(LM32_TSMAC_RX_PRE_SHRINK_CNT); + tsmac->rxDribNib = tsmacread(LM32_TSMAC_RX_DRIB_NIB_CNT); + tsmac->rxUnsupOPCD = tsmacread(LM32_TSMAC_RX_UNSUP_OPCD_CNT); + tsmac->rxByteCnt = tsmacread(LM32_TSMAC_RX_BYTE_CNT); + + tsmac->txUnicast = tsmacread(LM32_TSMAC_TX_UNICAST_CNT); + tsmac->txPauseFrame = tsmacread(LM32_TSMAC_TX_PAUSE_FRM_CNT); + tsmac->txMulticast = tsmacread(LM32_TSMAC_TX_MULTICAST_CNT); + tsmac->txBroadcast = tsmacread(LM32_TSMAC_TX_BRDCAST_CNT); + tsmac->txVLANTag = tsmacread(LM32_TSMAC_TX_VLAN_TAG_CNT); + tsmac->txBadFCS = tsmacread(LM32_TSMAC_TX_BAD_FCS_CNT); + tsmac->txJumboCnt = tsmacread(LM32_TSMAC_TX_JUMBO_CNT); + tsmac->txByteCnt = tsmacread(LM32_TSMAC_TX_BYTE_CNT); + + printk("RX Interrupts: %8d", tsmac->rxInterrupts); + printk(" RX Len Chk Error: %8d", tsmac->rxLenCheckError); + printk(" RX Long Frame: %8d\n", tsmac->rxLongFrame); + printk("RX Short Frame: %8d", tsmac->rxShortFrame); + printk(" RX IPG Violation: %8d", tsmac->rxIPGViolation); + printk(" RX CRC Errors: %8d\n", tsmac->rxCRCError); + printk("RX OK Packets: %8d", tsmac->rxOKPackets); + printk(" RX Control Frame: %8d", tsmac->rxControlFrame); + printk(" RX Pause Frame: %8d\n", tsmac->rxPauseFrame); + printk("RX Multicast: %8d", tsmac->rxMulticast); + printk(" RX Broadcast: %8d", tsmac->rxBroadcast); + printk(" RX VLAN Tag: %8d\n", tsmac->rxVLANTag); + printk("RX Pre Shrink: %8d", tsmac->rxPreShrink); + printk(" RX Dribb. Nibble: %8d", tsmac->rxDribNib); + printk(" RX Unsupp. OPCD: %8d\n", tsmac->rxUnsupOPCD); + printk("RX Byte Count: %8d", tsmac->rxByteCnt); + printk(" RX FIFO Full: %8d\n", tsmac->rxFifoFull); + + printk("TX Interrupts: %8d", tsmac->txInterrupts); + printk(" TX Unicast: %8d", tsmac->txUnicast); + printk(" TX Pause Frame: %8d\n", tsmac->txPauseFrame); + printk("TX Multicast: %8d", tsmac->txMulticast); + printk(" TX Broadcast: %8d", tsmac->txBroadcast); + printk(" TX VLAN Tag: %8d\n", tsmac->txVLANTag); + printk("TX Bad FSC: %8d", tsmac->txBadFCS); + printk(" TX Jumbo Frame: %8d", tsmac->txJumboCnt); + printk(" TX Byte Count: %8d\n", tsmac->txByteCnt); + printk("TX FIFO Full: %8d\n", tsmac->txFifoFull); +} + +/* + * TSMAC ioctl handler + */ + +int tsmac_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data) +{ + struct tsmac_softc *tsmac = ifp->if_softc; + int error = 0; + + switch (command) { + case SIOCGIFADDR: + case SIOCSIFADDR: + ether_ioctl (ifp, command, data); + break; + + case SIOCSIFFLAGS: + switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { + case IFF_RUNNING: + tsmac_stop ((struct ifnet *) tsmac); + break; + + case IFF_UP: + tsmac_init ((struct ifnet *) tsmac); + break; + + case IFF_UP | IFF_RUNNING: + tsmac_stop ((struct ifnet *) tsmac); + tsmac_init ((struct ifnet *) tsmac); + break; + + default: + break; + } + break; + + case SIO_RTEMS_SHOW_STATS: + tsmac_stats (tsmac); + break; + + default: + error = EINVAL; + break; + } + return error; +} + +/* + * Attach a TSMAC driver + */ +int rtems_tsmac_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching) +{ + struct tsmac_softc *tsmac; + struct ifnet *ifp; + int mtu, i; + int unit; + char *unitName; + + if ((unit = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0) + { + printk(TSMAC_NAME ": Driver name parsing failed.\n"); + return 0; + } + + if ((unit < 0) || (unit >= TSMAC_NUM)) + { + printk(TSMAC_NAME ": Bad unit number %d.\n", unit); + return 0; + } + + tsmac = &tsmac_softc[unit]; + + ifp = &tsmac->arpcom.ac_if; + if (ifp->if_softc != NULL) + { + printk(TSMAC_NAME ": Driver already in use.\n"); + return 0; + } + + /* Base address for TSMAC */ + if (config->bpar == 0) + { + printk(TSMAC_NAME ": Using default base address 0x%08x.\n", TS_MAC_CORE_BASE_ADDRESS); + config->bpar = TS_MAC_CORE_BASE_ADDRESS; + } + tsmac->ioaddr = config->bpar; + + /* Hardware address for TSMAC */ + if (config->hardware_address == 0) + { + printk(TSMAC_NAME ": Using default hardware address.\n"); + tsmac->arpcom.ac_enaddr[0] = TSMAC_MAC0; + tsmac->arpcom.ac_enaddr[1] = TSMAC_MAC1; + tsmac->arpcom.ac_enaddr[2] = TSMAC_MAC2; + tsmac->arpcom.ac_enaddr[3] = TSMAC_MAC3; + tsmac->arpcom.ac_enaddr[4] = TSMAC_MAC4; + tsmac->arpcom.ac_enaddr[5] = TSMAC_MAC5; + } + else + memcpy(tsmac->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN); + + printk(TSMAC_NAME ": MAC address "); + for (i = 0; i < ETHER_ADDR_LEN; i++) + { + printk("%02x", tsmac->arpcom.ac_enaddr[i]); + if (i != ETHER_ADDR_LEN-1) + printk(":"); + else + printk("\n"); + } + + if (config->mtu) + mtu = config->mtu; + else + mtu = ETHERMTU; + + /* + * Set up network interface values + */ + ifp->if_softc = tsmac; + ifp->if_unit = unit; + ifp->if_name = unitName; + ifp->if_mtu = mtu; + ifp->if_init = tsmac_init; + ifp->if_ioctl = tsmac_ioctl; + ifp->if_start = tsmac_start; + ifp->if_output = ether_output; + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; + + if (ifp->if_snd.ifq_maxlen == 0) + ifp->if_snd.ifq_maxlen = ifqmaxlen; + + if_attach(ifp); + ether_ifattach(ifp); +} + +rtems_isr tsmac_interrupt_handler(rtems_vector_number vector) +{ + struct tsmac_softc *tsmac = &tsmac_softc[0]; + uint32_t irq_stat, rx_stat, tx_stat; + + irq_stat = tsmacread(LM32_TSMAC_INTR_SRC); + if (irq_stat & INTR_RX_PKT_RDY) + { + tsmac->rxInterrupts++; + rtems_event_send(tsmac->rxDaemonTid, INTERRUPT_EVENT); + } + + if (irq_stat & INTR_TX_PKT_SENT) + { + tsmac->txInterrupts++; + rtems_event_send(tsmac->txDaemonTid, INTERRUPT_EVENT); + } + + rx_stat = tsmacread(LM32_TSMAC_RX_STATUS); + if (rx_stat & STAT_RX_FIFO_FULL) + tsmac->rxFifoFull++; + + tx_stat = tsmacread(LM32_TSMAC_TX_STATUS); + if (tx_stat & STAT_TX_FIFO_FULL) + tsmac->txFifoFull++; + + lm32_interrupt_ack(TSMAC_IRQMASK); +} + diff --git a/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.h b/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.h new file mode 100644 index 0000000000..1c7f063bb0 --- /dev/null +++ b/c/src/lib/libbsp/lm32/shared/tsmac/tsmac.h @@ -0,0 +1,160 @@ +/* + * This file contains definitions for LatticeMico32 TSMAC (Tri-Speed MAC) + * + * COPYRIGHT (c) 1989-1999. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + * + * Jukka Pietarinen <jukka.pietarinen@mrf.fi>, 2008, + * Micro-Research Finland Oy + */ + +#ifndef _BSPTSMAC_H +#define _BSPTSMAC_H + +/* FIFO Registers */ + +#define LM32_TSMAC_RX_LEN_FIFO (0x000) +#define LM32_TSMAC_RX_DATA_FIFO (0x004) +#define LM32_TSMAC_TX_LEN_FIFO (0x008) +#define LM32_TSMAC_TX_DATA_FIFO (0x00C) + +/* Control and Status Registers */ + +#define LM32_TSMAC_VERID (0x100) +#define LM32_TSMAC_INTR_SRC (0x104) +#define INTR_RX_SMRY (0x00020000) +#define INTR_TX_SMRY (0x00010000) +#define INTR_RX_FIFO_FULL (0x00001000) +#define INTR_RX_ERROR (0x00000800) +#define INTR_RX_FIFO_ERROR (0x00000400) +#define INTR_RX_FIFO_ALMOST_FULL (0x00000200) +#define INTR_RX_PKT_RDY (0x00000100) +#define INTR_TX_FIFO_FULL (0x00000010) +#define INTR_TX_DISCFRM (0x00000008) +#define INTR_TX_FIFO_ALMOST_EMPTY (0x00000004) +#define INTR_TX_FIFO_ALMOST_FULL (0x00000002) +#define INTR_TX_PKT_SENT (0x00000001) +#define LM32_TSMAC_INTR_ENB (0x108) +#define INTR_ENB (0x00040000) +#define LM32_TSMAC_RX_STATUS (0x10C) +#define STAT_RX_FIFO_FULL (0x00000010) +#define STAT_RX_ERROR (0x00000008) +#define STAT_RX_FIFO_ERROR (0x00000004) +#define STAT_RX_FIFO_ALMOST_FULL (0x00000002) +#define STAT_RX_PKT_RDY (0x00000001) +#define LM32_TSMAC_TX_STATUS (0x110) +#define STAT_TX_FIFO_FULL (0x00000010) +#define STAT_TX_DISCFRM (0x00000008) +#define STAT_TX_FIFO_ALMOST_EMPTY (0x00000004) +#define STAT_TX_FIFO_ALMOST_FULL (0x00000002) +#define STAT_TX_PKT_SENT (0x00000001) +#define LM32_TSMAC_RX_FRAMES_CNT (0x114) +#define LM32_TSMAC_TX_FRAMES_CNT (0x118) +#define LM32_TSMAC_RX_FIFO_TH (0x11C) +#define LM32_TSMAC_TX_FIFO_TH (0x120) +#define LM32_TSMAC_SYS_CTL (0x124) +#define SYS_CTL_TX_FIFO_FLUSH (0x00000010) +#define SYS_CTL_RX_FIFO_FLUSH (0x00000008) +#define SYS_CTL_TX_SNDPAUSREQ (0x00000004) +#define SYS_CTL_TX_FIFOCTRL (0x00000002) +#define SYS_CTL_IGNORE_NEXT_PKT (0x00000001) +#define LM32_TSMAC_PAUSE_TMR (0x128) + +/* Tri-Speed MAC Registers */ + +#define LM32_TSMAC_MAC_REGS_DATA (0x200) +#define LM32_TSMAC_MAC_REGS_ADDR_RW (0x204) +#define REGS_ADDR_WRITE (0x80000000) +#define LM32_TSMAC_MODE_BYTE0 (0x000) +#define MODE_TX_EN (1<<3) +#define MODE_RX_EN (1<<2) +#define MODE_FC_EN (1<<1) +#define MODE_GBIT_EN (1<<0) +#define LM32_TSMAC_TX_RX_CTL_BYTE0 (0x002) +#define TX_RX_CTL_RECEIVE_SHORT (1<<8) +#define TX_RX_CTL_RECEIVE_BRDCST (1<<7) +#define TX_RX_CTL_DIS_RTRY (1<<6) +#define TX_RX_CTL_HDEN (1<<5) +#define TX_RX_CTL_RECEIVE_MLTCST (1<<4) +#define TX_RX_CTL_RECEIVE_PAUSE (1<<3) +#define TX_RX_CTL_TX_DIS_FCS (1<<2) +#define TX_RX_CTL_DISCARD_FCS (1<<1) +#define TX_RX_CTL_PRMS (1<<0) +#define LM32_TSMAC_MAX_PKT_SIZE_BYTE0 (0x004) +#define LM32_TSMAC_IPG_VAL_BYTE0 (0x008) +#define LM32_TSMAC_MAC_ADDR_0_BYTE0 (0x00A) +#define LM32_TSMAC_MAC_ADDR_1_BYTE0 (0x00C) +#define LM32_TSMAC_MAC_ADDR_2_BYTE0 (0x00E) +#define LM32_TSMAC_TX_RX_STS_BYTE0 (0x012) +#define TX_RX_STS_RX_IDLE (1<<10) +#define TX_RX_STS_TAGGED_FRAME (1<<9) +#define TX_RX_STS_BRDCST_FRAME (1<<8) +#define TX_RX_STS_MULTCST_FRAME (1<<7) +#define TX_RX_STS_IPG_SHRINK (1<<6) +#define TX_RX_STS_SHORT_FRAME (1<<5) +#define TX_RX_STS_LONG_FRAME (1<<4) +#define TX_RX_STS_ERROR_FRAME (1<<3) +#define TX_RX_STS_CRC (1<<2) +#define TX_RX_STS_PAUSE_FRAME (1<<1) +#define TX_RX_STS_TX_IDLE (1<<0) +#define LM32_TSMAC_GMII_MNG_CTL_BYTE0 (0x014) +#define GMII_MNG_CTL_CMD_FIN (1<<14) +#define GMII_MNG_CTL_READ_PHYREG (0) +#define GMII_MNG_CTL_WRITE_PHYREG (1<<13) +#define GMII_MNG_CTL_PHY_ADD_MASK (0x001f) +#define GMII_MNG_CTL_PHY_ADD_SHIFT (8) +#define GMII_MNG_CTL_REG_ADD_MASK (0x001f) +#define GMII_MNG_CTL_REG_ADD_SHIFT (0) +#define LM32_TSMAC_GMII_MNG_DAT_BYTE0 (0x016) +#define LM32_TSMAC_MLT_TAB_0_BYTE0 (0x022) +#define LM32_TSMAC_MLT_TAB_1_BYTE0 (0x024) +#define LM32_TSMAC_MLT_TAB_2_BYTE0 (0x026) +#define LM32_TSMAC_MLT_TAB_3_BYTE0 (0x028) +#define LM32_TSMAC_MLT_TAB_4_BYTE0 (0x02A) +#define LM32_TSMAC_MLT_TAB_5_BYTE0 (0x02C) +#define LM32_TSMAC_MLT_TAB_6_BYTE0 (0x02E) +#define LM32_TSMAC_MLT_TAB_7_BYTE0 (0x030) +#define LM32_TSMAC_VLAN_TAG_BYTE0 (0x032) +#define LM32_TSMAC_PAUS_OP_BYTE0 (0x034) + +/* Receive Statistics Counters */ + +#define LM32_TSMAC_RX_PKT_IGNR_CNT (0x300) +#define LM32_TSMAC_RX_LEN_CHK_ERR_CNT (0x304) +#define LM32_TSMAC_RX_LNG_FRM_CNT (0x308) +#define LM32_TSMAC_RX_SHRT_FRM_CNT (0x30C) +#define LM32_TSMAC_RX_IPG_VIOL_CNT (0x310) +#define LM32_TSMAC_RX_CRC_ERR_CNT (0x314) +#define LM32_TSMAC_RX_OK_PKT_CNT (0x318) +#define LM32_TSMAC_RX_CTL_FRM_CNT (0x31C) +#define LM32_TSMAC_RX_PAUSE_FRM_CNT (0x320) +#define LM32_TSMAC_RX_MULTICAST_CNT (0x324) +#define LM32_TSMAC_RX_BRDCAST_CNT (0x328) +#define LM32_TSMAC_RX_VLAN_TAG_CNT (0x32C) +#define LM32_TSMAC_RX_PRE_SHRINK_CNT (0x330) +#define LM32_TSMAC_RX_DRIB_NIB_CNT (0x334) +#define LM32_TSMAC_RX_UNSUP_OPCD_CNT (0x338) +#define LM32_TSMAC_RX_BYTE_CNT (0x33C) + +/* Transmit Statistics Counters */ + +#define LM32_TSMAC_TX_UNICAST_CNT (0x400) +#define LM32_TSMAC_TX_PAUSE_FRM_CNT (0x404) +#define LM32_TSMAC_TX_MULTICAST_CNT (0x408) +#define LM32_TSMAC_TX_BRDCAST_CNT (0x40C) +#define LM32_TSMAC_TX_VLAN_TAG_CNT (0x410) +#define LM32_TSMAC_TX_BAD_FCS_CNT (0x414) +#define LM32_TSMAC_TX_JUMBO_CNT (0x418) +#define LM32_TSMAC_TX_BYTE_CNT (0x41C) + +#ifdef CPU_U32_FIX +void ipalign(struct mbuf *m); +#endif + +#endif /* _BSPTSMAC_H */ |