summaryrefslogtreecommitdiffstats
path: root/c/src/libchip
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-03 07:20:11 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-04-04 10:13:28 +0200
commit27de4e1fb8bcdbdd8cb882fc0d7a2c152b4e027a (patch)
treedef0664dcddc53fd5d599b455c64f76ca2293606 /c/src/libchip
parentbsps: Move config macros to RTEMS_BSP_CONFIGURE (diff)
downloadrtems-27de4e1fb8bcdbdd8cb882fc0d7a2c152b4e027a.tar.bz2
bsps: Move libchip to bsps
This patch is a part of the BSP source reorganization. Update #3285.
Diffstat (limited to 'c/src/libchip')
-rw-r--r--c/src/libchip/Makefile.am71
-rw-r--r--c/src/libchip/display/disp_fonts.h55
-rw-r--r--c/src/libchip/display/disp_hcms29xx.c932
-rw-r--r--c/src/libchip/display/font_hcms29xx.c1820
-rw-r--r--c/src/libchip/display/font_hcms29xx.h36
-rw-r--r--c/src/libchip/flash/am29lv160.c473
-rw-r--r--c/src/libchip/i2c/i2c-2b-eeprom.c177
-rw-r--r--c/src/libchip/i2c/i2c-ds1621.c128
-rw-r--r--c/src/libchip/i2c/i2c-sc620.c95
-rw-r--r--c/src/libchip/i2c/spi-flash-m25p40.c60
-rw-r--r--c/src/libchip/i2c/spi-fram-fm25l256.c60
-rw-r--r--c/src/libchip/i2c/spi-memdrv.c442
-rw-r--r--c/src/libchip/i2c/spi-sd-card.c1322
-rw-r--r--c/src/libchip/ide/ata.c1360
-rw-r--r--c/src/libchip/ide/ata_util.c215
-rw-r--r--c/src/libchip/ide/ide_controller.c200
-rw-r--r--c/src/libchip/network/README12
-rw-r--r--c/src/libchip/network/README.3com3
-rw-r--r--c/src/libchip/network/README.cs890026
-rw-r--r--c/src/libchip/network/README.dec21140116
-rw-r--r--c/src/libchip/network/README.i825861
-rw-r--r--c/src/libchip/network/README.open_eth72
-rw-r--r--c/src/libchip/network/README.sonic135
-rw-r--r--c/src/libchip/network/README.tulipclone101
-rw-r--r--c/src/libchip/network/cs8900.c1216
-rw-r--r--c/src/libchip/network/cs8900.c.bsp510
-rw-r--r--c/src/libchip/network/cs8900.h.bsp38
-rw-r--r--c/src/libchip/network/dec21140.c1112
-rw-r--r--c/src/libchip/network/elnk.c3553
-rw-r--r--c/src/libchip/network/greth.c1196
-rw-r--r--c/src/libchip/network/i82586.c2198
-rw-r--r--c/src/libchip/network/i82586reg.h448
-rw-r--r--c/src/libchip/network/if_dc.c3849
-rw-r--r--c/src/libchip/network/if_fxp.c2339
-rw-r--r--c/src/libchip/network/if_fxpreg.h370
-rw-r--r--c/src/libchip/network/open_eth.c767
-rw-r--r--c/src/libchip/network/smc91111.c1653
-rw-r--r--c/src/libchip/network/smc91111config.h118
-rw-r--r--c/src/libchip/network/sonic.c1685
-rw-r--r--c/src/libchip/rtc/README.ds16433
-rw-r--r--c/src/libchip/rtc/README.icm717048
-rw-r--r--c/src/libchip/rtc/README.m48t0844
-rw-r--r--c/src/libchip/rtc/README.m48t181
-rw-r--r--c/src/libchip/rtc/README.mc146818a1
-rw-r--r--c/src/libchip/rtc/STATUS33
-rw-r--r--c/src/libchip/rtc/ds1375.c461
-rw-r--r--c/src/libchip/rtc/icm7170.c168
-rw-r--r--c/src/libchip/rtc/icm7170_reg.c60
-rw-r--r--c/src/libchip/rtc/icm7170_reg2.c20
-rw-r--r--c/src/libchip/rtc/icm7170_reg4.c20
-rw-r--r--c/src/libchip/rtc/icm7170_reg8.c20
-rw-r--r--c/src/libchip/rtc/m48t08.c161
-rw-r--r--c/src/libchip/rtc/m48t08_reg.c60
-rw-r--r--c/src/libchip/rtc/m48t08_reg2.c20
-rw-r--r--c/src/libchip/rtc/m48t08_reg4.c20
-rw-r--r--c/src/libchip/rtc/m48t08_reg8.c20
-rw-r--r--c/src/libchip/rtc/mc146818a.c180
-rw-r--r--c/src/libchip/rtc/mc146818a_ioreg.c56
-rw-r--r--c/src/libchip/rtc/rtcprobe.c21
-rw-r--r--c/src/libchip/serial/README13
-rw-r--r--c/src/libchip/serial/README.mc6868183
-rw-r--r--c/src/libchip/serial/README.ns1655082
-rw-r--r--c/src/libchip/serial/README.xr886812
-rw-r--r--c/src/libchip/serial/README.z85c3074
-rw-r--r--c/src/libchip/serial/STATUS48
-rw-r--r--c/src/libchip/serial/mc68681.c776
-rw-r--r--c/src/libchip/serial/mc68681_baud.c124
-rw-r--r--c/src/libchip/serial/mc68681_p.h323
-rw-r--r--c/src/libchip/serial/mc68681_reg.c61
-rw-r--r--c/src/libchip/serial/mc68681_reg2.c20
-rw-r--r--c/src/libchip/serial/mc68681_reg4.c20
-rw-r--r--c/src/libchip/serial/mc68681_reg8.c20
-rw-r--r--c/src/libchip/serial/ns16550-context.c814
-rw-r--r--c/src/libchip/serial/ns16550.c875
-rw-r--r--c/src/libchip/serial/serprobe.c13
-rw-r--r--c/src/libchip/serial/z85c30.c893
-rw-r--r--c/src/libchip/serial/z85c30_p.h420
-rw-r--r--c/src/libchip/serial/z85c30_reg.c72
78 files changed, 1 insertions, 35113 deletions
diff --git a/c/src/libchip/Makefile.am b/c/src/libchip/Makefile.am
index 89c9688a8c..74c83f14c8 100644
--- a/c/src/libchip/Makefile.am
+++ b/c/src/libchip/Makefile.am
@@ -1,77 +1,8 @@
include $(top_srcdir)/automake/compile.am
-noinst_LIBRARIES =
-noinst_PROGRAMS =
-
-# display
-noinst_LIBRARIES += libdisplay.a
-libdisplay_a_SOURCES = display/disp_hcms29xx.c display/font_hcms29xx.c
-libdisplay_a_CPPFLAGS = $(AM_CPPFLAGS)
-
-# flash
-noinst_LIBRARIES += libflash.a
-libflash_a_SOURCES = flash/am29lv160.c
-libflash_a_CPPFLAGS = $(AM_CPPFLAGS)
-
-# ide
-noinst_LIBRARIES += libide.a
-libide_a_SOURCES = ide/ata.c ide/ata_util.c ide/ide_controller.c
-libide_a_CPPFLAGS = $(AM_CPPFLAGS)
-
-# network
-if HAS_NETWORKING
-noinst_LIBRARIES += libnetchip.a
-libnetchip_a_CPPFLAGS = $(AM_CPPFLAGS)
-libnetchip_a_SOURCES = network/cs8900.c network/dec21140.c network/i82586.c \
- network/sonic.c network/if_fxp.c network/elnk.c network/open_eth.c \
- network/if_dc.c
-if !HAS_SMP
-libnetchip_a_SOURCES += network/greth.c
-endif
-libnetchip_a_SOURCES += network/smc91111.c network/smc91111config.h
-endif
-
-
-# rtc
-noinst_LIBRARIES += librtcio.a
-librtcio_a_CPPFLAGS = $(AM_CPPFLAGS)
-librtcio_a_SOURCES = rtc/rtcprobe.c rtc/icm7170.c rtc/icm7170_reg.c \
- rtc/icm7170_reg2.c rtc/icm7170_reg4.c rtc/icm7170_reg8.c rtc/m48t08.c \
- rtc/m48t08_reg.c rtc/m48t08_reg2.c rtc/m48t08_reg4.c rtc/m48t08_reg8.c \
- rtc/mc146818a.c rtc/mc146818a_ioreg.c rtc/ds1375.c
-
-
-# i2c
-noinst_LIBRARIES += libi2cio.a
-
-libi2cio_a_CPPFLAGS = $(AM_CPPFLAGS)
-libi2cio_a_SOURCES = i2c/i2c-ds1621.h \
- i2c/i2c-2b-eeprom.h \
- i2c/spi-memdrv.h \
- i2c/spi-flash-m25p40.h \
- i2c/spi-fram-fm25l256.h \
- i2c/i2c-ds1621.c \
- i2c/i2c-2b-eeprom.c \
- i2c/i2c-sc620.c \
- i2c/spi-memdrv.c \
- i2c/spi-flash-m25p40.c \
- i2c/spi-fram-fm25l256.c \
- i2c/spi-sd-card.c
-
-# serial
-noinst_LIBRARIES += libserialio.a
-libserialio_a_CPPFLAGS = $(AM_CPPFLAGS)
-libserialio_a_SOURCES = serial/mc68681.c serial/mc68681_baud.c \
- serial/mc68681_reg.c serial/mc68681_reg2.c serial/mc68681_reg4.c \
- serial/mc68681_reg8.c serial/ns16550.c serial/z85c30.c \
- serial/z85c30_reg.c serial/serprobe.c serial/mc68681_p.h \
- serial/z85c30_p.h
-libserialio_a_SOURCES += serial/ns16550-context.c
-
-
## shmdr
if HAS_MP
-noinst_LIBRARIES += libshmdr.a
+noinst_LIBRARIES = libshmdr.a
libshmdr_a_CPPFLAGS = $(AM_CPPFLAGS)
libshmdr_a_SOURCES = shmdr/addlq.c shmdr/cnvpkt.c shmdr/getlq.c shmdr/dump.c \
shmdr/fatal.c shmdr/getpkt.c shmdr/init.c shmdr/initlq.c shmdr/intr.c \
diff --git a/c/src/libchip/display/disp_fonts.h b/c/src/libchip/display/disp_fonts.h
deleted file mode 100644
index 39e909390a..0000000000
--- a/c/src/libchip/display/disp_fonts.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*===============================================================*\
-| Project: display driver for HCMS29xx |
-+-----------------------------------------------------------------+
-| File: disp_fonts.h |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-| This file declares general data structures for font management |
-\*===============================================================*/
-
-#ifndef DISP_FONTS_H
-#define DISP_FONTS_H
-
-#include <rtems.h>
-
-typedef int8_t disp_font_dimen;
-
-struct disp_font_bounding_box
-{
- disp_font_dimen w, h, x, y;
-};
-
-struct disp_font_glyph
-{
- struct disp_font_bounding_box bb;
- disp_font_dimen wx, wy;
- const unsigned char *bitmap;
-};
-
-struct disp_font_base
-{
- int8_t trans;
- struct disp_font_bounding_box fbb;
- disp_font_dimen ascent, descent;
- uint8_t default_char;
- struct disp_font_glyph *latin1[256];
-};
-
-typedef struct disp_font_base *disp_font_t;
-
-/* Prototypes ------------------------------------------------- */
-
-/* End -------------------------------------------------------- */
-
-#endif /* not defined DISP_FONTS_H */
diff --git a/c/src/libchip/display/disp_hcms29xx.c b/c/src/libchip/display/disp_hcms29xx.c
deleted file mode 100644
index 5730b36ea9..0000000000
--- a/c/src/libchip/display/disp_hcms29xx.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/*===============================================================*\
-| Project: display driver for HCMS29xx |
-+-----------------------------------------------------------------+
-| File: disp_hcms29xx.c |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| http://www.rtems.org/license/LICENSE. |
-+-----------------------------------------------------------------+
-| this file contains the SPI based driver for a HCMS29xx 4 digit |
-| alphanumeric LED display |
-\*===============================================================*/
-
-#include <string.h>
-#include <stdlib.h>
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <bsp.h>
-#include <rtems/libi2c.h>
-#include <libchip/disp_hcms29xx.h>
-#include "font_hcms29xx.h"
-#define FONT_BASE font_hcms29xx_base
-
-
-#define DISP_HCMS29XX_DIGIT_CNT (4)
-#define DISP_HCMS29XX_SEMA_NAME rtems_build_name('D','4','I','Q')
-#define DISP_HCMS29XX_TRNS_SEMA_NAME rtems_build_name('D','4','T','R')
-#define DISP_HCMS29XX_TIMER_NAME rtems_build_name('D','4','T','M')
-#define DISP_HCMS29XX_TASK_NAME rtems_build_name('D','4','T','A')
-
-#define DISP_HCMS29XX_EVENT_TIMER RTEMS_EVENT_1
-#define DISP_HCMS29XX_EVENT_NEWSTR RTEMS_EVENT_2
-
-
-static disp_font_t disp_hcms29xx_font_normal;
-static disp_font_t disp_hcms29xx_font_rotate;
-const rtems_libi2c_tfr_mode_t spi_disphcms29xx_tfr_mode = {
- .baudrate = 1000000,
- .bits_per_char = 8,
- .lsb_first = true,
- .clock_inv = true,
- .clock_phs = true,
- .idle_char = 0
-};
-
-static disp_hcms29xx_drv_t disp_hcms29xx_drv_tbl;
-
-/*=========================================
- * font management functions
- */
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_font_struct_size
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| compute size of font data structure tree |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- disp_font_t src, /* source font */
- size_t *dst_size /* destination: size of font struct*/
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
-
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- size_t font_size = 0;
- size_t glyph_idx;
- /*
- * check parameters
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- (src == NULL)) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- if (rc == RTEMS_SUCCESSFUL) {
- font_size =
- sizeof(*src); /* font_base structure */
- }
- glyph_idx = 0;
- while ((rc == RTEMS_SUCCESSFUL) &&
- (glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0])))) {
- if (src->latin1[glyph_idx] != NULL) {
- font_size += sizeof(*(src->latin1[glyph_idx]))
- + (size_t) src->latin1[glyph_idx]->bb.w;
- }
- glyph_idx++;
- }
- *dst_size = font_size;
-
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static inline unsigned char disp_hcms29xx_bitswap
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| swap data bits in byte (7<->0 , 6<->1 etc) |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- unsigned char byte
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- unsigned char result = 0;
- int smsk,dmsk;
- for (smsk = 0x01,dmsk=0x80;
- smsk < 0x100;
- smsk<<=1 ,dmsk>>=1) {
- if ((byte & smsk) != 0) {
- result |= (unsigned char) dmsk;
- }
- }
- return result;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_copy_font
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| copy font data from source to dest font structure |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- disp_font_t src, /* source font */
- struct disp_font_base *dst, /* ptr to destination font */
- int shift_cnt, /* shift count for font */
- bool do_rotate /* rotate font, if true */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
-
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- char *alloc_next = (char *)dst;
- size_t glyph_idx = 0;
- int glyph_size;
- unsigned char byte;
- int bcnt;
-
- /*
- * check parameters
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- ((src == NULL) ||
- (dst == NULL))) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- /*
- * copy font_base structure
- */
- if (rc == RTEMS_SUCCESSFUL) {
- *dst = *src;
- alloc_next += sizeof(*dst);
- }
- /*
- * for all glyphs: assign own glyph memory
- */
- glyph_idx = 0;
- while ((rc == RTEMS_SUCCESSFUL) &&
- glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0]))) {
- if (src->latin1[glyph_idx] != NULL) {
- /*
- * allocate space for glyph
- */
- dst->latin1[glyph_idx] = (struct disp_font_glyph *)alloc_next;
- alloc_next += sizeof(*(dst->latin1[glyph_idx]));
- /*
- * copy source values.
- * Note: bitmap will be reassigned later
- */
- *(struct disp_font_glyph *)(dst->latin1[glyph_idx]) =
- *(src->latin1[glyph_idx]);
- }
- else {
- dst->latin1[glyph_idx] = NULL;
- }
- glyph_idx++;
- }
-
- /*
- * for all glyphs: reassign bitmap
- */
- glyph_idx = 0;
- while ((rc == RTEMS_SUCCESSFUL) &&
- glyph_idx < (sizeof(src->latin1)/sizeof(src->latin1[0]))) {
- if (src->latin1[glyph_idx] != NULL) {
- glyph_size = src->latin1[glyph_idx]->bb.w;
- /*
- * allocate space for glyph_bitmap
- */
- dst->latin1[glyph_idx]->bitmap = (const unsigned char *) alloc_next;
- alloc_next += glyph_size;
- /*
- * copy/transform bitmap
- */
- for (bcnt = 0;bcnt < glyph_size;bcnt++) {
- if (do_rotate) {
- byte = src->latin1[glyph_idx]->bitmap[glyph_size - 1 - bcnt];
- byte = disp_hcms29xx_bitswap(byte);
- }
- else {
- byte = src->latin1[glyph_idx]->bitmap[bcnt];
- }
- if (shift_cnt < 0) {
- byte = byte >> shift_cnt;
- }
- else if (shift_cnt > 0) {
- byte = byte >> shift_cnt;
- }
- ((unsigned char *)(dst->latin1[glyph_idx]->bitmap))[bcnt] = byte;
- }
- }
- glyph_idx++;
- }
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_alloc_copy_font
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| copy font data from source to dest font structure, alloc all data |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- const disp_font_t src, /* source font */
- disp_font_t *dst, /* ptr to destination font */
- int shift_cnt, /* shift count for font */
- bool do_rotate /* rotate font, if true */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
-
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- size_t src_size = 0;
- /*
- * check parameters
- */
- if ((rc == RTEMS_SUCCESSFUL) &&
- ((src == NULL)
- || (dst == NULL))) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- /*
- * determine size of source data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_font_struct_size(src,&src_size);
- }
- /*
- * allocate proper data area
- */
- if (rc == RTEMS_SUCCESSFUL) {
- *dst = malloc(src_size);
- if (*dst == NULL) {
- rc = RTEMS_UNSATISFIED;
- }
- }
- /*
- * scan through source data, copy to dest
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_copy_font(src,*dst,shift_cnt,do_rotate);
- }
- return rc;
-}
-
-/*=========================================
- * SPI communication functions
- */
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_send_to_display
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| request access semaphore to SPI, prepare buffer descriptors, start |
-| transfer via SPI to display |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- disp_hcms29xx_drv_t *softc_ptr,
- const volatile char *disp_buffer /* start of chars to display (4 chars or 'til \0)*/
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- bool char_avail;
- const struct disp_font_glyph *glyph_ptr;
- disp_font_t curr_font;
- int i, ret_cnt;
- unsigned char c;
-
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(softc_ptr->disp_param.minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(softc_ptr->disp_param.minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &spi_disphcms29xx_tfr_mode);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(softc_ptr->disp_param.minor,true);
- }
-
- /*
- * send data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- curr_font =
- softc_ptr->disp_param.rotate
- ? disp_hcms29xx_font_rotate
- : disp_hcms29xx_font_normal;
-
- char_avail = true;
- /*
- * FIXME: for rotated display, write last character first...
- * maybe we should copy everything to a common buffer and use
- * ONE SPI transfer?
- */
- for (i = 0;
- ((rc == RTEMS_SUCCESSFUL) &&
- (i < DISP_HCMS29XX_DIGIT_CNT));
- i++) {
- /* test for end of string... */
- c = disp_buffer[i]; /* perform consistent read of disp_buffer */
- if (char_avail && (c == '\0')) {
- char_avail = false;
- }
- glyph_ptr = (char_avail
- ? curr_font->latin1[c]
- : NULL);
- if (glyph_ptr == NULL) {
- glyph_ptr = curr_font->latin1[' '];
- }
-
- /*
- * send 5 bytes from (char *)glyph_ptr->bitmap to SPI
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_write_bytes(softc_ptr->disp_param.minor,
- glyph_ptr->bitmap,5);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- }
- /*
- * finish transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(softc_ptr->disp_param.minor);
- }
-
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_send_to_control
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| request access semaphore to SPI, prepare buffer descriptors, start |
-| transfer via SPI to display |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- disp_hcms29xx_drv_t *softc_ptr,
- int pwm, /* value for pwm of LEDs, 0..15 */
- int peak, /* value for peak current for LEDs, 0..3 */
- int sleep, /* value to make display "sleep" (0..1 */
- int div, /* divider for external osc input, unused here */
- int chain /* mode to drive other displays, unused here */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- int run, ret_cnt;
- uint8_t ctrl_buffer;
-
- /* two accesses, control word 0 and 1 */
- for (run = 0;
- ((rc == RTEMS_SUCCESSFUL) && (run <= 1));
- run++) {
- if (rc == RTEMS_SUCCESSFUL) {
- if (run == 0) {
- ctrl_buffer =
- (0 << 7) |
- ((sleep & 0x01) << 6) |
- ((peak & 0x03) << 4) |
- ((pwm & 0x0f) << 0);
- }
- else {
- ctrl_buffer =
- (1 << 7) |
- ((div & 0x01) << 1) |
- ((chain & 0x01) << 0);
- }
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(softc_ptr->disp_param.minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(softc_ptr->disp_param.minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &spi_disphcms29xx_tfr_mode);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(softc_ptr->disp_param.minor,true);
- }
-
- /*
- * send 1 byte from ctrl_buffer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_write_bytes(softc_ptr->disp_param.minor,
- &ctrl_buffer,1);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- } /* next run ... */
-
- /*
- * finish transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(softc_ptr->disp_param.minor);
- }
-
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_timer_service_routine disp_hcms29xx_timer_sr
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| this task updates the string in the display |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
-(
- rtems_id id, /* ID of timer, not used */
- void * arg /* calling arg: softc_ptr */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <none used> |
-\*=========================================================================*/
-{
- disp_hcms29xx_drv_t *softc_ptr = arg;
-
- rtems_event_send(softc_ptr->disp_param.task_id, DISP_HCMS29XX_EVENT_TIMER);
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_task disp_hcms29xx_update_task
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| this task updates the string in the display |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_task_argument argument
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| <never exits> |
-\*=========================================================================*/
-{
- rtems_event_set my_events;
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- int disp_offset = 0;
- rtems_id disp_hcms29xx_timer_id;
- disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
-
- /*
- * initialize display:
- */
- /*
- * set control attributes for display
- * maximum brightness...
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_send_to_control(softc_ptr,
- 14,3,1,0,0);/* pwm/peak/nosleep/div/chain */
- }
-
- /*
- * set display to blank
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_send_to_display(softc_ptr,
- "");
- }
-
- /*
- * create timer for scrolling
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_timer_create(DISP_HCMS29XX_TIMER_NAME,
- &disp_hcms29xx_timer_id);
- }
-
- while (rc == RTEMS_SUCCESSFUL) {
- /*
- * wait for any event
- */
- rc = rtems_event_receive(DISP_HCMS29XX_EVENT_NEWSTR |
- DISP_HCMS29XX_EVENT_TIMER ,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &my_events);
- if (my_events & DISP_HCMS29XX_EVENT_NEWSTR) {
- /*
- * fetch new string consistently into local buffer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_semaphore_obtain(softc_ptr->disp_param.trns_sema_id,
- RTEMS_WAIT,RTEMS_NO_TIMEOUT);
- }
- if (rc == RTEMS_SUCCESSFUL) {
- strncpy(softc_ptr->disp_param.disp_buffer,
- softc_ptr->disp_param.trns_buffer,
- sizeof(softc_ptr->disp_param.disp_buffer));
- softc_ptr->disp_param.disp_buffer[sizeof(softc_ptr->disp_param.disp_buffer)-1] = '\0';
- softc_ptr->disp_param.disp_buf_cnt =
- (int) strlen(softc_ptr->disp_param.disp_buffer);
- }
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_semaphore_release(softc_ptr->disp_param.trns_sema_id);
- }
- /*
- * set initial offset to negative value
- * to make string static for some ticks
- */
- disp_offset = -4;
- }
- if (my_events & DISP_HCMS29XX_EVENT_TIMER) {
- /*
- * increase disp_offset, if possible, otherwise reset it
- */
- if ((disp_offset < 0) ||
- (disp_offset < softc_ptr->disp_param.disp_buf_cnt-
- DISP_HCMS29XX_DIGIT_CNT/2)) {
- disp_offset++;
- }
- else {
- disp_offset = -4;
- }
- }
- /*
- * display string, starting from disp_offset
- */
- if (disp_offset < 0) {
- rc = disp_hcms29xx_send_to_display(softc_ptr,
- softc_ptr->disp_param.disp_buffer);
- }
- else if (disp_offset
- < (softc_ptr->disp_param.disp_buf_cnt - DISP_HCMS29XX_DIGIT_CNT)) {
- rc = disp_hcms29xx_send_to_display(softc_ptr,
- softc_ptr->disp_param.disp_buffer+disp_offset);
- }
- else {
- rc = disp_hcms29xx_send_to_display(softc_ptr,
- softc_ptr->disp_param.disp_buffer
- + softc_ptr->disp_param.disp_buf_cnt
- - DISP_HCMS29XX_DIGIT_CNT);
- }
- /*
- * activate timer, if needed
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if (softc_ptr->disp_param.disp_buf_cnt > DISP_HCMS29XX_DIGIT_CNT) {
- rc = rtems_timer_fire_after(disp_hcms29xx_timer_id,
- 50,
- disp_hcms29xx_timer_sr,
- NULL);
- }
- else {
- rc = rtems_timer_cancel(disp_hcms29xx_timer_id);
- }
- }
- }
- /*
- * FIXME: display task is dead...
- */
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code disp_hcms29xx_update
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| move given string to display task |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- disp_hcms29xx_drv_t *softc_ptr,
- const char *src
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
-
- /*
- * obtain trns semaphore
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_semaphore_obtain(softc_ptr->disp_param.trns_sema_id,
- RTEMS_WAIT,RTEMS_NO_TIMEOUT);
- }
- /*
- * copy string...
- */
- strncpy(softc_ptr->disp_param.trns_buffer,src,
- sizeof(softc_ptr->disp_param.trns_buffer));
- softc_ptr->disp_param.trns_buffer[sizeof(softc_ptr->disp_param.trns_buffer)-1] = '\0';
-
- /*
- * release trns semaphore
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_semaphore_release(softc_ptr->disp_param.trns_sema_id);
- }
-
- /*
- * send event to task
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_event_send(softc_ptr->disp_param.task_id,
- DISP_HCMS29XX_EVENT_NEWSTR);
- }
-
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_device_driver disp_hcms29xx_dev_initialize
- (
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| prepare the display device driver to accept write calls |
-| register device with its name |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-/*
- * Initialize and register the device
- */
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
-
- /*
- * initialize font management
- * FIXME: check, that default glyph exists
- * FIXME: check font size to be 5x7
- */
- /*
- * translate font according to direction/baseline
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_alloc_copy_font(
- &FONT_BASE,
- &disp_hcms29xx_font_normal,
- FONT_BASE.descent, /* shift to visibility... */
- FALSE); /* do not rotate */
- }
- /* FIXME: translate font for rotation */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = disp_hcms29xx_alloc_copy_font(&FONT_BASE,
- &disp_hcms29xx_font_rotate,
- 0, /* do not shift */
- true); /* rotate font */
- }
- /*
- * create the trns_buffer semaphore
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_semaphore_create (DISP_HCMS29XX_TRNS_SEMA_NAME,1,
- RTEMS_PRIORITY
- |RTEMS_BINARY_SEMAPHORE
- |RTEMS_INHERIT_PRIORITY
- |RTEMS_NO_PRIORITY_CEILING
- |RTEMS_LOCAL,
- 0,
- &softc_ptr->disp_param.trns_sema_id);
- }
-
- /*
- * create and start display task
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_task_create(DISP_HCMS29XX_TASK_NAME,
- 20,
- RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_INTERRUPT_LEVEL(0) | RTEMS_TIMESLICE,
- RTEMS_DEFAULT_ATTRIBUTES,
- &softc_ptr->disp_param.task_id);
- }
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_task_start(softc_ptr->disp_param.task_id,
- disp_hcms29xx_update_task,0);
- }
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_device_driver disp_hcms29xx_dev_open
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| open the display device |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
- /*
- * ensure, that disp_hcms29xx device is assumed to be empty
- */
- softc_ptr->disp_param.dev_buf_cnt = 0;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_device_driver disp_hcms29xx_dev_write
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| write to display device |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
- rtems_libio_rw_args_t *args = arg;
- uint32_t cnt;
- disp_hcms29xx_drv_t *softc_ptr = &disp_hcms29xx_drv_tbl;
-
- for (cnt = 0;cnt < args->count;cnt++) {
- /*
- * accumulate characters written into display dev buffer
- */
- if (((softc_ptr->disp_param.dev_buf_cnt > 0)
- &&((args->buffer[cnt] == '\n')
- || (args->buffer[cnt] == '\0'))
- )
- ||( softc_ptr->disp_param.dev_buf_cnt >=
- (int) sizeof(softc_ptr->disp_param.dev_buffer) - 1)) {
- softc_ptr->disp_param.dev_buffer[softc_ptr->disp_param.dev_buf_cnt] = '\0';
- /*
- * transfer string to display string, redisplay it...
- */
- disp_hcms29xx_update(softc_ptr,softc_ptr->disp_param.dev_buffer);
- softc_ptr->disp_param.dev_buf_cnt = 0;
- }
- /*
- * write to dev_buf, if '\n' occured or display device buffer is full
- */
- if ((args->buffer[cnt] != '\n') &&
- (args->buffer[cnt] != '\0')) {
- softc_ptr->disp_param.dev_buffer[softc_ptr->disp_param.dev_buf_cnt++] =
- args->buffer[cnt];
- }
- }
- args->bytes_moved = args->count;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_device_driver disp_hcms29xx_dev_close
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| close the display device |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| rtems_status_code |
-\*=========================================================================*/
-{
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * driver operation tables
- */
-static rtems_driver_address_table disp_hcms29xx_ops = {
- .initialization_entry = disp_hcms29xx_dev_initialize,
- .open_entry = disp_hcms29xx_dev_open,
- .write_entry = disp_hcms29xx_dev_write,
- .close_entry = disp_hcms29xx_dev_close
-};
-
-
-static disp_hcms29xx_drv_t disp_hcms29xx_drv_tbl = {
- {/* public fields */
- .ops = &disp_hcms29xx_ops,
- .size = sizeof (disp_hcms29xx_drv_t),
- },
- { /* our private fields */
- 0,
- { 0 },
- 0,
- { 0 },
- { 0 },
- 0,
- 0,
- 0,
- false
- }
-};
-
-rtems_libi2c_drv_t *disp_hcms29xx_driver_descriptor =
- &disp_hcms29xx_drv_tbl.libi2c_drv_entry;
-
diff --git a/c/src/libchip/display/font_hcms29xx.c b/c/src/libchip/display/font_hcms29xx.c
deleted file mode 100644
index e25cca2eca..0000000000
--- a/c/src/libchip/display/font_hcms29xx.c
+++ /dev/null
@@ -1,1820 +0,0 @@
-/*===============================================================*\
-| Project: display driver for HCMS29xx |
-+-----------------------------------------------------------------+
-| File: font_hcms29xx.c |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| http://www.rtems.org/license/LICENSE. |
-+-----------------------------------------------------------------+
-| This file defines the 5x7 bit font used in disp_hcms29xx |
-\*===============================================================*/
-
-#include <stddef.h>
-#include "disp_fonts.h"
-
-const unsigned char bitmap_hp_fixed_5_7_0 [5] = {
- 0x08,
- 0x1c,
- 0x3e,
- 0x7f,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_0 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_0,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_1 [5] = {
- 0x30,
- 0x45,
- 0x48,
- 0x40,
- 0x30
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_1 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_1,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_2 [5] = {
- 0x45,
- 0x29,
- 0x11,
- 0x29,
- 0x45
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_2 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_2,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_3 [5] = {
- 0x7d,
- 0x09,
- 0x11,
- 0x21,
- 0x7d
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_3 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_3,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_4 [5] = {
- 0x7d,
- 0x09,
- 0x05,
- 0x05,
- 0x79
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_4 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_4,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_5 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x38,
- 0x44
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_5 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_5,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_6 [5] = {
- 0x7e,
- 0x01,
- 0x29,
- 0x2e,
- 0x10
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_6 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_6,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_7 [5] = {
- 0x30,
- 0x4a,
- 0x4d,
- 0x49,
- 0x30
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_7 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_7,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_8 [5] = {
- 0x60,
- 0x50,
- 0x48,
- 0x50,
- 0x60
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_8 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_8,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_9 [5] = {
- 0x1e,
- 0x04,
- 0x04,
- 0x38,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_9 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_9,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_10 [5] = {
- 0x3e,
- 0x49,
- 0x49,
- 0x49,
- 0x3e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_10 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_10,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_11 [5] = {
- 0x62,
- 0x14,
- 0x08,
- 0x10,
- 0x60
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_11 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_11,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_12 [5] = {
- 0x40,
- 0x3c,
- 0x20,
- 0x20,
- 0x1c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_12 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_12,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_13 [5] = {
- 0x08,
- 0x7c,
- 0x04,
- 0x7c,
- 0x02
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_13 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_13,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_14 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x3c,
- 0x04
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_14 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_14,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_15 [5] = {
- 0x41,
- 0x63,
- 0x55,
- 0x49,
- 0x41
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_15 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_15,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_16 [5] = {
- 0x10,
- 0x08,
- 0x78,
- 0x08,
- 0x04
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_16 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_16,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_17 [5] = {
- 0x18,
- 0x24,
- 0x7e,
- 0x24,
- 0x18
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_17 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_17,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_18 [5] = {
- 0x5e,
- 0x61,
- 0x01,
- 0x61,
- 0x5e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_18 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_18,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_19 [5] = {
- 0x78,
- 0x14,
- 0x15,
- 0x14,
- 0x78
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_19 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_19,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_20 [5] = {
- 0x38,
- 0x44,
- 0x45,
- 0x3c,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_20 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_20,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_21 [5] = {
- 0x78,
- 0x15,
- 0x14,
- 0x15,
- 0x78
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_21 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_21,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_22 [5] = {
- 0x38,
- 0x45,
- 0x44,
- 0x3d,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_22 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_22,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_23 [5] = {
- 0x3c,
- 0x43,
- 0x42,
- 0x43,
- 0x3c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_23 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_23,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_24 [5] = {
- 0x38,
- 0x45,
- 0x44,
- 0x45,
- 0x38
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_24 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_24,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_25 [5] = {
- 0x3c,
- 0x41,
- 0x40,
- 0x41,
- 0x3c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_25 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_25,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_26 [5] = {
- 0x38,
- 0x42,
- 0x40,
- 0x42,
- 0x38
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_26 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_26,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_27 [5] = {
- 0x08,
- 0x08,
- 0x2a,
- 0x1c,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_27 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_27,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_28 [5] = {
- 0x20,
- 0x7e,
- 0x02,
- 0x02,
- 0x02
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_28 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_28,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_29 [5] = {
- 0x12,
- 0x19,
- 0x15,
- 0x12,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_29 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_29,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_30 [5] = {
- 0x48,
- 0x7e,
- 0x49,
- 0x41,
- 0x42
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_30 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_30,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_31 [5] = {
- 0x01,
- 0x12,
- 0x7c,
- 0x12,
- 0x01
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_31 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_31,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_32 [5] = {
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_32 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_32,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_33 [5] = {
- 0x00,
- 0x5f,
- 0x00,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_33 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_33,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_34 [5] = {
- 0x00,
- 0x03,
- 0x00,
- 0x03,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_34 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_34,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_35 [5] = {
- 0x14,
- 0x7f,
- 0x14,
- 0x7f,
- 0x14
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_35 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_35,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_36 [5] = {
- 0x24,
- 0x2a,
- 0x7f,
- 0x2a,
- 0x12
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_36 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_36,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_37 [5] = {
- 0x23,
- 0x13,
- 0x08,
- 0x64,
- 0x62
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_37 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_37,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_38 [5] = {
- 0x36,
- 0x49,
- 0x56,
- 0x20,
- 0x50
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_38 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_38,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_39 [5] = {
- 0x00,
- 0x0b,
- 0x07,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_39 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_39,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_40 [5] = {
- 0x00,
- 0x00,
- 0x3e,
- 0x41,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_40 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_40,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_41 [5] = {
- 0x00,
- 0x41,
- 0x3e,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_41 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_41,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_42 [5] = {
- 0x08,
- 0x2a,
- 0x1c,
- 0x2a,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_42 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_42,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_43 [5] = {
- 0x08,
- 0x08,
- 0x3e,
- 0x08,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_43 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_43,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_44 [5] = {
- 0x00,
- 0x58,
- 0x38,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_44 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_44,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_45 [5] = {
- 0x08,
- 0x08,
- 0x08,
- 0x08,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_45 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_45,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_46 [5] = {
- 0x00,
- 0x30,
- 0x30,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_46 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_46,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_47 [5] = {
- 0x20,
- 0x10,
- 0x08,
- 0x04,
- 0x02
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_47 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_47,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_48 [5] = {
- 0x3e,
- 0x51,
- 0x49,
- 0x45,
- 0x3e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_48 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_48,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_49 [5] = {
- 0x00,
- 0x42,
- 0x7f,
- 0x40,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_49 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_49,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_50 [5] = {
- 0x62,
- 0x51,
- 0x49,
- 0x49,
- 0x46
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_50 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_50,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_51 [5] = {
- 0x22,
- 0x41,
- 0x49,
- 0x49,
- 0x36
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_51 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_51,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_52 [5] = {
- 0x18,
- 0x14,
- 0x12,
- 0x7f,
- 0x10
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_52 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_52,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_53 [5] = {
- 0x27,
- 0x45,
- 0x45,
- 0x45,
- 0x39
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_53 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_53,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_54 [5] = {
- 0x3c,
- 0x4a,
- 0x49,
- 0x49,
- 0x30
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_54 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_54,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_55 [5] = {
- 0x01,
- 0x71,
- 0x09,
- 0x05,
- 0x03
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_55 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_55,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_56 [5] = {
- 0x36,
- 0x49,
- 0x49,
- 0x49,
- 0x36
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_56 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_56,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_57 [5] = {
- 0x06,
- 0x49,
- 0x49,
- 0x29,
- 0x1e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_57 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_57,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_58 [5] = {
- 0x00,
- 0x36,
- 0x36,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_58 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_58,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_59 [5] = {
- 0x00,
- 0x5b,
- 0x3b,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_59 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_59,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_60 [5] = {
- 0x00,
- 0x08,
- 0x14,
- 0x22,
- 0x41
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_60 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_60,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_61 [5] = {
- 0x14,
- 0x14,
- 0x14,
- 0x14,
- 0x14
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_61 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_61,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_62 [5] = {
- 0x41,
- 0x22,
- 0x14,
- 0x08,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_62 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_62,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_63 [5] = {
- 0x02,
- 0x01,
- 0x51,
- 0x09,
- 0x06
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_63 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_63,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_64 [5] = {
- 0x3e,
- 0x41,
- 0x5d,
- 0x55,
- 0x1e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_64 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_64,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_65 [5] = {
- 0x7e,
- 0x09,
- 0x09,
- 0x09,
- 0x7e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_65 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_65,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_66 [5] = {
- 0x7e,
- 0x49,
- 0x49,
- 0x49,
- 0x36
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_66 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_66,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_67 [5] = {
- 0x3e,
- 0x41,
- 0x41,
- 0x41,
- 0x22
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_67 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_67,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_68 [5] = {
- 0x7f,
- 0x41,
- 0x41,
- 0x41,
- 0x3e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_68 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_68,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_69 [5] = {
- 0x7f,
- 0x49,
- 0x49,
- 0x49,
- 0x41
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_69 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_69,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_70 [5] = {
- 0x7f,
- 0x09,
- 0x09,
- 0x09,
- 0x01
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_70 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_70,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_71 [5] = {
- 0x3e,
- 0x41,
- 0x41,
- 0x51,
- 0x32
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_71 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_71,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_72 [5] = {
- 0x7f,
- 0x08,
- 0x08,
- 0x08,
- 0x7f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_72 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_72,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_73 [5] = {
- 0x00,
- 0x41,
- 0x7f,
- 0x41,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_73 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_73,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_74 [5] = {
- 0x20,
- 0x40,
- 0x40,
- 0x40,
- 0x3f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_74 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_74,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_75 [5] = {
- 0x7f,
- 0x08,
- 0x14,
- 0x22,
- 0x41
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_75 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_75,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_76 [5] = {
- 0x7f,
- 0x40,
- 0x40,
- 0x40,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_76 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_76,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_77 [5] = {
- 0x7f,
- 0x02,
- 0x0c,
- 0x02,
- 0x7f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_77 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_77,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_78 [5] = {
- 0x7f,
- 0x04,
- 0x08,
- 0x10,
- 0x7f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_78 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_78,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_79 [5] = {
- 0x3e,
- 0x41,
- 0x41,
- 0x41,
- 0x3e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_79 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_79,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_80 [5] = {
- 0x7f,
- 0x09,
- 0x09,
- 0x09,
- 0x06
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_80 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_80,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_81 [5] = {
- 0x3e,
- 0x41,
- 0x51,
- 0x21,
- 0x5e
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_81 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_81,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_82 [5] = {
- 0x7f,
- 0x09,
- 0x19,
- 0x29,
- 0x46
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_82 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_82,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_83 [5] = {
- 0x26,
- 0x49,
- 0x49,
- 0x49,
- 0x32
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_83 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_83,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_84 [5] = {
- 0x01,
- 0x01,
- 0x7f,
- 0x01,
- 0x01
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_84 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_84,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_85 [5] = {
- 0x3f,
- 0x40,
- 0x40,
- 0x40,
- 0x3f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_85 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_85,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_86 [5] = {
- 0x07,
- 0x18,
- 0x60,
- 0x18,
- 0x07
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_86 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_86,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_87 [5] = {
- 0x7f,
- 0x20,
- 0x18,
- 0x20,
- 0x7f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_87 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_87,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_88 [5] = {
- 0x63,
- 0x14,
- 0x08,
- 0x14,
- 0x63
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_88 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_88,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_89 [5] = {
- 0x03,
- 0x04,
- 0x78,
- 0x04,
- 0x03
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_89 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_89,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_90 [5] = {
- 0x61,
- 0x51,
- 0x49,
- 0x45,
- 0x43
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_90 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_90,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_91 [5] = {
- 0x00,
- 0x00,
- 0x7f,
- 0x41,
- 0x41
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_91 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_91,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_92 [5] = {
- 0x02,
- 0x04,
- 0x08,
- 0x10,
- 0x20
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_92 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_92,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_93 [5] = {
- 0x41,
- 0x41,
- 0x7f,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_93 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_93,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_94 [5] = {
- 0x04,
- 0x02,
- 0x7f,
- 0x02,
- 0x04
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_94 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_94,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_95 [5] = {
- 0x40,
- 0x40,
- 0x40,
- 0x40,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_95 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_95,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_96 [5] = {
- 0x00,
- 0x07,
- 0x0b,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_96 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_96,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_97 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x3c,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_97 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_97,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_98 [5] = {
- 0x7f,
- 0x48,
- 0x44,
- 0x44,
- 0x38
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_98 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_98,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_99 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x44,
- 0x44
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_99 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_99,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_100 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x48,
- 0x7f
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_100 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_100,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_101 [5] = {
- 0x38,
- 0x54,
- 0x54,
- 0x54,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_101 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_101,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_102 [5] = {
- 0x08,
- 0x7e,
- 0x09,
- 0x02,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_102 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_102,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_103 [5] = {
- 0x08,
- 0x14,
- 0x54,
- 0x54,
- 0x3c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_103 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_103,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_104 [5] = {
- 0x7f,
- 0x08,
- 0x04,
- 0x04,
- 0x78
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_104 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_104,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_105 [5] = {
- 0x00,
- 0x44,
- 0x7d,
- 0x40,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_105 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_105,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_106 [5] = {
- 0x20,
- 0x40,
- 0x44,
- 0x3d,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_106 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_106,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_107 [5] = {
- 0x00,
- 0x7f,
- 0x10,
- 0x28,
- 0x44
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_107 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_107,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_108 [5] = {
- 0x00,
- 0x41,
- 0x7f,
- 0x40,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_108 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_108,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_109 [5] = {
- 0x78,
- 0x04,
- 0x18,
- 0x04,
- 0x78
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_109 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_109,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_110 [5] = {
- 0x7c,
- 0x08,
- 0x04,
- 0x04,
- 0x78
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_110 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_110,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_111 [5] = {
- 0x38,
- 0x44,
- 0x44,
- 0x44,
- 0x38
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_111 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_111,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_112 [5] = {
- 0x7c,
- 0x14,
- 0x24,
- 0x24,
- 0x18
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_112 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_112,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_113 [5] = {
- 0x18,
- 0x24,
- 0x14,
- 0x7c,
- 0x40
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_113 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_113,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_114 [5] = {
- 0x00,
- 0x7c,
- 0x08,
- 0x04,
- 0x04
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_114 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_114,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_115 [5] = {
- 0x48,
- 0x54,
- 0x54,
- 0x54,
- 0x20
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_115 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_115,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_116 [5] = {
- 0x04,
- 0x3e,
- 0x44,
- 0x20,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_116 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_116,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_117 [5] = {
- 0x3c,
- 0x40,
- 0x40,
- 0x20,
- 0x7c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_117 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_117,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_118 [5] = {
- 0x1c,
- 0x20,
- 0x40,
- 0x20,
- 0x1c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_118 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_118,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_119 [5] = {
- 0x3c,
- 0x40,
- 0x30,
- 0x40,
- 0x3c
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_119 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_119,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_120 [5] = {
- 0x44,
- 0x28,
- 0x10,
- 0x28,
- 0x44
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_120 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_120,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_121 [5] = {
- 0x04,
- 0x48,
- 0x30,
- 0x08,
- 0x04
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_121 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_121,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_122 [5] = {
- 0x44,
- 0x64,
- 0x54,
- 0x4c,
- 0x44
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_122 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_122,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_123 [5] = {
- 0x00,
- 0x08,
- 0x36,
- 0x41,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_123 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_123,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_124 [5] = {
- 0x00,
- 0x00,
- 0x77,
- 0x00,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_124 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_124,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_125 [5] = {
- 0x00,
- 0x41,
- 0x36,
- 0x08,
- 0x00
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_125 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_125,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_126 [5] = {
- 0x08,
- 0x04,
- 0x08,
- 0x10,
- 0x08
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_126 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_126,
-};
-
-const unsigned char bitmap_hp_fixed_5_7_127 [5] = {
- 0x2a,
- 0x55,
- 0x2a,
- 0x55,
- 0x2a
-};
-struct disp_font_glyph glyph_hp_fixed_5_7_127 = {
- {5,7,0,0},
- 5, 0, bitmap_hp_fixed_5_7_127,
-};
-
-const struct disp_font_base font_hcms29xx_base = {
- 1, /* trans */
- {5, 7, 0, -1}, /* fbb w, h, x, y */
- 7, 0, /* ascent, descent */
- 0, /* default_char */
- {&glyph_hp_fixed_5_7_0,
- &glyph_hp_fixed_5_7_1,
- &glyph_hp_fixed_5_7_2,
- &glyph_hp_fixed_5_7_3,
- &glyph_hp_fixed_5_7_4,
- &glyph_hp_fixed_5_7_5,
- &glyph_hp_fixed_5_7_6,
- &glyph_hp_fixed_5_7_7,
- &glyph_hp_fixed_5_7_8,
- &glyph_hp_fixed_5_7_9,
- &glyph_hp_fixed_5_7_10,
- &glyph_hp_fixed_5_7_11,
- &glyph_hp_fixed_5_7_12,
- &glyph_hp_fixed_5_7_13,
- &glyph_hp_fixed_5_7_14,
- &glyph_hp_fixed_5_7_15,
- &glyph_hp_fixed_5_7_16,
- &glyph_hp_fixed_5_7_17,
- &glyph_hp_fixed_5_7_18,
- &glyph_hp_fixed_5_7_19,
- &glyph_hp_fixed_5_7_20,
- &glyph_hp_fixed_5_7_21,
- &glyph_hp_fixed_5_7_22,
- &glyph_hp_fixed_5_7_23,
- &glyph_hp_fixed_5_7_24,
- &glyph_hp_fixed_5_7_25,
- &glyph_hp_fixed_5_7_26,
- &glyph_hp_fixed_5_7_27,
- &glyph_hp_fixed_5_7_28,
- &glyph_hp_fixed_5_7_29,
- &glyph_hp_fixed_5_7_30,
- &glyph_hp_fixed_5_7_31,
- &glyph_hp_fixed_5_7_32,
- &glyph_hp_fixed_5_7_33,
- &glyph_hp_fixed_5_7_34,
- &glyph_hp_fixed_5_7_35,
- &glyph_hp_fixed_5_7_36,
- &glyph_hp_fixed_5_7_37,
- &glyph_hp_fixed_5_7_38,
- &glyph_hp_fixed_5_7_39,
- &glyph_hp_fixed_5_7_40,
- &glyph_hp_fixed_5_7_41,
- &glyph_hp_fixed_5_7_42,
- &glyph_hp_fixed_5_7_43,
- &glyph_hp_fixed_5_7_44,
- &glyph_hp_fixed_5_7_45,
- &glyph_hp_fixed_5_7_46,
- &glyph_hp_fixed_5_7_47,
- &glyph_hp_fixed_5_7_48,
- &glyph_hp_fixed_5_7_49,
- &glyph_hp_fixed_5_7_50,
- &glyph_hp_fixed_5_7_51,
- &glyph_hp_fixed_5_7_52,
- &glyph_hp_fixed_5_7_53,
- &glyph_hp_fixed_5_7_54,
- &glyph_hp_fixed_5_7_55,
- &glyph_hp_fixed_5_7_56,
- &glyph_hp_fixed_5_7_57,
- &glyph_hp_fixed_5_7_58,
- &glyph_hp_fixed_5_7_59,
- &glyph_hp_fixed_5_7_60,
- &glyph_hp_fixed_5_7_61,
- &glyph_hp_fixed_5_7_62,
- &glyph_hp_fixed_5_7_63,
- &glyph_hp_fixed_5_7_64,
- &glyph_hp_fixed_5_7_65,
- &glyph_hp_fixed_5_7_66,
- &glyph_hp_fixed_5_7_67,
- &glyph_hp_fixed_5_7_68,
- &glyph_hp_fixed_5_7_69,
- &glyph_hp_fixed_5_7_70,
- &glyph_hp_fixed_5_7_71,
- &glyph_hp_fixed_5_7_72,
- &glyph_hp_fixed_5_7_73,
- &glyph_hp_fixed_5_7_74,
- &glyph_hp_fixed_5_7_75,
- &glyph_hp_fixed_5_7_76,
- &glyph_hp_fixed_5_7_77,
- &glyph_hp_fixed_5_7_78,
- &glyph_hp_fixed_5_7_79,
- &glyph_hp_fixed_5_7_80,
- &glyph_hp_fixed_5_7_81,
- &glyph_hp_fixed_5_7_82,
- &glyph_hp_fixed_5_7_83,
- &glyph_hp_fixed_5_7_84,
- &glyph_hp_fixed_5_7_85,
- &glyph_hp_fixed_5_7_86,
- &glyph_hp_fixed_5_7_87,
- &glyph_hp_fixed_5_7_88,
- &glyph_hp_fixed_5_7_89,
- &glyph_hp_fixed_5_7_90,
- &glyph_hp_fixed_5_7_91,
- &glyph_hp_fixed_5_7_92,
- &glyph_hp_fixed_5_7_93,
- &glyph_hp_fixed_5_7_94,
- &glyph_hp_fixed_5_7_95,
- &glyph_hp_fixed_5_7_96,
- &glyph_hp_fixed_5_7_97,
- &glyph_hp_fixed_5_7_98,
- &glyph_hp_fixed_5_7_99,
- &glyph_hp_fixed_5_7_100,
- &glyph_hp_fixed_5_7_101,
- &glyph_hp_fixed_5_7_102,
- &glyph_hp_fixed_5_7_103,
- &glyph_hp_fixed_5_7_104,
- &glyph_hp_fixed_5_7_105,
- &glyph_hp_fixed_5_7_106,
- &glyph_hp_fixed_5_7_107,
- &glyph_hp_fixed_5_7_108,
- &glyph_hp_fixed_5_7_109,
- &glyph_hp_fixed_5_7_110,
- &glyph_hp_fixed_5_7_111,
- &glyph_hp_fixed_5_7_112,
- &glyph_hp_fixed_5_7_113,
- &glyph_hp_fixed_5_7_114,
- &glyph_hp_fixed_5_7_115,
- &glyph_hp_fixed_5_7_116,
- &glyph_hp_fixed_5_7_117,
- &glyph_hp_fixed_5_7_118,
- &glyph_hp_fixed_5_7_119,
- &glyph_hp_fixed_5_7_120,
- &glyph_hp_fixed_5_7_121,
- &glyph_hp_fixed_5_7_122,
- &glyph_hp_fixed_5_7_123,
- &glyph_hp_fixed_5_7_124,
- &glyph_hp_fixed_5_7_125,
- &glyph_hp_fixed_5_7_126,
- &glyph_hp_fixed_5_7_127,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL}
-};
diff --git a/c/src/libchip/display/font_hcms29xx.h b/c/src/libchip/display/font_hcms29xx.h
deleted file mode 100644
index 8638fcf600..0000000000
--- a/c/src/libchip/display/font_hcms29xx.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*===============================================================*\
-| Project: display driver for HCMS29xx |
-+-----------------------------------------------------------------+
-| File: font_hcms29xx.h |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| http://www.rtems.org/license/LICENSE. |
-+-----------------------------------------------------------------+
-| This file declares the 5x7 bit font used in disp_hcms29xx |
-\*===============================================================*/
-
-#ifndef FONT_HCMS29XX_H
-#define FONT_HCMS29XX_H
-
-#include "disp_fonts.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern struct disp_font_base font_hcms29xx_base;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not defined FONT_HCMS29XX_H */
diff --git a/c/src/libchip/flash/am29lv160.c b/c/src/libchip/flash/am29lv160.c
deleted file mode 100644
index 5cfaae4f24..0000000000
--- a/c/src/libchip/flash/am29lv160.c
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * RTEMS Project (http://www.rtems.org/)
- *
- * Copyright 2007 Chris Johns (chrisj@rtems.org)
- */
-/**
- * Provide flash support for the AM26LV160 device.
- *
- * The M29W160D is the same device.
- */
-
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-
-#include <rtems.h>
-
-#include <libchip/am29lv160.h>
-
-#ifndef AM26LV160_ERROR_TRACE
-#define AM26LV160_ERROR_TRACE (0)
-#endif
-
-/**
- * Boot blocks at the top
- */
-const rtems_fdisk_segment_desc rtems_am29lv160t_segments[4] =
-{
- {
- .count = 31,
- .segment = 0,
- .offset = 0x00000000,
- .size = RTEMS_FDISK_KBYTES (64)
- },
- {
- .count = 1,
- .segment = 31,
- .offset = 0x001f0000,
- .size = RTEMS_FDISK_KBYTES (32)
- },
- {
- .count = 2,
- .segment = 32,
- .offset = 0x001f8000,
- .size = RTEMS_FDISK_KBYTES (8)
- },
- {
- .count = 1,
- .segment = 34,
- .offset = 0x001fc000,
- .size = RTEMS_FDISK_KBYTES (16)
- }
-};
-
-/**
- * Boot blocks at the bottom.
- */
-const rtems_fdisk_segment_desc rtems_am29lv160b_segments[] =
-{
- {
- .count = 1,
- .segment = 0,
- .offset = 0x00000000,
- .size = RTEMS_FDISK_KBYTES (16)
- },
- {
- . count = 2,
- .segment = 1,
- .offset = 0x00004000,
- .size = RTEMS_FDISK_KBYTES (8)
- },
- {
- .count = 1,
- .segment = 3,
- .offset = 0x00008000,
- .size = RTEMS_FDISK_KBYTES (32)
- },
- {
- .count = 31,
- .segment = 4,
- .offset = 0x00010000,
- .size = RTEMS_FDISK_KBYTES (64)
- }
-};
-
-static int
-rtems_am29lv160_blank (const rtems_fdisk_segment_desc* sd,
- uint32_t device,
- uint32_t segment,
- uint32_t offset,
- uint32_t size)
-{
- const rtems_am29lv160_config* ac = &rtems_am29lv160_configuration[device];
- volatile uint8_t* seg_8 = ac->base;
- volatile uint32_t* seg_32;
- uint32_t count;
-
- offset += sd->offset + (segment - sd->segment) * sd->size;
-
- seg_8 += offset;
-
- count = offset & (sizeof (uint32_t) - 1);
- size -= count;
-
- while (count--)
- if (*seg_8++ != 0xff)
- {
-#if AM26LV160_ERROR_TRACE
- printf ("AM26LV160: blank check error: %p = 0x%02x\n",
- seg_8 - 1, *(seg_8 - 1));
-#endif
- return EIO;
- }
-
- seg_32 = (volatile uint32_t*) seg_8;
-
- count = size / sizeof (uint32_t);
- size -= count * sizeof (uint32_t);
-
- while (count--)
- if (*seg_32++ != 0xffffffff)
- {
-#if AM26LV160_ERROR_TRACE
- printf ("AM26LV160: blank check error: %p = 0x%08lx\n",
- seg_32 - 1, *(seg_32 - 1));
-#endif
- return EIO;
- }
-
- seg_8 = (volatile uint8_t*) seg_32;
-
- while (size--)
- if (*seg_8++ != 0xff)
- {
-#if AM26LV160_ERROR_TRACE
- printf ("AM26LV160: blank check error: %p = 0x%02x\n",
- seg_8 - 1, *(seg_8 - 1));
-#endif
- return EIO;
- }
-
- return 0;
-}
-
-static int
-rtems_am29lv160_verify (const rtems_fdisk_segment_desc* sd,
- uint32_t device,
- uint32_t segment,
- uint32_t offset,
- const void* buffer,
- uint32_t size)
-{
- const rtems_am29lv160_config* ac = &rtems_am29lv160_configuration[device];
- const uint8_t* addr = ac->base;
-
- addr += (sd->offset + (segment - sd->segment) * sd->size) + offset;
-
- if (memcmp (addr, buffer, size) != 0)
- return EIO;
-
- return 0;
-}
-
-static int
-rtems_am29lv160_toggle_wait_8 (volatile uint8_t* status)
-{
- while (1)
- {
- volatile uint8_t status1 = *status;
- volatile uint8_t status2 = *status;
-
- if (((status1 ^ status2) & (1 << 6)) == 0)
- return 0;
-
- if ((status1 & (1 << 5)) != 0)
- {
- status1 = *status;
- status2 = *status;
-
- if (((status1 ^ status2) & (1 << 6)) == 0)
- return 0;
-
-#if AM26LV160_ERROR_TRACE
- printf ("AM26LV160: error bit detected: %p = 0x%04x\n",
- status, status1);
-#endif
-
- *status = 0xf0;
- return EIO;
- }
- }
-}
-
-static int
-rtems_am29lv160_toggle_wait_16 (volatile uint16_t* status)
-{
- while (1)
- {
- volatile uint16_t status1 = *status;
- volatile uint16_t status2 = *status;
-
- if (((status1 ^ status2) & (1 << 6)) == 0)
- return 0;
-
- if ((status1 & (1 << 5)) != 0)
- {
- status1 = *status;
- status2 = *status;
-
- if (((status1 ^ status2) & (1 << 6)) == 0)
- return 0;
-
-#if AM26LV160_ERROR_TRACE
- printf ("AM26LV160: error bit detected: %p = 0x%04x/0x%04x\n",
- status, status1, status2);
-#endif
-
- *status = 0xf0;
- return EIO;
- }
- }
-}
-
-static int
-rtems_am29lv160_write_data_8 (volatile uint8_t* base,
- uint32_t offset,
- const uint8_t* data,
- uint32_t size)
-{
- volatile uint8_t* seg = base + offset;
- rtems_interrupt_level level;
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
-
- while (size)
- {
- rtems_interrupt_disable (level);
- *(base + 0xaaa) = 0xaa;
- *(base + 0x555) = 0x55;
- *(base + 0xaaa) = 0xa0;
- *seg = *data++;
- rtems_interrupt_enable (level);
- if (rtems_am29lv160_toggle_wait_8 (seg++) != 0)
- return EIO;
- size--;
- }
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
-
- return 0;
-}
-
-static int
-rtems_am29lv160_write_data_16 (volatile uint16_t* base,
- uint32_t offset,
- const uint16_t* data,
- uint32_t size)
-{
- volatile uint16_t* seg = base + (offset / 2);
- rtems_interrupt_level level;
-
- size /= 2;
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
-
- while (size)
- {
- rtems_interrupt_disable (level);
- *(base + 0x555) = 0xaa;
- *(base + 0x2aa) = 0x55;
- *(base + 0x555) = 0xa0;
- *seg = *data++;
- rtems_interrupt_enable (level);
- if (rtems_am29lv160_toggle_wait_16 (seg++) != 0)
- return EIO;
- size--;
- }
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
-
- return 0;
-}
-
-static int
-rtems_am29lv160_read (const rtems_fdisk_segment_desc* sd,
- uint32_t device,
- uint32_t segment,
- uint32_t offset,
- void* buffer,
- uint32_t size)
-{
- unsigned char* addr =
- rtems_am29lv160_configuration[device].base +
- sd->offset + ((segment - sd->segment) * sd->size) + offset;
- memcpy (buffer, addr, size);
- return 0;
-}
-
-/*
- * @todo Fix the odd alignment and odd sizes.
- */
-static int
-rtems_am29lv160_write (const rtems_fdisk_segment_desc* sd,
- uint32_t device,
- uint32_t segment,
- uint32_t offset,
- const void* buffer,
- uint32_t size)
-{
- int ret = rtems_am29lv160_verify (sd, device, segment, offset, buffer, size);
-
- if (ret != 0)
- {
- const rtems_am29lv160_config* ac = &rtems_am29lv160_configuration[device];
- uint32_t soffset;
-
- soffset = offset + sd->offset + ((segment - sd->segment) * sd->size);
-
- if (offset & 1)
- printf ("rtems_am29lv160_write: offset is odd\n");
-
- if (size & 1)
- printf ("rtems_am29lv160_write: size is odd\n");
-
- if (ac->bus_8bit)
- ret = rtems_am29lv160_write_data_8 (ac->base, soffset, buffer, size);
- else
- ret = rtems_am29lv160_write_data_16 (ac->base, soffset, buffer, size);
-
- /*
- * Verify the write worked.
- */
- if (ret == 0)
- {
- ret = rtems_am29lv160_verify (sd, device, segment, offset, buffer, size);
-#if AM26LV160_ERROR_TRACE
- if (ret)
- printf ("AM26LV160: verify failed: %ld-%ld-%08lx: s=%ld\n",
- device, segment, offset, size);
-#endif
- }
- }
-
- return ret;
-}
-
-static int
-rtems_am29lv160_erase (const rtems_fdisk_segment_desc* sd,
- uint32_t device,
- uint32_t segment)
-{
- int ret = rtems_am29lv160_blank (sd, device, segment, 0, sd->size);
- if (ret != 0)
- {
- const rtems_am29lv160_config* ac = &rtems_am29lv160_configuration[device];
- uint32_t offset;
- rtems_interrupt_level level;
-
- offset = sd->offset + ((segment - sd->segment) * sd->size);
-
- if (ac->bus_8bit)
- {
- volatile uint8_t* base = ac->base;
- volatile uint8_t* seg = base + offset;
-
- /*
- * Issue a reset.
- */
- rtems_interrupt_disable (level);
- *base = 0xf0;
- *(base + 0xaaa) = 0xaa;
- *(base + 0x555) = 0x55;
- *(base + 0xaaa) = 0x80;
- *(base + 0xaaa) = 0xaa;
- *(base + 0x555) = 0x55;
- *seg = 0x30;
- rtems_interrupt_enable (level);
-
- ret = rtems_am29lv160_toggle_wait_8 (seg);
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
- }
- else
- {
- volatile uint16_t* base = ac->base;
- volatile uint16_t* seg = base + (offset / 2);
-
- /*
- * Issue a reset.
- */
- rtems_interrupt_disable (level);
- *base = 0xf0;
- *(base + 0x555) = 0xaa;
- *(base + 0x2aa) = 0x55;
- *(base + 0x555) = 0x80;
- *(base + 0x555) = 0xaa;
- *(base + 0x2aa) = 0x55;
- *seg = 0x30;
- rtems_interrupt_enable (level);
-
- ret = rtems_am29lv160_toggle_wait_16 (seg);
-
- /*
- * Issue a reset.
- */
- *base = 0xf0;
- }
-
- /*
- * Check the erase worked.
- */
- if (ret == 0)
- {
- ret = rtems_am29lv160_blank (sd, device, segment, 0, sd->size);
-#if AM26LV160_ERROR_TRACE
- if (ret)
- printf ("AM26LV160: erase failed: %ld-%ld\n", device, segment);
-#endif
- }
- }
-
- return ret;
-}
-
-static int
-rtems_am29lv160_erase_device (const rtems_fdisk_device_desc* dd,
- uint32_t device)
-{
- uint32_t segment;
-
- for (segment = 0; segment < dd->segment_count; segment++)
- {
- uint32_t seg_segment;
-
- for (seg_segment = 0;
- seg_segment < dd->segments[segment].count;
- seg_segment++)
- {
- int ret = rtems_am29lv160_erase (&dd->segments[segment],
- device,
- segment + seg_segment);
- if (ret)
- return ret;
- }
- }
-
- return 0;
-}
-
-const rtems_fdisk_driver_handlers rtems_am29lv160_handlers =
-{
- .read = rtems_am29lv160_read,
- .write = rtems_am29lv160_write,
- .blank = rtems_am29lv160_blank,
- .verify = rtems_am29lv160_verify,
- .erase = rtems_am29lv160_erase,
- .erase_device = rtems_am29lv160_erase_device
-};
diff --git a/c/src/libchip/i2c/i2c-2b-eeprom.c b/c/src/libchip/i2c/i2c-2b-eeprom.c
deleted file mode 100644
index 4a8b5fdb9c..0000000000
--- a/c/src/libchip/i2c/i2c-2b-eeprom.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Trivial i2c driver for reading "2-byte eeproms".
- * On 'open' the read-pointer is reset to 0, subsequent
- * read operations slurp data from there...
- */
-
-/*
- * Authorship
- * ----------
- * This software was created by
- * Till Straumann <strauman@slac.stanford.edu>, 2005,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * This software was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/i2c-2b-eeprom.h>
-#include <rtems/libio.h>
-
-#define EEPROM_PG_SZ 32
-#define ALGN(x) (((uint32_t)(x) + EEPROM_PG_SZ) & ~(EEPROM_PG_SZ-1))
-
-static rtems_status_code
-send_file_ptr (rtems_device_minor_number minor, unsigned pos, int tout)
-{
- int sc;
- unsigned char bytes[2];
-
- bytes[0] = (pos >> 8) & 0xff;
- bytes[1] = (pos) & 0xff;
-
- /* poll addressing the next page; if 'tout' is <=0 we only try once
- * and return the status. If 'tout' is positive, we try 'tout' times
- * and return RTEMS_TIMEOUT if it didnt work
- */
- while ((sc = rtems_libi2c_start_write_bytes (minor, bytes, 2)) < 0) {
- if (--tout <= 0)
- return tout ? -sc : RTEMS_TIMEOUT;
- rtems_task_wake_after (1);
- }
- return RTEMS_SUCCESSFUL;
-}
-
-static rtems_status_code
-i2c_2b_eeprom_write (rtems_device_major_number major,
- rtems_device_minor_number minor, void *arg)
-{
- rtems_libio_rw_args_t *rwargs = arg;
- unsigned off = rwargs->offset;
- int cnt = rwargs->count;
- unsigned char *buf = (unsigned char *)rwargs->buffer;
- int sc;
- unsigned end;
- int l;
-
- if (cnt <= 0)
- return RTEMS_SUCCESSFUL;
-
- if ((sc = send_file_ptr (minor, off, 0)))
- return sc;
-
- do {
- /* write up to next page boundary */
- end = ALGN (off);
- l = end - off;
- if (l > cnt)
- l = cnt;
-
- sc = rtems_libi2c_write_bytes (minor, buf, l);
- if (sc < 0)
- return -sc;
-
- sc = rtems_libi2c_send_stop (minor);
- if (sc)
- return sc;
-
- rwargs->bytes_moved += l;
-
- buf += l;
- cnt -= l;
- off += l;
-
- /* poll addressing the next page */
- if ((sc = send_file_ptr (minor, off, 100)))
- return sc;
-
- } while (cnt > 0);
-
- return rtems_libi2c_send_stop (minor);
-}
-
-static rtems_status_code
-i2c_2b_eeprom_read (rtems_device_major_number major,
- rtems_device_minor_number minor, void *arg)
-{
- int sc;
- rtems_libio_rw_args_t *rwargs = arg;
-
- if (RTEMS_SUCCESSFUL != (sc = send_file_ptr (minor, rwargs->offset, 0)))
- return -sc;
-
- sc = rtems_libi2c_start_read_bytes(
- minor,
- (unsigned char *)rwargs->buffer,
- rwargs->count
- );
-
- if (sc < 0) {
- rwargs->bytes_moved = 0;
- return -sc;
- }
- rwargs->bytes_moved = sc;
-
- return rtems_libi2c_send_stop (minor);
-}
-
-static rtems_driver_address_table myops = {
- .read_entry = i2c_2b_eeprom_read,
- .write_entry = i2c_2b_eeprom_write,
-};
-
-static rtems_libi2c_drv_t my_drv_tbl = {
- .ops = &myops,
- .size = sizeof (my_drv_tbl),
-};
-
-/* provide a second table for R/O access */
-static rtems_driver_address_table my_ro_ops = {
- .read_entry = i2c_2b_eeprom_read,
-};
-
-static rtems_libi2c_drv_t my_ro_drv_tbl = {
- .ops = &my_ro_ops,
- .size = sizeof (my_ro_drv_tbl),
-};
-
-
-rtems_libi2c_drv_t *i2c_2b_eeprom_driver_descriptor = &my_drv_tbl;
-rtems_libi2c_drv_t *i2c_2b_eeprom_ro_driver_descriptor = &my_ro_drv_tbl;
diff --git a/c/src/libchip/i2c/i2c-ds1621.c b/c/src/libchip/i2c/i2c-ds1621.c
deleted file mode 100644
index 51f64de679..0000000000
--- a/c/src/libchip/i2c/i2c-ds1621.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Trivial i2c driver for the maxim DS1621 temperature sensor;
- * just implements reading constant conversions with 8-bit
- * resolution.
- * Demonstrates the implementation of a i2c high-level driver.
- */
-
-/*
- * Authorship
- * ----------
- * This software was created by
- * Till Straumann <strauman@slac.stanford.edu>, 2005,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * This software was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/i2c-ds1621.h>
-
-#include <rtems/libio.h>
-
-
-static rtems_status_code
-ds1621_init (rtems_device_major_number major, rtems_device_minor_number minor,
- void *arg)
-{
- int sc;
- unsigned char csr[2] = { DS1621_CMD_CSR_ACCESS, 0 }, cmd;
-
- /* First start command acquires a lock for the bus */
-
- /* Initialize; switch continuous conversion on */
- sc = rtems_libi2c_start_write_bytes (minor, csr, 1);
- if (sc < 0)
- return -sc;
-
- sc = rtems_libi2c_start_read_bytes (minor, csr + 1, 1);
- if (sc < 0)
- return -sc;
-
- csr[1] &= ~DS1621_CSR_1SHOT;
-
- sc = rtems_libi2c_start_write_bytes (minor, csr, 2);
- if (sc < 0)
- return -sc;
-
- /* Start conversion */
- cmd = DS1621_CMD_START_CONV;
-
- sc = rtems_libi2c_start_write_bytes (minor, &cmd, 1);
- if (sc < 0)
- return -sc;
-
- /* sending 'stop' relinquishes the bus mutex -- don't hold it
- * across system calls!
- */
- return rtems_libi2c_send_stop (minor);
-}
-
-static rtems_status_code
-ds1621_read (rtems_device_major_number major, rtems_device_minor_number minor,
- void *arg)
-{
- int sc;
- rtems_libio_rw_args_t *rwargs = arg;
- unsigned char cmd = DS1621_CMD_READ_TEMP;
-
- sc = rtems_libi2c_start_write_bytes (minor, &cmd, 1);
- if (sc < 0)
- return -sc;
- if (sc < 1)
- return RTEMS_IO_ERROR;
- sc = rtems_libi2c_start_read_bytes(minor, (unsigned char *)rwargs->buffer, 1);
- if (sc < 0) {
- rwargs->bytes_moved = 0;
- return -sc;
- }
- rwargs->bytes_moved = 1;
- return rtems_libi2c_send_stop (minor);
-}
-
-static rtems_driver_address_table myops = {
- .initialization_entry = ds1621_init,
- .read_entry = ds1621_read,
-};
-
-static rtems_libi2c_drv_t my_drv_tbl = {
- .ops = &myops,
- .size = sizeof (my_drv_tbl),
-};
-
-rtems_libi2c_drv_t *i2c_ds1621_driver_descriptor = &my_drv_tbl;
diff --git a/c/src/libchip/i2c/i2c-sc620.c b/c/src/libchip/i2c/i2c-sc620.c
deleted file mode 100644
index e4dd2d0871..0000000000
--- a/c/src/libchip/i2c/i2c-sc620.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file
- *
- * @brief I2C Driver for SEMTECH SC620 Octal LED Driver
- */
-
-/*
- * Copyright (c) 2013 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * 82178 Puchheim
- * Germany
- * <rtems@embedded-brains.de>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifdef HAVE_CONFIG_H
- #include "config.h"
-#endif
-
-#include <libchip/i2c-sc620.h>
-
-#include <rtems/libio.h>
-
-#define SC620_REG_COUNT 10
-
-static rtems_status_code i2c_sc620_write(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code sc = RTEMS_IO_ERROR;
- rtems_libio_rw_args_t *rw = arg;
- unsigned char *buf = (unsigned char *) &rw->buffer[0];
-
- if (rw->count == 2 && buf[0] < SC620_REG_COUNT) {
- int rv;
-
- rv = rtems_libi2c_start_write_bytes(
- minor, buf, 2
- );
- if (rv == 2) {
- sc = rtems_libi2c_send_stop(minor);
- }
- }
-
- rw->bytes_moved = sc == RTEMS_SUCCESSFUL ? 2 : 0;
-
- return sc;
-}
-
-static rtems_status_code i2c_sc620_read(
- rtems_device_major_number major,
- rtems_device_minor_number minor,
- void *arg
-)
-{
- rtems_status_code sc = RTEMS_IO_ERROR;
- rtems_libio_rw_args_t *rw = arg;
- unsigned char *buf = (unsigned char *) &rw->buffer[0];
-
- if (rw->count == 1 && buf[0] < SC620_REG_COUNT) {
- int rv;
-
- rv = rtems_libi2c_start_write_bytes(minor, buf, 1);
- if (rv == 1) {
- sc = rtems_libi2c_send_addr(minor, 0);
- if (sc == RTEMS_SUCCESSFUL) {
- rv = rtems_libi2c_read_bytes(minor, buf, 1);
- if (rv == 1) {
- sc = rtems_libi2c_send_stop(minor);
- }
- }
- }
- }
-
- rw->bytes_moved = sc == RTEMS_SUCCESSFUL ? 1 : 0;
-
- return sc;
-}
-
-static rtems_driver_address_table i2c_sc620_ops = {
- .read_entry = i2c_sc620_read,
- .write_entry = i2c_sc620_write
-};
-
-rtems_libi2c_drv_t i2c_sc620_driver = {
- .ops = &i2c_sc620_ops,
- .size = sizeof(i2c_sc620_driver)
-};
diff --git a/c/src/libchip/i2c/spi-flash-m25p40.c b/c/src/libchip/i2c/spi-flash-m25p40.c
deleted file mode 100644
index 075a4510b9..0000000000
--- a/c/src/libchip/i2c/spi-flash-m25p40.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*===============================================================*\
-| Project: SPI driver for M25P40 like spi flash device |
-+-----------------------------------------------------------------+
-| Copyright (c) 2007 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-\*===============================================================*/
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/spi-flash-m25p40.h>
-#include <rtems/libio.h>
-
-
-static spi_memdrv_t spi_flash_m25p40_rw_drv_t = {
- {/* public fields */
- .ops = &spi_memdrv_rw_ops, /* operations of general memdrv */
- .size = sizeof (spi_flash_m25p40_rw_drv_t),
- },
- { /* our private fields */
- .baudrate = 2000000,
- .erase_before_program = true,
- .empty_state = 0xff,
- .page_size = 256, /* programming page size in bytes */
- .sector_size = 0x10000, /* 64K - erase sector size in bytes */
- .mem_size = 0x80000, /* 512K - total capacity in bytes */
- }
-};
-
-rtems_libi2c_drv_t *spi_flash_m25p40_rw_driver_descriptor =
-&spi_flash_m25p40_rw_drv_t.libi2c_drv_entry;
-
-static spi_memdrv_t spi_flash_m25p40_ro_drv_t = {
- {/* public fields */
- .ops = &spi_memdrv_ro_ops, /* operations of general memdrv */
- .size = sizeof (spi_flash_m25p40_ro_drv_t),
- },
- { /* our private fields */
- .baudrate = 2000000,
- .erase_before_program = true,
- .empty_state = 0xff,
- .page_size = 256, /* programming page size in bytes */
- .sector_size = 0x10000, /* 64K erase sector size in bytes */
- .mem_size = 0x80000, /* 512K total capacity in bytes */
- }
-};
-
-rtems_libi2c_drv_t *spi_flash_m25p40_ro_driver_descriptor =
-&spi_flash_m25p40_ro_drv_t.libi2c_drv_entry;
diff --git a/c/src/libchip/i2c/spi-fram-fm25l256.c b/c/src/libchip/i2c/spi-fram-fm25l256.c
deleted file mode 100644
index 086feb82bb..0000000000
--- a/c/src/libchip/i2c/spi-fram-fm25l256.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*===============================================================*\
-| Project: SPI driver for FM25L256 like spi fram device |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-\*===============================================================*/
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/spi-fram-fm25l256.h>
-#include <rtems/libio.h>
-
-
-static spi_memdrv_t spi_fram_fm25l256_rw_drv_t = {
- {/* public fields */
- .ops = &spi_memdrv_rw_ops, /* operations of general memdrv */
- .size = sizeof (spi_fram_fm25l256_rw_drv_t),
- },
- { /* our private fields */
- .baudrate = 2000000,
- .erase_before_program = false,
- .empty_state = 0xff,
- .page_size = 0x8000, /* 32K programming page size in bytes */
- .sector_size = 1, /* erase sector size in bytes */
- .mem_size = 0x8000, /* 32K total capacity in bytes */
- }
-};
-
-rtems_libi2c_drv_t *spi_fram_fm25l256_rw_driver_descriptor =
-&spi_fram_fm25l256_rw_drv_t.libi2c_drv_entry;
-
-static spi_memdrv_t spi_fram_fm25l256_ro_drv_t = {
- {/* public fields */
- .ops = &spi_memdrv_ro_ops, /* operations of general memdrv */
- .size = sizeof (spi_fram_fm25l256_ro_drv_t),
- },
- { /* our private fields */
- .baudrate = 2000000,
- .erase_before_program = false,
- .empty_state = 0xff,
- .page_size = 0x8000, /* 32k programming page size in bytes */
- .sector_size = 1, /* erase sector size in bytes */
- .mem_size = 0x8000, /* 32k total capacity in bytes */
- }
-};
-
-rtems_libi2c_drv_t *spi_fram_fm25l256_ro_driver_descriptor =
-&spi_fram_fm25l256_ro_drv_t.libi2c_drv_entry;
diff --git a/c/src/libchip/i2c/spi-memdrv.c b/c/src/libchip/i2c/spi-memdrv.c
deleted file mode 100644
index 593029732e..0000000000
--- a/c/src/libchip/i2c/spi-memdrv.c
+++ /dev/null
@@ -1,442 +0,0 @@
-/*===============================================================*\
-| Project: SPI driver for spi memory devices |
-+-----------------------------------------------------------------+
-| Copyright (c) 2008 |
-| Embedded Brains GmbH |
-| Obere Lagerstr. 30 |
-| D-82178 Puchheim |
-| Germany |
-| rtems@embedded-brains.de |
-+-----------------------------------------------------------------+
-| The license and distribution terms for this file may be |
-| found in the file LICENSE in this distribution or at |
-| |
-| http://www.rtems.org/license/LICENSE. |
-| |
-+-----------------------------------------------------------------+
-\*===============================================================*/
-/*
- * FIXME: currently, this driver only supports read/write accesses
- * erase accesses are to be completed
- */
-
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-
-#include <libchip/spi-memdrv.h>
-#include <rtems/libio.h>
-
-#define SPI_MEM_CMD_WREN 0x06
-#define SPI_MEM_CMD_WRDIS 0x04
-#define SPI_MEM_CMD_RDID 0x9F
-#define SPI_MEM_CMD_RDSR 0x05
-#define SPI_MEM_CMD_WRSR 0x01
-#define SPI_MEM_CMD_READ 0x03
-#define SPI_MEM_CMD_PP 0x02 /* page program */
-#define SPI_MEM_CMD_SE 0xD8 /* sector erase */
-#define SPI_MEM_CMD_BE 0xC7 /* bulk erase */
-#define SPI_MEM_CMD_DP 0xB9 /* deep power down */
-#define SPI_MEM_CMD_RES 0xAB /* release from deep power down */
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code spi_memdrv_minor2param_ptr
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| translate given minor device number to param pointer |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_minor_number minor, /* minor number of device */
- spi_memdrv_param_t **param_ptr /* ptr to param ptr */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- spi_memdrv_t *drv_ptr;
-
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_GET_DRV_T,
- &drv_ptr);
- }
- if ((rc == RTEMS_SUCCESSFUL) &&
- (drv_ptr->libi2c_drv_entry.size != sizeof(spi_memdrv_t))) {
- rc = RTEMS_INVALID_SIZE;
- }
- if (rc == RTEMS_SUCCESSFUL) {
- *param_ptr = &(drv_ptr->spi_memdrv_param);
- }
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-static rtems_status_code spi_memdrv_wait_ms
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| wait a certain interval given in ms |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- int ms /* time to wait in milliseconds */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_interval ticks_per_second;
-
- ticks_per_second = rtems_clock_get_ticks_per_second();
- (void) rtems_task_wake_after(ticks_per_second * ms / 1000);
- return 0;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_status_code spi_memdrv_write
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| write a block of data to flash |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major, /* major device number */
- rtems_device_minor_number minor, /* minor device number */
- void *arg /* ptr to write argument struct */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- rtems_libio_rw_args_t *rwargs = arg;
- off_t off = rwargs->offset;
- int cnt = rwargs->count;
- unsigned char *buf = (unsigned char *)rwargs->buffer;
- int bytes_sent = 0;
- int curr_cnt;
- unsigned char cmdbuf[4];
- int ret_cnt = 0;
- int cmd_size;
- spi_memdrv_param_t *mem_param_ptr;
- rtems_libi2c_tfr_mode_t tfr_mode = {
- .baudrate = 20000000, /* maximum bits per second */
- .bits_per_char = 8, /* how many bits per byte/word/longword? */
- .lsb_first = FALSE, /* FALSE: send MSB first */
- .clock_inv = FALSE, /* FALSE: non-inverted clock (high active) */
- .clock_phs = FALSE /* FALSE: clock starts in middle of data tfr */
- } ;
-
- /*
- * get mem parameters
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_minor2param_ptr(minor,&mem_param_ptr);
- }
- /*
- * check arguments
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if ((cnt <= 0) ||
- (cnt > mem_param_ptr->mem_size) ||
- (off > (mem_param_ptr->mem_size-cnt))) {
- rc = RTEMS_INVALID_SIZE;
- }
- else if (buf == NULL) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- }
- while ((rc == RTEMS_SUCCESSFUL) &&
- (cnt > bytes_sent)) {
- curr_cnt = cnt - bytes_sent;
- if ((mem_param_ptr->page_size > 0) &&
- (off / mem_param_ptr->page_size) !=
- ((off+curr_cnt+1) / mem_param_ptr->page_size)) {
- curr_cnt = mem_param_ptr->page_size - (off % mem_param_ptr->page_size);
- }
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- tfr_mode.baudrate = mem_param_ptr->baudrate;
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- /*
- * send write_enable command
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_WREN;
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,1);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- /*
- * select device, set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
-
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
- /*
- * send "page program" command and address
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_PP;
- if (mem_param_ptr->mem_size > 0x10000 /* 256*256 */) {
- cmdbuf[1] = (off >> 16) & 0xff;
- cmdbuf[2] = (off >> 8) & 0xff;
- cmdbuf[3] = (off >> 0) & 0xff;
- cmd_size = 4;
- }
- else if (mem_param_ptr->mem_size > 256) {
- cmdbuf[1] = (off >> 8) & 0xff;
- cmdbuf[2] = (off >> 0) & 0xff;
- cmd_size = 3;
- }
- else {
- cmdbuf[1] = (off >> 0) & 0xff;
- cmd_size = 1;
- }
-
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,cmd_size);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * send write data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_write_bytes(minor,buf,curr_cnt);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- /*
- * wait proper time for data to store: 5ms
- * FIXME: select proper interval or poll, until device is finished
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_wait_ms(5);
- }
- /*
- * adjust bytecount to be sent and pointers
- */
- bytes_sent += curr_cnt;
- off += curr_cnt;
- buf += curr_cnt;
- }
- rwargs->bytes_moved = bytes_sent;
- return rc;
-}
-
-/*=========================================================================*\
-| Function: |
-\*-------------------------------------------------------------------------*/
-rtems_status_code spi_memdrv_read
-(
-/*-------------------------------------------------------------------------*\
-| Purpose: |
-| read a block of data from flash |
-+---------------------------------------------------------------------------+
-| Input Parameters: |
-\*-------------------------------------------------------------------------*/
- rtems_device_major_number major, /* major device number */
- rtems_device_minor_number minor, /* minor device number */
- void *arg /* ptr to read argument struct */
-)
-/*-------------------------------------------------------------------------*\
-| Return Value: |
-| o = ok or error code |
-\*=========================================================================*/
-{
- rtems_status_code rc = RTEMS_SUCCESSFUL;
- rtems_libio_rw_args_t *rwargs = arg;
- off_t off = rwargs->offset;
- int cnt = rwargs->count;
- unsigned char *buf = (unsigned char *)rwargs->buffer;
- unsigned char cmdbuf[4];
- int ret_cnt = 0;
- int cmd_size;
- spi_memdrv_param_t *mem_param_ptr;
- rtems_libi2c_tfr_mode_t tfr_mode = {
- .baudrate = 20000000, /* maximum bits per second */
- .bits_per_char = 8, /* how many bits per byte/word/longword? */
- .lsb_first = FALSE, /* FALSE: send MSB first */
- .clock_inv = FALSE, /* FALSE: non-inverted clock (high active) */
- .clock_phs = FALSE /* FALSE: clock starts in middle of data tfr */
- };
-
- /*
- * get mem parameters
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = spi_memdrv_minor2param_ptr(minor,&mem_param_ptr);
- }
- /*
- * check arguments
- */
- if (rc == RTEMS_SUCCESSFUL) {
- if ((cnt <= 0) ||
- (cnt > mem_param_ptr->mem_size) ||
- (off > (mem_param_ptr->mem_size-cnt))) {
- rc = RTEMS_INVALID_SIZE;
- }
- else if (buf == NULL) {
- rc = RTEMS_INVALID_ADDRESS;
- }
- }
- /*
- * select device, set transfer mode, address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_start(minor);
- }
- /*
- * set transfer mode
- */
- if (rc == RTEMS_SUCCESSFUL) {
- tfr_mode.baudrate = mem_param_ptr->baudrate;
- rc = -rtems_libi2c_ioctl(minor,
- RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
- &tfr_mode);
- }
- /*
- * address device
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_addr(minor,TRUE);
- }
-
- if (off >= mem_param_ptr->mem_size) {
- /*
- * HACK: beyond size of memory array? then read status register instead
- */
- /*
- * send read status register command
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_RDSR;
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,1);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- else {
- /*
- * send read command and address
- */
- if (rc == RTEMS_SUCCESSFUL) {
- cmdbuf[0] = SPI_MEM_CMD_READ;
- if (mem_param_ptr->mem_size > 0x10000 /* 256*256 */) {
- cmdbuf[1] = (off >> 16) & 0xff;
- cmdbuf[2] = (off >> 8) & 0xff;
- cmdbuf[3] = (off >> 0) & 0xff;
- cmd_size = 4;
- }
- else if (mem_param_ptr->mem_size > 256) {
- cmdbuf[1] = (off >> 8) & 0xff;
- cmdbuf[2] = (off >> 0) & 0xff;
- cmd_size = 3;
- }
- else {
- cmdbuf[1] = (off >> 0) & 0xff;
- cmd_size = 1;
- }
- ret_cnt = rtems_libi2c_write_bytes(minor,cmdbuf,cmd_size);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
- }
- /*
- * fetch read data
- */
- if (rc == RTEMS_SUCCESSFUL) {
- ret_cnt = rtems_libi2c_read_bytes (minor,buf,cnt);
- if (ret_cnt < 0) {
- rc = -ret_cnt;
- }
- }
-
- /*
- * terminate transfer
- */
- if (rc == RTEMS_SUCCESSFUL) {
- rc = rtems_libi2c_send_stop(minor);
- }
- rwargs->bytes_moved = (rc == RTEMS_SUCCESSFUL) ? ret_cnt : 0;
-
- return rc;
-}
-
-/*
- * driver operation tables
- */
-rtems_driver_address_table spi_memdrv_rw_ops = {
- .read_entry = spi_memdrv_read,
- .write_entry = spi_memdrv_write
-};
-
-rtems_driver_address_table spi_memdrv_ro_ops = {
- .read_entry = spi_memdrv_read,
-};
-
diff --git a/c/src/libchip/i2c/spi-sd-card.c b/c/src/libchip/i2c/spi-sd-card.c
deleted file mode 100644
index a343f7faa8..0000000000
--- a/c/src/libchip/i2c/spi-sd-card.c
+++ /dev/null
@@ -1,1322 +0,0 @@
-/**
- * @file
- *
- * @brief SD Card LibI2C driver.
- */
-
-/*
- * Copyright (c) 2008
- * Embedded Brains GmbH
- * Obere Lagerstr. 30
- * D-82178 Puchheim
- * Germany
- * rtems@embedded-brains.de
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <rtems.h>
-#include <rtems/libi2c.h>
-#include <rtems/libio.h>
-#include <rtems/diskdevs.h>
-#include <rtems/blkdev.h>
-
-#include <libchip/spi-sd-card.h>
-
-#include <rtems/status-checks.h>
-
-/**
- * @name Integer to and from Byte-Stream Converter
- * @{
- */
-
-static inline uint16_t sd_card_get_uint16( const uint8_t *s)
-{
- return (uint16_t) ((s [0] << 8) | s [1]);
-}
-
-static inline uint32_t sd_card_get_uint32( const uint8_t *s)
-{
- return ((uint32_t) s [0] << 24) | ((uint32_t) s [1] << 16) | ((uint32_t) s [2] << 8) | (uint32_t) s [3];
-}
-
-static inline void sd_card_put_uint16( uint16_t v, uint8_t *s)
-{
- *s++ = (uint8_t) (v >> 8);
- *s = (uint8_t) (v);
-}
-
-static inline void sd_card_put_uint32( uint32_t v, uint8_t *s)
-{
- *s++ = (uint8_t) (v >> 24);
- *s++ = (uint8_t) (v >> 16);
- *s++ = (uint8_t) (v >> 8);
- *s = (uint8_t) (v);
-}
-
-/** @} */
-
-#define SD_CARD_BUSY_TOKEN 0
-
-#define SD_CARD_BLOCK_SIZE_DEFAULT 512
-
-#define SD_CARD_COMMAND_RESPONSE_START 7
-
-/**
- * @name Commands
- * @{
- */
-
-#define SD_CARD_CMD_GO_IDLE_STATE 0
-#define SD_CARD_CMD_SEND_OP_COND 1
-#define SD_CARD_CMD_SEND_IF_COND 8
-#define SD_CARD_CMD_SEND_CSD 9
-#define SD_CARD_CMD_SEND_CID 10
-#define SD_CARD_CMD_STOP_TRANSMISSION 12
-#define SD_CARD_CMD_SEND_STATUS 13
-#define SD_CARD_CMD_SET_BLOCKLEN 16
-#define SD_CARD_CMD_READ_SINGLE_BLOCK 17
-#define SD_CARD_CMD_READ_MULTIPLE_BLOCK 18
-#define SD_CARD_CMD_SET_BLOCK_COUNT 23
-#define SD_CARD_CMD_WRITE_BLOCK 24
-#define SD_CARD_CMD_WRITE_MULTIPLE_BLOCK 25
-#define SD_CARD_CMD_PROGRAM_CSD 27
-#define SD_CARD_CMD_SET_WRITE_PROT 28
-#define SD_CARD_CMD_CLR_WRITE_PROT 29
-#define SD_CARD_CMD_SEND_WRITE_PROT 30
-#define SD_CARD_CMD_TAG_SECTOR_START 32
-#define SD_CARD_CMD_TAG_SECTOR_END 33
-#define SD_CARD_CMD_UNTAG_SECTOR 34
-#define SD_CARD_CMD_TAG_ERASE_GROUP_START 35
-#define SD_CARD_CMD_TAG_ERASE_GROUP_END 36
-#define SD_CARD_CMD_UNTAG_ERASE_GROUP 37
-#define SD_CARD_CMD_ERASE 38
-#define SD_CARD_CMD_LOCK_UNLOCK 42
-#define SD_CARD_CMD_APP_CMD 55
-#define SD_CARD_CMD_GEN_CND 56
-#define SD_CARD_CMD_READ_OCR 58
-#define SD_CARD_CMD_CRC_ON_OFF 59
-
-/** @} */
-
-/**
- * @name Application Commands
- * @{
- */
-
-#define SD_CARD_ACMD_SD_SEND_OP_COND 41
-
-/** @} */
-
-/**
- * @name Command Flags
- * @{
- */
-
-#define SD_CARD_FLAG_HCS 0x40000000U
-
-#define SD_CARD_FLAG_VHS_2_7_TO_3_3 0x00000100U
-
-#define SD_CARD_FLAG_CHECK_PATTERN 0x000000aaU
-
-/** @} */
-
-/**
- * @name Command Fields
- * @{
- */
-
-#define SD_CARD_COMMAND_SET_COMMAND( c, cmd) (c) [1] = (uint8_t) (0x40 + ((cmd) & 0x3f))
-
-#define SD_CARD_COMMAND_SET_ARGUMENT( c, arg) sd_card_put_uint32( (arg), &((c) [2]))
-
-#define SD_CARD_COMMAND_SET_CRC7( c, crc7) ((c) [6] = ((crc7) << 1) | 1U)
-
-#define SD_CARD_COMMAND_GET_CRC7( c) ((c) [6] >> 1)
-
-/** @} */
-
-/**
- * @name Response Fields
- * @{
- */
-
-#define SD_CARD_IS_RESPONSE( r) (((r) & 0x80) == 0)
-
-#define SD_CARD_IS_ERRORLESS_RESPONSE( r) (((r) & 0x7e) == 0)
-
-#define SD_CARD_IS_NOT_IDLE_RESPONSE( r) (((r) & 0x81) == 0)
-
-#define SD_CARD_IS_DATA_ERROR( r) (((r) & 0xe0) == 0)
-
-#define SD_CARD_IS_DATA_REJECTED( r) (((r) & 0x1f) != 0x05)
-
-/** @} */
-
-/**
- * @name Card Identification
- * @{
- */
-
-#define SD_CARD_CID_SIZE 16
-
-#define SD_CARD_CID_GET_MID( cid) ((cid) [0])
-#define SD_CARD_CID_GET_OID( cid) sd_card_get_uint16( cid + 1)
-#define SD_CARD_CID_GET_PNM( cid, i) ((char) (cid) [3 + (i)])
-#define SD_CARD_CID_GET_PRV( cid) ((cid) [9])
-#define SD_CARD_CID_GET_PSN( cid) sd_card_get_uint32( cid + 10)
-#define SD_CARD_CID_GET_MDT( cid) ((cid) [14])
-#define SD_CARD_CID_GET_CRC7( cid) ((cid) [15] >> 1)
-
-/** @} */
-
-/**
- * @name Card Specific Data
- * @{
- */
-
-#define SD_CARD_CSD_SIZE 16
-
-#define SD_CARD_CSD_GET_CSD_STRUCTURE( csd) ((csd) [0] >> 6)
-#define SD_CARD_CSD_GET_SPEC_VERS( csd) (((csd) [0] >> 2) & 0xf)
-#define SD_CARD_CSD_GET_TAAC( csd) ((csd) [1])
-#define SD_CARD_CSD_GET_NSAC( csd) ((uint32_t) (csd) [2])
-#define SD_CARD_CSD_GET_TRAN_SPEED( csd) ((csd) [3])
-#define SD_CARD_CSD_GET_C_SIZE( csd) ((((uint32_t) (csd) [6] & 0x3) << 10) + (((uint32_t) (csd) [7]) << 2) + ((((uint32_t) (csd) [8]) >> 6) & 0x3))
-#define SD_CARD_CSD_GET_C_SIZE_MULT( csd) ((((csd) [9] & 0x3) << 1) + (((csd) [10] >> 7) & 0x1))
-#define SD_CARD_CSD_GET_READ_BLK_LEN( csd) ((uint32_t) (csd) [5] & 0xf)
-#define SD_CARD_CSD_GET_WRITE_BLK_LEN( csd) ((((uint32_t) (csd) [12] & 0x3) << 2) + ((((uint32_t) (csd) [13]) >> 6) & 0x3))
-#define SD_CARD_CSD_1_GET_C_SIZE( csd) ((((uint32_t) (csd) [7] & 0x3f) << 16) + (((uint32_t) (csd) [8]) << 8) + (uint32_t) (csd) [9])
-
-/** @} */
-
-#define SD_CARD_INVALIDATE_RESPONSE_INDEX( e) e->response_index = SD_CARD_COMMAND_SIZE
-
-/**
- * @name Data Start and Stop Tokens
- * @{
- */
-
-#define SD_CARD_START_BLOCK_SINGLE_BLOCK_READ 0xfe
-#define SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ 0xfe
-#define SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE 0xfe
-#define SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE 0xfc
-#define SD_CARD_STOP_TRANSFER_MULTIPLE_BLOCK_WRITE 0xfd
-
-/** @} */
-
-/**
- * @name Card Specific Data Functions
- * @{
- */
-
-static inline uint32_t sd_card_block_number( const uint8_t *csd)
-{
- uint32_t size = SD_CARD_CSD_GET_C_SIZE( csd);
- uint32_t mult = 1U << (SD_CARD_CSD_GET_C_SIZE_MULT( csd) + 2);
- return (size + 1) * mult;
-}
-
-static inline uint32_t sd_card_capacity( const uint8_t *csd)
-{
- uint32_t block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( csd);
- return sd_card_block_number( csd) * block_size;
-}
-
-static inline uint32_t sd_card_transfer_speed( const uint8_t *csd)
-{
- uint32_t s = SD_CARD_CSD_GET_TRAN_SPEED( csd);
- uint32_t e = s & 0x7;
- uint32_t m = s >> 3;
- switch (e) {
- case 0: s = 10000; break;
- case 1: s = 100000; break;
- case 2: s = 1000000; break;
- case 3: s = 10000000; break;
- default: s = 0; break;
- }
- switch (m) {
- case 1: s *= 10; break;
- case 2: s *= 12; break;
- case 3: s *= 13; break;
- case 4: s *= 15; break;
- case 5: s *= 20; break;
- case 6: s *= 25; break;
- case 7: s *= 30; break;
- case 8: s *= 35; break;
- case 9: s *= 40; break;
- case 10: s *= 45; break;
- case 11: s *= 50; break;
- case 12: s *= 55; break;
- case 13: s *= 60; break;
- case 14: s *= 70; break;
- case 15: s *= 80; break;
- default: s *= 0; break;
- }
- return s;
-}
-
-static inline uint32_t sd_card_access_time( const uint8_t *csd)
-{
- uint32_t ac = SD_CARD_CSD_GET_TAAC( csd);
- uint32_t e = ac & 0x7;
- uint32_t m = ac >> 3;
- switch (e) {
- case 0: ac = 1; break;
- case 1: ac = 10; break;
- case 2: ac = 100; break;
- case 3: ac = 1000; break;
- case 4: ac = 10000; break;
- case 5: ac = 100000; break;
- case 6: ac = 1000000; break;
- case 7: ac = 10000000; break;
- default: ac = 0; break;
- }
- switch (m) {
- case 1: ac *= 10; break;
- case 2: ac *= 12; break;
- case 3: ac *= 13; break;
- case 4: ac *= 15; break;
- case 5: ac *= 20; break;
- case 6: ac *= 25; break;
- case 7: ac *= 30; break;
- case 8: ac *= 35; break;
- case 9: ac *= 40; break;
- case 10: ac *= 45; break;
- case 11: ac *= 50; break;
- case 12: ac *= 55; break;
- case 13: ac *= 60; break;
- case 14: ac *= 70; break;
- case 15: ac *= 80; break;
- default: ac *= 0; break;
- }
- return ac / 10;
-}
-
-static inline uint32_t sd_card_max_access_time( const uint8_t *csd, uint32_t transfer_speed)
-{
- uint64_t ac = sd_card_access_time( csd);
- uint32_t ac_100ms = transfer_speed / 80;
- uint32_t n = SD_CARD_CSD_GET_NSAC( csd) * 100;
- /* ac is in ns, transfer_speed in bps, max_access_time in bytes.
- max_access_time is 100 times typical access time (taac+nsac) */
- ac = ac * transfer_speed / 80000000;
- ac = ac + 100*n;
- if ((uint32_t)ac > ac_100ms)
- return ac_100ms;
- else
- return (uint32_t)ac;
-}
-
-/** @} */
-
-/**
- * @name CRC functions
- *
- * Based on http://en.wikipedia.org/wiki/Computation_of_CRC
- *
- * @{
- */
-
-static uint8_t sd_card_compute_crc7 (uint8_t *data, size_t len)
-{
- uint8_t e, f, crc;
- size_t i;
-
- crc = 0;
- for (i = 0; i < len; i++) {
- e = crc ^ data[i];
- f = e ^ (e >> 4) ^ (e >> 7);
- crc = (f << 1) ^ (f << 4);
- }
- return crc >> 1;
-}
-
-static uint16_t sd_card_compute_crc16 (uint8_t *data, size_t len)
-{
- uint8_t s, t;
- uint16_t crc;
- size_t i;
-
- crc = 0;
- for (i = 0; i < len; i++) {
- s = data[i] ^ (crc >> 8);
- t = s ^ (s >> 4);
- crc = (crc << 8) ^ t ^ (t << 5) ^ (t << 12);
- }
- return crc;
-}
-
-/** @} */
-
-/**
- * @name Communication Functions
- * @{
- */
-
-static inline int sd_card_query( sd_card_driver_entry *e, uint8_t *in, int n)
-{
- return rtems_libi2c_read_bytes( e->bus, in, n);
-}
-
-static int sd_card_wait( sd_card_driver_entry *e)
-{
- int rv = 0;
- int r = 0;
- int n = 2;
- /* For writes, the timeout is 2.5 times that of reads; since we
- don't know if it is a write or read, assume write.
- FIXME should actually look at R2W_FACTOR for non-HC cards. */
- int retries = e->n_ac_max * 25 / 10;
- /* n_ac_max/100 is supposed to be the average waiting time. To
- approximate this, we start with waiting n_ac_max/150 and
- gradually increase the waiting time. */
- int wait_time_bytes = (retries + 149) / 150;
- while (e->busy) {
- /* Query busy tokens */
- rv = sd_card_query( e, e->response, n);
- RTEMS_CHECK_RV( rv, "Busy");
-
- /* Search for non busy tokens */
- for (r = 0; r < n; ++r) {
- if (e->response [r] != SD_CARD_BUSY_TOKEN) {
- e->busy = false;
- return 0;
- }
- }
- retries -= n;
- if (retries <= 0) {
- return -RTEMS_TIMEOUT;
- }
-
- if (e->schedule_if_busy) {
- uint64_t wait_time_us = wait_time_bytes;
- wait_time_us *= 8000000;
- wait_time_us /= e->transfer_mode.baudrate;
- rtems_task_wake_after( RTEMS_MICROSECONDS_TO_TICKS(wait_time_us));
- retries -= wait_time_bytes;
- wait_time_bytes = wait_time_bytes * 15 / 10;
- } else {
- n = SD_CARD_COMMAND_SIZE;
- }
- }
- return 0;
-}
-
-static int sd_card_send_command( sd_card_driver_entry *e, uint32_t command, uint32_t argument)
-{
- int rv = 0;
- rtems_libi2c_read_write_t rw = {
- .rd_buf = e->response,
- .wr_buf = e->command,
- .byte_cnt = SD_CARD_COMMAND_SIZE
- };
- int r = 0;
- uint8_t crc7;
-
- SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
-
- /* Wait until card is not busy */
- rv = sd_card_wait( e);
- RTEMS_CHECK_RV( rv, "Wait");
-
- /* Write command and read response */
- SD_CARD_COMMAND_SET_COMMAND( e->command, command);
- SD_CARD_COMMAND_SET_ARGUMENT( e->command, argument);
- crc7 = sd_card_compute_crc7( e->command + 1, 5);
- SD_CARD_COMMAND_SET_CRC7( e->command, crc7);
- rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_READ_WRITE, &rw);
- RTEMS_CHECK_RV( rv, "Write command and read response");
-
- /* Check respose */
- for (r = SD_CARD_COMMAND_RESPONSE_START; r < SD_CARD_COMMAND_SIZE; ++r) {
- RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, e->response [r]);
- e->response_index = r;
- if (SD_CARD_IS_RESPONSE( e->response [r])) {
- if (SD_CARD_IS_ERRORLESS_RESPONSE( e->response [r])) {
- return 0;
- } else {
- RTEMS_SYSLOG_ERROR( "Command error [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
- goto sd_card_send_command_error;
- }
- } else if (e->response [r] != SD_CARD_IDLE_TOKEN) {
- RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, e->response [r]);
- goto sd_card_send_command_error;
- }
- }
-
- RTEMS_SYSLOG_ERROR( "Timeout\n");
-
-sd_card_send_command_error:
-
- RTEMS_SYSLOG_ERROR( "Response:");
- for (r = 0; r < SD_CARD_COMMAND_SIZE; ++r) {
- if (e->response_index == r) {
- RTEMS_SYSLOG_PRINT( " %02" PRIx8 ":[%02" PRIx8 "]", e->command [r], e->response [r]);
- } else {
- RTEMS_SYSLOG_PRINT( " %02" PRIx8 ":%02" PRIx8 "", e->command [r], e->response [r]);
- }
- }
- RTEMS_SYSLOG_PRINT( "\n");
-
- return -RTEMS_IO_ERROR;
-}
-
-static int sd_card_send_register_command( sd_card_driver_entry *e, uint32_t command, uint32_t argument, uint32_t *reg)
-{
- int rv = 0;
- uint8_t crc7;
-
- rv = sd_card_send_command( e, command, argument);
- RTEMS_CHECK_RV( rv, "Send command");
-
- if (e->response_index + 5 > SD_CARD_COMMAND_SIZE) {
- /*
- * TODO: If this happens in the wild we need to implement a
- * more sophisticated response query.
- */
- RTEMS_SYSLOG_ERROR( "Unexpected response position\n");
- return -RTEMS_IO_ERROR;
- }
-
- crc7 = sd_card_compute_crc7( e->response + e->response_index, 5);
- if (crc7 != SD_CARD_COMMAND_GET_CRC7( e->response + e->response_index) &&
- SD_CARD_COMMAND_GET_CRC7( e->response + e->response_index) != 0x7f) {
- RTEMS_SYSLOG_ERROR( "CRC check failed on register command\n");
- return -RTEMS_IO_ERROR;
- }
-
- *reg = sd_card_get_uint32( e->response + e->response_index + 1);
-
- return 0;
-}
-
-static int sd_card_stop_multiple_block_read( sd_card_driver_entry *e)
-{
- int rv = 0;
- uint8_t crc7;
-
- SD_CARD_COMMAND_SET_COMMAND( e->command, SD_CARD_CMD_STOP_TRANSMISSION);
- SD_CARD_COMMAND_SET_ARGUMENT( e->command, 0);
- /*crc7 = sd_card_compute_crc7( e->command + 1, 5);*/
- crc7 = 0x30; /* Help compiler - command and argument are constants */
- SD_CARD_COMMAND_SET_CRC7( e->command, crc7);
- rv = rtems_libi2c_write_bytes( e->bus, e->command, SD_CARD_COMMAND_SIZE);
- RTEMS_CHECK_RV( rv, "Write stop transfer token");
-
- return 0;
-}
-
-static int sd_card_stop_multiple_block_write( sd_card_driver_entry *e)
-{
- int rv = 0;
- uint8_t stop_transfer [3] = { SD_CARD_IDLE_TOKEN, SD_CARD_STOP_TRANSFER_MULTIPLE_BLOCK_WRITE, SD_CARD_IDLE_TOKEN };
-
- /* Wait until card is not busy */
- rv = sd_card_wait( e);
- RTEMS_CHECK_RV( rv, "Wait");
-
- /* Send stop token */
- rv = rtems_libi2c_write_bytes( e->bus, stop_transfer, 3);
- RTEMS_CHECK_RV( rv, "Write stop transfer token");
-
- /* Card is now busy */
- e->busy = true;
-
- return 0;
-}
-
-static int sd_card_read( sd_card_driver_entry *e, uint8_t start_token, uint8_t *in, int n)
-{
- int rv = 0;
-
- /* Discard command response */
- int r = e->response_index + 1;
-
- /* Standard response size */
- int response_size = SD_CARD_COMMAND_SIZE;
-
- /* Where the response is stored */
- uint8_t *response = e->response;
-
- /* Data input index */
- int i = 0;
-
- /* CRC check of data */
- uint16_t crc16;
-
- /* Maximum number of tokens to read. */
- int retries = e->n_ac_max;
-
- SD_CARD_INVALIDATE_RESPONSE_INDEX( e);
-
- while (true) {
- RTEMS_DEBUG_PRINT( "Search from %u to %u\n", r, response_size - 1);
-
- /* Search the data start token in in current response buffer */
- retries -= (response_size - r);
- while (r < response_size) {
- RTEMS_DEBUG_PRINT( "Token [%02u]: 0x%02x\n", r, response [r]);
- if (response [r] == start_token) {
- /* Discard data start token */
- ++r;
- goto sd_card_read_start;
- } else if (SD_CARD_IS_DATA_ERROR( response [r])) {
- RTEMS_SYSLOG_ERROR( "Data error token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
- return -RTEMS_IO_ERROR;
- } else if (response [r] != SD_CARD_IDLE_TOKEN) {
- RTEMS_SYSLOG_ERROR( "Unexpected token [%02i]: 0x%02" PRIx8 "\n", r, response [r]);
- return -RTEMS_IO_ERROR;
- }
- ++r;
- }
-
- if (retries <= 0) {
- RTEMS_SYSLOG_ERROR( "Timeout\n");
- return -RTEMS_IO_ERROR;
- }
-
- if (e->schedule_if_busy)
- rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
-
- /* Query more. We typically have to wait between 10 and 100
- bytes. To reduce overhead, read the response in chunks of
- 50 bytes - this doesn't introduce too much copy overhead
- but does allow SPI DMA transfers to work efficiently. */
- response = in;
- response_size = 50;
- if (response_size > n)
- response_size = n;
- rv = sd_card_query( e, response, response_size);
- RTEMS_CHECK_RV( rv, "Query data start token");
-
- /* Reset start position */
- r = 0;
- }
-
-sd_card_read_start:
-
- /* Read data */
- while (r < response_size && i < n) {
- in [i++] = response [r++];
- }
-
- /* Read more data? */
- if (i < n) {
- rv = sd_card_query( e, &in [i], n - i);
- RTEMS_CHECK_RV( rv, "Read data");
- i += rv;
- }
-
- /* Read CRC 16 and N_RC */
- rv = sd_card_query( e, e->response, 3);
- RTEMS_CHECK_RV( rv, "Read CRC 16");
-
- crc16 = sd_card_compute_crc16 (in, n);
- if ((e->response[0] != ((crc16 >> 8) & 0xff)) ||
- (e->response[1] != (crc16 & 0xff))) {
- RTEMS_SYSLOG_ERROR( "CRC check failed on read\n");
- return -RTEMS_IO_ERROR;
- }
-
- return i;
-}
-
-static int sd_card_write( sd_card_driver_entry *e, uint8_t start_token, uint8_t *out, int n)
-{
- int rv = 0;
- uint8_t crc16_bytes [2] = { 0, 0 };
- uint16_t crc16;
-
- /* Data output index */
- int o = 0;
-
- /* Wait until card is not busy */
- rv = sd_card_wait( e);
- RTEMS_CHECK_RV( rv, "Wait");
-
- /* Write data start token */
- rv = rtems_libi2c_write_bytes( e->bus, &start_token, 1);
- RTEMS_CHECK_RV( rv, "Write data start token");
-
- /* Write data */
- o = rtems_libi2c_write_bytes( e->bus, out, n);
- RTEMS_CHECK_RV( o, "Write data");
-
- /* Write CRC 16 */
- crc16 = sd_card_compute_crc16(out, n);
- crc16_bytes[0] = (crc16>>8) & 0xff;
- crc16_bytes[1] = (crc16) & 0xff;
- rv = rtems_libi2c_write_bytes( e->bus, crc16_bytes, 2);
- RTEMS_CHECK_RV( rv, "Write CRC 16");
-
- /* Read data response */
- rv = sd_card_query( e, e->response, 2);
- RTEMS_CHECK_RV( rv, "Read data response");
- if (SD_CARD_IS_DATA_REJECTED( e->response [0])) {
- RTEMS_SYSLOG_ERROR( "Data rejected: 0x%02" PRIx8 "\n", e->response [0]);
- return -RTEMS_IO_ERROR;
- }
-
- /* Card is now busy */
- e->busy = true;
-
- return o;
-}
-
-static inline rtems_status_code sd_card_start( sd_card_driver_entry *e)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
-
- sc = rtems_libi2c_send_start( e->bus);
- RTEMS_CHECK_SC( sc, "Send start");
-
- rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
- RTEMS_CHECK_RV_SC( rv, "Set transfer mode");
-
- sc = rtems_libi2c_send_addr( e->bus, 1);
- RTEMS_CHECK_SC( sc, "Send address");
-
- return RTEMS_SUCCESSFUL;
-}
-
-static inline rtems_status_code sd_card_stop( sd_card_driver_entry *e)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
-
- sc = rtems_libi2c_send_stop( e->bus);
- RTEMS_CHECK_SC( sc, "Send stop");
-
- return RTEMS_SUCCESSFUL;
-}
-
-static rtems_status_code sd_card_init( sd_card_driver_entry *e)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
- uint8_t block [SD_CARD_BLOCK_SIZE_DEFAULT];
- uint32_t transfer_speed = 0;
- uint32_t read_block_size = 0;
- uint32_t write_block_size = 0;
- uint8_t csd_structure = 0;
- uint64_t capacity = 0;
- uint8_t crc7;
-
- /* Assume first that we have a SD card and not a MMC card */
- bool assume_sd = true;
-
- /*
- * Assume high capacity until proven wrong (applies to SD and not yet
- * existing MMC).
- */
- bool high_capacity = true;
-
- bool do_cmd58 = true;
- uint32_t cmd_arg = 0;
- uint32_t if_cond_test = SD_CARD_FLAG_VHS_2_7_TO_3_3 | SD_CARD_FLAG_CHECK_PATTERN;
- uint32_t if_cond_reg = if_cond_test;
-
- /* Start */
- sc = sd_card_start( e);
- RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Start");
-
- /* Wait until card is not busy */
- rv = sd_card_wait( e);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Wait");
-
- /* Send idle tokens for at least 74 clock cycles with active chip select */
- memset( block, SD_CARD_IDLE_TOKEN, SD_CARD_BLOCK_SIZE_DEFAULT);
- rv = rtems_libi2c_write_bytes( e->bus, block, SD_CARD_BLOCK_SIZE_DEFAULT);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Active chip select delay");
-
- /* Stop */
- sc = sd_card_stop( e);
- RTEMS_CHECK_SC( sc, "Stop");
-
- /* Start with inactive chip select */
- sc = rtems_libi2c_send_start( e->bus);
- RTEMS_CHECK_SC( sc, "Send start");
-
- /* Set transfer mode */
- rv = rtems_libi2c_ioctl( e->bus, RTEMS_LIBI2C_IOCTL_SET_TFRMODE, &e->transfer_mode);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Set transfer mode");
-
- /* Send idle tokens with inactive chip select */
- rv = sd_card_query( e, e->response, SD_CARD_COMMAND_SIZE);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Inactive chip select delay");
-
- /* Activate chip select */
- sc = rtems_libi2c_send_addr( e->bus, 1);
- RTEMS_CLEANUP_SC( sc, sd_card_driver_init_cleanup, "Send address");
-
- /* Stop multiple block write */
- sd_card_stop_multiple_block_write( e);
-
- /* Get card status */
- sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
-
- /* Stop multiple block read */
- sd_card_stop_multiple_block_read( e);
-
- /* Switch to SPI mode */
- rv = sd_card_send_command( e, SD_CARD_CMD_GO_IDLE_STATE, 0);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_GO_IDLE_STATE");
-
- /*
- * Get interface condition, CMD8. This is new for SD 2.x and enables
- * getting the High Capacity Support flag HCS and checks that the
- * voltage is right. Some MMCs accept this command but will still fail
- * on ACMD41. SD 1.x cards will fails this command and do not support
- * HCS (> 2G capacity).
- */
- rv = sd_card_send_register_command( e, SD_CARD_CMD_SEND_IF_COND, if_cond_reg, &if_cond_reg);
-
- /*
- * Regardless of whether CMD8 above passes or fails, send ACMD41. If
- * card is MMC it will fail. But older SD < 2.0 (which fail CMD8) will
- * always stay "idle" if cmd_arg is non-zero, so set to 0 above on
- * fail.
- */
- if (rv < 0) {
- /* Failed CMD8, so SD 1.x or MMC */
- cmd_arg = 0;
- } else {
- cmd_arg = SD_CARD_FLAG_HCS;
- }
-
- /* Enable CRC */
- sd_card_send_command( e, SD_CARD_CMD_CRC_ON_OFF, 1);
-
- /* Initialize card */
- while (true) {
- if (assume_sd) {
- /* This command (CMD55) supported by SD and (most?) MMCs */
- rv = sd_card_send_command( e, SD_CARD_CMD_APP_CMD, 0);
- if (rv < 0) {
- RTEMS_SYSLOG( "CMD55 failed. Assume MMC and try CMD1\n");
- assume_sd = false;
- continue;
- }
-
- /*
- * This command (ACMD41) only supported by SD. Always
- * fails if MMC.
- */
- rv = sd_card_send_command( e, SD_CARD_ACMD_SD_SEND_OP_COND, cmd_arg);
- if (rv < 0) {
- /*
- * This *will* fail for MMC. If fails, bad/no
- * card or card is MMC, do CMD58 then CMD1.
- */
- RTEMS_SYSLOG( "ACMD41 failed. Assume MMC and do CMD58 (once) then CMD1\n");
- assume_sd = false;
- cmd_arg = SD_CARD_FLAG_HCS;
- do_cmd58 = true;
- continue;
- } else {
- /*
- * Passed ACMD41 so SD. It is now save to
- * check if_cond_reg from CMD8. Reject the
- * card in case of a indicated bad voltage.
- */
- if (if_cond_reg != if_cond_test) {
- RTEMS_CLEANUP_RV_SC( -1, sc, sd_card_driver_init_cleanup, "Bad voltage for SD");
- }
- }
- } else {
- /*
- * Does not seem to be SD card. Do init for MMC.
- * First send CMD58 once to enable check for HCS
- * (similar to CMD8 of SD) with bits 30:29 set to 10b.
- * This will work for MMC >= 4.2. Older cards (<= 4.1)
- * may may not respond to CMD1 unless CMD58 is sent
- * again with zero argument.
- */
- if (do_cmd58) {
- rv = sd_card_send_command( e, SD_CARD_CMD_READ_OCR, cmd_arg);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC");
-
- /* A one-shot call */
- do_cmd58 = false;
- }
-
- /* Do CMD1 */
- rv = sd_card_send_command( e, SD_CARD_CMD_SEND_OP_COND, 0);
- if (rv < 0) {
- if (cmd_arg != 0) {
- /*
- * Send CMD58 again with zero argument
- * value. Proves card is not
- * high_capacity.
- */
- cmd_arg = 0;
- do_cmd58 = true;
- high_capacity = false;
- continue;
- }
-
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed to initialize MMC");
- }
- }
-
- /*
- * Not idle?
- *
- * This hangs forever if the card remains not idle and sends
- * always a valid response.
- */
- if (SD_CARD_IS_NOT_IDLE_RESPONSE( e->response [e->response_index])) {
- break;
- }
-
- /* Invoke the scheduler */
- rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);
- }
-
- /* Now we know if we are SD or MMC */
- if (assume_sd) {
- if (cmd_arg == 0) {
- /* SD is < 2.0 so never high capacity (<= 2G) */
- high_capacity = 0;
- } else {
- uint32_t reg = 0;
-
- /*
- * SD is definitely 2.x. Now need to send CMD58 to get
- * the OCR to see if the HCS bit is set (capacity > 2G)
- * or if bit is off (capacity <= 2G, standard
- * capacity).
- */
- rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, 0, &reg);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for SD 2.x");
-
- /* Check HCS bit of OCR */
- high_capacity = (reg & SD_CARD_FLAG_HCS) != 0;
- }
- } else {
- /*
- * Card is MMC. Unless already proven to be not HCS (< 4.2)
- * must do CMD58 again to check the OCR bits 30:29.
- */
- if (high_capacity) {
- uint32_t reg = 0;
-
- /*
- * The argument should still be correct since was never
- * set to 0
- */
- rv = sd_card_send_register_command( e, SD_CARD_CMD_READ_OCR, cmd_arg, &reg);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Failed CMD58 for MMC 4.2");
-
- /* Check HCS bit of the OCR */
- high_capacity = (reg & SD_CARD_FLAG_HCS) != 0;
- }
- }
-
- /* Card Identification */
- if (e->verbose) {
- rv = sd_card_send_command( e, SD_CARD_CMD_SEND_CID, 0);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SEND_CID");
- rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, block, SD_CARD_CID_SIZE);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Read: SD_CARD_CMD_SEND_CID");
- RTEMS_SYSLOG( "*** Card Identification ***\n");
- RTEMS_SYSLOG( "Manufacturer ID : %" PRIu8 "\n", SD_CARD_CID_GET_MID( block));
- RTEMS_SYSLOG( "OEM/Application ID : %" PRIu16 "\n", SD_CARD_CID_GET_OID( block));
- RTEMS_SYSLOG(
- "Product name : %c%c%c%c%c%c\n",
- SD_CARD_CID_GET_PNM( block, 0),
- SD_CARD_CID_GET_PNM( block, 1),
- SD_CARD_CID_GET_PNM( block, 2),
- SD_CARD_CID_GET_PNM( block, 3),
- SD_CARD_CID_GET_PNM( block, 4),
- SD_CARD_CID_GET_PNM( block, 5)
- );
- RTEMS_SYSLOG( "Product revision : %" PRIu8 "\n", SD_CARD_CID_GET_PRV( block));
- RTEMS_SYSLOG( "Product serial number : %" PRIu32 "\n", SD_CARD_CID_GET_PSN( block));
- RTEMS_SYSLOG( "Manufacturing date : %" PRIu8 "\n", SD_CARD_CID_GET_MDT( block));
- RTEMS_SYSLOG( "7-bit CRC checksum : %" PRIu8 "\n", SD_CARD_CID_GET_CRC7( block));
- crc7 = sd_card_compute_crc7( block, 15);
- if (crc7 != SD_CARD_CID_GET_CRC7( block))
- RTEMS_SYSLOG( " Failed! (computed %02" PRIx8 ")\n", crc7);
- }
-
- /* Card Specific Data */
-
- /* Read CSD */
- rv = sd_card_send_command( e, SD_CARD_CMD_SEND_CSD, 0);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SEND_CSD");
- rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, block, SD_CARD_CSD_SIZE);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Read: SD_CARD_CMD_SEND_CSD");
-
- crc7 = sd_card_compute_crc7( block, 15);
- if (crc7 != SD_CARD_CID_GET_CRC7( block)) {
- RTEMS_SYSLOG( "SD_CARD_CMD_SEND_CSD CRC failed\n");
- sc = RTEMS_IO_ERROR;
- goto sd_card_driver_init_cleanup;
- }
-
- /* CSD Structure */
- csd_structure = SD_CARD_CSD_GET_CSD_STRUCTURE( block);
-
- /* Transfer speed and access time */
- transfer_speed = sd_card_transfer_speed( block);
- e->transfer_mode.baudrate = transfer_speed;
- e->n_ac_max = sd_card_max_access_time( block, transfer_speed);
-
- /* Block sizes and capacity */
- if (csd_structure == 0 || !assume_sd) {
- /* Treat MMC same as CSD Version 1.0 */
-
- read_block_size = 1U << SD_CARD_CSD_GET_READ_BLK_LEN( block);
- e->block_size_shift = SD_CARD_CSD_GET_WRITE_BLK_LEN( block);
- write_block_size = 1U << e->block_size_shift;
- if (read_block_size < write_block_size) {
- RTEMS_SYSLOG_ERROR( "Read block size smaller than write block size\n");
- return -RTEMS_IO_ERROR;
- }
- e->block_size = write_block_size;
- e->block_number = sd_card_block_number( block);
- capacity = sd_card_capacity( block);
- } else if (csd_structure == 1) {
- uint32_t c_size = SD_CARD_CSD_1_GET_C_SIZE( block);
-
- /* Block size is fixed in CSD Version 2.0 */
- e->block_size_shift = 9;
- e->block_size = 512;
-
- e->block_number = (c_size + 1) * 1024;
- capacity = (c_size + 1) * 512 * 1024;
- read_block_size = 512;
- write_block_size = 512;
-
- /* Timeout is fixed at 100ms in CSD Version 2.0 */
- e->n_ac_max = transfer_speed / 80;
- } else {
- RTEMS_DO_CLEANUP_SC( RTEMS_IO_ERROR, sc, sd_card_driver_init_cleanup, "Unexpected CSD Structure number");
- }
-
- /* Print CSD information */
- if (e->verbose) {
- RTEMS_SYSLOG( "*** Card Specific Data ***\n");
- RTEMS_SYSLOG( "CSD structure : %" PRIu8 "\n", SD_CARD_CSD_GET_CSD_STRUCTURE( block));
- RTEMS_SYSLOG( "Spec version : %" PRIu8 "\n", SD_CARD_CSD_GET_SPEC_VERS( block));
- RTEMS_SYSLOG( "Access time [ns] : %" PRIu32 "\n", sd_card_access_time( block));
- RTEMS_SYSLOG( "Access time [N] : %" PRIu32 "\n", SD_CARD_CSD_GET_NSAC( block)*100);
- RTEMS_SYSLOG( "Max access time [N] : %" PRIu32 "\n", e->n_ac_max);
- RTEMS_SYSLOG( "Max read block size [B] : %" PRIu32 "\n", read_block_size);
- RTEMS_SYSLOG( "Max write block size [B] : %" PRIu32 "\n", write_block_size);
- RTEMS_SYSLOG( "Block size [B] : %" PRIu32 "\n", e->block_size);
- RTEMS_SYSLOG( "Block number : %" PRIu32 "\n", e->block_number);
- RTEMS_SYSLOG( "Capacity [B] : %" PRIu64 "\n", capacity);
- RTEMS_SYSLOG( "Max transfer speed [b/s] : %" PRIu32 "\n", transfer_speed);
- }
-
- if (high_capacity) {
- /* For high capacity cards the address is in blocks */
- e->block_size_shift = 0;
- } else if (e->block_size_shift == 10) {
- /*
- * Low capacity 2GByte cards with reported block size of 1024
- * need to be set back to block size of 512 per 'Simplified
- * Physical Layer Specification Version 2.0' section 4.3.2.
- * Otherwise, CMD16 fails if set to 1024.
- */
- e->block_size_shift = 9;
- e->block_size = 512;
- e->block_number *= 2;
- }
-
- /* Set read block size */
- rv = sd_card_send_command( e, SD_CARD_CMD_SET_BLOCKLEN, e->block_size);
- RTEMS_CLEANUP_RV_SC( rv, sc, sd_card_driver_init_cleanup, "Send: SD_CARD_CMD_SET_BLOCKLEN");
-
- /* Stop */
- sc = sd_card_stop( e);
- RTEMS_CHECK_SC( sc, "Stop");
-
- return RTEMS_SUCCESSFUL;
-
-sd_card_driver_init_cleanup:
-
- /* Stop */
- sd_card_stop( e);
-
- return sc;
-}
-/** @} */
-
-/**
- * @name Disk Driver Functions
- * @{
- */
-
-static int sd_card_disk_block_read( sd_card_driver_entry *e, rtems_blkdev_request *r)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
- uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
- uint32_t i = 0;
-
-#ifdef DEBUG
- /* Check request */
- if (r->bufs[0].block >= e->block_number) {
- RTEMS_SYSLOG_ERROR( "Start block number out of range");
- return -RTEMS_INTERNAL_ERROR;
- } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
- RTEMS_SYSLOG_ERROR( "Block count out of range");
- return -RTEMS_INTERNAL_ERROR;
- }
-#endif /* DEBUG */
-
- /* Start */
- sc = sd_card_start( e);
- RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_read_cleanup, "Start");
-
- if (r->bufnum == 1) {
-#ifdef DEBUG
- /* Check buffer */
- if (r->bufs [0].length != e->block_size) {
- RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_cleanup, "Buffer and disk block size are not equal");
- }
- RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
-#endif /* DEBUG */
-
- /* Single block read */
- rv = sd_card_send_command( e, SD_CARD_CMD_READ_SINGLE_BLOCK, start_address);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Send: SD_CARD_CMD_READ_SINGLE_BLOCK");
- rv = sd_card_read( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_READ, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Read: SD_CARD_CMD_READ_SINGLE_BLOCK");
- } else {
- /* Start multiple block read */
- rv = sd_card_send_command( e, SD_CARD_CMD_READ_MULTIPLE_BLOCK, start_address);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Send: SD_CARD_CMD_READ_MULTIPLE_BLOCK");
-
- /* Multiple block read */
- for (i = 0; i < r->bufnum; ++i) {
-#ifdef DEBUG
- /* Check buffer */
- if (r->bufs [i].length != e->block_size) {
- RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_read_stop_cleanup, "Buffer and disk block size are not equal");
- }
- RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
-#endif /* DEBUG */
-
- rv = sd_card_read( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_READ, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_stop_cleanup, "Read block");
- }
-
- /* Stop multiple block read */
- rv = sd_card_stop_multiple_block_read( e);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_read_cleanup, "Stop multiple block read");
- }
-
- /* Stop */
- sc = sd_card_stop( e);
- RTEMS_CHECK_SC_RV( sc, "Stop");
-
- /* Done */
- rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
-
- return 0;
-
-sd_card_disk_block_read_stop_cleanup:
-
- /* Stop multiple block read */
- sd_card_stop_multiple_block_read( e);
-
-sd_card_disk_block_read_cleanup:
-
- /* Stop */
- sd_card_stop( e);
-
- /* Done */
- rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
-
- return 0;
-}
-
-static int sd_card_disk_block_write( sd_card_driver_entry *e, rtems_blkdev_request *r)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- int rv = 0;
- uint32_t start_address = RTEMS_BLKDEV_START_BLOCK (r) << e->block_size_shift;
- uint32_t i = 0;
-
-#ifdef DEBUG
- /* Check request */
- if (r->bufs[0].block >= e->block_number) {
- RTEMS_SYSLOG_ERROR( "Start block number out of range");
- return -RTEMS_INTERNAL_ERROR;
- } else if (r->bufnum > e->block_number - RTEMS_BLKDEV_START_BLOCK (r)) {
- RTEMS_SYSLOG_ERROR( "Block count out of range");
- return -RTEMS_INTERNAL_ERROR;
- }
-#endif /* DEBUG */
-
- /* Start */
- sc = sd_card_start( e);
- RTEMS_CLEANUP_SC_RV( sc, rv, sd_card_disk_block_write_cleanup, "Start");
-
- if (r->bufnum == 1) {
-#ifdef DEBUG
- /* Check buffer */
- if (r->bufs [0].length != e->block_size) {
- RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_cleanup, "Buffer and disk block size are not equal");
- }
- RTEMS_DEBUG_PRINT( "[01:01]: buffer = 0x%08x, size = %u\n", r->bufs [0].buffer, r->bufs [0].length);
-#endif /* DEBUG */
-
- /* Single block write */
- rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_BLOCK, start_address);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Send: SD_CARD_CMD_WRITE_BLOCK");
- rv = sd_card_write( e, SD_CARD_START_BLOCK_SINGLE_BLOCK_WRITE, (uint8_t *) r->bufs [0].buffer, (int) e->block_size);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Write: SD_CARD_CMD_WRITE_BLOCK");
- } else {
- /* Start multiple block write */
- rv = sd_card_send_command( e, SD_CARD_CMD_WRITE_MULTIPLE_BLOCK, start_address);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Send: SD_CARD_CMD_WRITE_MULTIPLE_BLOCK");
-
- /* Multiple block write */
- for (i = 0; i < r->bufnum; ++i) {
-#ifdef DEBUG
- /* Check buffer */
- if (r->bufs [i].length != e->block_size) {
- RTEMS_DO_CLEANUP_RV( -RTEMS_INTERNAL_ERROR, rv, sd_card_disk_block_write_stop_cleanup, "Buffer and disk block size are not equal");
- }
- RTEMS_DEBUG_PRINT( "[%02u:%02u]: buffer = 0x%08x, size = %u\n", i + 1, r->bufnum, r->bufs [i].buffer, r->bufs [i].length);
-#endif /* DEBUG */
-
- rv = sd_card_write( e, SD_CARD_START_BLOCK_MULTIPLE_BLOCK_WRITE, (uint8_t *) r->bufs [i].buffer, (int) e->block_size);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_stop_cleanup, "Write block");
- }
-
- /* Stop multiple block write */
- rv = sd_card_stop_multiple_block_write( e);
- RTEMS_CLEANUP_RV( rv, sd_card_disk_block_write_cleanup, "Stop multiple block write");
- }
-
- /* Get card status */
- rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
- RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
-
- /* Stop */
- sc = sd_card_stop( e);
- RTEMS_CHECK_SC_RV( sc, "Stop");
-
- /* Done */
- rtems_blkdev_request_done( r, RTEMS_SUCCESSFUL);
-
- return 0;
-
-sd_card_disk_block_write_stop_cleanup:
-
- /* Stop multiple block write */
- sd_card_stop_multiple_block_write( e);
-
-sd_card_disk_block_write_cleanup:
-
- /* Get card status */
- rv = sd_card_send_command( e, SD_CARD_CMD_SEND_STATUS, 0);
- RTEMS_CHECK_RV( rv, "Send: SD_CARD_CMD_SEND_STATUS");
-
- /* Stop */
- sd_card_stop( e);
-
- /* Done */
- rtems_blkdev_request_done( r, RTEMS_IO_ERROR);
-
- return 0;
-}
-
-static int sd_card_disk_ioctl( rtems_disk_device *dd, uint32_t req, void *arg)
-{
- RTEMS_DEBUG_PRINT( "sd_card_disk_ioctl minor = %u, req = 0x%08x, arg = %p\n",
- (unsigned)rtems_filesystem_dev_minor_t(dd->dev), (unsigned)req, arg);
- if (req == RTEMS_BLKIO_REQUEST) {
- rtems_device_minor_number minor = rtems_disk_get_minor_number( dd);
- sd_card_driver_entry *e = &sd_card_driver_table [minor];
- rtems_blkdev_request *r = (rtems_blkdev_request *) arg;
- int (*f)( sd_card_driver_entry *, rtems_blkdev_request *);
- uint32_t retries = e->retries;
- int result;
-
- switch (r->req) {
- case RTEMS_BLKDEV_REQ_READ:
- f = sd_card_disk_block_read;
- break;
- case RTEMS_BLKDEV_REQ_WRITE:
- f = sd_card_disk_block_write;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- do {
- result = f( e, r);
- } while (retries-- > 0 && result != 0);
- return result;
-
- } else if (req == RTEMS_BLKIO_CAPABILITIES) {
- *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
- return 0;
- } else {
- return rtems_blkdev_ioctl( dd, req, arg );
- }
-}
-
-static rtems_status_code sd_card_disk_init( rtems_device_major_number major, rtems_device_minor_number minor, void *arg)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
-
- /* Initialize disk IO */
- sc = rtems_disk_io_initialize();
- RTEMS_CHECK_SC( sc, "Initialize RTEMS disk IO");
-
- for (minor = 0; minor < sd_card_driver_table_size; ++minor) {
- sd_card_driver_entry *e = &sd_card_driver_table [minor];
- dev_t dev = rtems_filesystem_make_dev_t( major, minor);
- uint32_t retries = e->retries;
-
- /* Initialize SD Card */
- do {
- sc = sd_card_init( e);
- } while (retries-- > 0 && sc != RTEMS_SUCCESSFUL);
- RTEMS_CHECK_SC( sc, "Initialize SD Card");
-
- /* Create disk device */
- sc = rtems_disk_create_phys( dev, e->block_size, e->block_number, sd_card_disk_ioctl, NULL, e->device_name);
- RTEMS_CHECK_SC( sc, "Create disk device");
- }
-
- return RTEMS_SUCCESSFUL;
-}
-
-/** @} */
-
-static const rtems_driver_address_table sd_card_disk_ops = {
- .initialization_entry = sd_card_disk_init,
- .open_entry = rtems_blkdev_generic_open,
- .close_entry = rtems_blkdev_generic_close,
- .read_entry = rtems_blkdev_generic_read,
- .write_entry = rtems_blkdev_generic_write,
- .control_entry = rtems_blkdev_generic_ioctl
-};
-
-rtems_status_code sd_card_register( void)
-{
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- rtems_device_major_number major = 0;
-
- sc = rtems_io_register_driver( 0, &sd_card_disk_ops, &major);
- RTEMS_CHECK_SC( sc, "Register disk SD Card driver");
-
- return RTEMS_SUCCESSFUL;
-}
diff --git a/c/src/libchip/ide/ata.c b/c/src/libchip/ide/ata.c
deleted file mode 100644
index 7bb3f6ec73..0000000000
--- a/c/src/libchip/ide/ata.c
+++ /dev/null
@@ -1,1360 +0,0 @@
-/*
- * ata.c
- *
- * ATA RTEMS driver. ATA driver is hardware independant implementation of
- * ATA-2 standard, working draft X3T10/0948D, revision 4c. ATA driver bases
- * on RTEMS IDE controller driver.
- *
- * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
- * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- */
-#include <errno.h>
-#include <rtems/chain.h>
-#include <assert.h>
-#include <string.h> /* for "memset" declaration */
-
-#include <rtems/diskdevs.h>
-#include <rtems/blkdev.h>
-#include <libchip/ide_ctrl_io.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ata_internal.h>
-#include <libchip/ata.h>
-
-#define ATA_DEBUG 0
-
-#if ATA_DEBUG
-#include <stdio.h>
-bool ata_trace;
-#define ata_printf if (ata_trace) printf
-#endif
-
-#if CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE
-#include <rtems/irq.h>
-#define ATA_IRQ_CHAIN_MAX_CNT 4 /* support up to 4 ATA devices */
-typedef struct {
- rtems_irq_number name;
- rtems_chain_control irq_chain;
-} ata_irq_chain_t;
-
-ata_irq_chain_t ata_irq_chain[ATA_IRQ_CHAIN_MAX_CNT];
-int ata_irq_chain_cnt = 0;
-#endif
-
-static rtems_id ata_lock;
-static void
-rtems_ata_lock (void)
-{
- rtems_status_code sc = rtems_semaphore_obtain (ata_lock,
- RTEMS_WAIT,
- RTEMS_NO_TIMEOUT);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
-}
-
-static void
-rtems_ata_unlock (void)
-{
- rtems_status_code sc = rtems_semaphore_release (ata_lock);
- if (sc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
-}
-
-#define RTEMS_ATA_LOCK_ATTRIBS \
- (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | \
- RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
-
-/* FIXME: case if ATA device is FLASH device need more attention */
-#undef ATA_DEV_IS_FLASH_DISK
-
-/* Array indexed by controllers minor number */
-static ata_ide_ctrl_t ata_ide_ctrls[IDE_CTRL_MAX_MINOR_NUMBER];
-
-/*
- * Mapping from ATA-minor numbers to
- * controller-minor and device on this controller.
- */
-static ata_ide_dev_t ata_devs[2 * IDE_CTRL_MAX_MINOR_NUMBER];
-static int ata_devs_number;
-
-/* Flag meaning that ATA driver has already been initialized */
-static bool ata_initialized = false;
-
-
-/* task and queue used for asynchronous I/O operations */
-static rtems_id ata_task_id;
-static rtems_id ata_queue_id;
-
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
-/* Mapping of interrupt vectors to devices */
-static rtems_chain_control ata_int_vec[ATA_MAX_RTEMS_INT_VEC_NUMBER + 1];
-#endif
-
-static void
-ata_process_request(rtems_device_minor_number ctrl_minor);
-
-static void
-ata_add_to_controller_queue(rtems_device_minor_number ctrl_minor,
- ata_req_t *areq);
-
-/*
- * read/write, open/close and ioctl are provided by general block device
- * driver. Only initialization and ata-specific ioctl are here.
- */
-
-/* ata_io_data_request --
- * Form read/write request for an ATA device and enqueue it to
- * IDE controller.
- *
- * PARAMETERS:
- * device - device identifier
- * req - read/write request from block device driver
- *
- * RETURNS:
- * RTEMS_SUCCESSFUL on success, or error code if
- * error occured
- */
-static rtems_status_code
-ata_io_data_request(dev_t device, rtems_blkdev_request *req)
-{
- ata_req_t *areq; /* ATA request */
- rtems_device_minor_number rel_minor; /* relative minor which indexes
- * ata_devs array
- */
- rtems_device_minor_number ctrl_minor;
- uint8_t dev;
-
- rel_minor = (rtems_filesystem_dev_minor_t(device)) /
- ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
-
- /* get controller which serves the ATA device */
- ctrl_minor = ata_devs[rel_minor].ctrl_minor;
-
- /* get ATA device identifier (0 or 1) */
- dev = ata_devs[rel_minor].device;
-
- areq = malloc(sizeof(ata_req_t));
- if (areq == NULL)
- {
- rtems_blkdev_request_done(req, RTEMS_NO_MEMORY);
- return RTEMS_SUCCESSFUL;
- }
-
- areq->breq = req;
- areq->cnt = req->bufnum;
- areq->cbuf = 0;
- areq->pos = 0;
-
- /* set up registers masks */
- areq->regs.to_write = ATA_REGISTERS_POSITION;
- areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
-
- /* choose device on the controller for which the command will be issued */
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] =
- (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
-
- /* Find ATA command and its type */
- if (ATA_DEV_INFO(ctrl_minor, dev).mode_active & ATA_MODES_DMA)
- {
- /* XXX: never has been tested */
- areq->type = ATA_COMMAND_TYPE_DMA;
- if (req->req == RTEMS_BLKDEV_REQ_READ)
- areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_READ_DMA;
- else
- areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_WRITE_DMA;
- }
- else
- {
- if (req->req == RTEMS_BLKDEV_REQ_READ)
- {
- areq->type = ATA_COMMAND_TYPE_PIO_IN;
- areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_READ_SECTORS;
-#if ATA_DEBUG
- ata_printf("ata_io_data_request: type: READ: %lu, %lu cmd:%02x\n",
- req->bufs[0].block, req->bufnum,
- areq->regs.regs[IDE_REGISTER_COMMAND]);
-#endif
- }
- else
- {
- areq->type = ATA_COMMAND_TYPE_PIO_OUT;
- areq->regs.regs[IDE_REGISTER_COMMAND] = ATA_COMMAND_WRITE_SECTORS;
-#if ATA_DEBUG
- ata_printf("ata_io_data_request: type: WRITE: %lu, %lu cmd:%02x\n",
- req->bufs[0].block, req->bufnum,
- areq->regs.regs[IDE_REGISTER_COMMAND]);
-#endif
- }
- }
-
- /*
- * Fill position registers
- */
- if (ATA_DEV_INFO(ctrl_minor, dev).lba_avaible)
- {
- uint32_t start = req->bufs[0].block;
- areq->regs.regs[IDE_REGISTER_LBA0] = (uint8_t)start;
- areq->regs.regs[IDE_REGISTER_LBA1] = (uint8_t)(start >> 8);
- areq->regs.regs[IDE_REGISTER_LBA2] = (uint8_t)(start >> 16);
- /* Set as the head register write above */
- areq->regs.regs[IDE_REGISTER_LBA3] |= (uint8_t) (start >> 24);
- areq->regs.regs[IDE_REGISTER_LBA3] |= IDE_REGISTER_LBA3_L;
- }
- else
- {
- uint32_t count = req->bufs[0].block;
-
- areq->regs.regs[IDE_REGISTER_SECTOR_NUMBER] =
- (count % ATA_DEV_INFO(ctrl_minor, dev).sectors) + 1;
-
- /* now count = number of tracks: */
- count /= ATA_DEV_INFO(ctrl_minor, dev).sectors;
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
- (count / ATA_DEV_INFO(ctrl_minor, dev).cylinders);
-
- /* now count = number of cylinders */
- count %= ATA_DEV_INFO(ctrl_minor, dev).cylinders;
- areq->regs.regs[IDE_REGISTER_CYLINDER_LOW] = (uint8_t)count;
- areq->regs.regs[IDE_REGISTER_CYLINDER_HIGH] = (uint8_t)(count >> 8);
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &=
- ~IDE_REGISTER_DEVICE_HEAD_L;
- }
-
- /*
- * Fill sector count register. We have a number of buffers (bufnum) which
- * can be of a specific length (bufs[0].length / ATA_SECTOR_SIZE).
- */
- areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] =
- areq->breq->bufnum * (areq->breq->bufs[0].length / ATA_SECTOR_SIZE);
-
- /* add request to the queue of awaiting requests to the controller */
- ata_add_to_controller_queue(ctrl_minor, areq);
-
- return RTEMS_SUCCESSFUL;
-}
-
-/* ata_non_data_request --
- * Form and serve request of NON DATA type for an ATA device.
- * Processing of NON DATA request is SYNChronous operation.
- *
- * PARAMETERS:
- * device - device identifier
- * cmd - command
- * argp - arguments for command
- *
- * RETURNS:
- * RTEMS_SUCCESSFUL on success, or error code if
- * error occured
- */
-static rtems_status_code
-ata_non_data_request(dev_t device, uint32_t cmd, void *argp)
-{
- rtems_status_code rc;
- ata_req_t *areq; /* ATA request */
- rtems_device_minor_number rel_minor; /* relative minor which indexes
- * ata_devs array
- */
- rtems_device_minor_number ctrl_minor;
- uint8_t dev;
- ata_queue_msg_t msg;
-
- rel_minor = (rtems_filesystem_dev_minor_t(device)) /
- ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
-
- /* get controller which serves the ATA device */
- ctrl_minor = ata_devs[rel_minor].ctrl_minor;
-
- /* get ATA device identifier (0 or 1) */
- dev = ata_devs[rel_minor].device;
-
- /* form the request */
- areq = malloc(sizeof(ata_req_t));
- if (areq == NULL)
- {
- return RTEMS_NO_MEMORY;
- }
- memset(areq, 0, sizeof(ata_req_t));
-
- areq->type = ATA_COMMAND_TYPE_NON_DATA;
- areq->regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] |=
- (dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS);
- areq->breq = NULL;
- areq->regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
-
- /*
- * depending on command fill command register and additional registers
- * which are needed for command execution
- */
- switch(cmd)
- {
- case ATAIO_SET_MULTIPLE_MODE:
- areq->regs.regs[IDE_REGISTER_COMMAND] =
- ATA_COMMAND_SET_MULTIPLE_MODE;
- areq->regs.to_write |=
- ATA_REGISTERS_VALUE(IDE_REGISTER_SECTOR_COUNT);
- areq->regs.regs[IDE_REGISTER_SECTOR_COUNT] = *(uint8_t*)argp;
- break;
-
- default:
- free(areq);
- return RTEMS_INVALID_NUMBER;
- break;
- }
-
- rc = rtems_semaphore_create(rtems_build_name('I', 'D', 'E', 'S'),
- 0,
- RTEMS_FIFO | RTEMS_COUNTING_SEMAPHORE |
- RTEMS_NO_INHERIT_PRIORITY |
- RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL,
- 0,
- &(areq->sema));
- if (rc != RTEMS_SUCCESSFUL)
- {
- free(areq);
- return rc;
- }
-
- ata_add_to_controller_queue(ctrl_minor, areq);
-
- /* wait for request processing... */
- rc = rtems_semaphore_obtain(areq->sema, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
- if (rc != RTEMS_SUCCESSFUL)
- {
- free(areq);
- return rc;
- }
-
- rtems_semaphore_delete(areq->sema);
-
- /*
- * if no error occurred and if necessary, update internal ata driver data
- * structures to reflect changes (in device configuration, for example)
- */
- if (areq->status == RTEMS_SUCCESSFUL)
- {
- switch(cmd)
- {
- case ATAIO_SET_MULTIPLE_MODE:
- /* invalid operation now */
- default:
- rc = RTEMS_INVALID_NUMBER;
- break;
- }
- }
- else
- {
- /* XXX: should be correct error processing: for ex, may be
- * ABRT and then we should return RTEMS_NOT_IMPLEMENTED
- */
- rc = RTEMS_IO_ERROR;
- }
-
- /* tell ata driver that controller ready to serve next request */
- ATA_SEND_EVT(msg, ATA_MSG_SUCCESS_EVT, ctrl_minor, 0);
-
- return rc;
-}
-
-/* ata_process_request --
- * Get first request from controller's queue and process it.
- *
- * PARAMETERS:
- * ctrl_minor - controller identifier
- *
- * RETURNS:
- * NONE
- */
-static void
-ata_process_request(rtems_device_minor_number ctrl_minor)
-{
- ata_req_t *areq;
- uint16_t byte; /* emphasize that only 8 low bits is meaningful */
- ata_queue_msg_t msg;
- uint8_t i;
-#if 0
- uint8_t dev;
-#endif
- uint16_t val;
- ISR_Level level;
-
- /* if no requests to controller then do nothing */
- if (rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
- return;
-
- /* get first request in the controller's queue */
- _ISR_Local_disable(level);
- areq = (ata_req_t *)rtems_chain_first(&ata_ide_ctrls[ctrl_minor].reqs);
- _ISR_Local_enable(level);
-
-#if 0
- /* get ATA device identifier (0 or 1) */
- dev = areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
- IDE_REGISTER_DEVICE_HEAD_DEV;
-#endif
-
- /* execute device select protocol */
- ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD,
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
-
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
- } while ((byte & IDE_REGISTER_STATUS_BSY) ||
- (!(byte & IDE_REGISTER_STATUS_DRDY)));
-
- /* fill in all necessary registers on the controller */
- for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
- {
- uint32_t reg = (1 << i);
- if (areq->regs.to_write & reg)
- ide_controller_write_register(ctrl_minor, i, areq->regs.regs[i]);
- }
-
-#if ATA_DEBUG
- ata_printf("ata_process_request: type: %d\n", areq->type);
-#endif
-
- /* continue to execute ATA protocols depending on type of request */
- if (areq->type == ATA_COMMAND_TYPE_PIO_OUT)
- {
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
- &byte);
- } while (byte & IDE_REGISTER_STATUS_BSY);
-
- if (byte & IDE_REGISTER_STATUS_DRQ)
- {
- if (areq->cnt)
- {
- int ccbuf = areq->cbuf;
- ide_controller_write_data_block(ctrl_minor,
- areq->breq->bufs[0].length * areq->cnt,
- areq->breq->bufs, &areq->cbuf,
- &areq->pos);
- ccbuf = areq->cbuf - ccbuf;
- areq->cnt -= ccbuf;
- }
- }
- else
- {
- if (IDE_Controller_Table[ctrl_minor].int_driven == false)
- {
- ide_controller_read_register(
- ctrl_minor,
- IDE_REGISTER_ALTERNATE_STATUS_OFFSET,
- &val);
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
- &val);
-
- ATA_SEND_EVT(msg, ATA_MSG_ERROR_EVT, ctrl_minor,
- RTEMS_IO_ERROR);
- }
- }
- }
-
- if (IDE_Controller_Table[ctrl_minor].int_driven == false)
- {
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
- &byte);
- } while (byte & IDE_REGISTER_STATUS_BSY);
-
- ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
- }
-}
-
-/* ata_request_done --
- * Extract request from controller queue, execute callback if necessary
- * and process next request for the controller.
- *
- * PARAMETERS:
- * areq - ATA request
- * ctrl_minor - controller identifier
- * status - status with which request has been done
- * error - error, if status != RTEMS_SUCCESSFUL
- *
- * RETURNS:
- * NONE
- */
-static inline void
-ata_request_done(ata_req_t *areq, rtems_device_minor_number ctrl_minor,
- rtems_status_code status)
-{
- assert(areq);
-
-#if ATA_DEBUG
- ata_printf("ata_request_done: entry\n");
-#endif
-
- ATA_EXEC_CALLBACK(areq, status);
- rtems_chain_extract(&areq->link);
-
- if (!rtems_chain_is_empty(&ata_ide_ctrls[ctrl_minor].reqs))
- {
- free(areq);
- ata_process_request(ctrl_minor);
- return;
- }
-
- free(areq);
-
-#if ATA_DEBUG
- ata_printf("ata_request_done: exit\n");
-#endif
-}
-
-/* ata_non_data_request_done --
- * Set up request status and release request's semaphore.
- *
- * PARAMETERS:
- * areq - ATA request
- * ctrl_minor - controller identifier
- * status - status with which request has been done
- * error - error, if status != RTEMS_SUCCESSFUL
- *
- * RETURNS:
- * NONE
- */
-static inline void
-ata_non_data_request_done(ata_req_t *areq,
- rtems_device_minor_number ctrl_minor,
- rtems_status_code status, int info)
-{
-#if ATA_DEBUG
- ata_printf("ata_non_data_request_done: entry\n");
-#endif
-
- areq->status = status;
- areq->info = info;
- rtems_semaphore_release(areq->sema);
-}
-
-
-/* ata_add_to_controller_queue --
- * Add request to the controller's queue.
- *
- * PARAMETERS:
- * ctrl_minor - controller identifier
- * areq - ATA request
- *
- * RETURNS:
- * NONE
- */
-static void
-ata_add_to_controller_queue(rtems_device_minor_number ctrl_minor,
- ata_req_t *areq)
-{
- rtems_ata_lock();
-
- rtems_chain_append(&ata_ide_ctrls[ctrl_minor].reqs, &areq->link);
- if (rtems_chain_has_only_one_node(&ata_ide_ctrls[ctrl_minor].reqs))
- {
-
- ata_queue_msg_t msg;
-
-#if ATA_DEBUG_DOES_NOT_WORK_WITH_QEMU
- uint16_t val;
- /*
- * read IDE_REGISTER_ALTERNATE_STATUS instead IDE_REGISTER_STATUS
- * to prevent clearing of pending interrupt
- */
- ide_controller_read_register(ctrl_minor,
- IDE_REGISTER_ALTERNATE_STATUS,
- &val);
- if (val & IDE_REGISTER_STATUS_BSY)
- return;
-#endif
- ATA_SEND_EVT(msg, ATA_MSG_PROCESS_NEXT_EVT, ctrl_minor, 0);
- }
-
- rtems_ata_unlock();
-}
-
-
-/* ata_interrupt_handler --
- * ATA driver interrrupt handler. If interrrupt happend it mapped it to
- * controller (controllerS, if a number of controllers share one int line)
- * and generates ATA event(s).
- *
- * PARAMETERS:
- * vec - interrupt vector
- *
- * RETURNS:
- * NONE
- */
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
-static rtems_isr ata_interrupt_handler(rtems_vector_number vec)
-{
- rtems_chain_node *the_node = rtems_chain_first(&ata_int_vec[vec]);
- ata_queue_msg_t msg;
- uint16_t byte; /* emphasize that only 8 low bits is meaningful */
-
- for ( ; !rtems_chain_is_tail(&ata_int_vec[vec], the_node) ; )
- {
- /* if (1) - is temporary hack - currently I don't know how to identify
- * controller which asserted interrupt if few controllers share one
- * interrupt line
- */
- if (1)
- {
- msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
- ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
- &byte);
- ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
- }
- the_node = the_node->next;
- }
-}
-#else
-static void ata_interrupt_handler(rtems_irq_hdl_param handle)
-{
- uintptr_t ata_irq_chain_index = (uintptr_t) handle;
- rtems_chain_node *the_node =
- rtems_chain_last(&ata_irq_chain[ata_irq_chain_index].irq_chain);
- ata_queue_msg_t msg;
- uint16_t byte; /* emphasize that only 8 low bits is meaningful */
-
-
- for ( ; !rtems_chain_is_tail(&ata_irq_chain[ata_irq_chain_index].irq_chain,
- the_node) ; )
- {
- /* if (1) - is temporary hack - currently I don't know how to identify
- * controller which asserted interrupt if few controllers share one
- * interrupt line
- */
- if (1)
- {
- msg.ctrl_minor = ((ata_int_st_t *)the_node)->ctrl_minor;
- ide_controller_read_register(msg.ctrl_minor, IDE_REGISTER_STATUS,
- &byte);
- ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, msg.ctrl_minor, 0);
- }
- the_node = the_node->next;
- }
-}
-
-static void ata_interrupt_on(const rtems_irq_connect_data *ptr)
- {
-
- /* enable ATA device interrupt */
- ide_controller_write_register(0,
- IDE_REGISTER_DEVICE_CONTROL_OFFSET,
- 0x00
- );
- }
-
-
-static void ata_interrupt_off(const rtems_irq_connect_data *ptr)
- {
-
- /* disable ATA device interrupt */
- ide_controller_write_register(0,
- IDE_REGISTER_DEVICE_CONTROL_OFFSET,
- IDE_REGISTER_DEVICE_CONTROL_nIEN
- );
- }
-
-
-static int ata_interrupt_isOn(const rtems_irq_connect_data *ptr)
- {
- uint16_t byte; /* emphasize that only 8 low bits is meaningful */
-
- /* return int. status od ATA device */
- ide_controller_read_register(0,
- IDE_REGISTER_DEVICE_CONTROL_OFFSET,
- &byte
- );
-
- return !(byte & IDE_REGISTER_DEVICE_CONTROL_nIEN);
- }
-
-
-static rtems_irq_connect_data ata_irq_data =
- {
-
- 0, /* filled out before use... */
- ata_interrupt_handler,/* filled out before use... */
- NULL,
- ata_interrupt_on,
- ata_interrupt_off,
- ata_interrupt_isOn
- };
-#endif
-
-/* ata_pio_in_protocol --
- * ATA PIO_IN protocol implementation, see specification
- *
- * PARAMETERS:
- * ctrl_minor - controller identifier
- * areq - ATA request
- *
- * RETURNS:
- * NONE
- */
-static inline void
-ata_pio_in_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
-{
- uint16_t val;
-#if 0
- uint8_t dev;
-#endif
- ata_queue_msg_t msg;
-
-#if 0
- dev = areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
- IDE_REGISTER_DEVICE_HEAD_DEV;
-#endif
-
- if (areq->cnt)
- {
- int ccbuf = areq->cbuf;
- ide_controller_read_data_block(ctrl_minor,
- areq->breq->bufs[0].length * areq->cnt,
- areq->breq->bufs, &areq->cbuf, &areq->pos);
- ccbuf = areq->cbuf - ccbuf;
- areq->cnt -= ccbuf;
- }
-
- if (areq->cnt == 0)
- {
- ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
- }
- else if (IDE_Controller_Table[ctrl_minor].int_driven == false)
- {
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
- } while (val & IDE_REGISTER_STATUS_BSY);
-
- ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
- }
-}
-
-/* ata_pio_out_protocol --
- * ATA PIO_OUT protocol implementation, see specification
- *
- * PARAMETERS:
- * ctrl_minor - controller identifier
- * areq - ATA request
- *
- * RETURNS:
- * NONE
- */
-static inline void
-ata_pio_out_protocol(rtems_device_minor_number ctrl_minor, ata_req_t *areq)
-{
- uint16_t val;
-#if 0
- uint8_t dev;
-#endif
- ata_queue_msg_t msg;
-
-#if ATA_DEBUG
- ata_printf("ata_pio_out_protocol:\n");
-#endif
-
-#if 0
- dev = areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
- IDE_REGISTER_DEVICE_HEAD_DEV;
-#endif
-
- if (areq->cnt == 0)
- {
- ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
- }
- else
- {
- if (areq->cnt)
- {
- int ccbuf = areq->cbuf;
- ide_controller_write_data_block(ctrl_minor,
- areq->breq->bufs[0].length * areq->cnt,
- areq->breq->bufs, &areq->cbuf,
- &areq->pos);
- ccbuf = areq->cbuf - ccbuf;
- areq->cnt -= ccbuf;
- }
- if (IDE_Controller_Table[ctrl_minor].int_driven == false)
- {
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
- &val);
- } while (val & IDE_REGISTER_STATUS_BSY);
-
- ATA_SEND_EVT(msg, ATA_MSG_GEN_EVT, ctrl_minor, 0);
- }
- }
-}
-
-/* ata_queue_task --
- * Task which manages ATA driver events queue.
- *
- * PARAMETERS:
- * arg - ignored
- *
- * RETURNS:
- * NONE
- *
- * NOTES:
- * should be non-preemptive
- */
-static rtems_task
-ata_queue_task(rtems_task_argument arg)
-{
- ata_queue_msg_t msg;
- size_t size;
- ata_req_t *areq;
- rtems_device_minor_number ctrl_minor;
- uint16_t val;
- uint16_t val1;
- rtems_status_code rc;
- ISR_Level level;
-
- rtems_ata_lock();
-
- while (1)
- {
- rtems_ata_unlock();
-
- /* get event which has happend */
- rc = rtems_message_queue_receive(ata_queue_id, &msg, &size, RTEMS_WAIT,
- RTEMS_NO_TIMEOUT);
- if (rc != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
-
- /* get controller on which event has happend */
- ctrl_minor = msg.ctrl_minor;
-
- rtems_ata_lock();
-
- /* get current request to the controller */
- _ISR_Local_disable(level);
- areq = (ata_req_t *)rtems_chain_first(&ata_ide_ctrls[ctrl_minor].reqs);
- _ISR_Local_enable(level);
-
- switch(msg.type)
- {
- case ATA_MSG_PROCESS_NEXT_EVT:
- /* process next request in the controller queue */
- ata_process_request(ctrl_minor);
- break;
-
- case ATA_MSG_SUCCESS_EVT:
- /*
- * finish processing of current request with successful
- * status and start processing of the next request in the
- * controller queue
- */
- ata_request_done(areq, ctrl_minor, RTEMS_SUCCESSFUL);
- break;
-
- case ATA_MSG_ERROR_EVT:
- /*
- * finish processing of current request with error
- * status and start processing of the next request in the
- * controller queue
- */
- ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
- break;
-
- case ATA_MSG_GEN_EVT:
- /*
- * continue processing of the current request to the
- * controller according to current request state and
- * ATA protocol
- */
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS,
- &val);
- /* process error case */
- if (val & IDE_REGISTER_STATUS_ERR)
- {
- ide_controller_read_register(ctrl_minor,
- IDE_REGISTER_ERROR,
- &val);
- if (val & (IDE_REGISTER_ERROR_UNC |
- IDE_REGISTER_ERROR_ICRC |
- IDE_REGISTER_ERROR_IDNF |
- IDE_REGISTER_ERROR_NM |
- IDE_REGISTER_ERROR_MED))
- {
- if (areq->type == ATA_COMMAND_TYPE_NON_DATA)
- ata_non_data_request_done(areq, ctrl_minor,
- RTEMS_UNSATISFIED,
- RTEMS_IO_ERROR);
- else
- ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
- break;
- }
- }
-
- switch(areq->type)
- {
- case ATA_COMMAND_TYPE_PIO_IN:
- ata_pio_in_protocol(ctrl_minor, areq);
- break;
-
- case ATA_COMMAND_TYPE_PIO_OUT:
- ata_pio_out_protocol(ctrl_minor, areq);
- break;
-
- case ATA_COMMAND_TYPE_NON_DATA:
- ide_controller_read_register(ctrl_minor,
- IDE_REGISTER_ERROR,
- &val1);
- ata_non_data_request_done(areq, ctrl_minor,
- RTEMS_SUCCESSFUL,
- val1);
- break;
-
- default:
-#if ATA_DEBUG
- ata_printf("ata_queue_task: non-supported command type\n");
-#endif
- ata_request_done(areq, ctrl_minor, RTEMS_IO_ERROR);
- break;
- }
- break;
-
- default:
-#if ATA_DEBUG
- ata_printf("ata_queue_task: internal error\n");
- rtems_task_delete (RTEMS_SELF);
-#endif
- rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
- break;
- }
- }
-}
-
-/* ata_ioctl --
- * ATA driver ioctl interface.
- *
- * PARAMETERS:
- * device - device identifier
- * cmd - command
- * argp - arguments
- *
- * RETURNS:
- * depend on 'cmd'
- */
-static int
-ata_ioctl(rtems_disk_device *dd, uint32_t cmd, void *argp)
-{
- dev_t device = rtems_disk_get_device_identifier(dd);
- rtems_status_code status;
- rtems_device_minor_number rel_minor;
-
- rel_minor = (rtems_filesystem_dev_minor_t(device)) /
- ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE;
-
- /*
- * in most cases this means that device 'device' is not an registred ATA
- * device
- */
- if (ata_devs[rel_minor].device == ATA_UNDEFINED_VALUE)
- {
- errno = ENODEV;
- return -1;
- }
-
- switch (cmd)
- {
- case RTEMS_BLKIO_REQUEST:
- status = ata_io_data_request(device, (rtems_blkdev_request *)argp);
- break;
-
- case ATAIO_SET_MULTIPLE_MODE:
- status = ata_non_data_request(device, cmd, argp);
- break;
-
- case RTEMS_BLKIO_CAPABILITIES:
- *((uint32_t*) argp) = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
- status = RTEMS_SUCCESSFUL;
- break;
-
- default:
- return rtems_blkdev_ioctl (dd, cmd, argp);
- break;
- }
-
- if (status != RTEMS_SUCCESSFUL)
- {
- errno = EIO;
- return -1;
- }
- return 0;
-}
-
-static void ata_execute_device_diagnostic(
- rtems_device_minor_number ctrl_minor,
- uint16_t *sector_buffer
-)
-{
-#if ATA_EXEC_DEVICE_DIAGNOSTIC
- ata_req_t areq;
- blkdev_request1 breq;
-
- ata_breq_init(&breq, sector_buffer);
-
- /*
- * Issue EXECUTE DEVICE DIAGNOSTIC ATA command for explore is
- * there any ATA device on the controller.
- *
- * This command may fail and it assumes we have a master device and may
- * be a slave device. I think the identify command will handle
- * detection better than this method.
- */
- memset(&areq, 0, sizeof(ata_req_t));
- areq.type = ATA_COMMAND_TYPE_NON_DATA;
- areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
- areq.regs.regs[IDE_REGISTER_COMMAND] =
- ATA_COMMAND_EXECUTE_DEVICE_DIAGNOSTIC;
- areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_ERROR);
-
- areq.breq = (rtems_blkdev_request *)&breq;
-
- /*
- * Process the request. Special processing of requests on
- * initialization phase is needed because at this moment there
- * is no multitasking enviroment
- */
- ata_process_request_on_init_phase(ctrl_minor, &areq);
-
- /*
- * check status of I/O operation
- */
- if (breq.req.status == RTEMS_SUCCESSFUL)
- {
- /* disassemble returned diagnostic codes */
- if (areq.info == ATA_DEV0_PASSED_DEV1_PASSED_OR_NOT_PRSNT)
- {
- printk("ATA: ctrl:%d: primary, secondary\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor,0).present = true;
- ATA_DEV_INFO(ctrl_minor,1).present = true;
- }
- else if (areq.info == ATA_DEV0_PASSED_DEV1_FAILED)
- {
- printk("ATA: ctrl:%d: primary\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor,0).present = true;
- ATA_DEV_INFO(ctrl_minor,1).present = false;
- }
- else if (areq.info < ATA_DEV1_PASSED_DEV0_FAILED)
- {
- printk("ATA: ctrl:%d: secondary\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor,0).present = false;
- ATA_DEV_INFO(ctrl_minor,1).present = true;
- }
- else
- {
- printk("ATA: ctrl:%d: none\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor, 0).present = false;
- ATA_DEV_INFO(ctrl_minor, 1).present = false;
- }
-
- /* refine the returned codes */
- if (ATA_DEV_INFO(ctrl_minor, 1).present)
- {
- uint16_t ec = 0;
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &ec);
- if (ec & ATA_DEV1_PASSED_DEV0_FAILED)
- {
- printk("ATA: ctrl:%d: secondary inforced\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor, 1).present = true;
- }
- else
- {
- printk("ATA: ctrl:%d: secondary removed\n", ctrl_minor);
- ATA_DEV_INFO(ctrl_minor, 1).present = false;
- }
- }
- }
- else
-#endif
- {
- ATA_DEV_INFO(ctrl_minor, 0).present = true;
- ATA_DEV_INFO(ctrl_minor,1).present = true;
- }
-}
-
-/*
- * ata_initialize --
- * Initializes all ATA devices found on initialized IDE controllers.
- *
- * PARAMETERS:
- * major - device major number
- * minor - device minor number
- * args - arguments
- *
- * RETURNS:
- * RTEMS_SUCCESSFUL on success, or error code if
- * error occured
- */
-rtems_device_driver
-rtems_ata_initialize(rtems_device_major_number major,
- rtems_device_minor_number minor_arg,
- void *args)
-{
- uint32_t ctrl_minor;
- rtems_status_code status;
- uint16_t *buffer;
- int i, dev = 0;
- char name[ATA_MAX_NAME_LENGTH];
- dev_t device;
- ata_int_st_t *int_st;
-
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
- rtems_isr_entry old_isr;
-#else
- int ata_irq_chain_use;
-#endif
-
- if (ata_initialized)
- return RTEMS_SUCCESSFUL;
-
- /* initialization of disk devices library */
- status = rtems_disk_io_initialize();
- if (status != RTEMS_SUCCESSFUL)
- return status;
-
- status = rtems_semaphore_create (rtems_build_name ('A', 'T', 'A', 'L'),
- 1, RTEMS_ATA_LOCK_ATTRIBS, 0,
- &ata_lock);
- if (status != RTEMS_SUCCESSFUL)
- return status;
-
- /* create queue for asynchronous requests handling */
- status = rtems_message_queue_create(
- rtems_build_name('A', 'T', 'A', 'Q'),
- ATA_DRIVER_MESSAGE_QUEUE_SIZE,
- sizeof(ata_queue_msg_t),
- RTEMS_FIFO | RTEMS_LOCAL,
- &ata_queue_id);
- if (status != RTEMS_SUCCESSFUL)
- {
- rtems_disk_io_done();
- return status;
- }
-
- /*
- * create ATA driver task, see comments for task implementation for
- * details
- */
- status = rtems_task_create(
- rtems_build_name ('A', 'T', 'A', 'T'),
- ((rtems_ata_driver_task_priority > 0)
- ? rtems_ata_driver_task_priority
- : ATA_DRIVER_TASK_DEFAULT_PRIORITY),
- ATA_DRIVER_TASK_STACK_SIZE,
- RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
- RTEMS_INTERRUPT_LEVEL(0),
- RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
- &ata_task_id);
- if (status != RTEMS_SUCCESSFUL)
- {
- rtems_message_queue_delete(ata_queue_id);
- rtems_disk_io_done();
- return status;
- }
-
- /*
- * start ATA driver task. Actually the task will not start immediately -
- * it will start only after multitasking support will be started
- */
- status = rtems_task_start(ata_task_id, ata_queue_task, 0);
- if (status != RTEMS_SUCCESSFUL)
- {
- rtems_task_delete(ata_task_id);
- rtems_message_queue_delete(ata_queue_id);
- rtems_disk_io_done();
- return status;
- }
-
- buffer = (uint16_t*)malloc(ATA_SECTOR_SIZE);
- if (buffer == NULL)
- {
- rtems_task_delete(ata_task_id);
- rtems_message_queue_delete(ata_queue_id);
- rtems_disk_io_done();
- return RTEMS_NO_MEMORY;
- }
-
- ata_devs_number = 0;
-
- for (i = 0; i < (2 * IDE_CTRL_MAX_MINOR_NUMBER); i++)
- ata_devs[i].device = ATA_UNDEFINED_VALUE;
-
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
- /* prepare ATA driver for handling interrupt driven devices */
- for (i = 0; i < ATA_MAX_RTEMS_INT_VEC_NUMBER; i++)
- rtems_chain_initialize_empty(&ata_int_vec[i]);
-#else
- for (i = 0; i < ATA_IRQ_CHAIN_MAX_CNT; i++) {
- rtems_chain_initialize_empty(&(ata_irq_chain[i].irq_chain));
- }
-#endif
-
- /*
- * during ATA driver initialization EXECUTE DEVICE DIAGNOSTIC and
- * IDENTIFY DEVICE ATA command should be issued; for these purposes ATA
- * requests should be formed; ATA requests contain block device request,
- * so form block device request first
- */
-
- /*
- * for each presented IDE controller execute EXECUTE DEVICE DIAGNOSTIC
- * ATA command; for each found device execute IDENTIFY DEVICE ATA
- * command
- */
- for (ctrl_minor = 0; ctrl_minor < IDE_Controller_Count; ctrl_minor++)
- if (IDE_Controller_Table[ctrl_minor].status == IDE_CTRL_INITIALIZED)
- {
- rtems_chain_initialize_empty(&ata_ide_ctrls[ctrl_minor].reqs);
-
- if (IDE_Controller_Table[ctrl_minor].int_driven == true)
- {
- int_st = malloc(sizeof(ata_int_st_t));
- if (int_st == NULL)
- {
- free(buffer);
- rtems_task_delete(ata_task_id);
- rtems_message_queue_delete(ata_queue_id);
- rtems_disk_io_done();
- return RTEMS_NO_MEMORY;
- }
-
- int_st->ctrl_minor = ctrl_minor;
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
- status = rtems_interrupt_catch(
- ata_interrupt_handler,
- IDE_Controller_Table[ctrl_minor].int_vec,
- &old_isr);
-#else
- /*
- * FIXME: check existing entries. if they use the same
- * IRQ name, then append int_st to respective chain
- * otherwise, use new ata_irq_chain entry
- */
- ata_irq_chain_use = -1;
- for (i = 0;
- ((i < ata_irq_chain_cnt) &&
- (ata_irq_chain_use < 0));i++) {
- if (ata_irq_chain[i].name ==
- IDE_Controller_Table[ctrl_minor].int_vec) {
- ata_irq_chain_use = i;
- }
- }
- if (ata_irq_chain_use < 0) {
- /*
- * no match found, try to use new channel entry
- */
- if (ata_irq_chain_cnt < ATA_IRQ_CHAIN_MAX_CNT) {
- ata_irq_chain_use = ata_irq_chain_cnt++;
-
- ata_irq_chain[ata_irq_chain_use].name =
- IDE_Controller_Table[ctrl_minor].int_vec;
- ata_irq_data.name =
- IDE_Controller_Table[ctrl_minor].int_vec;
- ata_irq_data.hdl = ata_interrupt_handler;
- ata_irq_data.handle = (rtems_irq_hdl_param) (uintptr_t) ctrl_minor;
-
- status = ((0 == BSP_install_rtems_irq_handler(&ata_irq_data))
- ? RTEMS_INVALID_NUMBER
- : RTEMS_SUCCESSFUL);
- }
- else {
- status = RTEMS_TOO_MANY;
- }
- }
-#endif
- if (status != RTEMS_SUCCESSFUL)
- {
- free(int_st);
- free(buffer);
- rtems_task_delete(ata_task_id);
- rtems_message_queue_delete(ata_queue_id);
- rtems_disk_io_done();
- return status;
- }
-#if CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE
- rtems_chain_append(
- &ata_int_vec[IDE_Controller_Table[ctrl_minor].int_vec],
- &int_st->link);
-#else
- rtems_chain_append(
- &(ata_irq_chain[ata_irq_chain_use].irq_chain),
- &int_st->link);
-#endif
-
- /* disable interrupts */
- ide_controller_write_register(ctrl_minor,
- IDE_REGISTER_DEVICE_CONTROL_OFFSET,
- IDE_REGISTER_DEVICE_CONTROL_nIEN);
- }
-
- ata_execute_device_diagnostic(ctrl_minor, buffer);
-
- /* for each found ATA device obtain it configuration */
- for (dev = 0; dev < 2; dev++)
- if (ATA_DEV_INFO(ctrl_minor, dev).present)
- {
- status = ata_identify_device(
- ctrl_minor,
- dev,
- buffer,
- &ATA_DEV_INFO(ctrl_minor, dev));
- if (status != RTEMS_SUCCESSFUL)
- continue;
-
- /*
- * choose most appropriate ATA device data I/O speed supported
- * by the controller
- */
- status = ide_controller_config_io_speed(
- ctrl_minor,
- ATA_DEV_INFO(ctrl_minor, dev).modes_available);
- if (status != RTEMS_SUCCESSFUL)
- continue;
-
- /*
- * Ok, let register new ATA device in the system
- */
- ata_devs[ata_devs_number].ctrl_minor = ctrl_minor;
- ata_devs[ata_devs_number].device = dev;
-
- /* The space leaves a hole for the character. */
- strcpy(name, "/dev/hd ");
- name[7] = 'a' + 2 * ctrl_minor + dev;
-
- device = rtems_filesystem_make_dev_t(
- major,
- (ata_devs_number *
- ATA_MINOR_NUM_RESERVED_PER_ATA_DEVICE));
- status = rtems_disk_create_phys(device, ATA_SECTOR_SIZE,
- ATA_DEV_INFO(ctrl_minor, dev).lba_avaible ?
- ATA_DEV_INFO(ctrl_minor, dev).lba_sectors :
- (ATA_DEV_INFO(ctrl_minor, dev).heads *
- ATA_DEV_INFO(ctrl_minor, dev).cylinders *
- ATA_DEV_INFO(ctrl_minor, dev).sectors),
- ata_ioctl, NULL, name);
- if (status != RTEMS_SUCCESSFUL)
- {
- ata_devs[ata_devs_number].device = ATA_UNDEFINED_VALUE;
- continue;
- }
- ata_devs_number++;
- }
- if (IDE_Controller_Table[ctrl_minor].int_driven == true)
- {
- ide_controller_write_register(ctrl_minor,
- IDE_REGISTER_DEVICE_CONTROL_OFFSET,
- 0x00);
- }
- }
-
- free(buffer);
- ata_initialized = true;
- return RTEMS_SUCCESSFUL;
-}
diff --git a/c/src/libchip/ide/ata_util.c b/c/src/libchip/ide/ata_util.c
deleted file mode 100644
index 68e0f0bbe5..0000000000
--- a/c/src/libchip/ide/ata_util.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * Copyright (c) 2010 embedded brains GmbH.
- *
- * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
- * Authors: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include <libchip/ide_ctrl_io.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ata_internal.h>
-
-/* ata_process_request_on_init_phase --
- * Process the ATA request during system initialization. Request
- * processing is syncronous and doesn't use multiprocessing enviroment.
- *
- * PARAMETERS:
- * ctrl_minor - controller identifier
- * areq - ATA request
- *
- * RETURNS:
- * NONE
- */
-void
-ata_process_request_on_init_phase(rtems_device_minor_number ctrl_minor,
- ata_req_t *areq)
-{
- uint16_t byte;/* emphasize that only 8 low bits is meaningful */
- uint8_t i;
-#if 0
- uint8_t dev;
-#endif
- uint16_t val, val1;
- volatile unsigned retries;
-
- assert(areq);
-
-#if 0
- dev = areq->regs.regs[IDE_REGISTER_DEVICE_HEAD] &
- IDE_REGISTER_DEVICE_HEAD_DEV;
-#endif
-
- ide_controller_write_register(ctrl_minor, IDE_REGISTER_DEVICE_HEAD,
- areq->regs.regs[IDE_REGISTER_DEVICE_HEAD]);
-
- retries = 0;
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
- /* If device (on INIT, i.e. it should be idle) is neither
- * busy nor ready something's fishy, i.e., there is probably
- * no device present.
- * I'd like to do a proper timeout but don't know of a portable
- * timeout routine (w/o using multitasking / rtems_task_wake_after())
- */
- if ( ! (byte & (IDE_REGISTER_STATUS_BSY | IDE_REGISTER_STATUS_DRDY))) {
- retries++;
- if ( 10000 == retries ) {
- /* probably no drive connected */
- areq->breq->status = RTEMS_UNSATISFIED;
- return;
- }
- }
- } while ((byte & IDE_REGISTER_STATUS_BSY) ||
- (!(byte & IDE_REGISTER_STATUS_DRDY)));
-
- for (i=0; i< ATA_MAX_CMD_REG_OFFSET; i++)
- {
- uint32_t reg = (1 << i);
- if (areq->regs.to_write & reg)
- ide_controller_write_register(ctrl_minor, i,
- areq->regs.regs[i]);
- }
-
- do {
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &byte);
- } while (byte & IDE_REGISTER_STATUS_BSY);
-
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_STATUS, &val);
- ide_controller_read_register(ctrl_minor, IDE_REGISTER_ERROR, &val1);
-
- if (val & IDE_REGISTER_STATUS_ERR)
- {
- areq->breq->status = RTEMS_IO_ERROR;
- return;
- }
-
- switch(areq->type)
- {
- case ATA_COMMAND_TYPE_PIO_IN:
- if (areq->cnt)
- {
- int ccbuf = areq->cbuf;
- ide_controller_read_data_block(ctrl_minor,
- areq->breq->bufs[0].length * areq->cnt,
- areq->breq->bufs, &areq->cbuf,
- &areq->pos);
- ccbuf = areq->cbuf - ccbuf;
- areq->cnt -= ccbuf;
- }
- if (areq->cnt == 0)
- {
- areq->breq->status = RTEMS_SUCCESSFUL;
- }
- else
- {
- /*
- * this shouldn't happend on the initialization
- * phase!
- */
- rtems_fatal_error_occurred(RTEMS_INTERNAL_ERROR);
- }
- break;
-
- case ATA_COMMAND_TYPE_NON_DATA:
- areq->breq->status = RTEMS_SUCCESSFUL;
- areq->info = val1;
- break;
-
- default:
- areq->breq->status = RTEMS_IO_ERROR;
- break;
- }
-}
-
-void ata_breq_init(blkdev_request1 *breq, uint16_t *sector_buffer)
-{
- memset(breq, 0, sizeof(*breq));
-
- breq->req.done_arg = breq;
- breq->req.bufnum = 1;
- breq->req.bufs [0].length = ATA_SECTOR_SIZE;
- breq->req.bufs [0].buffer = sector_buffer;
-}
-
-rtems_status_code ata_identify_device(
- rtems_device_minor_number ctrl_minor,
- int dev,
- uint16_t *sector_buffer,
- ata_dev_t *device_entry
-)
-{
- ata_req_t areq;
- blkdev_request1 breq;
-
- ata_breq_init(&breq, sector_buffer);
-
- /*
- * Issue DEVICE IDENTIFY ATA command and get device
- * configuration
- */
- memset(&areq, 0, sizeof(ata_req_t));
- areq.type = ATA_COMMAND_TYPE_PIO_IN;
- areq.regs.to_write = ATA_REGISTERS_VALUE(IDE_REGISTER_COMMAND);
- areq.regs.regs [IDE_REGISTER_COMMAND] = ATA_COMMAND_IDENTIFY_DEVICE;
- areq.regs.to_read = ATA_REGISTERS_VALUE(IDE_REGISTER_STATUS);
- areq.breq = (rtems_blkdev_request *)&breq;
- areq.cnt = breq.req.bufnum;
- areq.regs.regs [IDE_REGISTER_DEVICE_HEAD] |=
- dev << IDE_REGISTER_DEVICE_HEAD_DEV_POS;
-
- /*
- * Process the request. Special processing of requests on
- * initialization phase is needed because at this moment there
- * is no multitasking enviroment
- */
- ata_process_request_on_init_phase(ctrl_minor, &areq);
-
- /* check status of I/O operation */
- if (breq.req.status != RTEMS_SUCCESSFUL) {
- return RTEMS_IO_ERROR;
- }
-
- /*
- * Parse returned device configuration and fill in ATA internal
- * device info structure
- */
- device_entry->cylinders =
- CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_CLNDS]);
- device_entry->heads =
- CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_HEADS]);
- device_entry->sectors =
- CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_CURR_LOG_SECS]);
- device_entry->lba_sectors =
- CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS1]);
- device_entry->lba_sectors <<= 16;
- device_entry->lba_sectors += CF_LE_W(sector_buffer[ATA_IDENT_WORD_NUM_OF_USR_SECS0]);
- device_entry->lba_avaible =
- (CF_LE_W(sector_buffer[ATA_IDENT_WORD_CAPABILITIES]) >> 9) & 0x1;
-
- if ((CF_LE_W(sector_buffer[ATA_IDENT_WORD_FIELD_VALIDITY]) &
- ATA_IDENT_BIT_VALID) == 0) {
- /* no "supported modes" info -> use default */
- device_entry->mode_active = ATA_MODES_PIO3;
- } else {
- device_entry->modes_available =
- ((CF_LE_W(sector_buffer[64]) & 0x1) ? ATA_MODES_PIO3 : 0) |
- ((CF_LE_W(sector_buffer[64]) & 0x2) ? ATA_MODES_PIO4 : 0) |
- ((CF_LE_W(sector_buffer[63]) & 0x1) ? ATA_MODES_DMA0 : 0) |
- ((CF_LE_W(sector_buffer[63]) & 0x2) ?
- ATA_MODES_DMA0 | ATA_MODES_DMA1 : 0) |
- ((CF_LE_W(sector_buffer[63]) & 0x4) ?
- ATA_MODES_DMA0 | ATA_MODES_DMA1 | ATA_MODES_DMA2 : 0);
- if (device_entry->modes_available == 0) {
- return RTEMS_IO_ERROR;
- }
- }
-
- return RTEMS_SUCCESSFUL;
-}
diff --git a/c/src/libchip/ide/ide_controller.c b/c/src/libchip/ide/ide_controller.c
deleted file mode 100644
index 912f9e3157..0000000000
--- a/c/src/libchip/ide/ide_controller.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * ide_controller.c
- *
- * This is generic rtems driver for IDE controllers.
- *
- * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
- * Authors: Alexandra Kossovsky <sasha@oktet.ru>
- * Eugeny S. Mints <Eugeny.Mints@oktet.ru>
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- */
-
-#define IDE_CONTROLLER_TRACE 0
-
-#include <rtems/chain.h>
-#include <errno.h>
-#include <rtems/blkdev.h>
-
-#include <libchip/ide_ctrl.h>
-#include <libchip/ide_ctrl_cfg.h>
-#include <libchip/ide_ctrl_io.h>
-
-#if IDE_CONTROLLER_TRACE
-int ide_controller_trace = 1;
-#endif
-
-/*
- * ide_controller_initialize --
- * Initializes all configured IDE controllers. Controllers configuration
- * table is provided by BSP
- *
- * PARAMETERS:
- * major - device major number
- * minor_arg - device minor number
- * args - arguments
- *
- * RETURNS:
- * RTEMS_SUCCESSFUL on success, or error code if
- * error occured
- */
-rtems_device_driver
-ide_controller_initialize(rtems_device_major_number major,
- rtems_device_minor_number minor_arg,
- void *args)
-{
- unsigned long minor;
-
- /* FIXME: may be it should be done on compilation phase */
- if (IDE_Controller_Count > IDE_CTRL_MAX_MINOR_NUMBER)
- rtems_fatal_error_occurred(RTEMS_TOO_MANY);
-
- for (minor=0; minor < IDE_Controller_Count; minor++)
- {
- IDE_Controller_Table[minor].status = IDE_CTRL_NON_INITIALIZED;
-
- if ((IDE_Controller_Table[minor].probe == NULL ||
- IDE_Controller_Table[minor].probe(minor)) &&
- (IDE_Controller_Table[minor].fns->ctrl_probe == NULL ||
- IDE_Controller_Table[minor].fns->ctrl_probe(minor)))
- {
- dev_t dev;
- dev = rtems_filesystem_make_dev_t( major, minor );
- if (mknod(IDE_Controller_Table[minor].name,
- 0777 | S_IFBLK, dev ) < 0)
- rtems_fatal_error_occurred(errno);
- IDE_Controller_Table[minor].fns->ctrl_initialize(minor);
- IDE_Controller_Table[minor].status = IDE_CTRL_INITIALIZED;
- }
- }
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * ide_controller_read_data_block --
- * Read data block via controller's data register
- *
- * PARAMETERS:
- * minor - minor number of controller
- * block_size - number of bytes to read
- * bufs - set of buffers to store data
- * cbuf - number of current buffer from the set
- * pos - position inside current buffer 'cbuf'
- *
- * RETURNS:
- * NONE
- */
-void
-ide_controller_read_data_block(rtems_device_minor_number minor,
- uint32_t block_size,
- rtems_blkdev_sg_buffer *bufs,
- uint32_t *cbuf,
- uint32_t *pos)
-{
-#if IDE_CONTROLLER_TRACE
- if (ide_controller_trace)
- printk ("IDE data block read: %d:%d\n", *cbuf, bufs[*cbuf].block);
-#endif
- IDE_Controller_Table[minor].fns->ctrl_read_block(minor, block_size, bufs,
- cbuf, pos);
-}
-
-/*
- * ide_controller_write_data_block --
- * Write data block via controller's data register
- *
- * PARAMETERS:
- * minor - minor number of controller
- * block_size - number of bytes to write
- * bufs - set of buffers which store data
- * cbuf - number of current buffer from the set
- * pos - position inside current buffer 'cbuf'
- *
- * RETURNS:
- * NONE
- */
-void
-ide_controller_write_data_block(rtems_device_minor_number minor,
- uint32_t block_size,
- rtems_blkdev_sg_buffer *bufs,
- uint32_t *cbuf,
- uint32_t *pos)
-
-{
-#if IDE_CONTROLLER_TRACE
- if (ide_controller_trace)
- printk ("IDE data block write: %d:%d\n", *cbuf, bufs[*cbuf].block);
-#endif
- IDE_Controller_Table[minor].fns->ctrl_write_block(minor, block_size, bufs,
- cbuf, pos);
-}
-
-/*
- * ide_controller_read_register --
- * Read controller's register
- *
- * PARAMETERS:
- * minor - minor number of controller
- * reg - register to read
- * value - placeholder for result
- *
- * RETURNS
- * NONE
- */
-void
-ide_controller_read_register(rtems_device_minor_number minor,
- int reg,
- uint16_t *value)
-{
- IDE_Controller_Table[minor].fns->ctrl_reg_read(minor, reg, value);
-#if IDE_CONTROLLER_TRACE
- if (ide_controller_trace)
- printk ("IDE read reg: %d => %04x\n", reg, *value);
-#endif
-}
-
-/*
- * ide_controller_write_register --
- * Write controller's register
- *
- * PARAMETERS:
- * minor - minor number of controller
- * reg - register to write
- * value - value to write
- *
- * RETURNS:
- * NONE
- */
-void
-ide_controller_write_register(rtems_device_minor_number minor, int reg,
- uint16_t value)
-{
-#if IDE_CONTROLLER_TRACE
- if (ide_controller_trace)
- printk ("IDE write reg: %d => %04x\n", reg, value);
-#endif
- IDE_Controller_Table[minor].fns->ctrl_reg_write(minor, reg, value);
-}
-
-/*
- * ide_controller_config_io_speed --
- * Set controller's speed of IO operations
- *
- * PARAMETERS:
- * minor - minor number of controller
- * modes_available - speeds available
- *
- * RETURNS:
- * RTEMS_SUCCESSFUL on success, or error code if
- * error occured
- */
-rtems_status_code
-ide_controller_config_io_speed(int minor, uint16_t modes_available)
-{
- return IDE_Controller_Table[minor].fns->ctrl_config_io_speed(
- minor,
- modes_available);
-}
diff --git a/c/src/libchip/network/README b/c/src/libchip/network/README
deleted file mode 100644
index ecb996e65f..0000000000
--- a/c/src/libchip/network/README
+++ /dev/null
@@ -1,12 +0,0 @@
-This is the network interface controller portion of the libchip library.
-This directory contains the source code for reusable TCP/IP network driver
-support code. Each driver has its own configuration table and its
-chip specific attach routine must be called by a board specific
-attach routine. The board specific chip routine passes the chip
-configuration and network configuration to the resuable device driver.
-
-The reusable chip drivers do not directly access the controller.
-They access the registers on the controller via a set of
-functions which are provided by the BSP. These functions set and get
-general registers and data buffers.
-
diff --git a/c/src/libchip/network/README.3com b/c/src/libchip/network/README.3com
deleted file mode 100644
index b67061dec2..0000000000
--- a/c/src/libchip/network/README.3com
+++ /dev/null
@@ -1,3 +0,0 @@
-#
-# README.3com
-#
diff --git a/c/src/libchip/network/README.cs8900 b/c/src/libchip/network/README.cs8900
deleted file mode 100644
index ecd575230f..0000000000
--- a/c/src/libchip/network/README.cs8900
+++ /dev/null
@@ -1,26 +0,0 @@
-Target Support
-==============
-
-The target is required to provide the low level support routines as
-listed in the Configuration section of this file.
-
-The file cs8900.[ch].bsp are an example BSP files for DIMMPC target.
-
-Conditionals
-============
-CS8900_DATA_BUS_SWAPPED - XXX
-
-CS8900_TRACE - XXX
-
-CS8900_VERBOSE - XXX
-
-Todo
-====
-+ Build two versions -- one with swapped, one without.
-
-+ Document conditionals.
-
-Configuration
-=============
-See the cs8900.h header file for the documentation.
-
diff --git a/c/src/libchip/network/README.dec21140 b/c/src/libchip/network/README.dec21140
deleted file mode 100644
index f07bec7a36..0000000000
--- a/c/src/libchip/network/README.dec21140
+++ /dev/null
@@ -1,116 +0,0 @@
-This TULIP driver can be used on BSPs that support PCI bus.
-
-It can handle any DEC21140 and DEC21143 based Ethernet controller
-although the DEC21143 support has only been tested on Intel.
-
-It works on big or little endian target.
-
-The DEC21140 has been tested with powerpc/mcp750 BSP (OnBoard Ethernet
-controller) and i386/pc386 BSP (D-Link DFE-500TX Ethernet board).
-
-The DEC21143 has been tested only on the i386/pc386 using
-the Kingston KNE100TX with 21143PD chip.
-
-*****************************************************************
-******** ***************
-******** tests with ttcp benchmark for DEC driver ***************
-******** optimization ***************
-******** ***************
-*****************************************************************
-
-
-LINUX -> LINUX-ix86
-
-Transmitter :
-
-ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> genesis
-ttcp-t: 16777216 bytes in 1.87 real seconds = 8775.25 KB/sec +++
-ttcp-t: 2048 I/O calls, msec/call = 0.93, calls/sec = 1096.91
-ttcp-t: 0.0user 0.9sys 0:01real 51% 0i+0d 0maxrss 0+2pf 0+0csw
-
-Receiver :
-
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: 16777216 bytes in 1.88 real seconds = 8706.53 KB/sec +++
-ttcp-r: 10802 I/O calls, msec/call = 0.18, calls/sec = 5740.23
-ttcp-r: 0.0user 0.2sys 0:01real 13% 0i+0d 0maxrss 0+2pf 0+0csw
-
-==============================================================
-==============================================================
-==============================================================
-
-LINUX -> RTEMS-ix86 with tulip driver from pc386 bsp
-
-Transmitter :
-
-ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> neil-young-100
-ttcp-t: 16777216 bytes in 1.98 real seconds = 8294.76 KB/sec +++
-ttcp-t: 2048 I/O calls, msec/call = 0.99, calls/sec = 1036.85
-ttcp-t: 0.0user 0.1sys 0:01real 9% 0i+0d 0maxrss 0+2pf 0+0csw
-
-Receiver :
-
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: 16777216 bytes in 2.03 real seconds = 8065.14 KB/sec +++
-ttcp-r: 3088 I/O calls, msec/call = 0.67, calls/sec = 1520.09
-ttcp-r: 0.0user 2.0sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-==============================================================
-==============================================================
-==============================================================
-
-RTEMS-ix86 with tulip driver from pc386 bsp -> LINUX
-
-Transmitter :
-
-ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> 194.2.81.126
-ttcp-t: 16777216 bytes in 2.76 real seconds = 5938.77 KB/sec +++
-ttcp-t: 2048 I/O calls, msec/call = 1.38, calls/sec = 742.35
-ttcp-t: 0.0user 2.5sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-Receiver :
-
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: 16777216 bytes in 2.75 real seconds = 5948.53 KB/sec +++
-ttcp-r: 11349 I/O calls, msec/call = 0.25, calls/sec = 4120.48
-ttcp-r: 0.0user 0.1sys 0:02real 6% 0i+0d 0maxrss 0+2pf 0+0csw
-
-==============================================================
-==============================================================
-==============================================================
-
-LINUX -> RTEMS-ix86 with optimized tulip driver
-
-Transmitter :
-
-ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> neil-young-100
-ttcp-t: 16777216 bytes in 1.73 real seconds = 9470.13 KB/sec +++
-ttcp-t: 2048 I/O calls, msec/call = 0.87, calls/sec = 1183.77
-ttcp-t: 0.0user 0.1sys 0:01real 6% 0i+0d 0maxrss 0+2pf 0+0csw
-
-Receiver :
-
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: 16777216 bytes in 1.76 real seconds = 9315.33 KB/sec +++
-ttcp-r: 4558 I/O calls, msec/call = 0.40, calls/sec = 2591.51
-ttcp-r: 0.0user 1.7sys 0:01real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-==============================================================
-==============================================================
-==============================================================
-
-RTEMS-ix86 with optimized tulip driver -> LINUX
-
-Transmitter :
-
-ttcp-t: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp -> 194.2.81.126
-ttcp-t: 16777216 bytes in 2.09 real seconds = 7847.80 KB/sec +++
-ttcp-t: 2048 I/O calls, msec/call = 1.04, calls/sec = 980.98
-ttcp-t: 0.0user 2.0sys 0:02real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-Receiver :
-
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: 16777216 bytes in 2.08 real seconds = 7874.23 KB/sec +++
-ttcp-r: 11404 I/O calls, msec/call = 0.19, calls/sec = 5480.82
-ttcp-r: 0.0user 0.1sys 0:02real 8% 0i+0d 0maxrss 0+2pf 0+0csw
diff --git a/c/src/libchip/network/README.i82586 b/c/src/libchip/network/README.i82586
deleted file mode 100644
index a0990367ef..0000000000
--- a/c/src/libchip/network/README.i82586
+++ /dev/null
@@ -1 +0,0 @@
-TBD
diff --git a/c/src/libchip/network/README.open_eth b/c/src/libchip/network/README.open_eth
deleted file mode 100644
index af9d8882cf..0000000000
--- a/c/src/libchip/network/README.open_eth
+++ /dev/null
@@ -1,72 +0,0 @@
-Driver for opencores ethernet MAC - README
-------------------------------------------
-
-The device name for the driver is 'open_eth1', the attach
-function for the leon bsp is rtems_leon_open_eth_driver_attach().
-
-No cache flushing is made when a frame is received. On leon,
-this means that cache snooping must be configured in the
-vhdl model and enabled by software.
-
-TX interrupts are not used and masked in the interrupt mask
-register.
-
-For now, only 10 Mbit/s half-duplex is supported.
-100 Mbit/s operations does not work reliably, the transmitter
-locks up or skips frames. Seems to depend on the TX fifo
-implementation in the opencores MAC. Send a mail to
-jiri@gaisler.com if you know how to fix this.
-
-Tested only on leon, using the GR-PCI-XC2V board @ 40 MHz.
-Output from ttcp receiving 1 Mbyte file:
-
->>> ttcp -r -s
-ttcp-r: buflen=8192, nbuf=2048, align=16384/0, port=5001 tcp
-ttcp-r: socket
-ttcp-r: accept from 192.168.0.2
-ttcp-r: 1145339 bytes in 1.18 real seconds = 947.88 KB/sec +++
-ttcp-r: 792 I/O calls, msec/call = 1.53, calls/sec = 671.19
-ttcp-r: 0.0user 1.1sys 0:01real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-************ MBUF STATISTICS ************
-mbufs:1024 clusters: 128 free: 112
-drops: 0 waits: 0 drains: 0
- free:1007 data:17 header:0 socket:0
- pcb:0 rtable:0 htable:0 atable:0
- soname:0 soopts:0 ftable:0 rights:0
- ifaddr:0 control:0 oobdata:0
-
-************ INTERFACE STATISTICS ************
-***** open_eth1 *****
-Address:192.168.0.66 Broadcast Address:192.168.0.255
-Flags: Up Broadcast Running Simplex
-Send queue limit:50 length:0 Dropped:0
- Rx Packets:796 Rx Interrupts:796 Length:0
- Bad CRC:0 Overrun:0 Miss:0
- Tx Interrupts:0 Deferred:0 Missed Hearbeat:0
- No Carrier:0 Retransmit Limit:0 Late Collision:0
- Underrun:0 Raw output wait:0
-
-************ IP Statistics ************
- total packets received 795
- datagrams delivered to upper level 795
- total ip packets generated here 401
-
-************ TCP Statistics ************
- connections accepted 1
- connections established 1
- conn. closed (includes drops) 1
- segs where we tried to get rtt 2
- times we succeeded 2
- delayed acks sent 4
- total packets sent 401
- ack-only packets sent 6
- window update-only packets sent 394
- control (SYN|FIN|RST) packets sent 1
- total packets received 795
- packets received in sequence 792
- bytes received in sequence 1145339
- rcvd ack packets 2
- bytes acked by rcvd acks 2
- times hdr predict ok for data pkts 791
-
-
diff --git a/c/src/libchip/network/README.sonic b/c/src/libchip/network/README.sonic
deleted file mode 100644
index b2478b5571..0000000000
--- a/c/src/libchip/network/README.sonic
+++ /dev/null
@@ -1,135 +0,0 @@
-This SONIC driver does not make any attempt to support the SONIC chip
-in any of the following modes:
-
- + 16-bit
- + little endian
-
-It does not attempt to handle SONIC's older than Revision C. There is
-a bug in chips before that revision that must be handled in the driver.
-
-The configuration table should be discussed here but if you look in the
-include file for the sonic, it is reasonably obvious. :)
-
-The performance impact of transforming this driver into libchip format
-was minimal.
-
-The powerpc/dmv177 BSP used this driver and the following should
-serve as an example configuration table. This BSP was obsoleted after
-the 4.6 release series so the code is included here.
-
-======================================================================
-
-/*
- * DMV177 SONIC Configuration Information
- *
- * References:
- *
- * 1) SVME/DMV-171 Single Board Computer Documentation Package, #805905,
- * DY 4 Systems Inc., Kanata, Ontario, September, 1996.
- */
-
-#include <bsp.h>
-#include <rtems/rtems_bsdnet.h>
-#include <libchip/sonic.h>
-
-void dmv177_sonic_write_register(
- void *base,
- unsigned32 regno,
- unsigned32 value
-)
-{
- volatile unsigned32 *p = base;
-
-#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
- printf( "%p Write 0x%04x to %s (0x%02x)\n",
- &p[regno], value, SONIC_Reg_name[regno], regno );
- fflush( stdout );
-#endif
- p[regno] = value;
-}
-
-unsigned32 dmv177_sonic_read_register(
- void *base,
- unsigned32 regno
-)
-{
- volatile unsigned32 *p = base;
- unsigned32 value;
-
- value = p[regno];
-#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
- printf( "%p Read 0x%04x from %s (0x%02x)\n",
- &p[regno], value, SONIC_Reg_name[regno], regno );
- fflush( stdout );
-#endif
- return value;
-}
-
-/*
- * Default sizes of transmit and receive descriptor areas
- */
-#define RDA_COUNT 20 /* 20 */
-#define TDA_COUNT 20 /* 10 */
-
-/*
- * Default device configuration register values
- * Conservative, generic values.
- * DCR:
- * No extended bus mode
- * Unlatched bus retry
- * Programmable outputs unused
- * Asynchronous bus mode
- * User definable pins unused
- * No wait states (access time controlled by DTACK*)
- * 32-bit DMA
- * Empty/Fill DMA mode
- * Maximum Transmit/Receive FIFO
- * DC2:
- * Extended programmable outputs unused
- * Normal HOLD request
- * Packet compress output unused
- * No reject on CAM match
- */
-#define SONIC_DCR \
- (DCR_DW32 | DCR_WAIT0 | DCR_PO0 | DCR_PO1 | DCR_RFT24 | DCR_TFT28)
-#ifndef SONIC_DCR
-# define SONIC_DCR (DCR_DW32 | DCR_TFT28)
-#endif
-#ifndef SONIC_DC2
-# define SONIC_DC2 (0)
-#endif
-
-/*
- * Default location of device registers
- */
-#ifndef SONIC_BASE_ADDRESS
-# define SONIC_BASE_ADDRESS 0xF3000000
-# warning "Using default SONIC_BASE_ADDRESS."
-#endif
-
-/*
- * Default interrupt vector
- */
-#ifndef SONIC_VECTOR
-# define SONIC_VECTOR 1
-# warning "Using default SONIC_VECTOR."
-#endif
-
-sonic_configuration_t dmv177_sonic_configuration = {
- SONIC_BASE_ADDRESS, /* base address */
- SONIC_VECTOR, /* vector number */
- SONIC_DCR, /* DCR register value */
- SONIC_DC2, /* DC2 register value */
- TDA_COUNT, /* number of transmit descriptors */
- RDA_COUNT, /* number of receive descriptors */
- dmv177_sonic_write_register,
- dmv177_sonic_read_register
-};
-
-int rtems_dmv177_sonic_driver_attach(struct rtems_bsdnet_ifconfig *config)
-{
- return rtems_sonic_driver_attach( config, &dmv177_sonic_configuration );
-
-}
-
-======================================================================
diff --git a/c/src/libchip/network/README.tulipclone b/c/src/libchip/network/README.tulipclone
deleted file mode 100644
index 90332bfd61..0000000000
--- a/c/src/libchip/network/README.tulipclone
+++ /dev/null
@@ -1,101 +0,0 @@
-*****************************************************************
-******** ***************
-******** ttcp benchmark tests of dec2114x driver ***************
-******** adapted from FreeBSD's if_dc.c for RTEMS ***************
-******** by: Daron Chabot (12/15/03), ***************
-******** <daron@nucleus.usask.ca> ***************
-*****************************************************************
-
-Test Equipment:
------------------------
-- Intel 450 MHz P3's
-- RH Linux v7.3, 2.4.7-10 kernel, D-Link DFE-530TX (via-rhine)
-- RTEMS rtems-ss-20030703, pc386 BSP, Linksys LNE100TX ( actually,
-a cleverly disguised ADMtek Centaur, aka "Comet").
-- the PCs were directly connected ( RJ-45 X-over cable ) on a class C
-subnet (private)
-
-NOTE:
------------------------
-- the following lines must be added to the BSP's "bsp.h" file, or
-inserted into an application header (e.g. a "network_config.h" file, or
-similar):
-
-extern int rtems_dc_driver_attach(struct rtems_bsdnet_ifconfig *, int);
-#define BSP_DEC_NETWORK_DRIVER_NAME "tl1" /* "tl" as in "tulip-clone" */
-#define BSP_DEC_NETWORK_DRIVER_ATTACH rtems_dc_driver_attach
-
-
-**************************
-Linux Tx ----> RTEMS Rx: *
-**************************
-TRANSMITTER:
-ttcp-t: buflen=8192, nbuf=65536, align=16384/0, port=5001 tcp -> rtems
-ttcp-t: 536870912 bytes in 45.72 real seconds = 11468.54 KB/sec +++
-ttcp-t: 536870912 bytes in 6.87 CPU seconds = 76315.57 KB/cpu sec
-ttcp-t: 65536 I/O calls, msec/call = 0.71, calls/sec = 1433.57
-ttcp-t: 0.1user 6.7sys 0:45real 15% 0i+0d 0maxrss 0+2pf 0+0csw
-
-
-RECEIVER:
-ttcp-r: buflen=8192, nbuf=65536, align=16384/0, port=5001 tcp
-ttcp-r: 536870912 bytes in 45.72 real seconds = 11467.37 KB/sec +++
-ttcp-r: 536870912 bytes in 45.87 CPU seconds = 11467.37 KB/cpu sec
-ttcp-r: 370837 I/O calls, msec/call = 0.13, calls/sec = 8111.05
-ttcp-r: 0.0user 45.7sys 0:45real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-
-
-**************************
-RTEMS Tx ----> Linux Rx: *
-**************************
-TRANSMITTER:
-ttcp-t: buflen=8192, nbuf=65536, align=16384/0, port=5001 tcp ->192.168.1.1
-ttcp-t: 536870912 bytes in 46.22 real seconds = 11343.31 KB/sec +++
-ttcp-t: 536870912 bytes in 46.22 CPU seconds = 11343.31 KB/cpu sec
-ttcp-t: 65536 I/O calls, msec/call = 0.72, calls/sec = 1417.91
-ttcp-t: 0.0user 46.2sys 0:46real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-
-
-
-RECEIVER:
-ttcp-r: buflen=8192, nbuf=65536, align=16384/0, port=5001 tcp
-ttcp-r: 536870912 bytes in 46.22 real seconds = 11343.05 KB/sec +++
-ttcp-r: 536870912 bytes in 11.60 CPU seconds = 45197.24 KB/cpu sec
-ttcp-r: 356183 I/O calls, msec/call = 0.13, calls/sec = 7706.07
-ttcp-r: 0.6user 10.9sys 0:46real 25% 0i+0d 0maxrss 0+2pf 0+0csw
-
-
-
-****************************************************************************
-****************************************************************************
-****************************************************************************
-******************* Test with 40kB buffer size *****************************
-****************************************************************************
-****************************************************************************
-****************************************************************************
-
-
-**************************
-RTEMS Tx ----> Linux Rx: *
-**************************
-TRANSMITTER:
-ttcp-t: buflen=40960, nbuf=13107, align=16384/0, port=5001 tcp -> 192.168.1.1
-ttcp-t: 536862720 bytes in 46.23 real seconds = 11340.69 KB/sec +++
-ttcp-t: 536862720 bytes in 46.23 CPU seconds = 11340.69 KB/cpu sec
-ttcp-t: 13107 I/O calls, msec/call = 3.61, calls/sec = 283.52
-ttcp-t: 0.0user 46.2sys 0:46real 100% 0i+0d 0maxrss 0+0pf 0+0csw
-
-
-RECEIVER:
-ttcp-r: buflen=40960, nbuf=13107, align=16384/0, port=5001 tcp
-ttcp-r: 536862720 bytes in 46.23 real seconds = 11339.54 KB/sec +++
-ttcp-r: 536862720 bytes in 10.70 CPU seconds = 48998.13 KB/cpu sec
-ttcp-r: 355970 I/O calls, msec/call = 0.13, calls/sec = 7699.20
-ttcp-r: 0.5user 10.1sys 0:46real 23% 0i+0d 0maxrss 0+5pf 0+0csw
-
-
-
-****************************************************************************
-****************************************************************************
diff --git a/c/src/libchip/network/cs8900.c b/c/src/libchip/network/cs8900.c
deleted file mode 100644
index 650a0e1fef..0000000000
--- a/c/src/libchip/network/cs8900.c
+++ /dev/null
@@ -1,1216 +0,0 @@
-/*
- ------------------------------------------------------------------------
-
- Copyright Cybertec Pty Ltd, 2000
- All rights reserved Cybertec Pty Ltd, 2000
-
- Port to the DIMM PC copyright (c) 2004 Angelo Fraietta
- This project has been assisted by the Commonwealth Government
- through the Australia Council, its arts funding and advisory body.
-
- COPYRIGHT (c) 1989-1998.
- 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.org/license/LICENSE.
-
- ------------------------------------------------------------------------
-
- CS8900 RTEMS driver.
-
- See the header file for details.
-
-*/
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <errno.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <libchip/cs8900.h>
-
-/*
- * We expect to be able to read a complete packet into an mbuf.
- */
-
-#if (MCLBYTES < 1520)
-#error "CS8900 Driver must have MCLBYTES >= 1520"
-#endif
-
-/*
- * Task event usage.
- */
-
-#define CS8900_RX_OK_EVENT RTEMS_EVENT_1
-#define CS8900_TX_START_EVENT RTEMS_EVENT_1
-#define CS8900_TX_OK_EVENT RTEMS_EVENT_2
-#define CS8900_TX_WAIT_EVENT RTEMS_EVENT_3
-
-/*
- * IO Packet Page inteface.
- */
-
-static inline unsigned short
-io_pp_get_reg_16 (cs8900_device *cs, unsigned short reg)
-{
- rtems_interrupt_level level;
- unsigned short data;
- rtems_interrupt_disable (level);
- cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR,
- 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
- data = cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT0);
- rtems_interrupt_enable (level);
- return data;
-}
-
-static inline uint32_t
-io_pp_get_reg_32 (cs8900_device *cs, uint16_t reg)
-{
- rtems_interrupt_level level;
- uint32_t data;
- rtems_interrupt_disable (level);
- cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR,
- 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
- data = cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT0);
- data <<= 16;
- data |= cs8900_io_get_reg (cs, CS8900_IO_PP_DATA_PORT1);
- rtems_interrupt_enable (level);
- return data;
-}
-
-static inline void
-io_pp_set_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short data)
-{
- rtems_interrupt_level level;
- rtems_interrupt_disable (level);
- cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR,
- 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
- cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT0, data);
- rtems_interrupt_enable (level);
-}
-
-static inline void
-io_pp_set_reg_32 (cs8900_device *cs, unsigned short reg, unsigned long data)
-{
- cs8900_io_set_reg (cs, CS8900_IO_PACKET_PAGE_PTR,
- 0x3000 | CS8900_PPP_AUTO_INCREMENT | reg);
- cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT0, data >> 16);
- cs8900_io_set_reg (cs, CS8900_IO_PP_DATA_PORT1, data);
-}
-
-static inline void
-io_pp_bit_set_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short mask)
-{
- rtems_interrupt_level level;
- rtems_interrupt_disable (level);
- io_pp_set_reg_16 (cs, reg, io_pp_get_reg_16 (cs, reg) | mask);
- rtems_interrupt_enable (level);
-}
-
-static inline void
-io_pp_bit_clear_reg_16 (cs8900_device *cs, unsigned short reg, unsigned short mask)
-{
- rtems_interrupt_level level;
- rtems_interrupt_disable (level);
- io_pp_set_reg_16 (cs, reg, io_pp_get_reg_16 (cs, reg) & ~mask);
- rtems_interrupt_enable (level);
-}
-
-/*
- * Memory Mapped Packet Page interface.
- *
- * If the BSP does not configure mem_base use the I/O register accesses.
- */
-
-static inline unsigned short
-mem_pp_get_reg (cs8900_device *cs, unsigned short reg)
-{
- if (!cs->mem_base)
- return io_pp_get_reg_16 (cs, reg);
- return cs8900_mem_get_reg (cs, reg);
-}
-
-static inline void
-mem_pp_set_reg (cs8900_device *cs, unsigned short reg, unsigned short data)
-{
- if (!cs->mem_base)
- io_pp_set_reg_16 (cs, reg, data);
- else
- cs8900_mem_set_reg (cs, reg, data);
-}
-
-static inline void
-mem_pp_bit_set_reg (cs8900_device *cs, unsigned short reg, unsigned short mask)
-{
- if (!cs->mem_base)
- io_pp_bit_set_reg_16 (cs, reg, mask);
- else
- {
- rtems_interrupt_level level;
- rtems_interrupt_disable (level);
- mem_pp_set_reg (cs, reg, mem_pp_get_reg (cs, reg) | mask);
- rtems_interrupt_enable (level);
- }
-}
-
-static inline void
-mem_pp_bit_clear_reg (cs8900_device *cs, unsigned short reg, unsigned short mask)
-{
- if (!cs->mem_base)
- io_pp_bit_clear_reg_16 (cs, reg, mask);
- else
- {
- rtems_interrupt_level level;
- rtems_interrupt_disable (level);
- mem_pp_set_reg (cs, reg, mem_pp_get_reg (cs, reg) & ~mask);
- rtems_interrupt_enable (level);
- }
-}
-
-/*
- * Trace defines and control structures.
- */
-
-#define CS8900_T_INT (0)
-#define CS8900_T_RX_OK (1)
-#define CS8900_T_RX_DROPPED (2)
-#define CS8900_T_NO_MBUF (3)
-#define CS8900_T_NO_CLUSTERS (4)
-#define CS8900_T_RX_BEGIN (5)
-#define CS8900_T_RX_END (6)
-
-#if CS8900_TRACE
-
-static const char *cs8900_trace_labels[] =
-{
- "int",
- "rx ok",
- "rx dropped",
- "no mbuf",
- "no clusters",
- "rx begin",
- "rx end"
-};
-
-/*
- * Assumes a micro-second timer such as the Coldfire.
- */
-
-uint32_t rtems_read_timer ();
-
-static inline void
-cs8900_trace (cs8900_device *cs, unsigned short key, unsigned long var)
-{
- rtems_interrupt_level level;
-
- rtems_interrupt_disable (level);
-
- if (cs->trace_in < CS8900_TRACE_SIZE)
- {
- cs->trace_key[cs->trace_in] = key;
- cs->trace_var[cs->trace_in] = var;
- cs->trace_time[cs->trace_in] = rtems_read_timer ();
- cs->trace_in++;
- }
-
- rtems_interrupt_enable (level);
-}
-#else
-#define cs8900_trace(c, k, v)
-#endif
-
-void cs8900_get_mac_addr (cs8900_device *cs, unsigned char *mac_address)
-{
- unsigned short ma;
-
- /*
- * Only ever use IO calls for this function as it can be
- * called before memory mode has been enabled.
- */
-
- ma = io_pp_get_reg_16 (cs, CS8900_PP_IA);
- mac_address[0] = ma >> 8;
- mac_address[1] = ma;
-
- ma = io_pp_get_reg_16 (cs, CS8900_PP_IA + 2);
- mac_address[2] = ma >> 8;
- mac_address[3] = ma;
-
- ma = io_pp_get_reg_16 (cs, CS8900_PP_IA + 4);
- mac_address[4] = ma >> 8;
- mac_address[5] = ma;
-}
-
-/*
- * Bring the chip online.
- */
-
-static void
-cs8900_hardware_init (cs8900_device *cs)
-{
- unsigned long prod_id;
- unsigned short status;
-
- /*
- * Do nothing while the device is calibrating and checking the EEPROM.
- * We must wait 20msecs.
- */
-
- io_pp_bit_set_reg_16 (cs, CS8900_PP_SelfCTL, CS8900_SELF_CTRL_RESET);
-
- rtems_task_wake_after (RTEMS_MILLISECONDS_TO_TICKS (20));
-
- status = io_pp_get_reg_16 (cs, CS8900_PP_SelfST);
- if (status == 0) {
- printf("Reading status register again\n");
- status = io_pp_get_reg_16 (cs, CS8900_PP_SelfST);
- }
-
- if (((status & CS8900_SELF_STATUS_INITD) == 0) ||
- ((status & CS8900_SELF_STATUS_INITD) &&
- (status & CS8900_SELF_STATUS_EEPROM_PRESENT) &&
- (status & CS8900_SELF_STATUS_SIBUST)))
- {
- printf ("CS8900: %s. Initialisation aborted.\n",
- (status & CS8900_SELF_STATUS_INITD) ?
- "EEPROM read/write failed to complete" :
- "Failed to complete to reset");
- return;
- }
-
- /* Set the RX queue size if not set by the BSP. */
-
- if (cs->rx_queue_size == 0)
- cs->rx_queue_size = 10;
-
- /* Probe the device for its ID */
-
- prod_id = io_pp_get_reg_32 (cs, CS8900_PP_PROD_ID);
-
- if ((prod_id >> 16) != CS8900_ESIA_ID)
- {
- printf ("CS8900: Invalid EISA ID, read product code 0x%08lx\n", prod_id);
- return;
- }
-
- if ((prod_id & 0x000000ff) != 0)
- {
- printf ("CS8900: Unsupported product id, read product code 0x%08lx\n",
- prod_id);
- return;
- }
-
- printf ("CS8900 Rev %ld, %s, %s.\n",
- (prod_id >> 8) & 0x1f,
- status & CS8900_SELF_STATUS_3_3_V ? "3.3V" : "5.0V",
- status & CS8900_SELF_STATUS_EEPROM_PRESENT ?
- "EEPROM present" : "no EEPROM");
-
- /*
- * Switch to memory base accesses as they are faster. No indirect access.
- */
-
- if (cs->mem_base)
- {
- io_pp_set_reg_16 (cs, CS8900_PP_MEM_BASE, cs->mem_base);
- io_pp_set_reg_16 (cs, CS8900_PP_MEM_BASE + 2, (cs->mem_base >> 16) & 0xf);
-
- io_pp_set_reg_16 (cs,
- CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_RESET_RX_DMA |
- CS8900_BUS_CTRL_USE_SA |
- CS8900_BUS_CTRL_MEMORY_ENABLE);
- io_pp_set_reg_16 (cs,
- CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_USE_SA |
- CS8900_BUS_CTRL_MEMORY_ENABLE);
- }
-
- /*
- * We are now in memory mapped mode.
- */
-
- /*
- * Program the Line Control register with the mode we want.
- *
- * No auto detect support at the moment. Only 10BaseT.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_LineCFG, CS8900_LINE_CTRL_10BASET);
-
- /*
- * Ask the user for the MAC address, the program into the device.
- */
-
-#define MACO(o) cs->arpcom.ac_enaddr[o]
-
- mem_pp_set_reg (cs, CS8900_PP_IA,
- (((unsigned int) MACO (1)) << 8) |
- ((unsigned int) MACO (0)));
- mem_pp_set_reg (cs, CS8900_PP_IA + 2,
- (((unsigned int) MACO (3)) << 8) |
- ((unsigned int) MACO (2)));
- mem_pp_set_reg (cs, CS8900_PP_IA + 4,
- (((unsigned int) MACO (5)) << 8) |
- ((unsigned int) MACO (4)));
-
- /*
- * Set the Buffer configuration.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_BufCFG,
- CS8900_BUFFER_CONFIG_RDY_FOR_TX |
- CS8900_BUFFER_CONFIG_TX_UNDERRUN |
- CS8900_BUFFER_CONFIG_TX_COL_OVF |
- CS8900_BUFFER_CONFIG_RX_MISSED_OVF);
-
- /*
- * Set the Receiver configuration.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_RxCFG,
- CS8900_RX_CONFIG_RX_OK |
- CS8900_RX_CONFIG_CRC_ERROR |
- CS8900_RX_CONFIG_RUNT|
- CS8900_RX_CONFIG_EXTRA_DATA);
-
- /*
- * Set the Receiver control.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_RxCTL,
- CS8900_RX_CTRL_RX_OK |
- CS8900_RX_CTRL_MULTICAST |
- CS8900_RX_CTRL_INDIVIDUAL |
- CS8900_RX_CTRL_BROADCAST);
-
- /*
- * Set the Transmitter configuration.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_TxCFG,
- CS8900_TX_CONFIG_TX_OK |
- CS8900_TX_CONFIG_OUT_OF_WINDOW |
- CS8900_TX_CONFIG_JABBER |
- CS8900_TX_CONFIG_16_COLLISION);
-
- /*
- * Attach the interrupt handler.
- */
-
- cs8900_attach_interrupt (cs);
-
- /*
- * Program the interrupt level we require then enable interrupts.
- *
- * Note, this will need to change to support other levels.
- */
-
- mem_pp_set_reg (cs, CS8900_PP_INT, cs->irq_level & 3);
-
- mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_ENABLE_INT);
-}
-
-rtems_isr
-cs8900_interrupt (rtems_vector_number v, void *csp)
-{
- cs8900_device *cs = csp;
- unsigned short isq = 0;
- struct mbuf *m;
- unsigned char *p;
-
- ++cs->eth_stats.interrupts;
-
- while (1)
- {
- isq = mem_pp_get_reg (cs, CS8900_PP_ISQ);
-
- cs8900_trace (cs, CS8900_T_INT, isq);
-
- /*
- * No more interrupts to service.
- */
-
- if (isq == 0)
- return;
-
- switch (isq & 0x1f)
- {
- case 0x04:
-
- /*
- * RxEvent.
- */
-
- ++cs->eth_stats.rx_interrupts;
-
- if (isq & CS8900_RX_EVENT_RX_OK)
- {
- m = cs->rx_ready_head;
- if (m)
- {
- cs->rx_ready_head = m->m_nextpkt;
- if (cs->rx_ready_head == 0)
- cs->rx_ready_tail = 0;
- m->m_nextpkt = 0;
- cs->rx_ready_len--;
-
- p = mtod (m, unsigned char *);
-
- m->m_pkthdr.len = cs8900_get_data_block (cs, p);
-
- if (cs->rx_loaded_tail == 0)
- cs->rx_loaded_head = m;
- else
- cs->rx_loaded_tail->m_nextpkt = m;
- cs->rx_loaded_tail = m;
- cs->rx_loaded_len++;
-
- if (cs->rx_loaded_len == 1)
- {
- cs8900_trace (cs, CS8900_T_RX_OK, cs->rx_loaded_len);
- rtems_bsdnet_event_send (cs->rx_task, CS8900_RX_OK_EVENT);
- }
- }
- else
- {
- ++cs->eth_stats.rx_dropped;
-
- cs8900_trace (cs, CS8900_T_RX_DROPPED, cs->rx_loaded_len);
-
- if (cs->rx_loaded_len == 0)
- rtems_bsdnet_event_send (cs->rx_task, CS8900_RX_OK_EVENT);
- }
- }
- else
- {
- if (isq & CS8900_RX_EVENT_CRC_ERROR)
- ++cs->eth_stats.rx_crc_errors;
-
- if (isq & CS8900_RX_EVENT_RUNT)
- ++cs->eth_stats.rx_runt_errors;
-
- if (isq & CS8900_RX_EVENT_EXTRA_DATA)
- ++cs->eth_stats.rx_oversize_errors;
- }
- break;
-
- case 0x08:
-
- /*
- * TxEvent.
- */
-
- ++cs->eth_stats.tx_interrupts;
-
- if (cs->tx_active)
- {
- if (isq & CS8900_TX_EVENT_TX_OK)
- ++cs->eth_stats.tx_ok;
-
- cs->tx_active = 0;
-
- rtems_bsdnet_event_send (cs->tx_task, CS8900_TX_OK_EVENT);
- }
- break;
-
- case 0x0c:
-
- /*
- * BufEvent.
- */
-
- if (isq & CS8900_BUFFER_EVENT_RDY_FOR_TX)
- {
- if (cs->tx_active)
- {
- ++cs->eth_stats.tx_rdy4tx;
- rtems_bsdnet_event_send (cs->tx_task, CS8900_TX_WAIT_EVENT);
- }
- }
- else if (isq & CS8900_BUFFER_EVENT_TX_UNDERRUN)
- {
- ++cs->eth_stats.tx_underrun_errors;
- if (cs->tx_active)
- rtems_bsdnet_event_send (cs->tx_task, CS8900_TX_OK_EVENT);
- }
- else if (isq & CS8900_BUFFER_EVENT_SW_INT)
- {
- ++cs->eth_stats.int_swint_res;
- }
- break;
-
- case 0x10:
-
- /*
- * RxMiss.
- */
-
- cs->eth_stats.rx_missed_errors +=
- mem_pp_get_reg (cs, CS8900_PP_RxMISS) >> 6;
- break;
-
- case 0x12:
-
- /*
- * TxCol.
- */
-
- cs->eth_stats.tx_collisions +=
- mem_pp_get_reg (cs, CS8900_PP_TxCol) >> 6;
- break;
-
- default:
- break;
- }
- }
-
-}
-
-int
-cs8900_link_active (cs8900_device *cs)
-{
- return ((mem_pp_get_reg (cs, CS8900_PP_LineST) & CS8900_LINE_STATUS_LINK_OK) ?
- 1 : 0);
-}
-
-static inline void
-cs8900_rx_refill_queue (cs8900_device *cs)
-{
- struct ifnet *ifp = &cs->arpcom.ac_if;
- struct mbuf *m;
- rtems_interrupt_level level;
-
- /*
- * Hold a single queue of mbuf's at the interface. This
- * will lower the latency of the driver.
- */
-
- while (cs->rx_ready_len < cs->rx_queue_size)
- {
- MGETHDR (m, M_DONTWAIT, MT_DATA);
-
- if (!m)
- {
- ++cs->eth_stats.rx_no_mbufs;
- cs8900_trace (cs, CS8900_T_NO_MBUF, cs->eth_stats.rx_no_mbufs);
- return;
- }
-
- MCLGET (m, M_DONTWAIT);
-
- if (!m->m_ext.ext_buf)
- {
- ++cs->eth_stats.rx_no_clusters;
- cs8900_trace (cs, CS8900_T_NO_CLUSTERS, cs->eth_stats.rx_no_clusters);
- m_free (m);
- return;
- }
- m->m_pkthdr.rcvif = ifp;
- m->m_nextpkt = 0;
-
- rtems_interrupt_disable (level);
-
- if (cs->rx_ready_tail == 0)
- cs->rx_ready_head = m;
- else
- cs->rx_ready_tail->m_nextpkt = m;
- cs->rx_ready_tail = m;
- cs->rx_ready_len++;
-
- rtems_interrupt_enable (level);
- }
-}
-
-static void
-cs8900_rx_task (void *arg)
-{
- cs8900_device *cs = arg;
- struct ifnet *ifp = &cs->arpcom.ac_if;
- rtems_event_set events;
- struct mbuf *m;
- struct ether_header *eh;
- rtems_status_code sc;
- rtems_interrupt_level level;
-
- /*
- * Turn the receiver and transmitter on.
- */
-
- mem_pp_bit_set_reg (cs, CS8900_PP_LineCFG,
- CS8900_LINE_CTRL_RX_ON |
- CS8900_LINE_CTRL_TX_ON);
-
- /*
- * Start the software interrupt watchdog.
- */
-
- mem_pp_bit_set_reg (cs, CS8900_PP_BufCFG,
- CS8900_BUFFER_CONFIG_SW_INT);
- ++cs->eth_stats.int_swint_req;
-
- /*
- * Loop reading packets.
- */
-
- while (1)
- {
- cs8900_rx_refill_queue (cs);
-
- sc = rtems_bsdnet_event_receive (CS8900_RX_OK_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_MILLISECONDS_TO_TICKS (250),
- &events);
-
- cs8900_rx_refill_queue (cs);
-
- if (sc == RTEMS_TIMEOUT)
- {
- /*
- * We need to check the interrupt hardware in the cs8900a
- * has not locked up. It seems this occurs if the ISQ
- * queue fills up.
- * To test we generate a software interrupt and watch
- * a counter go up. If the counter does not go for 2
- * software interrupts requests we flush the ISQ queue.
- */
-
- if ((cs->eth_stats.int_swint_req - cs->eth_stats.int_swint_res) > 1)
- {
- printf ("cs8900: int lockup, isq flush\n");
-
- mem_pp_bit_clear_reg (cs, CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_ENABLE_INT);
-
- while (mem_pp_get_reg (cs, CS8900_PP_ISQ) != 0);
-
- cs->eth_stats.int_swint_req = cs->eth_stats.int_swint_res = 0;
- ++cs->eth_stats.int_lockup;
-
- mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_ENABLE_INT);
- }
-
- mem_pp_bit_set_reg (cs, CS8900_PP_BufCFG,
- CS8900_BUFFER_CONFIG_SW_INT);
- ++cs->eth_stats.int_swint_req;
- }
-
- cs8900_trace (cs, CS8900_T_RX_BEGIN, cs->rx_loaded_len);
-
- while (cs->rx_loaded_len)
- {
- rtems_interrupt_disable (level);
-
- m = cs->rx_loaded_head;
- if (m)
- {
- cs->rx_loaded_head = m->m_nextpkt;
- if (cs->rx_loaded_head == 0)
- cs->rx_loaded_tail = 0;
- m->m_nextpkt = 0;
- cs->rx_loaded_len--;
-
- rtems_interrupt_enable (level);
-
- m->m_pkthdr.rcvif = ifp;
-
- cs->eth_stats.rx_bytes += m->m_pkthdr.len;
-
- m->m_len = m->m_pkthdr.len = m->m_pkthdr.len - sizeof (struct ether_header);
-
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof (struct ether_header);
-
- ++cs->eth_stats.rx_packets;
-
- ether_input (ifp, eh, m);
- }
- else
- {
- rtems_interrupt_enable (level);
- }
- }
- cs8900_trace (cs, CS8900_T_RX_END, cs->rx_loaded_len);
- }
-}
-
-static void
-cs8900_tx_task (void *arg)
-{
- cs8900_device *cs = arg;
- struct ifnet *ifp = &cs->arpcom.ac_if;
- rtems_event_set events;
- struct mbuf *m;
- rtems_status_code sc;
-
- /*
- * Wait for the link to come up.
- */
-
- rtems_task_wake_after (RTEMS_MILLISECONDS_TO_TICKS (750));
-
- /*
- * Loop processing the tx queue.
- */
-
- while (1)
- {
- /*
- * Fetch the mbuf list from the interface's queue.
- */
-
- IF_DEQUEUE (&ifp->if_snd, m);
-
- /*
- * If something actually is present send it.
- */
-
- if (!m)
- {
- ifp->if_flags &= ~IFF_OACTIVE;
-
- rtems_bsdnet_event_receive (CS8900_TX_START_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- else
- {
- if (cs8900_link_active (cs))
- {
- int resending;
-
- do
- {
- unsigned short buf_status;
-
- resending = 0;
-
- cs->tx_active = 1;
-
- mem_pp_set_reg (cs, CS8900_PP_TxCMD,
- CS8900_TX_CMD_STATUS_TX_START_ENTIRE |
- CS8900_TX_CMD_STATUS_FORCE);
- mem_pp_set_reg (cs, CS8900_PP_TxLength, m->m_pkthdr.len);
-
- buf_status = mem_pp_get_reg (cs, CS8900_PP_BusST);
-
- /*
- * If the bid for memory in the device fails trash the
- * transmit and try again next time.
- */
-
- if (buf_status & CS8900_BUS_STATUS_TX_BID_ERROR)
- ++cs->eth_stats.tx_bid_errors;
- else
- {
- /*
- * If the buffer is not read enable the interrupt and then wait.
- */
-
- if ((buf_status & CS8900_BUS_STATUS_RDY_FOR_TX_NOW) == 0)
- {
- cs->eth_stats.tx_wait_for_rdy4tx++;
- sc = rtems_bsdnet_event_receive (CS8900_TX_WAIT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_MILLISECONDS_TO_TICKS (750),
- &events);
- if (sc == RTEMS_TIMEOUT)
- {
- /*
- * For some reason the wait request has been dropped,
- * so lets resend from the start.
- */
-
- printf ("tx resend\n");
- ++cs->eth_stats.tx_resends;
- resending = 1;
- }
- }
-
- if (!resending)
- {
- cs8900_tx_load (cs, m);
- cs->eth_stats.tx_packets++;
- cs->eth_stats.tx_bytes += m->m_pkthdr.len;
- }
- }
- }
- while (resending);
-
- m_freem (m);
-
- do
- {
- rtems_bsdnet_event_receive (CS8900_TX_OK_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- }
- while (cs->tx_active);
- }
- else
- {
- ++cs->eth_stats.tx_dropped;
- m_freem (m);
- }
- }
- }
-}
-
-static void
-cs8900_start (struct ifnet *ifp)
-{
- cs8900_device *cs = ifp->if_softc;
-
- /*
- * Tell the transmit daemon to wake up and send a packet.
- */
-
- ifp->if_flags |= IFF_OACTIVE;
-
- rtems_bsdnet_event_send (cs->tx_task, CS8900_TX_START_EVENT);
-}
-
-static void
-cs8900_stop (cs8900_device *cs)
-{
- mem_pp_bit_clear_reg (cs, CS8900_PP_LineCFG,
- CS8900_LINE_CTRL_RX_ON |
- CS8900_LINE_CTRL_TX_ON);
-
- mem_pp_bit_clear_reg (cs, CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_ENABLE_INT);
-}
-
-static const char *eth_statistics_labels[] =
-{
- "rx packets",
- "tx packets",
- "rx bytes",
- "tx bytes",
- "rx interrupts",
- "tx interrupts",
- "rx dropped",
- "rx no mbuf",
- "rx no custers",
- "rx oversize errors",
- "rx crc errors",
- "rx runt errors",
- "rx missed errors",
- "tx ok",
- "tx collisions",
- "tx bid errors",
- "tx wait for rdy4tx",
- "tx rdy4tx",
- "tx underrun errors",
- "tx dropped",
- "tx resends",
- "int swint req",
- "int swint res",
- "int lockup",
- "interrupts"
-};
-
-static void
-cs8900_stats (cs8900_device *cs)
-{
- int i;
- int max_label = 0;
- int len;
- unsigned long *value = (unsigned long*) &cs->eth_stats.rx_packets;
-
- cs->eth_stats.rx_missed_errors +=
- mem_pp_get_reg (cs, CS8900_PP_RxMISS) >> 6;
-
- cs->eth_stats.tx_collisions +=
- mem_pp_get_reg (cs, CS8900_PP_TxCol) >> 6;
-
- printf ("Network Driver Stats for CS8900 :\n");
-
- for (i = 0; i < (sizeof (eth_statistics_labels) / sizeof (const char *)); i++)
- {
- len = strlen (eth_statistics_labels[i]);
- if (len > max_label)
- max_label = len;
- }
-
- max_label += 2;
-
- printf ("%*s - %10u %*s - %10u\n",
- max_label, "rx ready len", cs->rx_ready_len,
- max_label, "rx loaded len", cs->rx_loaded_len);
-
- for (i = 0;
- i < (sizeof (eth_statistics_labels) / sizeof (const char *));
- i++)
- {
- printf ("%*s - %10lu",
- max_label, eth_statistics_labels[i], value[i]);
-
- i++;
-
- if (i < (sizeof (eth_statistics_labels) / sizeof (const char *)))
- printf (" %*s - %10lu",
- max_label, eth_statistics_labels[i], value[i]);
- printf ("\n");
- }
-
-#if CS8900_TRACE
-
- for (i = 0; i < cs->trace_in; i++)
- {
- printf ("%8ld.%03ld ", cs->trace_time[i] / 1000, cs->trace_time[i] % 1000);
-
- if (cs->trace_key[i] < sizeof (cs8900_trace_labels) / sizeof (char*))
- printf ("%s : ", cs8900_trace_labels[cs->trace_key[i]]);
- else
- printf ("unknown trace key, %d : ", cs->trace_key[i]);
-
- if (cs->trace_key[i] == CS8900_T_INT)
- {
- printf ("0x%04lx ", cs->trace_var[i]);
- if (cs->trace_var[i] == 0)
- printf ("end");
- else
- {
- switch (cs->trace_var[i] & 0x1f)
- {
- case 0x04:
- printf ("rx event");
- break;
-
- case 0x08:
- printf ("tx event");
- break;
-
- case 0x0c:
- printf ("buffer event");
- break;
-
- case 0x10:
- printf ("rx missed");
- break;
-
- case 0x12:
- printf ("tx collisions");
- break;
-
- case 0x1f:
- printf ("tx request");
- break;
-
- case 0x1e:
- printf ("tx wait 4 tx");
- break;
-
- case 0x1d:
- printf ("tx already active");
- break;
-
- default:
- printf ("unknown event");
- break;
- }
- }
- }
- else
- printf ("0x%08lx", cs->trace_var[i]);
-
- printf ("\n");
- }
-
- cs->trace_in = 0;
-
-#endif
-}
-
-static void
-cs8900_init (void *arg)
-{
- cs8900_device *cs = arg;
- struct ifnet *ifp = &cs->arpcom.ac_if;
-
- if (cs->rx_task == 0)
- {
-
- /*
- * Set up the hardware.
- */
-
- cs8900_hardware_init (cs);
-
- /*
- * Start driver task. We have only one task.
- */
-
- cs->rx_task = rtems_bsdnet_newproc ("CSr0", 4096, cs8900_rx_task, cs);
- cs->tx_task = rtems_bsdnet_newproc ("CSt0", 4096, cs8900_tx_task, cs);
- }
-
-#ifdef todo
- /*
- * Set flags appropriately
- */
- if (ifp->if_flags & IFF_PROMISC)
- else
-#endif
-
- /*
- * Tell the world that we're running.
- */
-
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Set the Line Control to bring the receive and transmitter online.
- */
-
- mem_pp_bit_set_reg (cs, CS8900_PP_LineCFG,
- CS8900_LINE_CTRL_RX_ON |
- CS8900_LINE_CTRL_TX_ON);
-
- mem_pp_bit_set_reg (cs, CS8900_PP_BusCTL,
- CS8900_BUS_CTRL_ENABLE_INT);
-}
-
-static int
-cs8900_ioctl (struct ifnet *ifp, ioctl_command_t cmd, caddr_t data)
-{
- cs8900_device *cs = ifp->if_softc;
- int error = 0;
-
- switch (cmd)
- {
- case SIOCGIFADDR:
- case SIOCSIFADDR:
-
- error = ether_ioctl (ifp, cmd, data);
- break;
-
- case SIOCSIFFLAGS:
-
- switch (ifp->if_flags & (IFF_UP | IFF_RUNNING))
- {
- case IFF_RUNNING:
-
- cs8900_stop (cs);
- break;
-
- case IFF_UP:
-
- cs8900_init (cs);
- break;
-
- case IFF_UP | IFF_RUNNING:
-
- cs8900_stop (cs);
- cs8900_init (cs);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
-
- cs8900_stats (cs);
- break;
-
- /* FIXME: Multicast commands must be added here. */
-
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-int
-cs8900_driver_attach (struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- cs8900_device *cs;
- struct ifnet *ifp;
- int mtu;
- int unit;
- char *name;
-
- /*
- * Parse driver name
- */
-
- if ((unit = rtems_bsdnet_parse_driver_name (config, &name)) < 0)
- return 0;
-
- cs = config->drv_ctrl;
- cs->dev = unit;
- ifp = &cs->arpcom.ac_if;
-
- if (attaching)
- {
- if (ifp->if_softc)
- {
- printf ("Driver `%s' already in use.\n", config->name);
- return 0;
- }
-
- /*
- * Process options
- */
-
- if (config->hardware_address)
- memcpy (cs->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- else
- cs8900_get_mac_addr (cs, cs->arpcom.ac_enaddr);
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- cs->accept_bcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values.
- */
-
- ifp->if_softc = cs;
- ifp->if_unit = unit;
- ifp->if_name = name;
- ifp->if_mtu = mtu;
- ifp->if_init = cs8900_init;
- ifp->if_ioctl = cs8900_ioctl;
- ifp->if_start = cs8900_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;
-
- /*
- * Attach the interface to the stack.
- */
-
- if_attach (ifp);
- ether_ifattach (ifp);
- }
- else
- {
- if (!ifp->if_softc)
- {
- printf ("Driver `%s' not found.\n", config->name);
- return 0;
- }
-
- cs8900_stop (cs);
- cs8900_detach_interrupt (cs);
- }
-
- return 1;
-}
diff --git a/c/src/libchip/network/cs8900.c.bsp b/c/src/libchip/network/cs8900.c.bsp
deleted file mode 100644
index 7b7374a0f2..0000000000
--- a/c/src/libchip/network/cs8900.c.bsp
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
- * RTEMS CS8900 Driver Setup for the DIMM-PC/i386 made by Kontron.
- *
- * Port to the DIMM PC copyright (c) 2004 Angelo Fraietta
- * This project has been assisted by the Commonwealth Government
- * through the Australia Council, its arts funding and advisory body.
- *
- * Port performed by Chris Johns, Cybertec Pty Ltd, Jan 2004.
- * Based on the Cybertec CS8900 driver setup for the SFP-101.
- *
- */
-
-#define CS8900_VERBOSE 0
-#define HAVE_MRB_CS8900_DATA_BUS_SWAPPED 1
-
-#include <bsp.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <arpa/inet.h>
-
-#include <rtems.h>
-#include <rtems/monitor.h>
-#include <rtems/rtems_bsdnet.h>
-#include <irq.h>
-
-#include "cs8900.h"
-
-#include <net/route.h>
-
-/*
- * Loopback interface.
- */
-
-extern int rtems_bsdnet_loopattach (struct rtems_bsdnet_ifconfig *, int);
-
-static struct rtems_bsdnet_ifconfig loopback_config =
-{
- "lo0", /* name */
- rtems_bsdnet_loopattach, /* attach function */
- NULL, /* link to next interface */
- "127.0.0.1", /* IP address */
- "255.0.0.0", /* IP net mask */
-};
-
-/*
- * Network configuration
- */
-
-struct rtems_bsdnet_config rtems_bsdnet_config =
-{
- &loopback_config,
- NULL,
- 20, /* Network task priority */
- 32 * 1024, /* Mbuf capacity */
- 96 * 1024, /* Mbuf cluster capacity */
-};
-
-
-static void cs8900_isr ();
-static void cs8900_int_off (const rtems_irq_connect_data* unused);
-static void cs8900_int_on (const rtems_irq_connect_data* unused);
-static int cs8900_int_is_on (const rtems_irq_connect_data *irq);
-
-/**
- * The device's data.
- */
-static cs8900_device cs8900;
-static rtems_irq_connect_data cs8900_irq =
-{
- 0,
- cs8900_isr,
- cs8900_int_on,
- cs8900_int_off,
- cs8900_int_is_on
-};
-
-#if CS8900_VERBOSE
-static int cs8900_io_verbose = 1;
-#endif
-
-/**
- * Device structure for attaching to the BSD stack.
- */
-static struct rtems_bsdnet_ifconfig cs8900_ifconfig =
-{
- "cs0", /* name */
- cs8900_driver_attach, /* attach funtion */
- NULL, /* next interface */
- NULL, /* ip address */
- NULL, /* ip netmask */
- NULL, /* hardware address */
- 0, /* ignore broadcast */
- 0, /* mtu */
- 0, /* rbuf count */
- 0, /* xbuf count */
- 0, /* port */
- 0, /* irno */
- 0, /* bpar */
- 0 /* drv ctrl */
-};
-
-
-/*
- * Commands to register.
- */
-
-rtems_monitor_command_entry_t rtems_bsdnet_commands[] =
-{
- {
- "ifstats",
- "Show the interface stats.\n",
- 0,
- (void*) rtems_bsdnet_show_if_stats,
- 0,
- 0,
- },
- {
- "ipstats",
- "Show the IP stats.\n",
- 0,
- (void*) rtems_bsdnet_show_ip_stats,
- 0,
- 0,
- },
- {
- "routes",
- "Show the inet routes.\n",
- 0,
- (void*) rtems_bsdnet_show_inet_routes,
- 0,
- 0,
- },
- {
- "mbufs",
- "Show the mbuf stats.\n",
- 0,
- (void*) rtems_bsdnet_show_mbuf_stats,
- 0,
- 0,
- },
- {
- "icmp",
- "Show the ICMP stats.\n",
- 0,
- (void*) rtems_bsdnet_show_icmp_stats,
- 0,
- 0,
- },
- {
- "udp",
- "Show the UDP stats.\n",
- 0,
- (void*) rtems_bsdnet_show_udp_stats,
- 0,
- 0,
- },
- {
- "tcp",
- "Show the TCP stats.\n",
- 0,
- (void*) rtems_bsdnet_show_tcp_stats,
- 0,
- 0,
- }
-};
-
-static void
-cs8900_isr ()
-{
- /*
- * Note: we could have a high priority task here to call the
- * drivers handler. The would lower the interrupt latancy
- * we aother wise have.
- */
- cs8900_interrupt (cs8900_irq.name, &cs8900);
-}
-
-static void
-cs8900_int_on (const rtems_irq_connect_data *unused)
-{
-}
-
-static void
-cs8900_int_off (const rtems_irq_connect_data *unused)
-{
-}
-
-static int
-cs8900_int_is_on (const rtems_irq_connect_data *irq)
-{
- return BSP_irq_enabled_at_i8259s (irq->name);
-}
-
-void cs8900_io_set_reg (cs8900_device *cs, unsigned short reg, unsigned short data)
-{
-#if CS8900_VERBOSE
- if (cs8900_io_verbose)
- printk ("CS8900: io set reg=0x%04x, data=0x%04x\n", reg, data);
-#endif
- outport_word (cs->io_base + reg, data);
-}
-
-unsigned short cs8900_io_get_reg (cs8900_device *cs, unsigned short reg)
-{
- unsigned short data;
- inport_word (cs->io_base + reg, data);
-#if CS8900_VERBOSE
- if (cs8900_io_verbose)
- printk ("CS8900: io get reg=0x%04x, data=0x%04x\n", reg, data);
-#endif
- return data;
-}
-
-void cs8900_mem_set_reg (cs8900_device *cs, unsigned long reg, unsigned short data)
-{
- printk ("CS8900: mem_set_reg register access called. Only IO supported.\n");
- while (1);
-}
-
-unsigned short cs8900_mem_get_reg (cs8900_device *cs, unsigned long reg)
-{
- printk ("CS8900: mem_get_reg register access called. Only IO supported.\n");
- while (1);
- return 0;
-}
-
-void cs8900_put_data_block (cs8900_device *cs, int len, unsigned char *data)
-{
- unsigned short *src = (unsigned short *) ((unsigned long) data);
-
- for (; len > 1; len -= 2)
- outport_word (cs->io_base, *src++);
-
- if (len)
- outport_word (cs->io_base, *src++);
-}
-
-unsigned short cs8900_get_data_block (cs8900_device *cs, unsigned char *data)
-{
- unsigned short *dst;
- int cnt;
- int len;
-
- /*
- * Drop the Rx status first.
- */
- inport_word (cs->io_base, len);
-
- /*
- * Now the length.
- */
- inport_word (cs->io_base, len);
-
- dst = (unsigned short *) ((unsigned long) data);
- cnt = len >> 1;
-
- while (cnt--)
- inport_word (cs->io_base, *dst++);
-
- if (len & 1)
- inport_word (cs->io_base, *dst++);
-
- return len;
-}
-
-void
-cs8900_tx_load (cs8900_device *cs, struct mbuf *m)
-{
- unsigned int len;
- unsigned char *src = 0;
- unsigned short *wsrc = 0;
- unsigned char remainder = 0;
- unsigned char word[2];
-
- while (m)
- {
- /*
- * We can get empty mbufs from the stack.
- */
-
- len = m->m_len;
- src = mtod (m, unsigned char*);
-
- if (len)
- {
- if (remainder)
- {
-#if HAVE_MRB_CS8900_DATA_BUS_SWAPPED
- word[1] = *src++;
-#else
- word[0] = *src++;
-#endif
- outport_word (cs->io_base, *((unsigned short*) (unsigned long) &word));
- len--;
- remainder = 0;
- }
-
- if (len & 1)
- {
- remainder = 1;
- len--;
- }
-
- wsrc = (unsigned short*) src;
-
- for (; len; len -= 2, src += 2)
- outport_word (cs->io_base, *wsrc++);
-
- if (remainder)
-#if HAVE_MRB_CS8900_DATA_BUS_SWAPPED
- word[0] = *src++;
-#else
- word[1] = *src++;
-#endif
- }
-
- m = m->m_next;
- }
-
- if (remainder)
- {
-#if HAVE_MRB_CS8900_DATA_BUS_SWAPPED
- word[1] = *src++;
-#else
- word[0] = *src++;
-#endif
- outport_word (cs->io_base, *((unsigned short*) (unsigned long) &word));
- }
-}
-
-void cs8900_attach_interrupt (cs8900_device *cs)
-{
- BSP_install_rtems_irq_handler (&cs8900_irq);
-}
-
-void cs8900_detach_interrupt (cs8900_device *cs)
-{
- BSP_remove_rtems_irq_handler (&cs8900_irq);
-}
-
-void
-BSP_cs8900_attach (unsigned long io_base, unsigned long mem_base, int intrp,
- const char* ip, const char* nm, const char* gw)
-{
- cs8900_device *cs = &cs8900;
- int flags;
- struct sockaddr_in address;
- struct sockaddr_in netmask;
- struct sockaddr_in broadcast;
- struct sockaddr_in gateway;
- int cmd;
-
- printf ("cso: io=0x%0lx mem=0 irq=%d\n", io_base, intrp);
-
- memset (cs, 0, sizeof (cs8900));
-
- cs->dev = 0;
- cs->rx_queue_size = 30;
- cs->io_base = io_base;
-
- if (mem_base)
- printf ("cs8900: memory mode is currently not supported.\n");
-
- cs->mem_base = 0;
-
- switch (intrp)
- {
- case 5:
- cs->irq_level = 3;
- break;
- case 10:
- cs->irq_level = 0;
- break;
- case 11:
- cs->irq_level = 1;
- break;
- case 12:
- cs->irq_level = 2;
- break;
- default:
- printf ("cs8900: unsupported IRQ level\n");
- return;
- }
-
- cs8900_irq.name = intrp;
-
- /*
- * Get the MAC adress from the CS8900.
- */
-
- cs8900_get_mac_addr (cs, cs->mac_address);
-
- /*
- * Setup the BSD interface configure structure.
- */
-
- cs8900_ifconfig.drv_ctrl = cs;
- cs8900_ifconfig.hardware_address = cs->mac_address;
-
- printf ("CS8900 initialisation\n");
-
- rtems_bsdnet_attach (&cs8900_ifconfig);
-
- /*
- * Configure the interface using the boot configuration.
- */
-
- flags = IFF_UP;
- if (rtems_bsdnet_ifconfig (cs8900_ifconfig.name,
- SIOCSIFFLAGS,
- &flags) < 0)
- {
- printf ("error: can't bring up %s: %s\n",
- cs8900_ifconfig.name, strerror (errno));
- return;
- }
-
- if (ip && strlen (ip) && nm && strlen (nm))
- {
- printf ("%s: addr: %s netmask: %s gateway: %s\n",
- cs8900_ifconfig.name, ip, nm, gw ? gw : "none");
-
- memset (&netmask, '\0', sizeof netmask);
- netmask.sin_len = sizeof netmask;
- netmask.sin_family = AF_INET;
-
- if (!inet_aton (nm, &netmask.sin_addr))
- {
- printf ("error: cannot parse the network mask: %s\n", nm);
- return;
- }
-
- memset (&address, '\0', sizeof address);
- address.sin_len = sizeof address;
- address.sin_family = AF_INET;
-
- if (!inet_aton (ip, &address.sin_addr))
- {
- printf ("error: cannot parse the ip address: %s\n", ip);
- return;
- }
-
- if (rtems_bsdnet_ifconfig (cs8900_ifconfig.name,
- SIOCSIFNETMASK,
- &netmask) < 0)
- {
- printf ("error: can't set %s netmask: %s\n",
- cs8900_ifconfig.name, strerror (errno));
- return;
- }
-
- if (rtems_bsdnet_ifconfig (cs8900_ifconfig.name,
- SIOCSIFADDR,
- &address) < 0)
- {
- printf ("error: can't set %s address: %s\n",
- cs8900_ifconfig.name, strerror (errno));
- return;
- }
-
- memset (&broadcast, '\0', sizeof broadcast);
- broadcast.sin_len = sizeof broadcast;
- broadcast.sin_family = AF_INET;
- broadcast.sin_addr.s_addr =
- (address.sin_addr.s_addr & netmask.sin_addr.s_addr) | ~netmask.sin_addr.s_addr;
-
- if (rtems_bsdnet_ifconfig (cs8900_ifconfig.name,
- SIOCSIFBRDADDR,
- &broadcast) < 0)
- {
- printf ("error: can't set %s broadcast address: %s\n",
- cs8900_ifconfig.name, strerror (errno));
- return;
- }
-
- if (gw && strlen (gw))
- {
- address.sin_addr.s_addr = INADDR_ANY;
- netmask.sin_addr.s_addr = INADDR_ANY;
- memset (&gateway, '\0', sizeof gateway);
- gateway.sin_len = sizeof gateway;
- gateway.sin_family = AF_INET;
-
- if (!inet_aton (gw, &gateway.sin_addr))
- printf ("warning: cannot parse the gateway address: %s\n", ip);
- else
- {
- if (rtems_bsdnet_rtrequest (RTM_ADD,
- (struct sockaddr *) &address,
- (struct sockaddr *) &gateway,
- (struct sockaddr *) &netmask,
- (RTF_UP | RTF_GATEWAY | RTF_STATIC), NULL) < 0)
- printf ("error: can't set default route: %s\n", strerror (errno));
- }
- }
- }
- else
- {
- rtems_bsdnet_do_bootp_and_rootfs ();
- }
-
- for (cmd = 0;
- cmd < sizeof (rtems_bsdnet_commands) / sizeof (rtems_monitor_command_entry_t);
- cmd++)
- rtems_monitor_insert_cmd (&rtems_bsdnet_commands[cmd]);
-}
diff --git a/c/src/libchip/network/cs8900.h.bsp b/c/src/libchip/network/cs8900.h.bsp
deleted file mode 100644
index 65ce0d2e93..0000000000
--- a/c/src/libchip/network/cs8900.h.bsp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * RTEMS CS8900 Driver Setup for the DIMM-PC/i386 made by Kontron.
- *
- * Port to the DIMM PC copyright (c) 2004 Angelo Fraietta
- * This project has been assisted by the Commonwealth Government
- * through the Australia Council, its arts funding and advisory body.
- *
- * Port performed by Chris Johns, Cybertec Pty Ltd, Jan 2004.
- * Based on the Cybertec CS8900 driver setup for the SFP-101.
- */
-
-#if !defined (__BSP_CS8900_H__)
-#define __BSP_CS8900_H__
-
-/**
- * BSP CS8900 Device initialisation and interface attach.
- *
- * @param io_base The I/O base address of the device.
- *
- * @param mem_base The memory base address. Currently not used.
- *
- * @param intrp The ISA bus IRQ. These are currently limited to
- * 5, 10, 11, and 12 as documented in the CS8900
- * manual.
- *
- * @param ip IP address in ASCII. For example 10.10.10.10. If the
- * pointer is a NULL (0) the interface will BOOTP.
- *
- * @param nm Network Mask in ASCII. For example 10.10.10.255.
- *
- * @param gw Address of the gateway machine. For example
- * 10.10.10.1.
- */
-
-void BSP_cs8900_attach (unsigned long io_base, unsigned long mem_base, int intrp,
- const char* ip, const char* nm, const char* gw);
-
-#endif
diff --git a/c/src/libchip/network/dec21140.c b/c/src/libchip/network/dec21140.c
deleted file mode 100644
index 6fd3d5b33f..0000000000
--- a/c/src/libchip/network/dec21140.c
+++ /dev/null
@@ -1,1112 +0,0 @@
-/*
- * RTEMS driver for TULIP based Ethernet Controller
- *
- * Copyright (C) 1999 Emmanuel Raguet. raguet@crf.canon.fr
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- * ------------------------------------------------------------------------
- * [22.05.2000,StWi/CWA] added support for the DEC/Intel 21143 chip
- *
- * Thanks go to Andrew Klossner who provided the vital information about the
- * Intel 21143 chip. FWIW: The 21143 additions to this driver were initially
- * tested with a PC386 BSP using a Kingston KNE100TX with 21143PD chip.
- *
- * The driver will automatically detect whether there is a 21140 or 21143
- * network card in the system and activate support accordingly. It will
- * look for the 21140 first. If the 21140 is not found the driver will
- * look for the 21143.
- *
- * 2004-11-10, Joel/Richard - 21143 support works on MVME2100.
- * ------------------------------------------------------------------------
- *
- * 2003-03-13, Greg Menke, gregory.menke@gsfc.nasa.gov
- *
- * Added support for up to 8 units (which is an arbitrary limit now),
- * consolidating their support into a single pair of rx/tx daemons and a
- * single ISR for all vectors servicing the DEC units. The driver now
- * simply uses whatever INTERRUPT_LINE the card supplies, requiring it
- * be configured either by the boot monitor or bspstart() hackery.
- * Tested on a MCP750 PPC based system with 2 DEC21140 boards.
- *
- * Also fixed a few bugs related to board configuration, start and stop.
- *
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <inttypes.h>
-
-/*
- * This driver only supports architectures with the new style
- * exception processing. The following checks try to keep this
- * from being compiled on systems which can't support this driver.
- */
-
-#if defined(__i386__)
- #define DEC21140_SUPPORTED
- #define PCI_DRAM_OFFSET 0
-#endif
-#if defined(__PPC__)
- #define DEC21140_SUPPORTED
-#endif
-
-#include <bsp.h>
-
-#if !defined(PCI_DRAM_OFFSET)
- #undef DEC21140_SUPPORTED
-#endif
-
-#if defined(DEC21140_SUPPORTED)
-#include <rtems/pci.h>
-
-#if defined(__PPC__)
-#include <libcpu/byteorder.h>
-#include <libcpu/io.h>
-#endif
-
-#if defined(__i386__)
-#include <libcpu/byteorder.h>
-#include <libcpu/page.h>
-#endif
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/bspIo.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 <bsp/irq.h>
-
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef free
-#undef free
-#endif
-
-#define DEC_DEBUG
-
-/* note: the 21143 isn't really a DEC, it's an Intel chip */
-#define PCI_VENDOR_ID_DEC 0x1011
-#define PCI_DEVICE_ID_DEC_21140 0x0009
-#define PCI_DEVICE_ID_DEC_21143 0x0019
-
-#define DRIVER_PREFIX "dc"
-
-#define IO_MASK 0x3
-#define MEM_MASK 0xF
-
-/* command and status registers, 32-bit access, only if IO-ACCESS */
-#define ioCSR0 0x00 /* bus mode register */
-#define ioCSR1 0x08 /* transmit poll demand */
-#define ioCSR2 0x10 /* receive poll demand */
-#define ioCSR3 0x18 /* receive list base address */
-#define ioCSR4 0x20 /* transmit list base address */
-#define ioCSR5 0x28 /* status register */
-#define ioCSR6 0x30 /* operation mode register */
-#define ioCSR7 0x38 /* interrupt mask register */
-#define ioCSR8 0x40 /* missed frame counter */
-#define ioCSR9 0x48 /* Ethernet ROM register */
-#define ioCSR10 0x50 /* reserved */
-#define ioCSR11 0x58 /* full-duplex register */
-#define ioCSR12 0x60 /* SIA status register */
-#define ioCSR13 0x68
-#define ioCSR14 0x70
-#define ioCSR15 0x78 /* SIA general register */
-
-/* command and status registers, 32-bit access, only if MEMORY-ACCESS */
-#define memCSR0 0x00 /* bus mode register */
-#define memCSR1 0x02 /* transmit poll demand */
-#define memCSR2 0x04 /* receive poll demand */
-#define memCSR3 0x06 /* receive list base address */
-#define memCSR4 0x08 /* transmit list base address */
-#define memCSR5 0x0A /* status register */
-#define memCSR6 0x0C /* operation mode register */
-#define memCSR7 0x0E /* interrupt mask register */
-#define memCSR8 0x10 /* missed frame counter */
-#define memCSR9 0x12 /* Ethernet ROM register */
-#define memCSR10 0x14 /* reserved */
-#define memCSR11 0x16 /* full-duplex register */
-#define memCSR12 0x18 /* SIA status register */
-#define memCSR13 0x1A
-#define memCSR14 0x1C
-#define memCSR15 0x1E /* SIA general register */
-
-#define DEC_REGISTER_SIZE 0x100 /* to reserve virtual memory */
-
-
-
-
-#define RESET_CHIP 0x00000001
-#if defined(__PPC__)
-#define CSR0_MODE 0x0030e002 /* 01b08000 */
-#else
-#define CSR0_MODE 0x0020e002 /* 01b08000 */
-#endif
-#define ROM_ADDRESS 0x00004800
-#define CSR6_INIT 0x022cc000 /* 022c0000 020c0000 */
-#define CSR6_TX 0x00002000
-#define CSR6_TXRX 0x00002002
-#define IT_SETUP 0x000100c0 /* 000100e0 */
-#define CLEAR_IT 0xFFFFFFFF
-#define NO_IT 0x00000000
-
-/* message descriptor entry */
-struct MD {
- /* used by hardware */
- volatile uint32_t status;
- volatile uint32_t counts;
- volatile uint32_t buf1, buf2;
- /* used by software */
- volatile struct mbuf *m;
- volatile struct MD *next;
-} __attribute__ ((packed));
-
-/*
-** These buffers allocated for each unit, so ensure
-**
-** rtems_bsdnet_config.mbuf_bytecount
-** rtems_bsdnet_config.mbuf_cluster_bytecount
-**
-** are adequately sized to provide enough clusters and mbufs for all the
-** units. The default bsdnet configuration is sufficient for one dec
-** unit, but will be nearing exhaustion with 2 or more. Although a
-** little expensive in memory, the following configuration should
-** eliminate all mbuf/cluster issues;
-**
-** rtems_bsdnet_config.mbuf_bytecount = 128*1024;
-** rtems_bsdnet_config.mbuf_cluster_bytecount = 256*1024;
-*/
-
-#define NRXBUFS 16 /* number of receive buffers */
-#define NTXBUFS 16 /* number of transmit buffers */
-
-/*
- * Number of DEC boards supported by this driver
- */
-#define NDECDRIVER 8
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define RBUF_SIZE 1536
-
-#define ET_MINLEN 60 /* minimum message length */
-
-/*
-** Events, one per unit. The event is sent to the rx task from the isr
-** or from the stack to the tx task whenever a unit needs service. The
-** rx/tx tasks identify the requesting unit(s) by their particular
-** events so only requesting units are serviced.
-*/
-
-static rtems_event_set unit_signals[NDECDRIVER]= { RTEMS_EVENT_1,
- RTEMS_EVENT_2,
- RTEMS_EVENT_3,
- RTEMS_EVENT_4,
- RTEMS_EVENT_5,
- RTEMS_EVENT_6,
- RTEMS_EVENT_7,
- RTEMS_EVENT_8 };
-
-#if defined(__PPC__)
-#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
-#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
-#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
-#else
-extern void Wait_X_ms( unsigned int timeToWait );
-#define phys_to_bus(address) ((unsigned int) ((address)))
-#define bus_to_phys(address) ((unsigned int) ((address)))
-#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
-#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
-#endif
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/*
- * Per-device data
- */
-struct dec21140_softc {
-
- struct arpcom arpcom;
-
- rtems_irq_connect_data irqInfo;
- rtems_event_set ioevent;
-
- int numRxbuffers, numTxbuffers;
-
- volatile struct MD *MDbase;
- volatile struct MD *nextRxMD;
- volatile unsigned char *bufferBase;
- int acceptBroadcast;
-
- volatile struct MD *TxMD;
- volatile struct MD *SentTxMD;
- int PendingTxCount;
- int TxSuspended;
-
- unsigned int port;
- volatile uint32_t *base;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long rxNotFirst;
- unsigned long rxNotLast;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxRunt;
- unsigned long rxBadCRC;
- unsigned long rxOverrun;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txHeartbeat;
- unsigned long txLateCollision;
- unsigned long txRetryLimit;
- unsigned long txUnderrun;
- unsigned long txLostCarrier;
- unsigned long txRawWait;
-};
-
-static struct dec21140_softc dec21140_softc[NDECDRIVER];
-static rtems_id rxDaemonTid;
-static rtems_id txDaemonTid;
-
-void dec21140_txDaemon (void *arg);
-
-/*
- * This routine reads a word (16 bits) from the serial EEPROM.
- */
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x02 /* EEPROM shift clock. */
-#define EE_CS 0x01 /* EEPROM chip select. */
-#define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */
-#define EE_WRITE_0 0x01
-#define EE_WRITE_1 0x05
-#define EE_DATA_READ 0x08 /* EEPROM chip data out. */
-#define EE_ENB (0x4800 | EE_CS)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
-
-static int eeget16(volatile uint32_t *ioaddr, int location)
-{
- int i;
- unsigned short retval = 0;
- int read_cmd = location | EE_READ_CMD;
-
- st_le32(ioaddr, EE_ENB & ~EE_CS);
- st_le32(ioaddr, EE_ENB);
-
- /* Shift the read command bits out. */
- for (i = 10; i >= 0; i--) {
- short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
- st_le32(ioaddr, EE_ENB | dataval);
- rtems_bsp_delay_in_bus_cycles(200);
- st_le32(ioaddr, EE_ENB | dataval | EE_SHIFT_CLK);
- rtems_bsp_delay_in_bus_cycles(200);
- st_le32(ioaddr, EE_ENB | dataval); /* Finish EEPROM a clock tick. */
- rtems_bsp_delay_in_bus_cycles(200);
- }
- st_le32(ioaddr, EE_ENB);
-
- for (i = 16; i > 0; i--) {
- st_le32(ioaddr, EE_ENB | EE_SHIFT_CLK);
- rtems_bsp_delay_in_bus_cycles(200);
- retval = (retval << 1) | ((ld_le32(ioaddr) & EE_DATA_READ) ? 1 : 0);
- st_le32(ioaddr, EE_ENB);
- rtems_bsp_delay_in_bus_cycles(200);
- }
-
- /* Terminate the EEPROM access. */
- st_le32(ioaddr, EE_ENB & ~EE_CS);
- return ( ((retval<<8)&0xff00) | ((retval>>8)&0xff) );
-}
-
-static void no_op(const rtems_irq_connect_data* irq)
-{
- return;
-}
-
-/*
- * DEC21140 interrupt handler
- */
-static rtems_isr
-dec21140Enet_interrupt_handler ( struct dec21140_softc *sc )
-{
- volatile uint32_t *tbase;
- uint32_t status;
-
- tbase = (uint32_t*)(sc->base);
-
- /*
- * Read status
- */
- status = ld_le32(tbase+memCSR5);
- st_le32((tbase+memCSR5), status);
-
- /*
- * Frame received?
- */
- if( status & 0x000000c0 )
- {
- sc->rxInterrupts++;
- rtems_bsdnet_event_send(rxDaemonTid, sc->ioevent);
- }
-}
-
-static rtems_isr
-dec21140Enet_interrupt_handler_entry(void)
-{
- int i;
-
- /*
- ** Check all the initialized dec units for interrupt service
- */
-
- for(i=0; i< NDECDRIVER; i++ )
- {
- if( dec21140_softc[i].base )
- dec21140Enet_interrupt_handler( &dec21140_softc[i] );
- }
-}
-
-/*
- * Initialize the ethernet hardware
- */
-static void
-dec21140Enet_initialize_hardware (struct dec21140_softc *sc)
-{
- int i,st;
- volatile uint32_t *tbase;
- volatile unsigned char *cp, *setup_frm, *eaddrs;
- volatile unsigned char *buffer;
- volatile struct MD *rmd;
-
-
-#ifdef DEC_DEBUG
- printk("dec2114x : %02x:%02x:%02x:%02x:%02x:%02x name '%s%d', io %x, mem %x, int %d\n",
- sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
- sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
- sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
- sc->arpcom.ac_if.if_name, sc->arpcom.ac_if.if_unit,
- sc->port, (unsigned) sc->base, sc->irqInfo.name );
-#endif
-
- tbase = sc->base;
-
- /*
- * WARNING : First write in CSR6
- * Then Reset the chip ( 1 in CSR0)
- */
- st_le32( (tbase+memCSR6), CSR6_INIT);
- st_le32( (tbase+memCSR0), RESET_CHIP);
- rtems_bsp_delay_in_bus_cycles(200);
-
- st_le32( (tbase+memCSR7), NO_IT);
-
- /*
- * Init CSR0
- */
- st_le32( (tbase+memCSR0), CSR0_MODE);
-
- /*
- * Init RX ring
- */
- cp = (volatile unsigned char *)malloc(((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))
- + (sc->numTxbuffers*RBUF_SIZE)
- + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
- sc->bufferBase = cp;
- cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
-#if defined(__i386__)
-#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
- if (_CPU_is_paging_enabled())
- _CPU_change_memory_mapping_attribute
- (NULL, cp,
- ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD))
- + (sc->numTxbuffers*RBUF_SIZE),
- PTE_CACHE_DISABLE | PTE_WRITABLE);
-#endif
-#endif
- rmd = (volatile struct MD*)cp;
- sc->MDbase = rmd;
- sc->nextRxMD = sc->MDbase;
-
- buffer = cp + ((sc->numRxbuffers+sc->numTxbuffers)*sizeof(struct MD));
- st_le32( (tbase+memCSR3), (long)(phys_to_bus((long)(sc->MDbase))));
-
- for (i=0 ; i<sc->numRxbuffers; i++)
- {
- struct mbuf *m;
-
- /* allocate an mbuf for each receive descriptor */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- rmd->m = m;
-
- rmd->buf2 = phys_to_bus(rmd+1);
- rmd->buf1 = phys_to_bus(mtod(m, void *));
- rmd->status = 0x80000000;
- rmd->counts = 0xfdc00000 | (RBUF_SIZE);
- rmd->next = rmd+1;
- rmd++;
- }
- /*
- * mark last RX buffer.
- */
- sc->MDbase [sc->numRxbuffers-1].buf2 = 0;
- sc->MDbase [sc->numRxbuffers-1].counts = 0xfec00000 | (RBUF_SIZE);
- sc->MDbase [sc->numRxbuffers-1].next = sc->MDbase;
-
-
-
- /*
- * Init TX ring
- */
- st_le32( (tbase+memCSR4), (long)(phys_to_bus((long)(rmd))) );
- for (i=0 ; i<sc->numTxbuffers; i++){
- (rmd+i)->buf2 = phys_to_bus(rmd+i+1);
- (rmd+i)->buf1 = phys_to_bus(buffer + (i*RBUF_SIZE));
- (rmd+i)->counts = 0x01000000;
- (rmd+i)->status = 0x0;
- (rmd+i)->next = rmd+i+1;
- (rmd+i)->m = 0;
- }
-
- /*
- * mark last TX buffer.
- */
- (rmd+sc->numTxbuffers-1)->buf2 = phys_to_bus(rmd);
- (rmd+sc->numTxbuffers-1)->next = rmd;
-
-
- /*
- * Build setup frame
- */
- setup_frm = (volatile unsigned char *)(bus_to_phys(rmd->buf1));
- eaddrs = (unsigned char *)(sc->arpcom.ac_enaddr);
- /* Fill the buffer with our physical address. */
- for (i = 1; i < 16; i++) {
- *setup_frm++ = eaddrs[0];
- *setup_frm++ = eaddrs[1];
- *setup_frm++ = eaddrs[0];
- *setup_frm++ = eaddrs[1];
- *setup_frm++ = eaddrs[2];
- *setup_frm++ = eaddrs[3];
- *setup_frm++ = eaddrs[2];
- *setup_frm++ = eaddrs[3];
- *setup_frm++ = eaddrs[4];
- *setup_frm++ = eaddrs[5];
- *setup_frm++ = eaddrs[4];
- *setup_frm++ = eaddrs[5];
- }
-
- /* Add the broadcast address when doing perfect filtering */
- memset((void*) setup_frm, 0xff, 12);
- rmd->counts = 0x09000000 | 192 ;
- rmd->status = 0x80000000;
- st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TX);
- st_le32( (tbase+memCSR1), 1);
-
- while (rmd->status != 0x7fffffff);
- rmd->counts = 0x01000000;
-
- sc->TxMD = rmd+1;
-
- sc->irqInfo.hdl = (rtems_irq_hdl)dec21140Enet_interrupt_handler_entry;
- sc->irqInfo.on = no_op;
- sc->irqInfo.off = no_op;
- sc->irqInfo.isOn = NULL;
-
-#ifdef DEC_DEBUG
- printk( "dec2114x: Installing IRQ %d\n", sc->irqInfo.name );
-#endif
-#ifdef BSP_SHARED_HANDLER_SUPPORT
- st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
-#else
- st = BSP_install_rtems_irq_handler( &sc->irqInfo );
-#endif
-
- if (!st)
- rtems_panic ("dec2114x : Interrupt name %d already in use\n", sc->irqInfo.name );
-}
-
-static void
-dec21140_rxDaemon (void *arg)
-{
- volatile struct MD *rmd;
- struct dec21140_softc *sc;
- struct ifnet *ifp;
- struct ether_header *eh;
- struct mbuf *m;
- unsigned int i,len;
- rtems_event_set events;
-
- for (;;)
- {
-
- rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- for(i=0; i< NDECDRIVER; i++ )
- {
- sc = &dec21140_softc[i];
- if( sc->base )
- {
- if( events & sc->ioevent )
- {
- ifp = &sc->arpcom.ac_if;
- rmd = sc->nextRxMD;
-
- /*
- ** Read off all the packets we've received on this unit
- */
- while((rmd->status & 0x80000000) == 0)
- {
- /* printk("unit %i rx\n", ifp->if_unit ); */
-
- /* pass on the packet in the mbuf */
- len = (rmd->status >> 16) & 0x7ff;
- m = (struct mbuf *)(rmd->m);
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod (m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- ether_input (ifp, eh, m);
-
- /* get a new mbuf for the 21140 */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- rmd->m = m;
- rmd->buf1 = phys_to_bus(mtod(m, void *));
-
- /* mark the descriptor as ready to receive */
- rmd->status = 0x80000000;
-
- rmd=rmd->next;
- }
-
- sc->nextRxMD = rmd;
- }
- }
- }
-
- }
-}
-
-static void
-sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct dec21140_softc *dp = ifp->if_softc;
- volatile struct MD *tmd;
- volatile unsigned char *temp;
- struct mbuf *n;
- unsigned int len;
- volatile uint32_t *tbase;
-
- tbase = dp->base;
- /*
- * Waiting for Transmitter ready
- */
-
- tmd = dp->TxMD;
- n = m;
-
- while ((tmd->status & 0x80000000) != 0)
- {
- tmd=tmd->next;
- }
-
- len = 0;
- temp = (volatile unsigned char *)(bus_to_phys(tmd->buf1));
-
- for (;;)
- {
- len += m->m_len;
- memcpy((void*) temp, (char *)m->m_data, m->m_len);
- temp += m->m_len ;
- if ((m = m->m_next) == NULL)
- break;
- }
-
- if (len < ET_MINLEN) len = ET_MINLEN;
- tmd->counts = 0xe1000000 | (len & 0x7ff);
- tmd->status = 0x80000000;
-
- st_le32( (tbase+memCSR1), 0x1);
-
- m_freem(n);
-
- dp->TxMD = tmd->next;
-}
-
-/*
- * Driver transmit daemon
- */
-void
-dec21140_txDaemon (void *arg)
-{
- struct dec21140_softc *sc;
- struct ifnet *ifp;
- struct mbuf *m;
- int i;
- rtems_event_set events;
-
- for (;;)
- {
- /*
- * Wait for packets bound for any of the dec units
- */
- rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-
- for(i=0; i< NDECDRIVER; i++ )
- {
- sc = &dec21140_softc[i];
- if( sc->base )
- {
- if( events & sc->ioevent )
- {
- ifp = &sc->arpcom.ac_if;
-
- /*
- * Send packets till queue is empty
- */
- for(;;)
- {
- IF_DEQUEUE(&ifp->if_snd, m);
- if( !m ) break;
- /* printk("unit %i tx\n", ifp->if_unit ); */
- sendpacket (ifp, m);
- }
-
- ifp->if_flags &= ~IFF_OACTIVE;
- }
- }
- }
-
- }
-}
-
-static void
-dec21140_start (struct ifnet *ifp)
-{
- struct dec21140_softc *sc = ifp->if_softc;
- rtems_bsdnet_event_send( txDaemonTid, sc->ioevent );
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/*
- * Initialize and start the device
- */
-static void
-dec21140_init (void *arg)
-{
- struct dec21140_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- volatile uint32_t *tbase;
-
- /*
- * Set up DEC21140 hardware if its not already been done
- */
- if( !sc->irqInfo.hdl )
- {
- dec21140Enet_initialize_hardware (sc);
- }
-
- /*
- * Enable RX and TX
- */
- tbase = sc->base;
- st_le32( (tbase+memCSR5), IT_SETUP);
- st_le32( (tbase+memCSR7), IT_SETUP);
- st_le32( (tbase+memCSR6), CSR6_INIT | CSR6_TXRX);
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/*
- * Stop the device
- */
-static void
-dec21140_stop (struct dec21140_softc *sc)
-{
- volatile uint32_t *tbase;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Stop the transmitter
- */
- tbase = sc->base;
- st_le32( (tbase+memCSR7), NO_IT);
- st_le32( (tbase+memCSR6), CSR6_INIT);
-
- /* free((void*)sc->bufferBase); */
-}
-
-/*
- * Show interface statistics
- */
-static void
-dec21140_stats (struct dec21140_softc *sc)
-{
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Not First:%-8lu", sc->rxNotFirst);
- printf (" Not Last:%-8lu\n", sc->rxNotLast);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Runt:%-8lu", sc->rxRunt);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Collision:%-8lu\n", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Deferred:%-8lu", sc->txDeferred);
- printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
- printf (" No Carrier:%-8lu", sc->txLostCarrier);
- printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
- printf (" Late Collision:%-8lu\n", sc->txLateCollision);
- printf (" Underrun:%-8lu", sc->txUnderrun);
- printf (" Raw output wait:%-8lu\n", sc->txRawWait);
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-dec21140_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct dec21140_softc *sc = 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:
- dec21140_stop (sc);
- break;
-
- case IFF_UP:
- dec21140_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- dec21140_stop (sc);
- dec21140_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- dec21140_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-
-/*
-int iftap(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m )
-{
- int i;
-
- if( ifp->if_unit == 1 ) return 0;
-
- printf("unit %i, src ", ifp->if_unit );
- for(i=0; i< ETHER_ADDR_LEN; i++) printf("%02x", (char) eh->ether_shost[i] );
- printf(" dest ");
- for(i=0; i< ETHER_ADDR_LEN; i++) printf("%02x", (char) eh->ether_dhost[i] );
- printf("\n");
-
- return -1;
-}
-*/
-
-/*
- * Attach an DEC21140 driver to the system
- */
-int
-rtems_dec21140_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
-{
- struct dec21140_softc *sc;
- struct ifnet *ifp;
- char *unitName;
- int unitNumber;
- int mtu;
- unsigned char cvalue;
-#if defined(__i386__)
- uint32_t value;
- uint8_t interrupt;
-#endif
- int pbus, pdev, pfun;
-#if defined(__PPC__)
- int tmp;
- uint32_t lvalue;
-#endif
-
- /*
- * Get the instance number for the board we're going to configure
- * from the user.
- */
- if( (unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) == -1 )
- {
- return 0;
- }
- if( strcmp(unitName, DRIVER_PREFIX) )
- {
- printk("dec2114x : unit name '%s' not %s\n", unitName, DRIVER_PREFIX );
- return 0;
- }
-
- /*
- * Find the board
- */
- if ( pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21140,
- unitNumber-1, &pbus, &pdev, &pfun) == -1 ) {
- if ( pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21143,
- unitNumber-1, &pbus, &pdev, &pfun) != -1 ) {
-
- /* the 21143 chip must be enabled before it can be accessed */
-#if defined(__i386__)
- pci_write_config_dword(pbus, pdev, pfun, 0x40, 0 );
-#else
- pci_write_config_dword(pbus, pdev, pfun, 0x40, PCI_DEVICE_ID_DEC_21143);
-#endif
-
- } else {
- printk("dec2114x : device '%s' not found on PCI bus\n", config->name );
- return 0;
- }
- }
-
-#ifdef DEC_DEBUG
- else {
- printk("dec21140 : found device '%s', bus 0x%02x, dev 0x%02x, func 0x%02x\n",
- config->name, pbus, pdev, pfun);
- }
-#endif
-
- if ((unitNumber < 1) || (unitNumber > NDECDRIVER))
- {
- printk("dec2114x : unit %i is invalid, must be (1 <= n <= %d)\n",
- unitNumber, NDECDRIVER);
- return 0;
- }
-
- sc = &dec21140_softc[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL)
- {
- printk("dec2114x : unit %i already in use.\n", unitNumber );
- return 0;
- }
-
-
- /*
- ** Get this unit's rx/tx event
- */
- sc->ioevent = unit_signals[unitNumber-1];
-
- /*
- ** Save the buffer counts
- */
- sc->numRxbuffers = (config->rbuf_count) ? config->rbuf_count : NRXBUFS;
- sc->numTxbuffers = (config->xbuf_count) ? config->xbuf_count : NTXBUFS;
-
-
- /*
- * Get card address spaces & retrieve its isr vector
- */
-#if defined(__i386__)
-
- pci_read_config_dword(pbus, pdev, pfun, 16, &value);
- sc->port = value & ~IO_MASK;
-
- pci_read_config_dword(pbus, pdev, pfun, 20, &value);
- if (_CPU_is_paging_enabled())
- _CPU_map_phys_address((void **) &(sc->base),
- (void *)(value & ~MEM_MASK),
- DEC_REGISTER_SIZE ,
- PTE_CACHE_DISABLE | PTE_WRITABLE);
- else
- sc->base = (uint32_t *)(value & ~MEM_MASK);
-
- pci_read_config_byte(pbus, pdev, pfun, 60, &interrupt);
- cvalue = interrupt;
-#endif
-#if defined(__PPC__)
- (void)pci_read_config_dword(pbus,
- pdev,
- pfun,
- PCI_BASE_ADDRESS_0,
- &lvalue);
-
- sc->port = lvalue & (unsigned int)(~IO_MASK);
-
- (void)pci_read_config_dword(pbus,
- pdev,
- pfun,
- PCI_BASE_ADDRESS_1,
- &lvalue);
-
- tmp = (unsigned int)(lvalue & (unsigned int)(~MEM_MASK))
- + (unsigned int)PCI_MEM_BASE;
-
- sc->base = (uint32_t*)(tmp);
-
- pci_read_config_byte(pbus,
- pdev,
- pfun,
- PCI_INTERRUPT_LINE,
- &cvalue);
-
-#endif
-
- /*
- ** Prep the board
- */
-
- pci_write_config_word(pbus, pdev, pfun,
- PCI_COMMAND,
- (uint16_t) ( PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER ) );
-
- /*
- ** Store the interrupt name, we'll use it later when we initialize
- ** the board.
- */
- memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
- sc->irqInfo.name = cvalue;
-
-
-#ifdef DEC_DEBUG
- printk("dec2114x : unit %d base address %p.\n", unitNumber, sc->base);
-#endif
-
-
- /*
- ** Setup ethernet address
- */
- if (config->hardware_address) {
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
- ETHER_ADDR_LEN);
- }
- else {
- union {char c[64]; unsigned short s[32];} rombuf;
- int i;
-
- for (i=0; i<32; i++){
- rombuf.s[i] = eeget16( sc->base + memCSR9, i);
- }
-#if defined(__i386__)
- for (i=0 ; i<(ETHER_ADDR_LEN/2); i++){
- sc->arpcom.ac_enaddr[2*i] = rombuf.c[20+2*i+1];
- sc->arpcom.ac_enaddr[2*i+1] = rombuf.c[20+2*i];
- }
-#endif
-#if defined(__PPC__)
- memcpy (sc->arpcom.ac_enaddr, rombuf.c+20, ETHER_ADDR_LEN);
-#endif
- }
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- sc->acceptBroadcast = !config->ignore_broadcast;
-
- /*
- * Set up network interface values
- */
-
-/* ifp->if_tap = iftap; */
-
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = dec21140_init;
- ifp->if_ioctl = dec21140_ioctl;
- ifp->if_start = dec21140_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;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
-
-#ifdef DEC_DEBUG
- printk( "dec2114x : driver attached\n" );
-#endif
-
- /*
- * Start driver tasks if this is the first dec unit initialized
- */
- if (txDaemonTid == 0)
- {
- rxDaemonTid = rtems_bsdnet_newproc( "DCrx", 4096,
- dec21140_rxDaemon, NULL);
-
- txDaemonTid = rtems_bsdnet_newproc( "DCtx", 4096,
- dec21140_txDaemon, NULL);
-#ifdef DEC_DEBUG
- printk( "dec2114x : driver tasks created\n" );
-#endif
- }
-
- return 1;
-};
-
-#endif /* DEC21140_SUPPORTED */
diff --git a/c/src/libchip/network/elnk.c b/c/src/libchip/network/elnk.c
deleted file mode 100644
index 29adbe9c21..0000000000
--- a/c/src/libchip/network/elnk.c
+++ /dev/null
@@ -1,3553 +0,0 @@
-/*
- * RTEMS driver for Etherlink based Ethernet Controllers
- *
- * Copyright (C) 2003, Gregory Menke, NASA/GSFC
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- * elnk.c
- *
- *
- */
-
-
-/*
- * Portions of this driver are taken from the Freebsd if_xl.c driver,
- * version "1.133 2003/03/19 01:48:14" and are covered by the license
- * text included below that was taken verbatim from the original file.
- * More particularly, all structures, variables, and #defines prefixed
- * with XL_ or xl_, along with their associated comments were taken
- * directly from the Freebsd driver and modified as required to suit the
- * purposes of this one. Additionally, much of the device setup &
- * manipulation logic was also copied and modified to suit. All types
- * and functions beginning with elnk are either my own creations or were
- * adapted from other RTEMS components, and regardless, are subject to
- * the standard OAR licensing terms given in the comments at the top of
- * this file.
- *
- * Greg Menke, 6/11/2003
- */
-
- /*
- * Copyright (c) 1997, 1998, 1999
- * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-
-/*
- * This driver only supports architectures with the new style
- * exception processing. The following checks try to keep this
- * from being compiled on systems which can't support this driver.
- */
-
-#if defined(__i386__)
-#define ELNK_SUPPORTED
- #define PCI_DRAM_OFFSET 0
-#endif
-
-#if defined(__PPC__)
-#define ELNK_SUPPORTED
-#endif
-
-#include <bsp.h>
-
-#if !defined(PCI_DRAM_OFFSET)
- #undef ELNK_SUPPORTED
-#endif
-
-/* #undef ELNK_SUPPORTED */
-
-
-#if defined(ELNK_SUPPORTED)
-#include <rtems/pci.h>
-
-#if defined(__PPC__)
-#include <libcpu/byteorder.h>
-#include <libcpu/io.h>
-#endif
-
-#if defined(__i386__)
-#include <libcpu/byteorder.h>
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <rtems/error.h>
-#include <rtems/bspIo.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 <net/if_media.h>
-#include <dev/mii/mii.h>
-#include <bsp/irq.h>
-
-#if defined(__i386__)
-#define IO_MASK 0x3
-#define MEM_MASK 0xF
-#endif
-
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef free
-#undef free
-#endif
-
-#define ELNK_DEBUG
-
-
-#define DRIVER_PREFIX "elnk"
-
-
-
-
-
-/*
-* These buffers allocated for each unit, so ensure
-*
-* rtems_bsdnet_config.mbuf_bytecount
-* rtems_bsdnet_config.mbuf_cluster_bytecount
-*
-* are adequately sized to provide enough clusters and mbufs for all the
-* units. The default bsdnet configuration is sufficient for one unit,
-* but will be nearing exhaustion with 2 or more. Although a little
-* expensive in memory, the following configuration should eliminate all
-* mbuf/cluster issues;
-*
-* rtems_bsdnet_config.mbuf_bytecount = 128*1024;
-* rtems_bsdnet_config.mbuf_cluster_bytecount = 256*1024;
-*
-* The default size in buffers of the rx & tx rings are given below.
-* This driver honors the rtems_bsdnet_ifconfig fields 'rbuf_count' and
-* 'xbuf_count', allowing the user to specify something else.
-*/
-
-#define RX_RING_SIZE 16 /* default number of receive buffers */
-#define TX_RING_SIZE 16 /* default number of transmit buffers */
-
-
-/*
- * Number of boards supported by this driver
- */
-#define NUM_UNITS 8
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define XL_PACKET_SIZE 1540
-
-
-/*
-** Events, one per unit. The event is sent to the rx task from the isr
-** or from the stack to the tx task whenever a unit needs service. The
-** rx/tx tasks identify the requesting unit(s) by their particular
-** events so only requesting units are serviced.
-*/
-
-static rtems_event_set unit_signals[NUM_UNITS]= { RTEMS_EVENT_1,
- RTEMS_EVENT_2,
- RTEMS_EVENT_3,
- RTEMS_EVENT_4,
- RTEMS_EVENT_5,
- RTEMS_EVENT_6,
- RTEMS_EVENT_7,
- RTEMS_EVENT_8 };
-
-
-
-
-#if defined(__PPC__)
-#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
-#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
-#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
-#else
-extern void Wait_X_ms( unsigned int timeToWait );
-#define phys_to_bus(address) ((unsigned int) ((address)))
-#define bus_to_phys(address) ((unsigned int) ((address)))
-#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
-#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
-#endif
-
-/* the actual duration waited in DELAY is not especially predictable,
- * though it will be consistent on a given host. It should not be
- * relied upon for specific timing given the vague per-bsp,
- * per-architecture implementation of the actual delay function. It
- * would probably be helpful to make this more accurate at some point...
- */
-#define DELAY(n) rtems_bsp_delay_in_bus_cycles( n*20 )
-
-
-
-
-/*
- * Register layouts.
- */
-#define XL_COMMAND 0x0E
-#define XL_STATUS 0x0E
-
-#define XL_TX_STATUS 0x1B
-#define XL_TX_FREE 0x1C
-#define XL_DMACTL 0x20
-#define XL_DOWNLIST_PTR 0x24
-#define XL_DOWN_POLL 0x2D /* 3c90xB only */
-#define XL_TX_FREETHRESH 0x2F
-#define XL_UPLIST_PTR 0x38
-#define XL_UPLIST_STATUS 0x30
-#define XL_UP_POLL 0x3D /* 3c90xB only */
-
-#define XL_PKTSTAT_UP_STALLED 0x00002000
-#define XL_PKTSTAT_UP_ERROR 0x00004000
-#define XL_PKTSTAT_UP_CMPLT 0x00008000
-
-#define XL_DMACTL_DN_CMPLT_REQ 0x00000002
-#define XL_DMACTL_DOWN_STALLED 0x00000004
-#define XL_DMACTL_UP_CMPLT 0x00000008
-#define XL_DMACTL_DOWN_CMPLT 0x00000010
-#define XL_DMACTL_UP_RX_EARLY 0x00000020
-#define XL_DMACTL_ARM_COUNTDOWN 0x00000040
-#define XL_DMACTL_DOWN_INPROG 0x00000080
-#define XL_DMACTL_COUNTER_SPEED 0x00000100
-#define XL_DMACTL_DOWNDOWN_MODE 0x00000200
-#define XL_DMACTL_TARGET_ABORT 0x40000000
-#define XL_DMACTL_MASTER_ABORT 0x80000000
-
-/*
- * Command codes. Some command codes require that we wait for
- * the CMD_BUSY flag to clear. Those codes are marked as 'mustwait.'
- */
-#define XL_CMD_RESET 0x0000 /* mustwait */
-#define XL_CMD_WINSEL 0x0800
-#define XL_CMD_COAX_START 0x1000
-#define XL_CMD_RX_DISABLE 0x1800
-#define XL_CMD_RX_ENABLE 0x2000
-#define XL_CMD_RX_RESET 0x2800 /* mustwait */
-#define XL_CMD_UP_STALL 0x3000 /* mustwait */
-#define XL_CMD_UP_UNSTALL 0x3001
-#define XL_CMD_DOWN_STALL 0x3002 /* mustwait */
-#define XL_CMD_DOWN_UNSTALL 0x3003
-#define XL_CMD_RX_DISCARD 0x4000
-#define XL_CMD_TX_ENABLE 0x4800
-#define XL_CMD_TX_DISABLE 0x5000
-#define XL_CMD_TX_RESET 0x5800 /* mustwait */
-#define XL_CMD_INTR_FAKE 0x6000
-#define XL_CMD_INTR_ACK 0x6800
-#define XL_CMD_INTR_ENB 0x7000
-#define XL_CMD_STAT_ENB 0x7800
-#define XL_CMD_RX_SET_FILT 0x8000
-#define XL_CMD_RX_SET_THRESH 0x8800
-#define XL_CMD_TX_SET_THRESH 0x9000
-#define XL_CMD_TX_SET_START 0x9800
-#define XL_CMD_DMA_UP 0xA000
-#define XL_CMD_DMA_STOP 0xA001
-#define XL_CMD_STATS_ENABLE 0xA800
-#define XL_CMD_STATS_DISABLE 0xB000
-#define XL_CMD_COAX_STOP 0xB800
-
-#define XL_CMD_SET_TX_RECLAIM 0xC000 /* 3c905B only */
-#define XL_CMD_RX_SET_HASH 0xC800 /* 3c905B only */
-
-#define XL_HASH_SET 0x0400
-#define XL_HASHFILT_SIZE 256
-
-/*
- * status codes
- * Note that bits 15 to 13 indicate the currently visible register window
- * which may be anything from 0 to 7.
- */
-#define XL_STAT_INTLATCH 0x0001 /* 0 */
-#define XL_STAT_ADFAIL 0x0002 /* 1 */
-#define XL_STAT_TX_COMPLETE 0x0004 /* 2 */
-#define XL_STAT_TX_AVAIL 0x0008 /* 3 first generation */
-#define XL_STAT_RX_COMPLETE 0x0010 /* 4 */
-#define XL_STAT_RX_EARLY 0x0020 /* 5 */
-#define XL_STAT_INTREQ 0x0040 /* 6 */
-#define XL_STAT_STATSOFLOW 0x0080 /* 7 */
-#define XL_STAT_DMADONE 0x0100 /* 8 first generation */
-#define XL_STAT_LINKSTAT 0x0100 /* 8 3c509B */
-#define XL_STAT_DOWN_COMPLETE 0x0200 /* 9 */
-#define XL_STAT_UP_COMPLETE 0x0400 /* 10 */
-#define XL_STAT_DMABUSY 0x0800 /* 11 first generation */
-#define XL_STAT_CMDBUSY 0x1000 /* 12 */
-
-/*
- * Interrupts we normally want enabled.
- */
-#define XL_INTRS \
- (XL_STAT_UP_COMPLETE | XL_STAT_STATSOFLOW | XL_STAT_ADFAIL| \
- XL_STAT_DOWN_COMPLETE | XL_STAT_TX_COMPLETE | XL_STAT_INTLATCH)
-
-
-
-/*
- * General constants that are fun to know.
- *
- * 3Com PCI vendor ID
- */
-#define TC_VENDORID 0x10B7
-
-/*
- * 3Com chip device IDs.
- */
-#define TC_DEVICEID_BOOMERANG_10BT 0x9000
-#define TC_DEVICEID_BOOMERANG_10BT_COMBO 0x9001
-#define TC_DEVICEID_BOOMERANG_10_100BT 0x9050
-#define TC_DEVICEID_BOOMERANG_100BT4 0x9051
-#define TC_DEVICEID_KRAKATOA_10BT 0x9004
-#define TC_DEVICEID_KRAKATOA_10BT_COMBO 0x9005
-#define TC_DEVICEID_KRAKATOA_10BT_TPC 0x9006
-#define TC_DEVICEID_CYCLONE_10FL 0x900A
-#define TC_DEVICEID_HURRICANE_10_100BT 0x9055
-#define TC_DEVICEID_CYCLONE_10_100BT4 0x9056
-#define TC_DEVICEID_CYCLONE_10_100_COMBO 0x9058
-#define TC_DEVICEID_CYCLONE_10_100FX 0x905A
-#define TC_DEVICEID_TORNADO_10_100BT 0x9200
-#define TC_DEVICEID_TORNADO_10_100BT_920B 0x9201
-#define TC_DEVICEID_HURRICANE_10_100BT_SERV 0x9800
-#define TC_DEVICEID_TORNADO_10_100BT_SERV 0x9805
-#define TC_DEVICEID_HURRICANE_SOHO100TX 0x7646
-#define TC_DEVICEID_TORNADO_HOMECONNECT 0x4500
-#define TC_DEVICEID_HURRICANE_555 0x5055
-#define TC_DEVICEID_HURRICANE_556 0x6055
-#define TC_DEVICEID_HURRICANE_556B 0x6056
-#define TC_DEVICEID_HURRICANE_575A 0x5057
-#define TC_DEVICEID_HURRICANE_575B 0x5157
-#define TC_DEVICEID_HURRICANE_575C 0x5257
-#define TC_DEVICEID_HURRICANE_656 0x6560
-#define TC_DEVICEID_HURRICANE_656B 0x6562
-#define TC_DEVICEID_TORNADO_656C 0x6564
-
-
-
-#define XL_RXSTAT_LENMASK 0x00001FFF
-#define XL_RXSTAT_UP_ERROR 0x00004000
-#define XL_RXSTAT_UP_CMPLT 0x00008000
-#define XL_RXSTAT_UP_OVERRUN 0x00010000
-#define XL_RXSTAT_RUNT 0x00020000
-#define XL_RXSTAT_ALIGN 0x00040000
-#define XL_RXSTAT_CRC 0x00080000
-#define XL_RXSTAT_OVERSIZE 0x00100000
-#define XL_RXSTAT_DRIBBLE 0x00800000
-#define XL_RXSTAT_UP_OFLOW 0x01000000
-#define XL_RXSTAT_IPCKERR 0x02000000 /* 3c905B only */
-#define XL_RXSTAT_TCPCKERR 0x04000000 /* 3c905B only */
-#define XL_RXSTAT_UDPCKERR 0x08000000 /* 3c905B only */
-#define XL_RXSTAT_BUFEN 0x10000000 /* 3c905B only */
-#define XL_RXSTAT_IPCKOK 0x20000000 /* 3c905B only */
-#define XL_RXSTAT_TCPCOK 0x40000000 /* 3c905B only */
-#define XL_RXSTAT_UDPCKOK 0x80000000 /* 3c905B only */
-
-#define XL_TXSTAT_LENMASK 0x00001FFF
-#define XL_TXSTAT_CRCDIS 0x00002000
-#define XL_TXSTAT_TX_INTR 0x00008000
-#define XL_TXSTAT_DL_COMPLETE 0x00010000
-#define XL_TXSTAT_IPCKSUM 0x02000000 /* 3c905B only */
-#define XL_TXSTAT_TCPCKSUM 0x04000000 /* 3c905B only */
-#define XL_TXSTAT_UDPCKSUM 0x08000000 /* 3c905B only */
-#define XL_TXSTAT_RND_DEFEAT 0x10000000 /* 3c905B only */
-#define XL_TXSTAT_EMPTY 0x20000000 /* 3c905B only */
-#define XL_TXSTAT_DL_INTR 0x80000000
-
-
-#define XL_FLAG_FUNCREG 0x0001
-#define XL_FLAG_PHYOK 0x0002
-#define XL_FLAG_EEPROM_OFFSET_30 0x0004
-#define XL_FLAG_WEIRDRESET 0x0008
-#define XL_FLAG_8BITROM 0x0010
-#define XL_FLAG_INVERT_LED_PWR 0x0020
-#define XL_FLAG_INVERT_MII_PWR 0x0040
-#define XL_FLAG_NO_XCVR_PWR 0x0080
-#define XL_FLAG_USE_MMIO 0x0100
-
-
-
-#define XL_EE_READ 0x0080 /* read, 5 bit address */
-#define XL_EE_WRITE 0x0040 /* write, 5 bit address */
-#define XL_EE_ERASE 0x00c0 /* erase, 5 bit address */
-#define XL_EE_EWEN 0x0030 /* erase, no data needed */
-#define XL_EE_8BIT_READ 0x0200 /* read, 8 bit address */
-#define XL_EE_BUSY 0x8000
-
-#define XL_EE_EADDR0 0x00 /* station address, first word */
-#define XL_EE_EADDR1 0x01 /* station address, next word, */
-#define XL_EE_EADDR2 0x02 /* station address, last word */
-#define XL_EE_PRODID 0x03 /* product ID code */
-#define XL_EE_MDATA_DATE 0x04 /* manufacturing data, date */
-#define XL_EE_MDATA_DIV 0x05 /* manufacturing data, division */
-#define XL_EE_MDATA_PCODE 0x06 /* manufacturing data, product code */
-#define XL_EE_MFG_ID 0x07
-#define XL_EE_PCI_PARM 0x08
-#define XL_EE_ROM_ONFO 0x09
-#define XL_EE_OEM_ADR0 0x0A
-#define XL_EE_OEM_ADR1 0x0B
-#define XL_EE_OEM_ADR2 0x0C
-#define XL_EE_SOFTINFO1 0x0D
-#define XL_EE_COMPAT 0x0E
-#define XL_EE_SOFTINFO2 0x0F
-#define XL_EE_CAPS 0x10 /* capabilities word */
-#define XL_EE_RSVD0 0x11
-#define XL_EE_ICFG_0 0x12
-#define XL_EE_ICFG_1 0x13
-#define XL_EE_RSVD1 0x14
-#define XL_EE_SOFTINFO3 0x15
-#define XL_EE_RSVD_2 0x16
-
-/*
- * Bits in the capabilities word
- */
-#define XL_CAPS_PNP 0x0001
-#define XL_CAPS_FULL_DUPLEX 0x0002
-#define XL_CAPS_LARGE_PKTS 0x0004
-#define XL_CAPS_SLAVE_DMA 0x0008
-#define XL_CAPS_SECOND_DMA 0x0010
-#define XL_CAPS_FULL_BM 0x0020
-#define XL_CAPS_FRAG_BM 0x0040
-#define XL_CAPS_CRC_PASSTHRU 0x0080
-#define XL_CAPS_TXDONE 0x0100
-#define XL_CAPS_NO_TXLENGTH 0x0200
-#define XL_CAPS_RX_REPEAT 0x0400
-#define XL_CAPS_SNOOPING 0x0800
-#define XL_CAPS_100MBPS 0x1000
-#define XL_CAPS_PWRMGMT 0x2000
-
-
-
-/*
- * Window 0 registers
- */
-#define XL_W0_EE_DATA 0x0C
-#define XL_W0_EE_CMD 0x0A
-#define XL_W0_RSRC_CFG 0x08
-#define XL_W0_ADDR_CFG 0x06
-#define XL_W0_CFG_CTRL 0x04
-
-#define XL_W0_PROD_ID 0x02
-#define XL_W0_MFG_ID 0x00
-
-/*
- * Window 1
- */
-
-#define XL_W1_TX_FIFO 0x10
-
-#define XL_W1_FREE_TX 0x0C
-#define XL_W1_TX_STATUS 0x0B
-#define XL_W1_TX_TIMER 0x0A
-#define XL_W1_RX_STATUS 0x08
-#define XL_W1_RX_FIFO 0x00
-
-/*
- * RX status codes
- */
-#define XL_RXSTATUS_OVERRUN 0x01
-#define XL_RXSTATUS_RUNT 0x02
-#define XL_RXSTATUS_ALIGN 0x04
-#define XL_RXSTATUS_CRC 0x08
-#define XL_RXSTATUS_OVERSIZE 0x10
-#define XL_RXSTATUS_DRIBBLE 0x20
-
-/*
- * TX status codes
- */
-#define XL_TXSTATUS_RECLAIM 0x02 /* 3c905B only */
-#define XL_TXSTATUS_OVERFLOW 0x04
-#define XL_TXSTATUS_MAXCOLS 0x08
-#define XL_TXSTATUS_UNDERRUN 0x10
-#define XL_TXSTATUS_JABBER 0x20
-#define XL_TXSTATUS_INTREQ 0x40
-#define XL_TXSTATUS_COMPLETE 0x80
-
-/*
- * Window 2
- */
-#define XL_W2_RESET_OPTIONS 0x0C /* 3c905B only */
-#define XL_W2_STATION_MASK_HI 0x0A
-#define XL_W2_STATION_MASK_MID 0x08
-#define XL_W2_STATION_MASK_LO 0x06
-#define XL_W2_STATION_ADDR_HI 0x04
-#define XL_W2_STATION_ADDR_MID 0x02
-#define XL_W2_STATION_ADDR_LO 0x00
-
-#define XL_RESETOPT_FEATUREMASK 0x0001|0x0002|0x004
-#define XL_RESETOPT_D3RESETDIS 0x0008
-#define XL_RESETOPT_DISADVFD 0x0010
-#define XL_RESETOPT_DISADV100 0x0020
-#define XL_RESETOPT_DISAUTONEG 0x0040
-#define XL_RESETOPT_DEBUGMODE 0x0080
-#define XL_RESETOPT_FASTAUTO 0x0100
-#define XL_RESETOPT_FASTEE 0x0200
-#define XL_RESETOPT_FORCEDCONF 0x0400
-#define XL_RESETOPT_TESTPDTPDR 0x0800
-#define XL_RESETOPT_TEST100TX 0x1000
-#define XL_RESETOPT_TEST100RX 0x2000
-
-#define XL_RESETOPT_INVERT_LED 0x0010
-#define XL_RESETOPT_INVERT_MII 0x4000
-
-/*
- * Window 3 (fifo management)
- */
-#define XL_W3_INTERNAL_CFG 0x00
-#define XL_W3_MAXPKTSIZE 0x04 /* 3c905B only */
-#define XL_W3_RESET_OPT 0x08
-#define XL_W3_FREE_TX 0x0C
-#define XL_W3_FREE_RX 0x0A
-#define XL_W3_MAC_CTRL 0x06
-
-#define XL_ICFG_CONNECTOR_MASK 0x00F00000
-#define XL_ICFG_CONNECTOR_BITS 20
-
-#define XL_ICFG_RAMSIZE_MASK 0x00000007
-#define XL_ICFG_RAMWIDTH 0x00000008
-#define XL_ICFG_ROMSIZE_MASK (0x00000040|0x00000080)
-#define XL_ICFG_DISABLE_BASSD 0x00000100
-#define XL_ICFG_RAMLOC 0x00000200
-#define XL_ICFG_RAMPART (0x00010000|0x00020000)
-#define XL_ICFG_XCVRSEL (0x00100000|0x00200000|0x00400000)
-#define XL_ICFG_AUTOSEL 0x01000000
-
-#define XL_XCVR_10BT 0x00
-#define XL_XCVR_AUI 0x01
-#define XL_XCVR_RSVD_0 0x02
-#define XL_XCVR_COAX 0x03
-#define XL_XCVR_100BTX 0x04
-#define XL_XCVR_100BFX 0x05
-#define XL_XCVR_MII 0x06
-#define XL_XCVR_RSVD_1 0x07
-#define XL_XCVR_AUTO 0x08 /* 3c905B only */
-
-#define XL_MACCTRL_DEFER_EXT_END 0x0001
-#define XL_MACCTRL_DEFER_0 0x0002
-#define XL_MACCTRL_DEFER_1 0x0004
-#define XL_MACCTRL_DEFER_2 0x0008
-#define XL_MACCTRL_DEFER_3 0x0010
-#define XL_MACCTRL_DUPLEX 0x0020
-#define XL_MACCTRL_ALLOW_LARGE_PACK 0x0040
-#define XL_MACCTRL_EXTEND_AFTER_COL 0x0080 (3c905B only)
-#define XL_MACCTRL_FLOW_CONTROL_ENB 0x0100 (3c905B only)
-#define XL_MACCTRL_VLT_END 0x0200 (3c905B only)
-
-/*
- * The 'reset options' register contains power-on reset values
- * loaded from the EEPROM. This includes the supported media
- * types on the card. It is also known as the media options register.
- */
-#define XL_W3_MEDIA_OPT 0x08
-
-#define XL_MEDIAOPT_BT4 0x0001 /* MII */
-#define XL_MEDIAOPT_BTX 0x0002 /* on-chip */
-#define XL_MEDIAOPT_BFX 0x0004 /* on-chip */
-#define XL_MEDIAOPT_BT 0x0008 /* on-chip */
-#define XL_MEDIAOPT_BNC 0x0010 /* on-chip */
-#define XL_MEDIAOPT_AUI 0x0020 /* on-chip */
-#define XL_MEDIAOPT_MII 0x0040 /* MII */
-#define XL_MEDIAOPT_VCO 0x0100 /* 1st gen chip only */
-
-#define XL_MEDIAOPT_10FL 0x0100 /* 3x905B only, on-chip */
-#define XL_MEDIAOPT_MASK 0x01FF
-
-/*
- * Window 4 (diagnostics)
- */
-#define XL_W4_UPPERBYTESOK 0x0D
-#define XL_W4_BADSSD 0x0C
-#define XL_W4_MEDIA_STATUS 0x0A
-#define XL_W4_PHY_MGMT 0x08
-#define XL_W4_NET_DIAG 0x06
-#define XL_W4_FIFO_DIAG 0x04
-#define XL_W4_VCO_DIAG 0x02
-
-#define XL_W4_CTRLR_STAT 0x08
-#define XL_W4_TX_DIAG 0x00
-
-#define XL_MII_CLK 0x01
-#define XL_MII_DATA 0x02
-#define XL_MII_DIR 0x04
-
-#define XL_MEDIA_SQE 0x0008
-#define XL_MEDIA_10TP 0x00C0
-#define XL_MEDIA_LNK 0x0080
-#define XL_MEDIA_LNKBEAT 0x0800
-
-#define XL_MEDIASTAT_CRCSTRIP 0x0004
-#define XL_MEDIASTAT_SQEENB 0x0008
-#define XL_MEDIASTAT_COLDET 0x0010
-#define XL_MEDIASTAT_CARRIER 0x0020
-#define XL_MEDIASTAT_JABGUARD 0x0040
-#define XL_MEDIASTAT_LINKBEAT 0x0080
-#define XL_MEDIASTAT_JABDETECT 0x0200
-#define XL_MEDIASTAT_POLREVERS 0x0400
-#define XL_MEDIASTAT_LINKDETECT 0x0800
-#define XL_MEDIASTAT_TXINPROG 0x1000
-#define XL_MEDIASTAT_DCENB 0x4000
-#define XL_MEDIASTAT_AUIDIS 0x8000
-
-#define XL_NETDIAG_TEST_LOWVOLT 0x0001
-#define XL_NETDIAG_ASIC_REVMASK (0x0002|0x0004|0x0008|0x0010|0x0020)
-#define XL_NETDIAG_UPPER_BYTES_ENABLE 0x0040
-#define XL_NETDIAG_STATS_ENABLED 0x0080
-#define XL_NETDIAG_TX_FATALERR 0x0100
-#define XL_NETDIAG_TRANSMITTING 0x0200
-#define XL_NETDIAG_RX_ENABLED 0x0400
-#define XL_NETDIAG_TX_ENABLED 0x0800
-#define XL_NETDIAG_FIFO_LOOPBACK 0x1000
-#define XL_NETDIAG_MAC_LOOPBACK 0x2000
-#define XL_NETDIAG_ENDEC_LOOPBACK 0x4000
-#define XL_NETDIAG_EXTERNAL_LOOP 0x8000
-
-/*
- * Window 5
- */
-#define XL_W5_STAT_ENB 0x0C
-#define XL_W5_INTR_ENB 0x0A
-#define XL_W5_RECLAIM_THRESH 0x09 /* 3c905B only */
-#define XL_W5_RX_FILTER 0x08
-#define XL_W5_RX_EARLYTHRESH 0x06
-#define XL_W5_TX_AVAILTHRESH 0x02
-#define XL_W5_TX_STARTTHRESH 0x00
-
-/*
- * RX filter bits
- */
-#define XL_RXFILTER_INDIVIDUAL 0x01
-#define XL_RXFILTER_ALLMULTI 0x02
-#define XL_RXFILTER_BROADCAST 0x04
-#define XL_RXFILTER_ALLFRAMES 0x08
-#define XL_RXFILTER_MULTIHASH 0x10 /* 3c905B only */
-
-/*
- * Window 6 (stats)
- */
-#define XL_W6_TX_BYTES_OK 0x0C
-#define XL_W6_RX_BYTES_OK 0x0A
-#define XL_W6_UPPER_FRAMES_OK 0x09
-#define XL_W6_DEFERRED 0x08
-#define XL_W6_RX_OK 0x07
-#define XL_W6_TX_OK 0x06
-#define XL_W6_RX_OVERRUN 0x05
-#define XL_W6_COL_LATE 0x04
-#define XL_W6_COL_SINGLE 0x03
-#define XL_W6_COL_MULTIPLE 0x02
-#define XL_W6_SQE_ERRORS 0x01
-#define XL_W6_CARRIER_LOST 0x00
-
-/*
- * Window 7 (bus master control)
- */
-#define XL_W7_BM_ADDR 0x00
-#define XL_W7_BM_LEN 0x06
-#define XL_W7_BM_STATUS 0x0B
-#define XL_W7_BM_TIMEr 0x0A
-
-/*
- * bus master control registers
- */
-#define XL_BM_PKTSTAT 0x20
-#define XL_BM_DOWNLISTPTR 0x24
-#define XL_BM_FRAGADDR 0x28
-#define XL_BM_FRAGLEN 0x2C
-#define XL_BM_TXFREETHRESH 0x2F
-#define XL_BM_UPPKTSTAT 0x30
-#define XL_BM_UPLISTPTR 0x38
-
-
-
-
-
-
-
-
-struct xl_mii_frame {
- u_int8_t mii_stdelim;
- u_int8_t mii_opcode;
- u_int8_t mii_phyaddr;
- u_int8_t mii_regaddr;
- u_int8_t mii_turnaround;
- u_int16_t mii_data;
-};
-
-/*
- * MII constants
- */
-#define XL_MII_STARTDELIM 0x01
-#define XL_MII_READOP 0x02
-#define XL_MII_WRITEOP 0x01
-#define XL_MII_TURNAROUND 0x02
-
-
-
-/*
- * The 3C905B adapters implement a few features that we want to
- * take advantage of, namely the multicast hash filter. With older
- * chips, you only have the option of turning on reception of all
- * multicast frames, which is kind of lame.
- *
- * We also use this to decide on a transmit strategy. For the 3c90xB
- * cards, we can use polled descriptor mode, which reduces CPU overhead.
- */
-#define XL_TYPE_905B 1
-#define XL_TYPE_90X 2
-
-#define XL_FLAG_FUNCREG 0x0001
-#define XL_FLAG_PHYOK 0x0002
-#define XL_FLAG_EEPROM_OFFSET_30 0x0004
-#define XL_FLAG_WEIRDRESET 0x0008
-#define XL_FLAG_8BITROM 0x0010
-#define XL_FLAG_INVERT_LED_PWR 0x0020
-#define XL_FLAG_INVERT_MII_PWR 0x0040
-#define XL_FLAG_NO_XCVR_PWR 0x0080
-#define XL_FLAG_USE_MMIO 0x0100
-
-#define XL_NO_XCVR_PWR_MAGICBITS 0x0900
-
-
-#define XL_MIN_FRAMELEN 60
-
-#define XL_LAST_FRAG 0x80000000
-
-
-
-
-
-
-
-struct xl_stats
-{
- /* accumulated stats */
- u_int16_t xl_carrier_lost;
- u_int16_t xl_sqe_errs;
- u_int16_t xl_tx_multi_collision;
- u_int16_t xl_tx_single_collision;
- u_int16_t xl_tx_late_collision;
- u_int16_t xl_rx_overrun;
- u_int16_t xl_tx_deferred;
-
- u_int32_t xl_rx_bytes_ok;
- u_int32_t xl_tx_bytes_ok;
-
- u_int32_t xl_tx_frames_ok;
- u_int32_t xl_rx_frames_ok;
-
- u_int16_t xl_badssd;
-
- /* non-accumulated stats */
- u_int16_t intstatus;
- u_int16_t rxstatus;
- u_int8_t txstatus;
- u_int16_t mediastatus;
-
- u_int32_t txcomplete_ints;
-
- u_int16_t miianr, miipar, miistatus, miicmd;
-
- u_int32_t device_interrupts;
- u_int32_t internalconfig;
- u_int16_t mac_control;
-
- u_int16_t smbstatus;
- u_int32_t dmactl;
- u_int16_t txfree;
-};
-
-
-
-struct xl_type
-{
- u_int16_t xl_vid;
- u_int16_t xl_did;
- char *xl_name;
-};
-
-
-
-/*
- * Various supported device vendors/types and their names.
- */
-static struct xl_type xl_devs[] = {
- { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
- "3Com 3c900-TPO Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
- "3Com 3c900-COMBO Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_BOOMERANG_10_100BT,
- "3Com 3c905-TX Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
- "3Com 3c905-T4 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT,
- "3Com 3c900B-TPO Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT_COMBO,
- "3Com 3c900B-COMBO Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT_TPC,
- "3Com 3c900B-TPC Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_CYCLONE_10FL,
- "3Com 3c900B-FL Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_10_100BT,
- "3Com 3c905B-TX Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT4,
- "3Com 3c905B-T4 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100FX,
- "3Com 3c905B-FX/SC Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100_COMBO,
- "3Com 3c905B-COMBO Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT,
- "3Com 3c905C-TX Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT_920B,
- "3Com 3c920B-EMB Integrated Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_10_100BT_SERV,
- "3Com 3c980 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT_SERV,
- "3Com 3c980C Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_SOHO100TX,
- "3Com 3cSOHO100-TX OfficeConnect" },
- { TC_VENDORID, TC_DEVICEID_TORNADO_HOMECONNECT,
- "3Com 3c450-TX HomeConnect" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_555,
- "3Com 3c555 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_556,
- "3Com 3c556 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_556B,
- "3Com 3c556B Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_575A,
- "3Com 3c575TX Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_575B,
- "3Com 3c575B Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_575C,
- "3Com 3c575C Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_656,
- "3Com 3c656 Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_HURRICANE_656B,
- "3Com 3c656B Fast Etherlink XL" },
- { TC_VENDORID, TC_DEVICEID_TORNADO_656C,
- "3Com 3c656C Fast Etherlink XL" },
- { 0, 0, NULL }
-};
-
-
-#define XL_TIMEOUT 1000
-
-
-
-
-
-
-/* rx message descriptor entry, ensure the struct is aligned to 8 bytes */
-struct RXMD
-{
- /* used by hardware */
- volatile uint32_t next;
- volatile uint32_t status;
- volatile uint32_t addr;
- volatile uint32_t length;
- /* used by software */
- struct mbuf *mbuf; /* scratch variable used in the tx ring */
- struct RXMD *next_md;
-} __attribute__ ((aligned (8), packed));
-
-
-
-
-
-#define NUM_FRAGS 6
-
-/*
- * tx message descriptor entry, ensure the struct is aligned to 8 bytes
- */
-
-struct tfrag
-{
- volatile uint32_t addr;
- volatile uint32_t length;
-} __attribute__ ((packed));
-
-struct TXMD
-{
- /* used by hardware */
- volatile uint32_t next;
- volatile uint32_t status;
- struct tfrag txfrags[NUM_FRAGS];
- /* used by software */
- struct mbuf *mbuf; /* scratch variable used in the tx ring */
- struct TXMD *next_md, *chainptr;
-} __attribute__ ((aligned (8), packed));
-
-
-
-
-
-#define NUM_CHAIN_LENGTHS 50
-
-
-
-/*
- * Per-device data
- */
-struct elnk_softc
-{
- struct arpcom arpcom;
-
- rtems_irq_connect_data irqInfo;
- rtems_event_set ioevent;
- unsigned int ioaddr;
-
- unsigned char *bufferBase, *ringBase;
-
- struct RXMD *rx_ring, *curr_rx_md;
- struct TXMD *tx_ring, *last_tx_md, *last_txchain_head;
-
- rtems_id stat_timer_id;
- uint32_t stats_update_ticks;
-
- struct xl_stats xl_stats;
-
- u_int8_t xl_unit; /* interface number */
- u_int8_t xl_type;
- int xl_flags;
- u_int16_t xl_media;
- u_int16_t xl_caps;
- u_int32_t xl_xcvr;
- u_int8_t xl_stats_no_timeout;
- u_int16_t xl_tx_thresh;
-
- int tx_idle;
-
- short chain_lengths[NUM_CHAIN_LENGTHS];
- int chlenIndex;
-
- unsigned short vendorID, deviceID;
- int acceptBroadcast;
- int numTxbuffers, numRxbuffers;
-};
-
-static struct elnk_softc elnk_softc[NUM_UNITS];
-static rtems_id rxDaemonTid;
-static rtems_id txDaemonTid;
-static rtems_id chainRecoveryQueue;
-
-
-
-
-
-
-
-#if defined(__i386__)
-
-#define CSR_WRITE_4(sc, reg, val) i386_outport_long( sc->ioaddr + reg, val )
-#define CSR_WRITE_2(sc, reg, val) i386_outport_word( sc->ioaddr + reg, val )
-#define CSR_WRITE_1(sc, reg, val) i386_outport_byte( sc->ioaddr + reg, val )
-
-
-inline unsigned int CSR_READ_4( struct elnk_softc *sc, int reg)
-{
- unsigned int myval;
- i386_inport_long( sc->ioaddr + reg, myval );
- return myval;
-}
-
-inline unsigned short CSR_READ_2( struct elnk_softc *sc, int reg)
-{
- unsigned short myval;
- i386_inport_word( sc->ioaddr + reg, myval );
- return myval;
-}
-
-inline unsigned char CSR_READ_1( struct elnk_softc *sc, int reg)
-{
- unsigned char myval;
- i386_inport_byte( sc->ioaddr + reg, myval );
- return myval;
-}
-
-#endif
-
-#if defined(__PPC__)
-
-#define CSR_WRITE_4(sc, reg, val) outl( val, sc->ioaddr + reg)
-#define CSR_WRITE_2(sc, reg, val) outw( val, sc->ioaddr + reg)
-#define CSR_WRITE_1(sc, reg, val) outb( val, sc->ioaddr + reg)
-
-#define CSR_READ_4(sc, reg) inl(sc->ioaddr + reg)
-#define CSR_READ_2(sc, reg) inw(sc->ioaddr + reg)
-#define CSR_READ_1(sc, reg) inb(sc->ioaddr + reg)
-
-#endif
-
-
-#define XL_SEL_WIN(x) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x)
-
-
-
-
-
-
-
-
-
-
-
-/*
- * Murphy's law says that it's possible the chip can wedge and
- * the 'command in progress' bit may never clear. Hence, we wait
- * only a finite amount of time to avoid getting caught in an
- * infinite loop. Normally this delay routine would be a macro,
- * but it isn't called during normal operation so we can afford
- * to make it a function.
- */
-static void
-xl_wait(struct elnk_softc *sc)
-{
- register int i;
-
- for(i = 0; i < XL_TIMEOUT; i++)
- {
- if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
- break;
- }
-
- if (i == XL_TIMEOUT)
- printk("etherlink : unit elnk%d command never completed\n", sc->xl_unit );
- return;
-}
-
-
-
-
-
-
-/*
- * MII access routines are provided for adapters with external
- * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
- * autoneg logic that's faked up to look like a PHY (3c905B-TX).
- * Note: if you don't perform the MDIO operations just right,
- * it's possible to end up with code that works correctly with
- * some chips/CPUs/processor speeds/bus speeds/etc but not
- * with others.
- */
-#define MII_SET(x) \
- CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
- CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x))
-
-#define MII_CLR(x) \
- CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
- CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x))
-
-/*
- * Sync the PHYs by setting data bit and strobing the clock 32 times.
- */
-static void
-xl_mii_sync(
- struct elnk_softc *sc)
-{
- register int i;
-
- XL_SEL_WIN(4);
- MII_SET(XL_MII_DIR|XL_MII_DATA);
-
- for (i = 0; i < 32; i++) {
- MII_SET(XL_MII_CLK);
- MII_SET(XL_MII_DATA);
- MII_CLR(XL_MII_CLK);
- MII_SET(XL_MII_DATA);
- }
-
- return;
-}
-
-/*
- * Clock a series of bits through the MII.
- */
-static void
-xl_mii_send(
- struct elnk_softc *sc,
- u_int32_t bits,
- int cnt )
-{
- int i;
-
- XL_SEL_WIN(4);
- MII_CLR(XL_MII_CLK);
-
- for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
- if (bits & i) {
- MII_SET(XL_MII_DATA);
- } else {
- MII_CLR(XL_MII_DATA);
- }
- MII_CLR(XL_MII_CLK);
- MII_SET(XL_MII_CLK);
- }
-}
-
-/*
- * Read an PHY register through the MII.
- */
-static int
-xl_mii_readreg(
- struct elnk_softc *sc,
- struct xl_mii_frame *frame )
-{
- int i, ack;
-
- /*
- * Set up frame for RX.
- */
- frame->mii_stdelim = XL_MII_STARTDELIM;
- frame->mii_opcode = XL_MII_READOP;
- frame->mii_turnaround = 0;
- frame->mii_data = 0;
-
- /*
- * Select register window 4.
- */
-
- XL_SEL_WIN(4);
-
- CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0);
- /*
- * Turn on data xmit.
- */
- MII_SET(XL_MII_DIR);
-
- xl_mii_sync(sc);
-
- /*
- * Send command/address info.
- */
- xl_mii_send(sc, frame->mii_stdelim, 2);
- xl_mii_send(sc, frame->mii_opcode, 2);
- xl_mii_send(sc, frame->mii_phyaddr, 5);
- xl_mii_send(sc, frame->mii_regaddr, 5);
-
- /* Idle bit */
- MII_CLR((XL_MII_CLK|XL_MII_DATA));
- MII_SET(XL_MII_CLK);
-
- /* Turn off xmit. */
- MII_CLR(XL_MII_DIR);
-
- /* Check for ack */
- MII_CLR(XL_MII_CLK);
- ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA;
- MII_SET(XL_MII_CLK);
-
- /*
- * Now try reading data bits. If the ack failed, we still
- * need to clock through 16 cycles to keep the PHY(s) in sync.
- */
- if (ack) {
- for(i = 0; i < 16; i++) {
- MII_CLR(XL_MII_CLK);
- MII_SET(XL_MII_CLK);
- }
- goto fail;
- }
-
- for (i = 0x8000; i; i >>= 1) {
- MII_CLR(XL_MII_CLK);
- if (!ack) {
- if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA)
- frame->mii_data |= i;
- }
- MII_SET(XL_MII_CLK);
- }
-
- fail:
-
- MII_CLR(XL_MII_CLK);
- MII_SET(XL_MII_CLK);
-
- if (ack)
- return(1);
- return(0);
-}
-
-/*
- * Write to a PHY register through the MII.
- */
-static int
-xl_mii_writereg(
- struct elnk_softc *sc,
- struct xl_mii_frame *frame )
-{
- /*
- * Set up frame for TX.
- */
-
- frame->mii_stdelim = XL_MII_STARTDELIM;
- frame->mii_opcode = XL_MII_WRITEOP;
- frame->mii_turnaround = XL_MII_TURNAROUND;
-
- /*
- * Select the window 4.
- */
- XL_SEL_WIN(4);
-
- /*
- * Turn on data output.
- */
- MII_SET(XL_MII_DIR);
-
- xl_mii_sync(sc);
-
- xl_mii_send(sc, frame->mii_stdelim, 2);
- xl_mii_send(sc, frame->mii_opcode, 2);
- xl_mii_send(sc, frame->mii_phyaddr, 5);
- xl_mii_send(sc, frame->mii_regaddr, 5);
- xl_mii_send(sc, frame->mii_turnaround, 2);
- xl_mii_send(sc, frame->mii_data, 16);
-
- /* Idle bit. */
- MII_SET(XL_MII_CLK);
- MII_CLR(XL_MII_CLK);
-
- /*
- * Turn off xmit.
- */
- MII_CLR(XL_MII_DIR);
-
- return(0);
-}
-
-static int
-xl_miibus_readreg(
- struct elnk_softc *sc,
- int phy,
- int reg )
-{
- struct xl_mii_frame frame;
-
- /*
- * Pretend that PHYs are only available at MII address 24.
- * This is to guard against problems with certain 3Com ASIC
- * revisions that incorrectly map the internal transceiver
- * control registers at all MII addresses. This can cause
- * the miibus code to attach the same PHY several times over.
- */
- if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
- {
- printk("etherlink : unit elnk%d xl_miibus_readreg returned\n", sc->xl_unit);
- return(0);
- }
-
- memset((char *)&frame, 0, sizeof(frame));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- xl_mii_readreg(sc, &frame);
-
- return(frame.mii_data);
-}
-
-static int
-xl_miibus_writereg(
- struct elnk_softc *sc,
- int phy,
- int reg,
- int data )
-{
- struct xl_mii_frame frame;
-
- if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
- {
- printk("etherlink : unit elnk%d xl_miibus_writereg returned\n", sc->xl_unit);
- return(0);
- }
-
- memset((char *)&frame, 0, sizeof(frame));
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
-
- xl_mii_writereg(sc, &frame);
-
- return(0);
-}
-
-
-
-
-
-
-
-
-
-/*
- * The EEPROM is slow: give it time to come ready after issuing
- * it a command.
- */
-static int
-xl_eeprom_wait(struct elnk_softc *sc)
-{
- int i;
-
- for (i = 0; i < 100; i++) {
- if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
- DELAY(162);
- else
- break;
- }
-
- if (i == 100) {
- printk("etherlink : unit elnk%d eeprom failed to come ready\n", sc->xl_unit);
- return(1);
- }
-
- return(0);
-}
-
-/*
- * Read a sequence of words from the EEPROM. Note that ethernet address
- * data is stored in the EEPROM in network byte order.
- */
-static int
-xl_read_eeprom(
- struct elnk_softc *sc,
- caddr_t dest,
- int off,
- int cnt,
- int swap)
-{
- int err = 0, i;
- u_int16_t word = 0, *ptr;
-#define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
-#define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F)
- /* WARNING! DANGER!
- * It's easy to accidentally overwrite the rom content!
- * Note: the 3c575 uses 8bit EEPROM offsets.
- */
- XL_SEL_WIN(0);
-
- if (xl_eeprom_wait(sc))
- return(1);
-
- if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
- off += 0x30;
-
- for (i = 0; i < cnt; i++) {
- if (sc->xl_flags & XL_FLAG_8BITROM)
- CSR_WRITE_2(sc, XL_W0_EE_CMD,
- XL_EE_8BIT_READ | EEPROM_8BIT_OFFSET(off + i));
- else
- CSR_WRITE_2(sc, XL_W0_EE_CMD,
- XL_EE_READ | EEPROM_5BIT_OFFSET(off + i));
- err = xl_eeprom_wait(sc);
- if (err)
- break;
- word = CSR_READ_2(sc, XL_W0_EE_DATA);
- ptr = (u_int16_t*)(dest + (i * 2));
- if (swap)
- *ptr = ntohs(word);
- else
- *ptr = word;
- }
-
- return(err ? 1 : 0);
-}
-
-
-
-
-static void
-xl_stats_update(
- rtems_id timerid,
- void *xsc)
-{
- struct elnk_softc *sc = (struct elnk_softc *)xsc;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- u_int32_t t1;
-
- sc->xl_stats.intstatus = CSR_READ_2(sc, XL_STATUS);
-
- sc->xl_stats.miianr = xl_miibus_readreg(sc, 0x18, MII_ANAR );
- sc->xl_stats.miipar = xl_miibus_readreg(sc, 0x18, MII_ANLPAR );
- sc->xl_stats.miistatus = xl_miibus_readreg(sc, 0x18, MII_BMSR );
- sc->xl_stats.miicmd = xl_miibus_readreg(sc, 0x18, MII_BMCR );
-
- XL_SEL_WIN(1);
- sc->xl_stats.rxstatus = CSR_READ_2(sc, XL_W1_RX_STATUS );
- sc->xl_stats.txstatus = CSR_READ_1(sc, XL_W1_TX_STATUS );
- sc->xl_stats.smbstatus = CSR_READ_2(sc, 2 );
-
- XL_SEL_WIN(3);
- sc->xl_stats.internalconfig = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
- sc->xl_stats.mac_control = CSR_READ_2(sc, XL_W3_MAC_CTRL);
- sc->xl_stats.txfree = CSR_READ_2(sc, XL_W3_FREE_TX );
-
-
- /* Read all the stats registers. */
- XL_SEL_WIN(6);
-
- sc->xl_stats.xl_carrier_lost += CSR_READ_1(sc, XL_W6_CARRIER_LOST);
- sc->xl_stats.xl_sqe_errs += CSR_READ_1(sc, XL_W6_SQE_ERRORS);
- sc->xl_stats.xl_tx_multi_collision += CSR_READ_1(sc, XL_W6_COL_MULTIPLE);
- sc->xl_stats.xl_tx_single_collision += CSR_READ_1(sc, XL_W6_COL_SINGLE);
- sc->xl_stats.xl_tx_late_collision += CSR_READ_1(sc, XL_W6_COL_LATE);
- sc->xl_stats.xl_rx_overrun += CSR_READ_1(sc, XL_W6_RX_OVERRUN);
- sc->xl_stats.xl_tx_deferred += CSR_READ_1(sc, XL_W6_DEFERRED);
-
- sc->xl_stats.xl_tx_frames_ok += CSR_READ_1(sc, XL_W6_TX_OK);
- sc->xl_stats.xl_rx_frames_ok += CSR_READ_1(sc, XL_W6_RX_OK);
-
- sc->xl_stats.xl_rx_bytes_ok += CSR_READ_2(sc, XL_W6_TX_BYTES_OK );
- sc->xl_stats.xl_tx_bytes_ok += CSR_READ_2(sc, XL_W6_RX_BYTES_OK );
-
- t1 = CSR_READ_1(sc, XL_W6_UPPER_FRAMES_OK);
- sc->xl_stats.xl_rx_frames_ok += ((t1 & 0x3) << 8);
- sc->xl_stats.xl_tx_frames_ok += (((t1 >> 4) & 0x3) << 8);
-
-
- ifp->if_ierrors += sc->xl_stats.xl_rx_overrun;
-
- ifp->if_collisions += sc->xl_stats.xl_tx_multi_collision +
- sc->xl_stats.xl_tx_single_collision +
- sc->xl_stats.xl_tx_late_collision;
-
- /*
- * Boomerang and cyclone chips have an extra stats counter
- * in window 4 (BadSSD). We have to read this too in order
- * to clear out all the stats registers and avoid a statsoflow
- * interrupt.
- */
- XL_SEL_WIN(4);
-
- t1 = CSR_READ_1(sc, XL_W4_UPPERBYTESOK);
- sc->xl_stats.xl_rx_bytes_ok += ((t1 & 0xf) << 16);
- sc->xl_stats.xl_tx_bytes_ok += (((t1 >> 4) & 0xf) << 16);
-
- sc->xl_stats.xl_badssd += CSR_READ_1(sc, XL_W4_BADSSD);
-
- sc->xl_stats.mediastatus = CSR_READ_2(sc, XL_W4_MEDIA_STATUS );
- sc->xl_stats.dmactl = CSR_READ_4(sc, XL_DMACTL );
-
-
- XL_SEL_WIN(7);
-
- if (!sc->xl_stats_no_timeout)
- rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
- return;
-}
-
-
-
-
-
-
-
-static void
-xl_reset(struct elnk_softc *sc)
-{
- register int i;
-
- XL_SEL_WIN(0);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
- ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
- XL_RESETOPT_DISADVFD:0));
-
- for (i = 0; i < XL_TIMEOUT; i++) {
- DELAY(10);
- if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
- break;
- }
-
- if (i == XL_TIMEOUT)
- printk("etherlink : unit elnk%d reset didn't complete\n", sc->xl_unit);
-
- /* Reset TX and RX. */
- /* Note: the RX reset takes an absurd amount of time
- * on newer versions of the Tornado chips such as those
- * on the 3c905CX and newer 3c908C cards. We wait an
- * extra amount of time so that xl_wait() doesn't complain
- * and annoy the users.
- */
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
- DELAY(100000);
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
- xl_wait(sc);
-
- if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||
- sc->xl_flags & XL_FLAG_INVERT_MII_PWR)
- {
- XL_SEL_WIN(2);
- CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,
- XL_W2_RESET_OPTIONS)
- | ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR)?XL_RESETOPT_INVERT_LED:0)
- | ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR)?XL_RESETOPT_INVERT_MII:0)
- );
- }
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(100000);
- return;
-}
-
-
-
-
-static void
-xl_stop(struct elnk_softc *sc)
-{
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
- ifp->if_timer = 0;
-
- rtems_timer_cancel( sc->stat_timer_id );
-
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISCARD);
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
- DELAY(800);
-
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
-
- return;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static void
-xl_setcfg(struct elnk_softc *sc)
-{
- u_int32_t icfg;
-
- XL_SEL_WIN(3);
- icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
-
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
-
- if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BT4)
- icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
-
- if (sc->xl_media & XL_MEDIAOPT_BTX)
- icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
-
- CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
-
- XL_SEL_WIN(7);
- return;
-}
-
-
-
-static void
-xl_setmode(
- struct elnk_softc *sc,
- int media)
-{
- u_int32_t icfg;
- u_int16_t mediastat;
-
- printk("etherlink : unit elnk%d selecting ", sc->xl_unit);
-
- XL_SEL_WIN(4);
- mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
- XL_SEL_WIN(3);
- icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
-
- if (sc->xl_media & XL_MEDIAOPT_BT) {
- if (IFM_SUBTYPE(media) == IFM_10_T) {
- printk("10baseT transceiver, ");
- sc->xl_xcvr = XL_XCVR_10BT;
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
- icfg |= (XL_XCVR_10BT << XL_ICFG_CONNECTOR_BITS);
- mediastat |= XL_MEDIASTAT_LINKBEAT|
- XL_MEDIASTAT_JABGUARD;
- mediastat &= ~XL_MEDIASTAT_SQEENB;
- }
- }
-
- if (sc->xl_media & XL_MEDIAOPT_BFX) {
- if (IFM_SUBTYPE(media) == IFM_100_FX) {
- printk("100baseFX port, ");
- sc->xl_xcvr = XL_XCVR_100BFX;
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
- icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);
- mediastat |= XL_MEDIASTAT_LINKBEAT;
- mediastat &= ~XL_MEDIASTAT_SQEENB;
- }
- }
-
- if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
- if (IFM_SUBTYPE(media) == IFM_10_5) {
- printk("AUI port, ");
- sc->xl_xcvr = XL_XCVR_AUI;
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
- icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
- mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
- XL_MEDIASTAT_JABGUARD);
- mediastat |= ~XL_MEDIASTAT_SQEENB;
- }
- if (IFM_SUBTYPE(media) == IFM_10_FL) {
- printk("10baseFL transceiver, ");
- sc->xl_xcvr = XL_XCVR_AUI;
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
- icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
- mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
- XL_MEDIASTAT_JABGUARD);
- mediastat |= ~XL_MEDIASTAT_SQEENB;
- }
- }
-
- if (sc->xl_media & XL_MEDIAOPT_BNC) {
- if (IFM_SUBTYPE(media) == IFM_10_2) {
- printk("BNC port, ");
- sc->xl_xcvr = XL_XCVR_COAX;
- icfg &= ~XL_ICFG_CONNECTOR_MASK;
- icfg |= (XL_XCVR_COAX << XL_ICFG_CONNECTOR_BITS);
- mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
- XL_MEDIASTAT_JABGUARD|
- XL_MEDIASTAT_SQEENB);
- }
- }
-
- if ((media & IFM_GMASK) == IFM_FDX ||
- IFM_SUBTYPE(media) == IFM_100_FX) {
- printk("full duplex\n");
- XL_SEL_WIN(3);
- CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
- } else {
- printk("half duplex\n");
- XL_SEL_WIN(3);
- CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
- (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
- }
-
- if (IFM_SUBTYPE(media) == IFM_10_2)
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
- else
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
-
- CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
- XL_SEL_WIN(4);
- CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
- DELAY(800);
- XL_SEL_WIN(7);
-
- return;
-}
-
-
-
-
-
-
-
-static void
-xl_choose_xcvr(
- struct elnk_softc *sc,
- int verbose)
-{
- u_int16_t devid;
-
- /*
- * Read the device ID from the EEPROM.
- * This is what's loaded into the PCI device ID register, so it has
- * to be correct otherwise we wouldn't have gotten this far.
- */
- xl_read_eeprom(sc, (caddr_t)&devid, XL_EE_PRODID, 1, 0);
-
- switch(devid) {
- case TC_DEVICEID_BOOMERANG_10BT: /* 3c900-TPO */
- case TC_DEVICEID_KRAKATOA_10BT: /* 3c900B-TPO */
- sc->xl_media = XL_MEDIAOPT_BT;
- sc->xl_xcvr = XL_XCVR_10BT;
- if (verbose)
- printk("etherlink : unit elnk%d guessing 10BaseT "
- "transceiver\n", sc->xl_unit);
- break;
- case TC_DEVICEID_BOOMERANG_10BT_COMBO: /* 3c900-COMBO */
- case TC_DEVICEID_KRAKATOA_10BT_COMBO: /* 3c900B-COMBO */
- sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
- sc->xl_xcvr = XL_XCVR_10BT;
- if (verbose)
- printk("etherlink : unit elnk%d guessing COMBO "
- "(AUI/BNC/TP)\n", sc->xl_unit);
- break;
- case TC_DEVICEID_KRAKATOA_10BT_TPC: /* 3c900B-TPC */
- sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
- sc->xl_xcvr = XL_XCVR_10BT;
- if (verbose)
- printk("etherlink : unit elnk%d guessing TPC (BNC/TP)\n", sc->xl_unit);
- break;
- case TC_DEVICEID_CYCLONE_10FL: /* 3c900B-FL */
- sc->xl_media = XL_MEDIAOPT_10FL;
- sc->xl_xcvr = XL_XCVR_AUI;
- if (verbose)
- printk("etherlink : unit elnk%d guessing 10baseFL\n", sc->xl_unit);
- break;
- case TC_DEVICEID_BOOMERANG_10_100BT: /* 3c905-TX */
- case TC_DEVICEID_HURRICANE_555: /* 3c555 */
- case TC_DEVICEID_HURRICANE_556: /* 3c556 */
- case TC_DEVICEID_HURRICANE_556B: /* 3c556B */
- case TC_DEVICEID_HURRICANE_575A: /* 3c575TX */
- case TC_DEVICEID_HURRICANE_575B: /* 3c575B */
- case TC_DEVICEID_HURRICANE_575C: /* 3c575C */
- case TC_DEVICEID_HURRICANE_656: /* 3c656 */
- case TC_DEVICEID_HURRICANE_656B: /* 3c656B */
- case TC_DEVICEID_TORNADO_656C: /* 3c656C */
- case TC_DEVICEID_TORNADO_10_100BT_920B: /* 3c920B-EMB */
- sc->xl_media = XL_MEDIAOPT_MII;
- sc->xl_xcvr = XL_XCVR_MII;
- if (verbose)
- printk("etherlink : unit elnk%d guessing MII\n", sc->xl_unit);
- break;
- case TC_DEVICEID_BOOMERANG_100BT4: /* 3c905-T4 */
- case TC_DEVICEID_CYCLONE_10_100BT4: /* 3c905B-T4 */
- sc->xl_media = XL_MEDIAOPT_BT4;
- sc->xl_xcvr = XL_XCVR_MII;
- if (verbose)
- printk("etherlink : unit elnk%d guessing 100BaseT4/MII\n", sc->xl_unit);
- break;
- case TC_DEVICEID_HURRICANE_10_100BT: /* 3c905B-TX */
- case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */
- case TC_DEVICEID_TORNADO_10_100BT_SERV: /* 3c980C-TX */
- case TC_DEVICEID_HURRICANE_SOHO100TX: /* 3cSOHO100-TX */
- case TC_DEVICEID_TORNADO_10_100BT: /* 3c905C-TX */
- case TC_DEVICEID_TORNADO_HOMECONNECT: /* 3c450-TX */
- sc->xl_media = XL_MEDIAOPT_BTX;
- sc->xl_xcvr = XL_XCVR_AUTO;
- if (verbose)
- printk("etherlink : unit elnk%d guessing 10/100 internal\n", sc->xl_unit);
- break;
- case TC_DEVICEID_CYCLONE_10_100_COMBO: /* 3c905B-COMBO */
- sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
- sc->xl_xcvr = XL_XCVR_AUTO;
- if (verbose)
- printk("etherlink : unit elnk%d guessing 10/100 "
- "plus BNC/AUI\n", sc->xl_unit);
- break;
- default:
- printk("etherlink : unit elnk%d unknown device ID: %x -- "
- "defaulting to 10baseT\n", sc->xl_unit, devid);
- sc->xl_media = XL_MEDIAOPT_BT;
- break;
- }
-
- return;
-}
-
-
-
-
-
-
-
-/*
- * This routine is a kludge to work around possible hardware faults
- * or manufacturing defects that can cause the media options register
- * (or reset options register, as it's called for the first generation
- * 3c90x adapters) to return an incorrect result. I have encountered
- * one Dell Latitude laptop docking station with an integrated 3c905-TX
- * which doesn't have any of the 'mediaopt' bits set. This screws up
- * the attach routine pretty badly because it doesn't know what media
- * to look for. If we find ourselves in this predicament, this routine
- * will try to guess the media options values and warn the user of a
- * possible manufacturing defect with his adapter/system/whatever.
- */
-static void
-xl_mediacheck(struct elnk_softc *sc)
-{
-
- xl_choose_xcvr(sc, 1);
-
- /*
- * If some of the media options bits are set, assume they are
- * correct. If not, try to figure it out down below.
- * XXX I should check for 10baseFL, but I don't have an adapter
- * to test with.
- */
- if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
- /*
- * Check the XCVR value. If it's not in the normal range
- * of values, we need to fake it up here.
- */
- if (sc->xl_xcvr <= XL_XCVR_AUTO)
- return;
- else {
- printk("etherlink : unit elnk%d bogus xcvr value "
- "in EEPROM (%" PRIx32 ")\n", sc->xl_unit, sc->xl_xcvr);
- printk("etherlink : unit elnk%d choosing new default based "
- "on card type\n", sc->xl_unit);
- }
- } else {
- if (sc->xl_type == XL_TYPE_905B &&
- sc->xl_media & XL_MEDIAOPT_10FL)
- return;
- printk("etherlink : unit elnk%d WARNING: no media options bits set in "
- "the media options register!!\n", sc->xl_unit);
- printk("etherlink : unit elnk%d this could be a manufacturing defect in "
- "your adapter or system\n", sc->xl_unit);
- printk("etherlink : unit elnk%d attempting to guess media type; you "
- "should probably consult your vendor\n", sc->xl_unit);
- }
-
- return;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static void no_op(const rtems_irq_connect_data* irq)
-{
- return;
-}
-
-
-
-
-static void
-elnk_start_txchain( struct elnk_softc *sc, struct TXMD *chainhead )
-{
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
-
- /* save the address of the TX list */
- sc->last_txchain_head = chainhead;
- sc->tx_idle = 0;
-
- xl_wait(sc);
-
- CSR_WRITE_4(sc, XL_DOWNLIST_PTR, phys_to_bus( sc->last_txchain_head ));
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
-}
-
-
-
-
-
-/*
- * ELNK interrupt handler
- */
-static rtems_isr
-elnk_interrupt_handler ( struct elnk_softc *sc )
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- u_int16_t status;
-
- while( ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS) && status != 0xFFFF)
- {
- sc->xl_stats.device_interrupts++;
-
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK | (status & XL_INTRS));
-
-#if 0
- printk("etherlink : unit elnk%d intstatus %04x\n", sc->xl_unit, status );
-#endif
-
- if (status & XL_STAT_UP_COMPLETE)
- {
-#if 0
- printk("etherlink : unit elnk%d rx\n", sc->xl_unit );
-#endif
- /* received packets */
- rtems_bsdnet_event_send(rxDaemonTid, sc->ioevent);
- }
-
- if( (status & XL_STAT_DOWN_COMPLETE) || (status & XL_STAT_TX_COMPLETE) )
- {
- /* all packets uploaded to the device */
- struct TXMD *chaintailmd = NULL;
-
-
- if( status & XL_STAT_TX_COMPLETE )
- {
- /* if we got a tx complete error, count it, then reset the
- transmitter. Consider the entire chain lost.. */
-
- ifp->if_oerrors++;
- sc->xl_stats.txcomplete_ints++;
-
- printk("etherlink : unit elnk%d transmit error\n", sc->xl_unit );
-
- /* reset, re-enable fifo */
-
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
-
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET | 1 );
-
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
-
- xl_wait(sc);
- }
-
-
- /* send the chain head to the tx task which will recover the
- whole chain */
- rtems_message_queue_send( chainRecoveryQueue, &sc->last_txchain_head, sizeof(struct TXMD *));
-
-
- /* set up the next chain */
- if( sc->last_txchain_head->chainptr )
- {
- /* check the head of the chain of packets we just finished,
- * if != 0, either this is a chain of 2 or more packets or
- * its a single packet chain and another chain is ready to
- * send.
- */
- if( (int)sc->last_txchain_head->chainptr == -1 )
- {
- /*
- ** single packet was sent so no indirection to the last
- ** entry in the chain. since chainptr is != 0, then
- ** another chain is ready starting from the packet AFTER
- ** the chain we just finished. - in this case the last
- ** chain's head == its tail
- */
- chaintailmd = sc->last_txchain_head;
- }
- else
- {
- /*
- ** otherwise, this is a pointer to the last packet in the
- ** chain of 2 or more packets. If the chain's last
- ** packet's chainptr is != 0, then another chain is ready
- ** to send.
- */
- chaintailmd = sc->last_txchain_head->chainptr;
- if( !chaintailmd->chainptr ) chaintailmd = NULL;
- }
- }
-
- if( chaintailmd )
- {
- /* the next MD is the start of another chain */
- elnk_start_txchain(sc, chaintailmd->next_md );
- }
- else
- {
- /* otherwise nothing to send, so go idle */
- sc->tx_idle = -1;
-
- /* wake up the tx daemon once so we're sure this last chain
- will be freed */
- rtems_bsdnet_event_send( txDaemonTid, sc->ioevent );
-#if 0
- printk("unit elnk%d tx done\n", sc->xl_unit );
-#endif
- }
- }
-
-
- if (status & XL_STAT_ADFAIL)
- {
- printk("etherlink : unit elnk%d Catastrophic bus failure\n", sc->xl_unit );
- }
- if (status & XL_STAT_STATSOFLOW)
- {
- sc->xl_stats_no_timeout = 1;
- xl_stats_update(sc->stat_timer_id,sc);
- sc->xl_stats_no_timeout = 0;
- }
- }
-
-
-#if 0
- {
- uint16_t intstatus, intenable, indenable;
-
- intstatus = CSR_READ_2(sc, XL_STATUS );
-
- XL_SEL_WIN(5);
- intenable = CSR_READ_2(sc, XL_W5_INTR_ENB );
- indenable = CSR_READ_2(sc, XL_W5_STAT_ENB );
- XL_SEL_WIN(7);
- printk("etherlink : unit elnk%d istat %04x, ien %04x, ind %04x\n", sc->xl_unit, intstatus, intenable, indenable );
- }
-#endif
-}
-
-
-
-
-
-static rtems_isr
-elnk_interrupt_handler_entry(void)
-{
- int i;
-
- /*
- ** Check all the initialized units for interrupt service
- */
-
- for(i=0; i< NUM_UNITS; i++ )
- {
- if( elnk_softc[i].ioaddr )
- elnk_interrupt_handler( &elnk_softc[i] );
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-/*
- * Initialize the ethernet hardware
- */
-static void
-elnk_initialize_hardware (struct elnk_softc *sc)
-{
- unsigned char *cp;
- int i, j, rxsize, txsize, ringsize;
-
- /*
- * Init RX ring
- */
- cp = (unsigned char *)malloc( (ringsize = ((rxsize = (sc->numRxbuffers * sizeof(struct RXMD))) +
- (txsize = (sc->numTxbuffers * sizeof(struct TXMD)))) ) +
- + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
- sc->bufferBase = cp;
- cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
-#if defined(__i386__)
-#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
- if (_CPU_is_paging_enabled())
- _CPU_change_memory_mapping_attribute
- (NULL, cp, ringsize, PTE_CACHE_DISABLE | PTE_WRITABLE);
-#endif
-#endif
- sc->ringBase = cp;
-
- /* build tx and rx rings */
-
- sc->rx_ring = (struct RXMD *)sc->ringBase;
- sc->tx_ring = (struct TXMD *)&sc->ringBase[ rxsize ];
-
- {
- struct mbuf *m;
- struct RXMD *nxtmd;
- /*
- * The rx ring is easy as its just an array of RXMD structs. New
- * mbuf entries are allocated from the stack whenever the rx
- * daemon forwards an incoming packet into it. Here, we
- * pre-allocate the rx mbufs for the rx ring entries.
- */
- for(i=0 ; i<sc->numRxbuffers; i++)
- {
- if( ((uint32_t)&sc->rx_ring[i] & 0x7) )
- {
- rtems_panic ("etherlink : unit elnk%d rx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
- }
-
- /* allocate an mbuf for each receive descriptor */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
-
- if( i == sc->numRxbuffers-1 )
- nxtmd = &sc->rx_ring[0];
- else
- nxtmd = &sc->rx_ring[i+1];
-
- sc->rx_ring[i].next_md = nxtmd;
- sc->rx_ring[i].mbuf = m;
-
- st_le32( &sc->rx_ring[i].status, 0);
- st_le32( &sc->rx_ring[i].next, (uint32_t)phys_to_bus( nxtmd ));
- st_le32( &sc->rx_ring[i].addr, (uint32_t)phys_to_bus( mtod(m, void *) ));
- st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
- }
- sc->curr_rx_md = &sc->rx_ring[0];
- }
-
-
- {
- struct TXMD *thismd, *nxtmd;
- /*
- * The tx ring is more complex. Each MD has an array of fragment
- * descriptors that are loaded from each packet as they arrive
- * from the stack. Each packet gets one ring entry, this allows
- * the lanboard to efficiently assemble the piecemeal packets into
- * a contiguous unit at transmit time, rather than spending
- * cputime concatenating them first. Although the next_md fields
- * form a ring, the DPD next is filled only when packets are added
- * to the tx chain, thus last entry of a series of packets has the
- * requisite dpd->next value == 0 to terminate the dma. mbuf
- * holds the packet info so it can be freed once the packet has
- * been sent. chainptr is used to link the head & tail of a chain
- * of 2 or more packets. A chain is formed when the tx daemon
- * gets 2 or more packets from the stack's queue in a service
- * period, so higher outgoing loads are handled as efficiently as
- * possible.
- */
-
- for(i=0 ; i<sc->numTxbuffers; i++)
- {
- if( ((uint32_t)&sc->tx_ring[i] & 0x7) )
- {
- rtems_panic ("etherlink : unit elnk%d tx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
- }
-
- if( i == sc->numTxbuffers-1 )
- nxtmd = &sc->tx_ring[0];
- else
- nxtmd = &sc->tx_ring[i+1];
-
- thismd = &sc->tx_ring[i];
-
- thismd->next_md = nxtmd;
- thismd->chainptr = NULL;
- thismd->mbuf = NULL;
-
- st_le32( &thismd->status, XL_TXSTAT_DL_COMPLETE );
- st_le32( &thismd->next, 0);
-
- for(j=0; j< NUM_FRAGS; j++)
- {
- st_le32( &thismd->txfrags[j].addr, 0 );
- st_le32( &thismd->txfrags[j].length, 0 );
- }
- }
- sc->last_tx_md = &sc->tx_ring[0];
- }
-
-
-
-
-#ifdef ELNK_DEBUG
- printk("etherlink : %02x:%02x:%02x:%02x:%02x:%02x name 'elnk%d', io %x, int %d\n",
- sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
- sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
- sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
- sc->xl_unit,
- (unsigned)sc->ioaddr, sc->irqInfo.name );
-#endif
-
-
- sc->irqInfo.hdl = (rtems_irq_hdl)elnk_interrupt_handler_entry;
- sc->irqInfo.on = no_op;
- sc->irqInfo.off = no_op;
- sc->irqInfo.isOn = NULL;
-
- if( sc->irqInfo.name != 255 )
- {
- int st;
-
-#ifdef BSP_SHARED_HANDLER_SUPPORT
- st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
-#else
- st = BSP_install_rtems_irq_handler( &sc->irqInfo );
-#endif
- if (!st)
- rtems_panic ("etherlink : unit elnk%d Interrupt name %d already in use\n", sc->xl_unit, sc->irqInfo.name );
- }
- else
- {
- printk("etherlink : unit elnk%d Interrupt not specified by device\n", sc->xl_unit );
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-static void
-elnk_rxDaemon (void *arg)
-{
- struct elnk_softc *sc;
- struct ether_header *eh;
- struct mbuf *m;
- struct RXMD *rmd;
- unsigned int i,len, rxstat;
- rtems_event_set events;
-
- for (;;)
- {
-
- rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
-
- for(;;)
- {
- for(i=0; i< NUM_UNITS; i++ )
- {
- sc = &elnk_softc[i];
- if( sc->ioaddr )
- {
- if( events & sc->ioevent )
- {
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- rmd = sc->curr_rx_md;
-
- /*
- ** Read off all the packets we've received on this unit
- */
- while( (rxstat = ld_le32(&rmd->status)) )
- {
- if (rxstat & XL_RXSTAT_UP_ERROR)
- {
- printk("unit %i up error\n", sc->xl_unit );
- ifp->if_ierrors++;
- }
-
- if( (rxstat & XL_RXSTAT_UP_CMPLT) )
- {
-
-#if 0
- {
- char *pkt, *delim;
- int i;
- pkt = mtod(rmd->mbuf, char *);
- printk("unit %i rx pkt (%08x) ", sc->xl_unit, pkt );
- for(delim="", i=0; i < sizeof(struct ether_header)+8; i++, delim=":")
- printk("%s%02x", delim, (char) pkt[i] );
- printk("\n");
- }
-#endif
-
- /* pass on the packet in the mbuf */
- len = ( ld_le32(&rmd->status) & XL_RXSTAT_LENMASK);
- m = rmd->mbuf;
- m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
-
- ether_input(ifp, eh, m);
-
- /* get a new mbuf */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- rmd->mbuf = m;
- st_le32( &rmd->status, 0 );
- st_le32( &rmd->addr, (uint32_t)phys_to_bus(mtod(m, void *)) );
- }
- else
- {
- /* some kind of packet failure */
- printk("etherlink : unit elnk%d bad receive status -- packet dropped\n", sc->xl_unit);
- ifp->if_ierrors++;
- }
- /* clear descriptor status */
- rmd->status = 0;
-
- rmd = rmd->next_md;
- }
-
- sc->curr_rx_md = rmd;
- }
- }
- }
-
- /*
- ** If more events are pending, service them before we go back to sleep
- */
- if( rtems_event_system_receive( RTEMS_ALL_EVENTS,
- RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
- 0,
- &events ) == RTEMS_UNSATISFIED ) break;
- }
- }
-}
-
-
-
-
-
-
-
-
-/*
- * Driver transmit daemon
- */
-static void
-elnk_txDaemon (void *arg)
-{
- struct elnk_softc *sc;
- struct ifnet *ifp;
- struct mbuf *m;
- struct TXMD *lastmd, *nextmd, *firstmd;
- int chainCount,i;
- rtems_event_set events;
-
- for (;;)
- {
- /*
- * Wait for any unit's signal to wake us up
- */
- rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-
- for(i=0; i< NUM_UNITS; i++ )
- {
- sc = &elnk_softc[i];
- if( sc->ioaddr )
- {
- if( events & sc->ioevent )
- {
- ifp = &sc->arpcom.ac_if;
-
- /*
- * Send packets till queue is empty or tx ring is full
- */
-
- chainCount = 0;
- firstmd = NULL;
-
- lastmd = sc->last_tx_md;
-
- for(;;)
- {
- /*
- ** Check the chain recovery queue whenever the tx
- ** daemon services the stack. Note this routine does
- ** not assume the context of one of the lanboard units
- ** because used tx mbufs are no longer associated with
- ** any unit.
- */
- {
- struct TXMD *chainhead, *chaintail;
- size_t esize;
-
- if( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
- RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL )
- {
- /* get a pointer to the tail */
- chaintail = chainhead->chainptr;
-
- /* if the tail points somewhere, free the entire
- chain */
- if( chaintail && (int)chaintail != -1 )
- {
- for(;;)
- {
- m_freem( chainhead->mbuf );
- st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
- chainhead->mbuf = NULL;
-
- if( chainhead == chaintail ) break;
- chainhead = chainhead->next_md;
- }
- }
- else
- {
- /* a single packet chain */
- m_freem( chainhead->mbuf );
- st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
- chainhead->mbuf = NULL;
- }
- }
- }
-
- nextmd = lastmd->next_md;
-
- /* stop when ring is full */
- if( ! (ld_le32(&nextmd->status) & XL_TXSTAT_DL_COMPLETE) )
- {
- printk("etherlink : unit elnk%d tx ring full!\n", sc->xl_unit);
- break;
- }
- /* sanity check the next packet descriptor */
- if( nextmd->mbuf )
- {
- printk("etherlink : unit elnk%d tx ring corrupt!\n", sc->xl_unit);
- break;
- }
-
-
-
- IF_DEQUEUE(&ifp->if_snd, m);
- if( !m ) break;
-
- {
- int i;
-
- nextmd->mbuf = m;
-
- for(i=0; i< NUM_FRAGS; i++)
- {
- st_le32( &nextmd->txfrags[i].length, ((m->m_next)?0:XL_LAST_FRAG) | ( m->m_len & XL_TXSTAT_LENMASK) );
- st_le32( &nextmd->txfrags[i].addr, (uint32_t)phys_to_bus( m->m_data ) );
- if ((m = m->m_next) == NULL)
- break;
- }
- if( m )
- {
- printk("etherlink : unit elnk%d tx fragments exhausted, truncating packet!\n", sc->xl_unit);
- st_le32( &nextmd->txfrags[NUM_FRAGS-1].length, XL_LAST_FRAG |
- ld_le32( &nextmd->txfrags[NUM_FRAGS-1].length) );
- }
- }
-
-#if 0
- {
- char *pkt = bus_to_phys( ld_le32( &nextmd->txfrags[i].addr )), *delim;
- int i;
- printk("unit %d queued pkt (%08x) ", sc->xl_unit, (uint32_t)pkt );
- for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
- printk("%s%02x", delim, (char) pkt[i] );
- printk("\n");
- }
-#endif
-
-
- /* this packet will be the new end of the list */
- st_le32( &nextmd->next, 0);
- st_le32( &nextmd->status, 0);
-
- if( !firstmd )
- {
- /* keep track of the first packet we add to the chain */
- firstmd = nextmd;
-
- /*
- ** use the chainbuf pointer of the last packet of
- ** the previous chain as a flag so when a
- ** dnComplete interrupt indicates the card is
- ** finished downloading the chain, the isr can
- ** immediately start the next which always begins
- ** with the next packet in the ring. Note several
- ** chains of packets may be assembled this way.
- */
- lastmd->chainptr = (struct TXMD *)-1;
- }
- else
- {
- /* hook this packet to the previous one */
- st_le32( &lastmd->next, (uint32_t)phys_to_bus( nextmd ));
- }
-
- ++chainCount;
- lastmd = nextmd;
- }
-
-
-
-
-
- if( firstmd )
- {
- /* only enter if we've queued one or more packets */
-
- /* save the last descriptor we set up in the chain */
- sc->last_tx_md = lastmd;
-
- /*
- * We've added one or more packets to a chain, flag
- * the last packet so we get an dnComplete interrupt
- * when the card finishes accepting the chain
- */
- st_le32( &lastmd->status, XL_TXSTAT_DL_INTR );
-
- /*
- * point the chain head's chainptr to the tail so we
- * can jump to the next chain to send inside the isr.
- * If we're only sending one packet, then don't bother
- * with the link, as the chainptr value will either be
- * 0 if theres no next chain or -1 if there is.
- */
- if( chainCount > 1 )
- {
- firstmd->chainptr = lastmd;
-
- sc->chain_lengths[sc->chlenIndex]= (short)chainCount;
- if( ++sc->chlenIndex == NUM_CHAIN_LENGTHS ) sc->chlenIndex = 0;
- }
-
- /*
- ** clear the last packet's chainptr flag. If another
- ** chain is added later but before this chain is
- ** finished being sent, this flag on this packet will
- ** be re-set to -1
- */
- lastmd->chainptr = NULL;
-
-#if 0
- printk("unit %d queued %d pkts, lastpkt status %08X\n",
- sc->xl_unit,
- chainCount,
- (uint32_t)ld_le32( &lastmd->status) );
-#endif
-
- if( sc->tx_idle == 0 && CSR_READ_4(sc, XL_DOWNLIST_PTR) == 0 )
- {
- printk("etherlink : unit elnk%d tx forced!\n", sc->xl_unit);
- sc->tx_idle = -1;
- }
-
- /*
- ** start sending this chain of packets if tx isn't
- ** busy, else the dnComplete interrupt will see there
- ** is another chain waiting and begin it immediately.
- */
- if( sc->tx_idle )
- {
-#if 0
- printk("etherlink : unit elnk%d tx started %d packets\n", sc->xl_unit, chainCount );
-#endif
- elnk_start_txchain(sc, firstmd);
- }
- }
-
-
- ifp->if_flags &= ~IFF_OACTIVE;
- }
- }
- }
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-static void
-elnk_start (struct ifnet *ifp)
-{
- struct elnk_softc *sc = ifp->if_softc;
-#if 0
- printk("unit %i tx signaled\n", sc->xl_unit );
-#endif
- ifp->if_flags |= IFF_OACTIVE;
- rtems_bsdnet_event_send( txDaemonTid, sc->ioevent );
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/*
- * Initialize and start the device
- */
-static void
-elnk_init (void *arg)
-{
- int i;
- struct elnk_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if( !(ifp->if_flags & IFF_RUNNING) )
- {
- xl_stop(sc);
- xl_reset(sc);
- sc->tx_idle = -1;
-
- {
- uint32_t cr,sr;
-
- xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_RESET );
-
- while( (cr = xl_miibus_readreg(sc, 0x18, MII_BMCR )) & BMCR_RESET )
- {
- DELAY(100000);
- }
-
- xl_miibus_writereg(sc, 0x18, MII_ANAR, ANAR_10 | ANAR_TX | ANAR_10_FD | ANAR_TX_FD ); /* ANAR_T4 */
- xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_STARTNEG | BMCR_AUTOEN );
-
- for (i=0; ((sr = xl_miibus_readreg(sc, 0x18, MII_BMSR)) & BMSR_ACOMP) == 0 && i < 20; i++)
- DELAY(10000);
- }
-
-
- /*
- * Set up hardware if its not already been done
- */
- if( !sc->irqInfo.hdl )
- {
- elnk_initialize_hardware(sc);
- }
-
- /*
- * Enable the card
- */
- {
- u_int8_t rxfilt;
-
- /* Init our MAC address */
- XL_SEL_WIN(2);
- for (i = 0; i < ETHER_ADDR_LEN; i++)
- {
- CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i, sc->arpcom.ac_enaddr[i]);
- }
-
- {
- int media = IFM_ETHER|IFM_100_TX|IFM_FDX;
-
- xl_mediacheck(sc);
-
- /* Choose a default media. */
- switch(sc->xl_xcvr) {
- case XL_XCVR_10BT:
- media = IFM_ETHER|IFM_10_T;
- xl_setmode(sc, media);
- break;
- case XL_XCVR_AUI:
- if (sc->xl_type == XL_TYPE_905B &&
- sc->xl_media == XL_MEDIAOPT_10FL) {
- media = IFM_ETHER|IFM_10_FL;
- xl_setmode(sc, media);
- } else {
- media = IFM_ETHER|IFM_10_5;
- xl_setmode(sc, media);
- }
- break;
- case XL_XCVR_COAX:
- media = IFM_ETHER|IFM_10_2;
- xl_setmode(sc, media);
- break;
- case XL_XCVR_AUTO:
- case XL_XCVR_100BTX:
- xl_setcfg(sc);
- break;
- case XL_XCVR_MII:
- printk(
- "etherlink : unit elnk%d MII media not supported!\n",
- sc->xl_unit);
- break;
- case XL_XCVR_100BFX:
- media = IFM_ETHER|IFM_100_FX;
- break;
- default:
- printk(
- "etherlink : unit elnk%d unknown XCVR type: %" PRId32 "\n",
- sc->xl_unit,
- sc->xl_xcvr);
- /*
- * This will probably be wrong, but it prevents
- * the ifmedia code from panicking.
- */
- media = IFM_ETHER|IFM_10_T;
- break;
- }
-
-
- if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
- XL_SEL_WIN(0);
- CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
- }
- }
-
-
-
- XL_SEL_WIN(2);
- /* Clear the station mask. */
- for (i = 0; i < 3; i++)
- CSR_WRITE_2(sc, XL_W2_STATION_MASK_LO + (i * 2), 0);
-
- /*
- * Set the TX freethresh value.
- * Note that this has no effect on 3c905B "cyclone"
- * cards but is required for 3c900/3c905 "boomerang"
- * cards in order to enable the download engine.
- */
- CSR_WRITE_1(sc, XL_TX_FREETHRESH, XL_PACKET_SIZE >> 8);
-
- /* Set the TX start threshold for best performance. */
- sc->xl_tx_thresh = XL_MIN_FRAMELEN;
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_SET_START|sc->xl_tx_thresh);
-
- /*
- * If this is a 3c905B, also set the tx reclaim threshold.
- * This helps cut down on the number of tx reclaim errors
- * that could happen on a busy network. The chip multiplies
- * the register value by 16 to obtain the actual threshold
- * in bytes, so we divide by 16 when setting the value here.
- * The existing threshold value can be examined by reading
- * the register at offset 9 in window 5.
- */
- if (sc->xl_type == XL_TYPE_905B) {
- CSR_WRITE_2(sc, XL_COMMAND,
- XL_CMD_SET_TX_RECLAIM|(XL_PACKET_SIZE >> 4));
- }
-
- /* Set RX filter bits. */
- XL_SEL_WIN(5);
- rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
-
- /* Set the individual bit to receive frames for this host only. */
- rxfilt |= XL_RXFILTER_INDIVIDUAL;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC) {
- rxfilt |= XL_RXFILTER_ALLFRAMES;
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
- } else {
- rxfilt &= ~XL_RXFILTER_ALLFRAMES;
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
- }
-
- /*
- * Set capture broadcast bit to capture broadcast frames.
- */
- if (ifp->if_flags & IFF_BROADCAST) {
- rxfilt |= XL_RXFILTER_BROADCAST;
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
- } else {
- rxfilt &= ~XL_RXFILTER_BROADCAST;
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
- }
-
-#if 0
- /*
- * Program the multicast filter, if necessary.
- */
- if (sc->xl_type == XL_TYPE_905B)
- xl_setmulti_hash(sc);
- else
- xl_setmulti(sc);
-#endif
- /*
- * Load the address of the RX list. We have to
- * stall the upload engine before we can manipulate
- * the uplist pointer register, then unstall it when
- * we're finished. We also have to wait for the
- * stall command to complete before proceeding.
- * Note that we have to do this after any RX resets
- * have completed since the uplist register is cleared
- * by a reset.
- */
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
- xl_wait(sc);
- CSR_WRITE_4(sc, XL_UPLIST_PTR, phys_to_bus( sc->curr_rx_md ));
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
- xl_wait(sc);
-
-
-#if 0
- if (sc->xl_type == XL_TYPE_905B) {
- /* Set polling interval */
- CSR_WRITE_1(sc, XL_DOWN_POLL, 64);
- xl_wait(sc);
- printk("etherlink : unit elnk%d tx polling enabled\n", sc->xl_unit );
- }
-#endif
-
- /*
- * If the coax transceiver is on, make sure to enable
- * the DC-DC converter.
- */
- XL_SEL_WIN(3);
- if (sc->xl_xcvr == XL_XCVR_COAX)
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
- else
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
-
- /* increase packet size to allow reception of 802.1q or ISL packets */
- if (sc->xl_type == XL_TYPE_905B)
- CSR_WRITE_2(sc, XL_W3_MAXPKTSIZE, XL_PACKET_SIZE);
- /* Clear out the stats counters. */
-
- memset( &sc->xl_stats, 0, sizeof(struct xl_stats));
-
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
- sc->xl_stats_no_timeout = 1;
- xl_stats_update(sc->stat_timer_id,sc);
- sc->xl_stats_no_timeout = 0;
- XL_SEL_WIN(4);
- CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE);
-
-
- /*
- * Enable interrupts.
- */
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
-
- /* Set the RX early threshold */
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2));
- CSR_WRITE_4(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY );
-
- /* Enable receiver and transmitter. */
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
- xl_wait(sc);
- CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
- xl_wait(sc);
-
- /* Select window 7 for normal operations. */
- XL_SEL_WIN(7);
-
- /* schedule the stats update timer */
- rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
- }
-}
-
-
-
-
-
-
-
-/*
- * Stop the device
- */
-static void
-elnk_stop (struct elnk_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int i;
-
- /*
- * Stop the transmitter
- */
- xl_stop(sc);
- xl_reset(sc);
- sc->tx_idle = -1;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- ** Clear out the rx & tx rings
- */
- {
- struct TXMD *chainhead;
- size_t esize;
-
- while( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
- RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL );
- }
-
- for(i=0 ; i<sc->numRxbuffers; i++)
- {
- st_le32( &sc->rx_ring[i].status, 0);
- st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
- }
-
- for(i=0 ; i<sc->numTxbuffers; i++)
- {
- st_le32( &sc->tx_ring[i].status, XL_TXSTAT_DL_COMPLETE );
- st_le32( &sc->tx_ring[i].next, 0);
- if( sc->tx_ring[i].mbuf )
- {
- m_free( sc->tx_ring[i].mbuf );
- sc->tx_ring[i].mbuf = NULL;
- }
- }
-}
-
-
-
-
-/*
- * Show interface statistics
- */
-static void
-elnk_stats (struct elnk_softc *sc)
-{
- printf(" MII PHY data { anr:%04x lpar:%04x stat:%04x ctl:%04x }\n",
- sc->xl_stats.miianr,
- sc->xl_stats.miipar,
- sc->xl_stats.miistatus,
- sc->xl_stats.miicmd);
-
- printf(" internalcfg:%08" PRIx32 " macctl:%04x dmactl:%08" PRIx32 "\n",
- sc->xl_stats.internalconfig,
- sc->xl_stats.mac_control,
- sc->xl_stats.dmactl);
-
- printf(" rxstatus:%04x txstatus:%02x smbstat:%04x\n",
- sc->xl_stats.rxstatus,
- sc->xl_stats.txstatus,
- sc->xl_stats.smbstatus);
-
- printf(" txfree:%04X intstatus:%04x mediastat:%04x\n",
- sc->xl_stats.txfree,
- sc->xl_stats.intstatus,
- sc->xl_stats.mediastatus);
-
-
- {
- int i, totalLengths= 0, numLengths= 0;
-
- for(i=0; i< NUM_CHAIN_LENGTHS; i++)
- {
- if( sc->chain_lengths[i] > -1 )
- {
- totalLengths += sc->chain_lengths[i];
- ++numLengths;
- }
- }
-
- printf(" interrupts:%-9" PRIu32 " txcmp_ints:%-5" PRIu32 " avg_chain_len:%-4d\n",
- sc->xl_stats.device_interrupts,
- sc->xl_stats.txcomplete_ints,
- numLengths ? (totalLengths / numLengths) : -1 );
- }
-
- printf(" carrier_lost:%-5d sqe_errs:%-5d\n",
- sc->xl_stats.xl_carrier_lost,
- sc->xl_stats.xl_sqe_errs);
-
- printf(" tx_multi_collision:%-5d tx_single_collision:%-5d\n",
- sc->xl_stats.xl_tx_multi_collision,
- sc->xl_stats.xl_tx_single_collision);
-
- printf(" tx_late_collision:%-5d rx_overrun:%-5d\n",
- sc->xl_stats.xl_tx_late_collision,
- sc->xl_stats.xl_rx_overrun);
-
- printf(" tx_deferred:%-5d badssd:%-5d\n",
- sc->xl_stats.xl_tx_deferred,
- sc->xl_stats.xl_badssd);
-
- printf(" rx_frames_ok:%-9" PRIu32 " tx_frames_ok:%-9" PRIu32 "\n",
- sc->xl_stats.xl_rx_frames_ok,
- sc->xl_stats.xl_tx_frames_ok);
-
- printf(" rx_bytes_ok:%-9" PRIu32 " tx_bytes_ok:%-9" PRIu32 "\n",
- sc->xl_stats.xl_rx_bytes_ok,
- sc->xl_stats.xl_tx_bytes_ok );
-}
-
-
-
-
-
-
-
-/*
- * Driver ioctl handler
- */
-static int
-elnk_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct elnk_softc *sc = 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:
- elnk_stop (sc);
- break;
-
- case IFF_UP:
- elnk_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- elnk_stop (sc);
- elnk_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- elnk_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-
-
-
-
-
-
-
-#if 0
-static int iftap(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m )
-{
- int i;
- char *delim, *pkt;
-
- printk("unit %i, src ", ifp->if_unit );
- for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
- printk("%s%02x", delim, (char) eh->ether_shost[i] );
-
- printk(" dest ");
-
- for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
- printk("%s%02x", delim, (char) eh->ether_dhost[i] );
- printk(" pkt ");
-
- pkt = (char *)eh;
- for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
- printk("%s%02x", delim, (char) pkt[i] );
-
- printk("\n");
- return 0;
-}
-#endif
-
-
-
-struct el_boards
-{
- int pbus,pdev,pfun, vid, did, tindex;
-};
-
-/* Prototype to avoid warning. This must be a global symbol. */
-int rtems_elnk_driver_attach(struct rtems_bsdnet_ifconfig *config, int attach);
-
-/*
- * Attach an ELNK driver to the system
- */
-int
-rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
-{
- struct elnk_softc *sc;
- struct ifnet *ifp;
- char *unitName;
- int unitNumber;
- int mtu, i;
- unsigned char cvalue;
- struct el_boards sysboards[NUM_UNITS];
- int numFound = 0;
- int pbus, pdev, pfun;
-#if defined(__i386__)
- uint32_t value;
- uint8_t interrupt;
-#endif
-#if defined(__PPC__)
- uint32_t lvalue;
-#endif
-
-
- /*
- * Get the instance number for the board we're going to configure
- * from the user.
- */
- if( (unitNumber = rtems_bsdnet_parse_driver_name( config, &unitName)) == -1 )
- {
- return 0;
- }
-
- if( strcmp(unitName, DRIVER_PREFIX) )
- {
- printk("etherlink : invalid unit name '%s'\n", unitName );
- return 0;
- }
-
- if ((unitNumber < 1) || (unitNumber > NUM_UNITS))
- {
- printk("etherlink : unit %i is invalid, must be (1 <= n <= %d)\n", unitNumber, NUM_UNITS);
- return 0;
- }
-
-
- {
- int done= 0, unum;
-
- /*
- * Run thru the list of boards, finding all that are present in
- * the system. Sort by slot,dev - and then use the unitNumber-1
- * to index the list and select the device. Yucky.
- */
- for( i=0; !done && xl_devs[i].xl_vid; i++)
- {
- for(unum= 1; !done &&
- pci_find_device( xl_devs[i].xl_vid, xl_devs[i].xl_did, unum-1,
- &sysboards[numFound].pbus,
- &sysboards[numFound].pdev,
- &sysboards[numFound].pfun)==0; unum++)
- {
- if( numFound == NUM_UNITS )
- {
- printk("etherlink : Maximum of %d units found, extra devices ignored.\n", NUM_UNITS );
- done=-1;
- }
- else
- {
- sysboards[numFound].vid = xl_devs[i].xl_vid;
- sysboards[numFound].did = xl_devs[i].xl_did;
- sysboards[numFound].tindex = i;
- ++numFound;
- }
- }
- }
-
- if( ! numFound )
- {
- printk("etherlink : No Etherlink devices found\n");
- return 0;
- }
-
- if( unitNumber-1 >= numFound )
- {
- printk("etherlink : device '%s' not found\n", config->name );
- return 0;
- }
-
- /*
- * Got the list of etherlink boards in the system, now sort by
- * slot,device. bubble sorts aren't all that wonderful, but this
- * is a short & infrequently sorted list.
- */
- if( numFound > 1 )
- {
- struct el_boards tboard;
- int didsort;
-
- do
- {
- didsort = 0;
-
- for(i=1; i<numFound; i++)
- {
- if( sysboards[i-1].pbus > sysboards[i].pbus ||
- (sysboards[i-1].pbus == sysboards[i].pbus && sysboards[i-1].pdev > sysboards[i].pdev) )
- {
- memcpy(&tboard, &sysboards[i-1], sizeof(struct el_boards));
- memcpy(&sysboards[i-1], &sysboards[i], sizeof(struct el_boards));
- memcpy(&sysboards[i], &tboard, sizeof(struct el_boards));
- didsort++;
- }
- }
- }
- while( didsort );
- }
-
- /*
- ** board list is sorted, now select the unit
- */
-
- pbus = sysboards[unitNumber-1].pbus;
- pdev = sysboards[unitNumber-1].pdev;
- pfun = sysboards[unitNumber-1].pfun;
- }
-
- sc = &elnk_softc[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL)
- {
- printk("etherlink : unit %i already in use.\n", unitNumber );
- return 0;
- }
-
- /*
- ** Save various things
- */
- sc->xl_unit = unitNumber;
- sc->xl_type = sysboards[ unitNumber-1 ].tindex;
-
- sc->vendorID = sysboards[numFound].vid;
- sc->deviceID = sysboards[numFound].did;
-
- sc->numRxbuffers = (config->rbuf_count) ? config->rbuf_count : RX_RING_SIZE;
- sc->numTxbuffers = (config->xbuf_count) ? config->xbuf_count : TX_RING_SIZE;
-
-
- for(i=0; i< NUM_CHAIN_LENGTHS; i++) sc->chain_lengths[i]= -1;
- sc->chlenIndex = 0;
-
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- sc->acceptBroadcast = !config->ignore_broadcast;
-
-
-
-#ifdef ELNK_DEBUG
- printk("etherlink : device '%s', name 'elnk%d', pci %02x:%02x.%02x, %d rx/%d tx buffers\n",
- xl_devs[sc->xl_type].xl_name, sc->xl_unit,
- pbus, pdev, pfun,
- sc->numRxbuffers, sc->numTxbuffers);
-#endif
-
-
- /*
- ** Create this unit's stats timer
- */
- if( rtems_timer_create( rtems_build_name( 'X', 'L', 't', (char)(sc->xl_unit & 255)),
- &sc->stat_timer_id ) != RTEMS_SUCCESSFUL )
- {
- printk("etherlink : unit elnk%d unable to create stats timer\n", sc->xl_unit );
- return 0;
- }
-
- /* update stats 1 times/second if things aren't incrementing fast
- * enough to trigger stats interrupts
- */
- sc->stats_update_ticks = rtems_clock_get_ticks_per_second();
-
- /*
- ** Get this unit's rx/tx event
- */
- sc->ioevent = unit_signals[unitNumber-1];
-
-
-#if defined(__i386__)
- pci_read_config_dword(pbus, pdev, pfun, 16, &value);
- sc->ioaddr = value & ~IO_MASK;
-
- pci_read_config_byte(pbus, pdev, pfun, 60, &interrupt);
- cvalue = interrupt;
-#endif
-#if defined(__PPC__)
- /*
- ** Prep the board
- */
- pci_write_config_word(pbus, pdev, pfun,
- PCI_COMMAND,
- (uint16_t)( PCI_COMMAND_IO |
- PCI_COMMAND_MASTER |
- PCI_COMMAND_INVALIDATE |
- PCI_COMMAND_WAIT ) );
- /*
- * Get the device's base address
- */
- pci_read_config_dword(pbus, pdev, pfun,
- PCI_BASE_ADDRESS_0,
- &lvalue);
-
- sc->ioaddr = (uint32_t)lvalue & PCI_BASE_ADDRESS_IO_MASK;
- /*
- ** Store the interrupt name, we'll use it later when we initialize
- ** the board.
- */
- pci_read_config_byte(pbus, pdev, pfun,
- PCI_INTERRUPT_LINE,
- &cvalue);
-#endif
-
- memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
- sc->irqInfo.name = cvalue;
-
-
- /*
- ** Establish basic board config, set node address from config or
- ** board eeprom, do stuff with additional device properties
- */
-
- {
- uint8_t pci_latency;
- uint8_t new_latency = 248;
-
- /* Check the PCI latency value. On the 3c590 series the latency timer
- must be set to the maximum value to avoid data corruption that occurs
- when the timer expires during a transfer. This bug exists the Vortex
- chip only. */
-#if defined(__i386__)
- pci_read_config_byte(pbus, pdev, pfun, 0x0d, &pci_latency);
-#endif
-#if defined(__PPC__)
- pci_read_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, &pci_latency);
-#endif
- if (pci_latency < new_latency)
- {
- printk("etherlink : unit elnk%d Overriding PCI latency, timer (CFLT) setting of %d, new value is %d.\n", sc->xl_unit, pci_latency, new_latency );
-#if defined(__i386__)
- pci_write_config_byte(pbus, pdev, pfun, 0x0d, new_latency);
-#endif
-#if defined(__PPC__)
- pci_write_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, new_latency);
-#endif
- }
- }
-
- /* Reset the adapter. */
- xl_reset(sc);
-
-
- {
- u_int16_t xcvr[2];
- u_char eaddr[ETHER_ADDR_LEN];
-
- sc->xl_flags = 0;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_555)
- sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_556 ||
- sc->deviceID == TC_DEVICEID_HURRICANE_556B)
- sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
- XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET |
- XL_FLAG_INVERT_LED_PWR | XL_FLAG_INVERT_MII_PWR;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_555 ||
- sc->deviceID == TC_DEVICEID_HURRICANE_556)
- sc->xl_flags |= XL_FLAG_8BITROM;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_556B)
- sc->xl_flags |= XL_FLAG_NO_XCVR_PWR;
-
- if (sc->deviceID == TC_DEVICEID_HURRICANE_575A ||
- sc->deviceID == TC_DEVICEID_HURRICANE_575B ||
- sc->deviceID == TC_DEVICEID_HURRICANE_575C ||
- sc->deviceID == TC_DEVICEID_HURRICANE_656B ||
- sc->deviceID == TC_DEVICEID_TORNADO_656C)
- sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
- XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_656)
- sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_575B)
- sc->xl_flags |= XL_FLAG_INVERT_LED_PWR;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_575C)
- sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
- if (sc->deviceID == TC_DEVICEID_TORNADO_656C)
- sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
- if (sc->deviceID == TC_DEVICEID_HURRICANE_656 ||
- sc->deviceID == TC_DEVICEID_HURRICANE_656B)
- sc->xl_flags |= XL_FLAG_INVERT_MII_PWR |
- XL_FLAG_INVERT_LED_PWR;
- if (sc->deviceID == TC_DEVICEID_TORNADO_10_100BT_920B)
- sc->xl_flags |= XL_FLAG_PHYOK;
-
-
- if (config->hardware_address)
- {
- memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- }
- else
- {
- if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1))
- {
- printk("etherlink : unit elnk%d Failed to read station address\n", sc->xl_unit );
- return 0;
- }
- memcpy((char *)&sc->arpcom.ac_enaddr, eaddr, ETHER_ADDR_LEN);
- }
-
- /*
- * Figure out the card type. 3c905B adapters have the
- * 'supportsNoTxLength' bit set in the capabilities
- * word in the EEPROM.
- */
- xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
- if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)
- sc->xl_type = XL_TYPE_905B;
- else
- sc->xl_type = XL_TYPE_90X;
-
-
- /*
- * Now we have to see what sort of media we have.
- * This includes probing for an MII interace and a
- * possible PHY.
- */
- XL_SEL_WIN(3);
- sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
-
- xl_read_eeprom(sc, (char *)&xcvr, XL_EE_ICFG_0, 2, 0);
- sc->xl_xcvr = xcvr[0] | xcvr[1] << 16;
- sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
- sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
-
-#if 0
- printk("etherlink : unit elnk%d EEPROM set xcvr to 0x%x\n", sc->xl_unit, sc->xl_xcvr);
-#endif
-
- {
- char msg[255];
- int i;
-
- struct _availmedia
- {
- int bit;
- char *name;
- } _am[]= {{ XL_MEDIAOPT_BT4, "100BaseT4" },
- { XL_MEDIAOPT_BTX, "100BaseTX" },
- { XL_MEDIAOPT_BFX, "100BaseFX" },
- { XL_MEDIAOPT_BT, "10BaseT" },
- { XL_MEDIAOPT_BNC, "10Base2" },
- { XL_MEDIAOPT_AUI, "10mbps AUI"},
- { XL_MEDIAOPT_MII, "MII"},
- { 0, NULL }};
-
- msg[0]= 0;
- for( i=0; _am[i].bit; i++)
- {
- if( sc->xl_media & _am[i].bit )
- sprintf( &msg[strlen(msg)], ",%s", _am[i].name );
- }
- if( !strlen(msg) ) strcpy( &msg[1], "<no media bits>");
-
- printk("etherlink : unit elnk%d available media : %s\n", sc->xl_unit, &msg[1]);
- }
-
- XL_SEL_WIN(7);
- }
-
-
-
- /*
- * Set up network interface
- */
- ifp->if_softc = sc;
- ifp->if_name = unitName;
- ifp->if_unit = sc->xl_unit;
- ifp->if_mtu = mtu;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
- if (ifp->if_snd.ifq_maxlen == 0)
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_init = elnk_init;
- ifp->if_start = elnk_start;
- ifp->if_ioctl = elnk_ioctl;
- ifp->if_output = ether_output;
-
-#if 0
- ifp->if_tap = iftap;
-#endif
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
-
-#ifdef ELNK_DEBUG
- printk( "etherlink : unit elnk%d driver attached\n", sc->xl_unit );
-#endif
-
- /*
- * Start driver tasks if this is the first unit initialized
- */
- if (txDaemonTid == 0)
- {
- if( rtems_message_queue_create( rtems_build_name('X','L','c','r'),
- sc->numTxbuffers+1,
- sizeof(struct TXMD *),
- RTEMS_FIFO | RTEMS_LOCAL,
- &chainRecoveryQueue ) != RTEMS_SUCCESSFUL )
- {
- rtems_panic( "etherlink : Unable to create TX buffer recovery queue\n" );
- }
-
-
- rxDaemonTid = rtems_bsdnet_newproc( "XLrx", 4096,
- elnk_rxDaemon, NULL);
-
- txDaemonTid = rtems_bsdnet_newproc( "XLtx", 4096,
- elnk_txDaemon, NULL);
-#ifdef ELNK_DEBUG
- printk( "etherlink : driver tasks created\n" );
-#endif
- }
-
- return 1;
-};
-
-#endif /* ELNK_SUPPORTED */
-
-/* eof */
diff --git a/c/src/libchip/network/greth.c b/c/src/libchip/network/greth.c
deleted file mode 100644
index 20be83ee48..0000000000
--- a/c/src/libchip/network/greth.c
+++ /dev/null
@@ -1,1196 +0,0 @@
-/*
- * Gaisler Research ethernet MAC driver
- * adapted from Opencores driver by Marko Isomaki
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- * 2007-09-07, Ported GBIT support from 4.6.5
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <bsp.h>
-
-#ifdef GRETH_SUPPORTED
-
-#include <inttypes.h>
-#include <errno.h>
-#include <rtems/bspIo.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <libchip/greth.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>
-
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef free
-#undef free
-#endif
-
-/* #define GRETH_DEBUG */
-
-#ifdef CPU_U32_FIX
-extern void ipalign(struct mbuf *m);
-#endif
-
-/* Used when reading from memory written by GRETH DMA unit */
-#ifndef GRETH_MEM_LOAD
-#define GRETH_MEM_LOAD(addr) (*(volatile unsigned int *)(addr))
-#endif
-
-/*
- * Number of OCs supported by this driver
- */
-#define NOCDRIVER 1
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define RBUF_SIZE 1518
-
-#define ET_MINLEN 64 /* minimum message length */
-
-/*
- * RTEMS event used by interrupt handler to signal driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/*
- * RTEMS event used to start transmit daemon.
- * This must not be the same as INTERRUPT_EVENT.
- */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
- /* event to send when tx buffers become available */
-#define GRETH_TX_WAIT_EVENT RTEMS_EVENT_3
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/* 4s Autonegotiation Timeout */
-#ifndef GRETH_AUTONEGO_TIMEOUT_MS
-#define GRETH_AUTONEGO_TIMEOUT_MS 4000
-#endif
-const struct timespec greth_tan = {
- GRETH_AUTONEGO_TIMEOUT_MS/1000,
- (GRETH_AUTONEGO_TIMEOUT_MS % 1000) *1000000
-};
-
-/* For optimizing the autonegotiation time */
-#define GRETH_AUTONEGO_PRINT_TIME
-
-/* Ethernet buffer descriptor */
-
-typedef struct _greth_rxtxdesc {
- volatile uint32_t ctrl; /* Length and status */
- uint32_t *addr; /* Buffer pointer */
-} greth_rxtxdesc;
-
-
-/*
- * Per-device data
- */
-struct greth_softc
-{
-
- struct arpcom arpcom;
-
- greth_regs *regs;
-
- int acceptBroadcast;
- rtems_id daemonTid;
-
- unsigned int tx_ptr;
- unsigned int tx_dptr;
- unsigned int tx_cnt;
- unsigned int rx_ptr;
- unsigned int txbufs;
- unsigned int rxbufs;
- greth_rxtxdesc *txdesc;
- greth_rxtxdesc *rxdesc;
- struct mbuf **rxmbuf;
- struct mbuf **txmbuf;
- rtems_vector_number vector;
-
- /* TX descriptor interrupt generation */
- int tx_int_gen;
- int tx_int_gen_cur;
- struct mbuf *next_tx_mbuf;
- int max_fragsize;
-
- /*Status*/
- struct phy_device_info phydev;
- int fd;
- int sp;
- int gb;
- int gbit_mac;
- int auto_neg;
- struct timespec auto_neg_time;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
-
- unsigned long rxPackets;
- unsigned long rxLengthError;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxOverrun;
-
- unsigned long txInterrupts;
-
- unsigned long txDeferred;
- unsigned long txHeartbeat;
- unsigned long txLateCollision;
- unsigned long txRetryLimit;
- unsigned long txUnderrun;
-
-};
-
-static struct greth_softc greth;
-
-int greth_process_tx_gbit(struct greth_softc *sc);
-int greth_process_tx(struct greth_softc *sc);
-
-static char *almalloc(int sz)
-{
- char *tmp;
- tmp = calloc(1,2*sz);
- tmp = (char *) (((uintptr_t)tmp+sz) & ~(sz -1));
- return(tmp);
-}
-
-/* GRETH interrupt handler */
-
-static void greth_interrupt_handler (void *arg)
-{
- uint32_t status;
- uint32_t ctrl;
- rtems_event_set events = 0;
- struct greth_softc *greth = arg;
-
- /* read and clear interrupt cause */
- status = greth->regs->status;
- greth->regs->status = status;
- ctrl = greth->regs->ctrl;
-
- /* Frame received? */
- if ((ctrl & GRETH_CTRL_RXIRQ) && (status & (GRETH_STATUS_RXERR | GRETH_STATUS_RXIRQ)))
- {
- greth->rxInterrupts++;
- /* Stop RX-Error and RX-Packet interrupts */
- ctrl &= ~GRETH_CTRL_RXIRQ;
- events |= INTERRUPT_EVENT;
- }
-
- if ( (ctrl & GRETH_CTRL_TXIRQ) && (status & (GRETH_STATUS_TXERR | GRETH_STATUS_TXIRQ)) )
- {
- greth->txInterrupts++;
- ctrl &= ~GRETH_CTRL_TXIRQ;
- events |= GRETH_TX_WAIT_EVENT;
- }
-
- /* Clear interrupt sources */
- greth->regs->ctrl = ctrl;
-
- /* Send the event(s) */
- if ( events )
- rtems_bsdnet_event_send (greth->daemonTid, events);
-}
-
-static uint32_t read_mii(uint32_t phy_addr, uint32_t reg_addr)
-{
- while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
- greth.regs->mdio_ctrl = (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_READ;
- while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
- if (!(greth.regs->mdio_ctrl & GRETH_MDIO_LINKFAIL))
- return((greth.regs->mdio_ctrl >> 16) & 0xFFFF);
- else {
- printf("greth: failed to read mii\n");
- return (0);
- }
-}
-
-static void write_mii(uint32_t phy_addr, uint32_t reg_addr, uint32_t data)
-{
- while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
- greth.regs->mdio_ctrl =
- ((data & 0xFFFF) << 16) | (phy_addr << 11) | (reg_addr << 6) | GRETH_MDIO_WRITE;
- while (greth.regs->mdio_ctrl & GRETH_MDIO_BUSY) {}
-}
-
-static void print_init_info(struct greth_softc *sc)
-{
- printf("greth: driver attached\n");
- if ( sc->auto_neg == -1 ){
- printf("Auto negotiation timed out. Selecting default config\n");
- }
- printf("**** PHY ****\n");
- printf("Vendor: %x Device: %x Revision: %d\n",sc->phydev.vendor, sc->phydev.device, sc->phydev.rev);
- printf("Current Operating Mode: ");
- if (sc->gb) {
- printf("1000 Mbit ");
- } else if (sc->sp) {
- printf("100 Mbit ");
- } else {
- printf("10 Mbit ");
- }
- if (sc->fd) {
- printf("Full Duplex\n");
- } else {
- printf("Half Duplex\n");
- }
-#ifdef GRETH_AUTONEGO_PRINT_TIME
- if ( sc->auto_neg ) {
- printf("Autonegotiation Time: %ldms\n", sc->auto_neg_time.tv_sec*1000 +
- sc->auto_neg_time.tv_nsec/1000000);
- }
-#endif
-}
-
-
-/*
- * Initialize the ethernet hardware
- */
-static void
-greth_initialize_hardware (struct greth_softc *sc)
-{
- struct mbuf *m;
- int i;
- int phyaddr;
- int phyctrl;
- int phystatus;
- int tmp1;
- int tmp2;
- struct timespec tstart, tnow;
-
- greth_regs *regs;
-
- regs = sc->regs;
-
- /* Reset the controller. */
- greth.rxInterrupts = 0;
- greth.rxPackets = 0;
-
- regs->ctrl = 0;
- regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
- regs->ctrl = 0; /* Reset OFF */
-
- /* Check if mac is gbit capable*/
- sc->gbit_mac = (regs->ctrl >> 27) & 1;
-
- /* Get the phy address which assumed to have been set
- correctly with the reset value in hardware*/
- phyaddr = (regs->mdio_ctrl >> 11) & 0x1F;
-
- /* get phy control register default values */
- while ((phyctrl = read_mii(phyaddr, 0)) & 0x8000) {}
-
- /* reset PHY and wait for completion */
- write_mii(phyaddr, 0, 0x8000 | phyctrl);
-
- while ((read_mii(phyaddr, 0)) & 0x8000) {}
- phystatus = read_mii(phyaddr, 1);
-
- /* Disable Gbit auto-neg advertisement if MAC does not support it */
-
- if ((!sc->gbit_mac) && (phystatus & 0x100)) write_mii(phyaddr, 9, 0);
-
- /* Restart auto-negotiation if available */
- if (phystatus & 0x08) {
- write_mii(phyaddr, 0, phyctrl | 0x1200);
- phyctrl = read_mii(phyaddr, 0);
- }
-
- /* Check if PHY is autoneg capable and then determine operating mode,
- otherwise force it to 10 Mbit halfduplex */
- sc->gb = 0;
- sc->fd = 0;
- sc->sp = 0;
- sc->auto_neg = 0;
- _Timespec_Set_to_zero(&sc->auto_neg_time);
- if ((phyctrl >> 12) & 1) {
- /*wait for auto negotiation to complete*/
- sc->auto_neg = 1;
- if (rtems_clock_get_uptime(&tstart) != RTEMS_SUCCESSFUL)
- printk("rtems_clock_get_uptime failed\n");
- while (!(((phystatus = read_mii(phyaddr, 1)) >> 5) & 1)) {
- if (rtems_clock_get_uptime(&tnow) != RTEMS_SUCCESSFUL)
- printk("rtems_clock_get_uptime failed\n");
- _Timespec_Subtract(&tstart, &tnow, &sc->auto_neg_time);
- if (_Timespec_Greater_than(&sc->auto_neg_time, &greth_tan)) {
- sc->auto_neg = -1; /* Failed */
- tmp1 = read_mii(phyaddr, 0);
- sc->gb = ((phyctrl >> 6) & 1) && !((phyctrl >> 13) & 1);
- sc->sp = !((phyctrl >> 6) & 1) && ((phyctrl >> 13) & 1);
- sc->fd = (phyctrl >> 8) & 1;
- goto auto_neg_done;
- }
- /* Wait about 30ms, time is PHY dependent */
- rtems_task_wake_after(rtems_clock_get_ticks_per_second()/32);
- }
- sc->phydev.adv = read_mii(phyaddr, 4);
- sc->phydev.part = read_mii(phyaddr, 5);
- if ((phystatus >> 8) & 1) {
- sc->phydev.extadv = read_mii(phyaddr, 9);
- sc->phydev.extpart = read_mii(phyaddr, 10);
- if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000FD) &&
- (sc->phydev.extpart & GRETH_MII_EXTPRT_1000FD)) {
- sc->gb = 1;
- sc->fd = 1;
- }
- else if ( (sc->phydev.extadv & GRETH_MII_EXTADV_1000HD) &&
- (sc->phydev.extpart & GRETH_MII_EXTPRT_1000HD)) {
- sc->gb = 1;
- sc->fd = 0;
- }
- }
- if ((sc->gb == 0) || ((sc->gb == 1) && (sc->gbit_mac == 0))) {
- if ( (sc->phydev.adv & GRETH_MII_100TXFD) &&
- (sc->phydev.part & GRETH_MII_100TXFD)) {
- sc->sp = 1;
- sc->fd = 1;
- }
- else if ( (sc->phydev.adv & GRETH_MII_100TXHD) &&
- (sc->phydev.part & GRETH_MII_100TXHD)) {
- sc->sp = 1;
- sc->fd = 0;
- }
- else if ( (sc->phydev.adv & GRETH_MII_10FD) &&
- (sc->phydev.part & GRETH_MII_10FD)) {
- sc->fd = 1;
- }
- }
- }
-auto_neg_done:
- sc->phydev.vendor = 0;
- sc->phydev.device = 0;
- sc->phydev.rev = 0;
- phystatus = read_mii(phyaddr, 1);
-
- /*Read out PHY info if extended registers are available */
- if (phystatus & 1) {
- tmp1 = read_mii(phyaddr, 2);
- tmp2 = read_mii(phyaddr, 3);
-
- sc->phydev.vendor = (tmp1 << 6) | ((tmp2 >> 10) & 0x3F);
- sc->phydev.rev = tmp2 & 0xF;
- sc->phydev.device = (tmp2 >> 4) & 0x3F;
- }
-
- /* Force to 10 mbit half duplex if the 10/100 MAC is used with a 1000 PHY*/
- /*check if marvell 88EE1111 PHY. Needs special reset handling */
- if ((phystatus & 1) && (sc->phydev.vendor == 0x005043) && (sc->phydev.device == 0x0C)) {
- if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
- write_mii(phyaddr, 0, sc->sp << 13);
- write_mii(phyaddr, 0, 0x8000);
- sc->gb = 0;
- sc->sp = 0;
- sc->fd = 0;
- }
- } else {
- if (((sc->gb) && !(sc->gbit_mac)) || !((phyctrl >> 12) & 1)) {
- write_mii(phyaddr, 0, sc->sp << 13);
- sc->gb = 0;
- sc->sp = 0;
- sc->fd = 0;
- }
- }
- while ((read_mii(phyaddr, 0)) & 0x8000) {}
-
- regs->ctrl = 0;
- regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
- regs->ctrl = 0;
-
- /* Initialize rx/tx descriptor pointers */
- sc->txdesc = (greth_rxtxdesc *) almalloc(1024);
- sc->rxdesc = (greth_rxtxdesc *) almalloc(1024);
- sc->tx_ptr = 0;
- sc->tx_dptr = 0;
- sc->tx_cnt = 0;
- sc->rx_ptr = 0;
- regs->txdesc = (uintptr_t) sc->txdesc;
- regs->rxdesc = (uintptr_t) sc->rxdesc;
-
- sc->rxmbuf = calloc(sc->rxbufs, sizeof(*sc->rxmbuf));
- sc->txmbuf = calloc(sc->txbufs, sizeof(*sc->txmbuf));
-
- for (i = 0; i < sc->txbufs; i++)
- {
- sc->txdesc[i].ctrl = 0;
- if (!(sc->gbit_mac)) {
- sc->txdesc[i].addr = malloc(GRETH_MAXBUF_LEN);
- }
-#ifdef GRETH_DEBUG
- /* printf("TXBUF: %08x\n", (int) sc->txdesc[i].addr); */
-#endif
- }
- for (i = 0; i < sc->rxbufs; i++)
- {
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- if (sc->gbit_mac)
- m->m_data += 2;
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- sc->rxmbuf[i] = m;
- sc->rxdesc[i].addr = (uint32_t *) mtod(m, uint32_t *);
- sc->rxdesc[i].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
-#ifdef GRETH_DEBUG
-/* printf("RXBUF: %08x\n", (int) sc->rxdesc[i].addr); */
-#endif
- }
- sc->rxdesc[sc->rxbufs - 1].ctrl |= GRETH_RXD_WRAP;
-
- /* set ethernet address. */
- regs->mac_addr_msb =
- sc->arpcom.ac_enaddr[0] << 8 | sc->arpcom.ac_enaddr[1];
-
- uint32_t mac_addr_lsb;
- mac_addr_lsb = sc->arpcom.ac_enaddr[2];
- mac_addr_lsb <<= 8;
- mac_addr_lsb |= sc->arpcom.ac_enaddr[3];
- mac_addr_lsb <<= 8;
- mac_addr_lsb |= sc->arpcom.ac_enaddr[4];
- mac_addr_lsb <<= 8;
- mac_addr_lsb |= sc->arpcom.ac_enaddr[5];
- regs->mac_addr_lsb = mac_addr_lsb;
-
- if ( sc->rxbufs < 10 ) {
- sc->tx_int_gen = sc->tx_int_gen_cur = 1;
- }else{
- sc->tx_int_gen = sc->tx_int_gen_cur = sc->txbufs/2;
- }
- sc->next_tx_mbuf = NULL;
-
- if ( !sc->gbit_mac )
- sc->max_fragsize = 1;
-
- /* clear all pending interrupts */
- regs->status = 0xffffffff;
-
- /* install interrupt handler */
- rtems_interrupt_handler_install(sc->vector, "greth", RTEMS_INTERRUPT_SHARED,
- greth_interrupt_handler, sc);
-
- regs->ctrl |= GRETH_CTRL_RXEN | (sc->fd << 4) | GRETH_CTRL_RXIRQ | (sc->sp << 7) | (sc->gb << 8);
-
- print_init_info(sc);
-}
-
-#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.
- */
-
-void ipalign(struct mbuf *m)
-{
- unsigned int *first, *last, data;
- unsigned int tmp;
-
- 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 = GRETH_MEM_LOAD(first);
- tmp = tmp << 16;
- first++;
- do {
- /* When snooping is not available the LDA instruction must be used
- * to avoid the cache to return an illegal value.
- * Load with forced cache miss
- */
- data = GRETH_MEM_LOAD(first);
- *first = tmp | (data >> 16);
- tmp = data << 16;
- first++;
- } while (first <= last);
-
- m->m_data = (caddr_t)(((int) m->m_data) + 2);
- }
-}
-#endif
-
-static void
-greth_Daemon (void *arg)
-{
- struct ether_header *eh;
- struct greth_softc *dp = (struct greth_softc *) &greth;
- struct ifnet *ifp = &dp->arpcom.ac_if;
- struct mbuf *m;
- unsigned int len, len_status, bad;
- rtems_event_set events;
- rtems_interrupt_level level;
- int first;
-#ifdef CPU_U32_FIX
- unsigned int tmp;
-#endif
-
- for (;;)
- {
- rtems_bsdnet_event_receive (INTERRUPT_EVENT | GRETH_TX_WAIT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
-
- if ( events & GRETH_TX_WAIT_EVENT ){
- /* TX interrupt.
- * We only end up here when all TX descriptors has been used,
- * and
- */
- if ( dp->gbit_mac )
- greth_process_tx_gbit(dp);
- else
- greth_process_tx(dp);
-
- /* If we didn't get a RX interrupt we don't process it */
- if ( (events & INTERRUPT_EVENT) == 0 )
- continue;
- }
-
-#ifdef GRETH_ETH_DEBUG
- printf ("r\n");
-#endif
- first=1;
- /* Scan for Received packets */
-again:
- while (!((len_status =
- GRETH_MEM_LOAD(&dp->rxdesc[dp->rx_ptr].ctrl)) & GRETH_RXD_ENABLE))
- {
- bad = 0;
- if (len_status & GRETH_RXD_TOOLONG)
- {
- dp->rxLengthError++;
- bad = 1;
- }
- if (len_status & GRETH_RXD_DRIBBLE)
- {
- dp->rxNonOctet++;
- bad = 1;
- }
- if (len_status & GRETH_RXD_CRCERR)
- {
- dp->rxBadCRC++;
- bad = 1;
- }
- if (len_status & GRETH_RXD_OVERRUN)
- {
- dp->rxOverrun++;
- bad = 1;
- }
- if (len_status & GRETH_RXD_LENERR)
- {
- dp->rxLengthError++;
- bad = 1;
- }
- if (!bad)
- {
- /* pass on the packet in the receive buffer */
- len = len_status & 0x7FF;
- m = dp->rxmbuf[dp->rx_ptr];
-#ifdef GRETH_DEBUG
- int i;
- printf("RX: 0x%08x, Len: %d : ", (int) m->m_data, len);
- for (i=0; i<len; i++)
- printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
- printf("\n");
-#endif
- m->m_len = m->m_pkthdr.len =
- len - sizeof (struct ether_header);
-
- eh = mtod (m, struct ether_header *);
-
- m->m_data += sizeof (struct ether_header);
-#ifdef CPU_U32_FIX
- if(!dp->gbit_mac) {
- /* OVERRIDE CACHED ETHERNET HEADER FOR NON-SNOOPING SYSTEMS */
- tmp = GRETH_MEM_LOAD((uintptr_t)eh);
- tmp = GRETH_MEM_LOAD(4+(uintptr_t)eh);
- tmp = GRETH_MEM_LOAD(8+(uintptr_t)eh);
- tmp = GRETH_MEM_LOAD(12+(uintptr_t)eh);
- (void)tmp;
- ipalign(m); /* Align packet on 32-bit boundary */
- }
-#endif
-
- ether_input (ifp, eh, m);
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- if (dp->gbit_mac)
- m->m_data += 2;
- dp->rxmbuf[dp->rx_ptr] = m;
- m->m_pkthdr.rcvif = ifp;
- dp->rxdesc[dp->rx_ptr].addr =
- (uint32_t *) mtod (m, uint32_t *);
- dp->rxPackets++;
- }
- if (dp->rx_ptr == dp->rxbufs - 1) {
- dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ | GRETH_RXD_WRAP;
- } else {
- dp->rxdesc[dp->rx_ptr].ctrl = GRETH_RXD_ENABLE | GRETH_RXD_IRQ;
- }
- rtems_interrupt_disable(level);
- dp->regs->ctrl |= GRETH_CTRL_RXEN;
- rtems_interrupt_enable(level);
- dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
- }
-
- /* Always scan twice to avoid deadlock */
- if ( first ){
- first=0;
- rtems_interrupt_disable(level);
- dp->regs->ctrl |= GRETH_CTRL_RXIRQ;
- rtems_interrupt_enable(level);
- goto again;
- }
-
- }
-
-}
-
-static int inside = 0;
-static int
-sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct greth_softc *dp = ifp->if_softc;
- unsigned char *temp;
- struct mbuf *n;
- unsigned int len;
- rtems_interrupt_level level;
-
- /*printf("Send packet entered\n");*/
- if (inside) printf ("error: sendpacket re-entered!!\n");
- inside = 1;
-
- /*
- * Is there a free descriptor available?
- */
- if (GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].ctrl) & GRETH_TXD_ENABLE){
- /* No. */
- inside = 0;
- return 1;
- }
-
- /* Remember head of chain */
- n = m;
-
- len = 0;
- temp = (unsigned char *) GRETH_MEM_LOAD(&dp->txdesc[dp->tx_ptr].addr);
-#ifdef GRETH_DEBUG
- printf("TXD: 0x%08x : BUF: 0x%08x\n", (int) m->m_data, (int) temp);
-#endif
- for (;;)
- {
-#ifdef GRETH_DEBUG
- int i;
- printf("MBUF: 0x%08x : ", (int) m->m_data);
- for (i=0;i<m->m_len;i++)
- printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
- printf("\n");
-#endif
- len += m->m_len;
- if (len <= RBUF_SIZE)
- memcpy ((void *) temp, (char *) m->m_data, m->m_len);
- temp += m->m_len;
- if ((m = m->m_next) == NULL)
- break;
- }
-
- m_freem (n);
-
- /* don't send long packets */
-
- if (len <= GRETH_MAXBUF_LEN) {
- if (dp->tx_ptr < dp->txbufs-1) {
- dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_ENABLE | len;
- } else {
- dp->txdesc[dp->tx_ptr].ctrl =
- GRETH_TXD_WRAP | GRETH_TXD_ENABLE | len;
- }
- dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
- rtems_interrupt_disable(level);
- dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
- rtems_interrupt_enable(level);
-
- }
- inside = 0;
-
- return 0;
-}
-
-
-static int
-sendpacket_gbit (struct ifnet *ifp, struct mbuf *m)
-{
- struct greth_softc *dp = ifp->if_softc;
- unsigned int len;
-
- unsigned int ctrl;
- int frags;
- struct mbuf *mtmp;
- int int_en;
- rtems_interrupt_level level;
-
- if (inside) printf ("error: sendpacket re-entered!!\n");
- inside = 1;
-
- len = 0;
-#ifdef GRETH_DEBUG
- printf("TXD: 0x%08x\n", (int) m->m_data);
-#endif
- /* Get number of fragments too see if we have enough
- * resources.
- */
- frags=1;
- mtmp=m;
- while(mtmp->m_next){
- frags++;
- mtmp = mtmp->m_next;
- }
-
- if ( frags > dp->max_fragsize )
- dp->max_fragsize = frags;
-
- if ( frags > dp->txbufs ){
- inside = 0;
- printf("GRETH: MBUF-chain cannot be sent. Increase descriptor count.\n");
- return -1;
- }
-
- if ( frags > (dp->txbufs-dp->tx_cnt) ){
- inside = 0;
- /* Return number of fragments */
- return frags;
- }
-
-
- /* Enable interrupt from descriptor every tx_int_gen
- * descriptor. Typically every 16 descriptor. This
- * is only to reduce the number of interrupts during
- * heavy load.
- */
- dp->tx_int_gen_cur-=frags;
- if ( dp->tx_int_gen_cur <= 0 ){
- dp->tx_int_gen_cur = dp->tx_int_gen;
- int_en = GRETH_TXD_IRQ;
- }else{
- int_en = 0;
- }
-
- /* At this stage we know that enough descriptors are available */
- for (;;)
- {
-
-#ifdef GRETH_DEBUG
- int i;
- printf("MBUF: 0x%08x, Len: %d : ", (int) m->m_data, m->m_len);
- for (i=0; i<m->m_len; i++)
- printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
- printf("\n");
-#endif
- len += m->m_len;
- dp->txdesc[dp->tx_ptr].addr = (uint32_t *)m->m_data;
-
- /* Wrap around? */
- if (dp->tx_ptr < dp->txbufs-1) {
- ctrl = GRETH_TXD_ENABLE;
- }else{
- ctrl = GRETH_TXD_ENABLE | GRETH_TXD_WRAP;
- }
-
- /* Enable Descriptor */
- if ((m->m_next) == NULL) {
- dp->txdesc[dp->tx_ptr].ctrl = ctrl | int_en | m->m_len;
- break;
- }else{
- dp->txdesc[dp->tx_ptr].ctrl = GRETH_TXD_MORE | ctrl | int_en | m->m_len;
- }
-
- /* Next */
- dp->txmbuf[dp->tx_ptr] = m;
- dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
- dp->tx_cnt++;
- m = m->m_next;
- }
- dp->txmbuf[dp->tx_ptr] = m;
- dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
- dp->tx_cnt++;
-
- /* Tell Hardware about newly enabled descriptor */
- rtems_interrupt_disable(level);
- dp->regs->ctrl = dp->regs->ctrl | GRETH_CTRL_TXEN;
- rtems_interrupt_enable(level);
-
- inside = 0;
-
- return 0;
-}
-
-int greth_process_tx_gbit(struct greth_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_interrupt_level level;
- int first=1;
-
- /*
- * Send packets till queue is empty
- */
- for (;;){
- /* Reap Sent packets */
- while((sc->tx_cnt > 0) && !(GRETH_MEM_LOAD(&sc->txdesc[sc->tx_dptr].ctrl) & GRETH_TXD_ENABLE)) {
- m_free(sc->txmbuf[sc->tx_dptr]);
- sc->tx_dptr = (sc->tx_dptr + 1) % sc->txbufs;
- sc->tx_cnt--;
- }
-
- if ( sc->next_tx_mbuf ){
- /* Get packet we tried but faild to transmit last time */
- m = sc->next_tx_mbuf;
- sc->next_tx_mbuf = NULL; /* Mark packet taken */
- }else{
- /*
- * Get the next mbuf chain to transmit from Stack.
- */
- IF_DEQUEUE (&ifp->if_snd, m);
- if (!m){
- /* Hardware has sent all schedule packets, this
- * makes the stack enter at greth_start next time
- * a packet is to be sent.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- break;
- }
- }
-
- /* Are there free descriptors available? */
- /* Try to send packet, if it a negative number is returned. */
- if ( (sc->tx_cnt >= sc->txbufs) || sendpacket_gbit(ifp, m) ){
- /* Not enough resources */
-
- /* Since we have taken the mbuf out of the "send chain"
- * we must remember to use that next time we come back.
- * or else we have dropped a packet.
- */
- sc->next_tx_mbuf = m;
-
- /* Not enough resources, enable interrupt for transmissions
- * this way we will be informed when more TX-descriptors are
- * available.
- */
- if ( first ){
- first = 0;
- rtems_interrupt_disable(level);
- ifp->if_flags |= IFF_OACTIVE;
- sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
- rtems_interrupt_enable(level);
-
- /* We must check again to be sure that we didn't
- * miss an interrupt (if a packet was sent just before
- * enabling interrupts)
- */
- continue;
- }
-
- return -1;
- }else{
- /* Sent Ok, proceed to process more packets if available */
- }
- }
- return 0;
-}
-
-int greth_process_tx(struct greth_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_interrupt_level level;
- int first=1;
-
- /*
- * Send packets till queue is empty
- */
- for (;;){
- if ( sc->next_tx_mbuf ){
- /* Get packet we tried but failed to transmit last time */
- m = sc->next_tx_mbuf;
- sc->next_tx_mbuf = NULL; /* Mark packet taken */
- }else{
- /*
- * Get the next mbuf chain to transmit from Stack.
- */
- IF_DEQUEUE (&ifp->if_snd, m);
- if (!m){
- /* Hardware has sent all schedule packets, this
- * makes the stack enter at greth_start next time
- * a packet is to be sent.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- break;
- }
- }
-
- /* Try to send packet, failed if it a non-zero number is returned. */
- if ( sendpacket(ifp, m) ){
- /* Not enough resources */
-
- /* Since we have taken the mbuf out of the "send chain"
- * we must remember to use that next time we come back.
- * or else we have dropped a packet.
- */
- sc->next_tx_mbuf = m;
-
- /* Not enough resources, enable interrupt for transmissions
- * this way we will be informed when more TX-descriptors are
- * available.
- */
- if ( first ){
- first = 0;
- rtems_interrupt_disable(level);
- ifp->if_flags |= IFF_OACTIVE;
- sc->regs->ctrl |= GRETH_CTRL_TXIRQ;
- rtems_interrupt_enable(level);
-
- /* We must check again to be sure that we didn't
- * miss an interrupt (if a packet was sent just before
- * enabling interrupts)
- */
- continue;
- }
-
- return -1;
- }else{
- /* Sent Ok, proceed to process more packets if available */
- }
- }
- return 0;
-}
-
-static void
-greth_start (struct ifnet *ifp)
-{
- struct greth_softc *sc = ifp->if_softc;
-
- if ( ifp->if_flags & IFF_OACTIVE )
- return;
-
- if ( sc->gbit_mac ){
- /* No use trying to handle this if we are waiting on GRETH
- * to send the previously scheduled packets.
- */
-
- greth_process_tx_gbit(sc);
- }else{
- greth_process_tx(sc);
- }
-}
-
-/*
- * Initialize and start the device
- */
-static void
-greth_init (void *arg)
-{
- struct greth_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->daemonTid == 0) {
-
- /*
- * Start driver tasks
- */
- sc->daemonTid = rtems_bsdnet_newproc ("DCrxtx", 4096,
- greth_Daemon, sc);
-
- /*
- * Set up GRETH hardware
- */
- greth_initialize_hardware (sc);
-
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/*
- * Stop the device
- */
-static void
-greth_stop (struct greth_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- sc->regs->ctrl = 0; /* RX/TX OFF */
- sc->regs->ctrl = GRETH_CTRL_RST; /* Reset ON */
- sc->regs->ctrl = 0; /* Reset OFF */
-
- sc->next_tx_mbuf = NULL;
-}
-
-
-/*
- * Show interface statistics
- */
-static void
-greth_stats (struct greth_softc *sc)
-{
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Rx Packets:%-8lu", sc->rxPackets);
- printf (" Length:%-8lu", sc->rxLengthError);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Maximal Frags:%-8d", sc->max_fragsize);
- printf (" GBIT MAC:%-8d", sc->gbit_mac);
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-greth_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct greth_softc *sc = 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:
- greth_stop (sc);
- break;
-
- case IFF_UP:
- greth_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- greth_stop (sc);
- greth_init (sc);
- break;
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- greth_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/*
- * Attach an GRETH driver to the system
- */
-int
-rtems_greth_driver_attach (struct rtems_bsdnet_ifconfig *config,
- greth_configuration_t *chip)
-{
- struct greth_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /* parse driver name */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- sc = &greth;
- ifp = &sc->arpcom.ac_if;
- memset (sc, 0, sizeof (*sc));
-
- if (config->hardware_address)
- {
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
- ETHER_ADDR_LEN);
- }
- else
- {
- memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
- }
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- sc->acceptBroadcast = !config->ignore_broadcast;
- sc->regs = chip->base_address;
- sc->vector = chip->vector;
- sc->txbufs = chip->txd_count;
- sc->rxbufs = chip->rxd_count;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = greth_init;
- ifp->if_ioctl = greth_ioctl;
- ifp->if_start = greth_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;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
-
-#ifdef GRETH_DEBUG
- printf ("GRETH : driver has been attached\n");
-#endif
- return 1;
-};
-
-#endif
diff --git a/c/src/libchip/network/i82586.c b/c/src/libchip/network/i82586.c
deleted file mode 100644
index c79af66e0d..0000000000
--- a/c/src/libchip/network/i82586.c
+++ /dev/null
@@ -1,2198 +0,0 @@
-/* $NetBSD: i82586.c,v 1.38 2001/07/07 05:35:39 thorpej Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Paul Kranenburg and Charles M. Hannum.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1997 Paul Kranenburg.
- * Copyright (c) 1992, 1993, University of Vermont and State
- * Agricultural College.
- * Copyright (c) 1992, 1993, Garrett A. Wollman.
- *
- * Portions:
- * Copyright (c) 1994, 1995, Rafal K. Boni
- * Copyright (c) 1990, 1991, William F. Jolitz
- * Copyright (c) 1990, The Regents of the University of California
- *
- * RTEMS:
- * Copyright (c) 2001, Chris Johns, Cybertec Pty Ltd,
- * http://www.cybertec.com.au/.
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of Vermont
- * and State Agricultural College and Garrett A. Wollman, by William F.
- * Jolitz, and by the University of California, Berkeley, Lawrence
- * Berkeley Laboratory, and its contributors.
- * 4. Neither the names of the Universities nor the names of the authors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Intel 82586 Ethernet chip
- * Register, bit, and structure definitions.
- *
- * Original StarLAN driver written by Garrett Wollman with reference to the
- * Clarkson Packet Driver code for this chip written by Russ Nelson and others.
- *
- * BPF support code taken from hpdev/if_le.c, supplied with tcpdump.
- *
- * 3C507 support is loosely based on code donated to NetBSD by Rafal Boni.
- *
- * Majorly cleaned up and 3C507 code merged by Charles Hannum.
- *
- * Converted to SUN ie driver by Charles D. Cranor,
- * October 1994, January 1995.
- * This sun version based on i386 version 1.30.
- */
-
-/*
- * The i82586 is a very painful chip, found in sun3's, sun-4/100's
- * sun-4/200's, and VME based suns. The byte order is all wrong for a
- * SUN, making life difficult. Programming this chip is mostly the same,
- * but certain details differ from system to system. This driver is
- * written so that different "ie" interfaces can be controled by the same
- * driver.
- */
-
-/*
-Mode of operation:
-
- We run the 82586 in a standard Ethernet mode. We keep NFRAMES
- received frame descriptors around for the receiver to use, and
- NRXBUF associated receive buffer descriptors, both in a circular
- list. Whenever a frame is received, we rotate both lists as
- necessary. (The 586 treats both lists as a simple queue.) We also
- keep a transmit command around so that packets can be sent off
- quickly.
-
- We configure the adapter in AL-LOC = 1 mode, which means that the
- Ethernet/802.3 MAC header is placed at the beginning of the receive
- buffer rather than being split off into various fields in the RFD.
- This also means that we must include this header in the transmit
- buffer as well.
-
- By convention, all transmit commands, and only transmit commands,
- shall have the I (IE_CMD_INTR) bit set in the command. This way,
- when an interrupt arrives at i82586_intr(), it is immediately possible
- to tell what precisely caused it. ANY OTHER command-sending
- routines should run at splnet(), and should post an acknowledgement
- to every interrupt they generate.
-
- To save the expense of shipping a command to 82586 every time we
- want to send a frame, we use a linked list of commands consisting
- of alternate XMIT and NOP commands. The links of these elements
- are manipulated (in iexmit()) such that the NOP command loops back
- to itself whenever the following XMIT command is not yet ready to
- go. Whenever an XMIT is ready, the preceding NOP link is pointed
- at it, while its own link field points to the following NOP command.
- Thus, a single transmit command sets off an interlocked traversal
- of the xmit command chain, with the host processor in control of
- the synchronization.
-*/
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <ctype.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <inttypes.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-#include <net/if_types.h>
-#include <net/if_dl.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include "i82586reg.h"
-#include <libchip/i82586var.h>
-
-#if defined(ALIGNBYTES) && defined(ALIGN)
-/* FIXME: Redefine because some versions of
- * RTEMS newlib and the BSDs ship a broken ALIGN */
-#undef ALIGN
-#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES)
-#else
-#define ALIGN(p) (p)
-#endif
-
-/*
- * A global way to change all async cmd requests at once. For RTEMS and running
- * as tasks I wanted to see if the tx race condition is effected by this.
- */
-#define ASYNC_OPTION (1)
-
-void i82586_reset (struct ie_softc *, int);
-void i82586_watchdog (struct ifnet *);
-void i82586_init (void *);
-int i82586_ioctl (struct ifnet *, ioctl_command_t cmd, caddr_t data);
-void i82586_start (struct ifnet *);
-
-void i82586_stop (struct ifnet *, int);
-int i82586_rint (struct ie_softc *, int);
-int i82586_tint (struct ie_softc *, int);
-
-int i82586_mediachange (struct ifnet *);
-void i82586_mediastatus (struct ifnet *, struct ifmediareq *);
-
-static void i82586_tx_task(void *arg);
-static void i82586_start_tx(struct ie_softc *sc);
-
-static int ie_readframe (struct ie_softc *, int);
-static struct mbuf *ieget (struct ie_softc *, int, int);
-static int i82586_get_rbd_list (struct ie_softc *, u_int16_t*,
- u_int16_t*, int *);
-static void i82586_release_rbd_list (struct ie_softc *,
- u_int16_t, u_int16_t);
-static int i82586_drop_frames (struct ie_softc *);
-static int i82586_chk_rx_ring (struct ie_softc *);
-
-static __inline__ void ie_ack (struct ie_softc *, u_int);
-static __inline__ void iexmit (struct ie_softc *);
-static void i82586_start_transceiver (struct ie_softc *);
-
-static void i82586_count_errors (struct ie_softc *);
-static void i82586_rx_errors (struct ie_softc *, int, int);
-static void i82586_setup_bufs (struct ie_softc *);
-static void setup_simple_command (struct ie_softc *, int, int);
-static int ie_cfg_setup (struct ie_softc *, int, int, int);
-static int ie_ia_setup (struct ie_softc *, int);
-static void ie_run_tdr (struct ie_softc *, int);
-static int ie_mc_setup (struct ie_softc *, int);
-static void ie_mc_reset (struct ie_softc *);
-static int i82586_start_cmd (struct ie_softc *, int, int, int, int);
-static int i82586_cmd_wait (struct ie_softc *);
-
-#if I82586_DEBUG
-static void print_softie(struct ie_softc *sc);
-static void print_rbd (struct ie_softc *, int);
-#endif
-
-#define min(l,r) ((l) < (r) ? (l) : (r))
-#define max(l,r) ((l) > (r) ? (l) : (r))
-
-#define delay(p) rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (p))
-
-#define i82586_WAKE_EVENT RTEMS_EVENT_1
-#define i82586_TX_EVENT RTEMS_EVENT_2
-
-static char *
-bitmask_snprintf(unsigned long value, const char *format, char *buf, int blen)
-{
- char *b = buf;
- int bit = 31;
-
- while (bit-- > *format)
- value <<= 1;
-
- format++;
-
- while (*format)
- {
- if (value & 0x80000000)
- while (isalnum((unsigned char)*format))
- *b++ = *format;
- else
- *b++ = '0';
-
- *b++ = ',';
-
- while (bit-- > *format)
- value <<= 1;
-
- format++;
- }
-
- *b = '\0';
- return buf;
-}
-
-/*
- * Front-ends call this function to attach to the MI driver.
- *
- * The front-end has responsibility for managing the ICP and ISCP
- * structures. Both of these are opaque to us. Also, the front-end
- * chooses a location for the SCB which is expected to be addressable
- * (through `sc->scb') as an offset against the shared-memory bus handle.
- *
- * The following MD interface function must be setup by the front-end
- * before calling here:
- *
- * hwreset - board dependent reset
- * hwinit - board dependent initialization
- * chan_attn - channel attention
- * intrhook - board dependent interrupt processing
- * memcopyin - shared memory copy: board to KVA
- * memcopyout - shared memory copy: KVA to board
- * ie_bus_read16 - read a sixteen-bit i82586 pointer
- * ie_bus_write16 - write a sixteen-bit i82586 pointer
- * ie_bus_write24 - write a twenty-four-bit i82586 pointer
- *
- */
-int
-i82586_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- struct ie_softc *sc;
- struct ifnet *ifp;
- char *name;
- int unit;
- int mtu;
-
- /*
- * Parse driver name
- */
-
- if ((unit = rtems_bsdnet_parse_driver_name (config, &name)) < 0)
- return 0;
-
- sc = config->drv_ctrl;
- ifp = &sc->arpcom.ac_if;
-
-#if I82586_DEBUG
- sc->sc_debug = 0; /*IED_TINT | IED_XMIT; */
-#endif
-
- if (attaching)
- {
- if (ifp->if_softc)
- {
- printf ("Driver `%s' already in use.\n", config->name);
- return 0;
- }
-
- /*
- * Process options
- */
-
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- ifp->if_softc = sc;
- ifp->if_unit = unit;
- ifp->if_name = name;
- ifp->if_mtu = mtu;
- ifp->if_init = i82586_init;
- ifp->if_ioctl = i82586_ioctl;
- ifp->if_start = i82586_start;
- ifp->if_output = ether_output;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
-
- if (ifp->if_snd.ifq_maxlen == 0)
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
-
- /* Attach the interface. */
- if_attach(ifp);
- ether_ifattach(ifp);
- return 1;
- }
- return 0;
-}
-
-
-/*
- * Interrupt Acknowledge. Mask in native byte-order.
- */
-static __inline__ void
-ie_ack(struct ie_softc *sc, u_int mask)
-{
- u_int status;
-
- IE_BUS_BARRIER(sc, 0, 0, BUS_SPACE_BARRIER_READ);
- status = sc->ie_bus_read16(sc, IE_SCB_STATUS(sc->scb));
- i82586_start_cmd(sc, status & mask, 0, 0, 0);
- if (sc->intrhook)
- sc->intrhook(sc, INTR_ACK);
-}
-
-
-/*
- * Read data off the interface, and turn it into an mbuf chain.
- *
- * This code is DRAMATICALLY different from the previous version; this
- * version tries to allocate the entire mbuf chain up front, given the
- * length of the data available. This enables us to allocate mbuf
- * clusters in many situations where before we would have had a long
- * chain of partially-full mbufs. This should help to speed up the
- * operation considerably. (Provided that it works, of course.)
- */
-static __inline struct mbuf *
-ieget(struct ie_softc *sc, int head, int totlen)
-{
- struct mbuf *m, *m0, *newm;
- int len, resid;
- int thisrboff, thismboff;
- struct ether_header eh;
-
- /*
- * Snarf the Ethernet header.
- */
- (sc->memcopyin)(sc, &eh, IE_RBUF_ADDR(sc, head),
- sizeof(struct ether_header));
-
- resid = totlen;
-
- MGETHDR(m0, M_DONTWAIT, MT_DATA);
- if (m0 == 0)
- return (0);
- m0->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- m0->m_pkthdr.len = totlen;
- len = MHLEN;
- m = m0;
-
- /*
- * This loop goes through and allocates mbufs for all the data we will
- * be copying in. It does not actually do the copying yet.
- */
- while (totlen > 0) {
- if (totlen >= MINCLSIZE) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0)
- goto bad;
- len = MCLBYTES;
- }
-
- if (m == m0) {
- caddr_t newdata = (caddr_t)
- ALIGN(m->m_data + sizeof(struct ether_header)) -
- sizeof(struct ether_header);
- len -= newdata - m->m_data;
- m->m_data = newdata;
- }
-
- m->m_len = len = min(totlen, len);
-
- totlen -= len;
- if (totlen > 0) {
- MGET(newm, M_DONTWAIT, MT_DATA);
- if (newm == 0)
- goto bad;
- len = MLEN;
- m = m->m_next = newm;
- }
- }
-
- m = m0;
- thismboff = 0;
-
- /*
- * Copy the Ethernet header into the mbuf chain.
- */
- memcpy(mtod(m, caddr_t), &eh, sizeof(struct ether_header));
- thismboff = sizeof(struct ether_header);
- thisrboff = sizeof(struct ether_header);
- resid -= sizeof(struct ether_header);
-
- /*
- * Now we take the mbuf chain (hopefully only one mbuf most of the
- * time) and stuff the data into it. There are no possible failures
- * at or after this point.
- */
- while (resid > 0) {
- int thisrblen = IE_RBUF_SIZE - thisrboff,
- thismblen = m->m_len - thismboff;
- len = min(thisrblen, thismblen);
-
- (sc->memcopyin)(sc, mtod(m, caddr_t) + thismboff,
- IE_RBUF_ADDR(sc,head) + thisrboff,
- (u_int)len);
- resid -= len;
-
- if (len == thismblen) {
- m = m->m_next;
- thismboff = 0;
- } else
- thismboff += len;
-
- if (len == thisrblen) {
- if (++head == sc->nrxbuf)
- head = 0;
- thisrboff = 0;
- } else
- thisrboff += len;
- }
-
- /*
- * Unless something changed strangely while we were doing the copy,
- * we have now copied everything in from the shared memory.
- * This means that we are done.
- */
- return (m0);
-
- bad:
- m_freem(m0);
- return (0);
-}
-
-/*
- * Setup all necessary artifacts for an XMIT command, and then pass the XMIT
- * command to the chip to be executed.
- */
-static __inline__ void
-iexmit(struct ie_softc *sc)
-{
- int off;
- int cur, prev;
-
- cur = sc->xctail;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_EMIT, cur);
-#endif
-
-#if I82586_DEBUG
- if (sc->sc_debug & IED_XMIT)
- printf("%s: xmit buffer %d\n", sc->arpcom.ac_if.if_name, cur);
-#endif
-
- /*
- * Setup the transmit command.
- */
- sc->ie_bus_write16(sc, IE_CMD_XMIT_DESC(sc->xmit_cmds, cur),
- IE_XBD_ADDR(sc->xbds, cur));
-
- sc->ie_bus_write16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds, cur), 0);
-
- if (sc->do_xmitnopchain) {
- /*
- * Gate this XMIT command to the following NOP
- */
- sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds, cur),
- IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
- sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
- IE_CMD_XMIT | IE_CMD_INTR);
-
- /*
- * Loopback at following NOP
- */
- sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, cur), 0);
- sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, cur),
- IE_CMD_NOP_ADDR(sc->nop_cmds, cur));
-
- /*
- * Gate preceding NOP to this XMIT command
- */
- prev = (cur + NTXBUF - 1) % NTXBUF;
- sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, prev), 0);
- sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, prev),
- IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
-
- off = IE_SCB_STATUS(sc->scb);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- if ((sc->ie_bus_read16(sc, off) & IE_CUS_ACTIVE) == 0) {
- printf("iexmit: CU not active\n");
- i82586_start_transceiver(sc);
- }
- } else {
- sc->ie_bus_write16(sc, IE_CMD_XMIT_LINK(sc->xmit_cmds,cur),
- 0xffff);
-
- sc->ie_bus_write16(sc, IE_CMD_XMIT_CMD(sc->xmit_cmds, cur),
- IE_CMD_XMIT | IE_CMD_INTR | IE_CMD_LAST);
-
- off = IE_SCB_CMDLST(sc->scb);
- sc->ie_bus_write16(sc, off, IE_CMD_XMIT_ADDR(sc->xmit_cmds, cur));
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
-
- if (i82586_start_cmd(sc, IE_CUC_START, 0, 0, ASYNC_OPTION))
- printf("%s: iexmit: start xmit command timed out\n",
- sc->arpcom.ac_if.if_name);
- }
-
- sc->arpcom.ac_if.if_timer = 5;
-}
-
-
-/*
- * Device timeout/watchdog routine.
- * Entered if the device neglects to generate an interrupt after a
- * transmit has been started on it.
- */
-void
-i82586_watchdog(struct ifnet *ifp)
-{
- struct ie_softc *sc = ifp->if_softc;
- printf("%s: device timeout\n", ifp->if_name);
- ++ifp->if_oerrors;
- i82586_reset(sc, 1);
-}
-
-static int
-i82586_cmd_wait(struct ie_softc *sc)
-{
- /* spin on i82586 command acknowledge; wait at most 0.9 (!) seconds */
- int i, off;
- u_int16_t cmd;
-
- for (i = 0; i < 900000; i++) {
- /* Read the command word */
- off = IE_SCB_CMD(sc->scb);
-
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- if ((cmd = sc->ie_bus_read16(sc, off)) == 0)
- return (0);
- delay(1);
- }
-
- off = IE_SCB_STATUS(sc->scb);
- printf("i82586_cmd_wait: timo(%ssync): scb status: 0x%x, cmd: 0x%x\n",
- sc->async_cmd_inprogress?"a":"",
- sc->ie_bus_read16(sc, off), cmd);
-
- return (1); /* Timeout */
-}
-
-/*
- * Send a command to the controller and wait for it to either complete
- * or be accepted, depending on the command. If the command pointer
- * is null, then pretend that the command is not an action command.
- * If the command pointer is not null, and the command is an action
- * command, wait for one of the MASK bits to turn on in the command's
- * status field.
- * If ASYNC is set, we just call the chip's attention and return.
- * We may have to wait for the command's acceptance later though.
- */
-static int
-i82586_start_cmd(struct ie_softc *sc, int cmd, int iecmdbuf, int mask, int async)
-{
- int i;
- int off;
-
- if (sc->async_cmd_inprogress != 0) {
- /*
- * If previous command was issued asynchronously, wait
- * for it now.
- */
- if (i82586_cmd_wait(sc) != 0)
- return (1);
- sc->async_cmd_inprogress = 0;
- }
-
- off = IE_SCB_CMD(sc->scb);
- sc->ie_bus_write16(sc, off, cmd);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
- (sc->chan_attn)(sc, CARD_RESET);
-
- if (async != 0) {
- sc->async_cmd_inprogress = 1;
- return (0);
- }
-
- if (IE_ACTION_COMMAND(cmd) && iecmdbuf) {
- int status;
- /*
- * Now spin-lock waiting for status. This is not a very nice
- * thing to do, and can kill performance pretty well...
- * According to the packet driver, the minimum timeout
- * should be .369 seconds.
- */
- for (i = 0; i < 369000; i++) {
- /* Read the command status */
- off = IE_CMD_COMMON_STATUS(iecmdbuf);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- status = sc->ie_bus_read16(sc, off);
- if (status & mask)
- return (0);
- delay(1);
- }
-
- } else {
- /*
- * Otherwise, just wait for the command to be accepted.
- */
- return (i82586_cmd_wait(sc));
- }
-
- /* Timeout */
- return (1);
-}
-
-
-/*
- * Transfer accumulated chip error counters to IF.
- */
-static __inline void
-i82586_count_errors(struct ie_softc *sc)
-{
- int scb = sc->scb;
-
- sc->arpcom.ac_if.if_ierrors +=
- sc->ie_bus_read16(sc, IE_SCB_ERRCRC(scb)) +
- sc->ie_bus_read16(sc, IE_SCB_ERRALN(scb)) +
- sc->ie_bus_read16(sc, IE_SCB_ERRRES(scb)) +
- sc->ie_bus_read16(sc, IE_SCB_ERROVR(scb));
-
- /* Clear error counters */
- sc->ie_bus_write16(sc, IE_SCB_ERRCRC(scb), 0);
- sc->ie_bus_write16(sc, IE_SCB_ERRALN(scb), 0);
- sc->ie_bus_write16(sc, IE_SCB_ERRRES(scb), 0);
- sc->ie_bus_write16(sc, IE_SCB_ERROVR(scb), 0);
-}
-
-
-static void
-i82586_rx_errors(struct ie_softc *sc, int fn, int status)
-{
- char bits[128];
-
- printf("%s: rx error (frame# %d): %s\n", sc->arpcom.ac_if.if_name, fn,
- bitmask_snprintf(status, IE_FD_STATUSBITS, bits, sizeof(bits)));
-}
-
-/*
- * i82586 interrupt entry point.
- */
-rtems_isr
-i82586_intr(rtems_vector_number vec, void *arg)
-{
- struct ie_softc *sc = arg;
-
-#if I82586_DEBUG
- static unsigned long icnt = 0;
- I82586_TRACE(sc, I82586_INTS_REQ, icnt++);
-#endif
-
- /*
- * Implementation dependent interrupt handling. It must at least
- * disabled interrupts from the i82586. It is hoped this can
- * happen somewhere outside the i82586.
- */
- if (sc->intrhook)
- (sc->intrhook)(sc, INTR_ENTER);
-
- /*
- * Wake the task to handle the interrupt. It will
- * enabled the interrupts when it has finished.
- */
- rtems_bsdnet_event_send (sc->intr_task, i82586_WAKE_EVENT);
-}
-
-/*
- * i82586 interrupt task. The task is actually an extension of the interrupt
- * with a context switch in the middle. The RTEMS TCP/IP stack requires a task
- * be used to talk to the stack as a network semaphore is claimed. This
- * cannot happen during an interrupt.
- */
-static void
-i82586_intr_task(void *arg)
-{
- struct ie_softc *sc = arg;
- rtems_event_set events;
- u_int status;
- int off;
- int reset;
-
- /*
- * Not sure this is a good idea but as a out path exists and
- * roads lead to it, it seems ok.
- */
- for (;;) {
- rtems_bsdnet_event_receive (i82586_WAKE_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- 0, &events);
-
- off = IE_SCB_STATUS(sc->scb);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- status = sc->ie_bus_read16(sc, off) & IE_ST_WHENCE;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_INTS_IN, status);
-#endif
-
- reset = 0;
-
- while ((status & IE_ST_WHENCE) != 0) {
-#if I82586_DEBUG
- if (sc->sc_debug)
- printf ("%s: -------\n%s: scbstatus=0x%x\n",
- sc->arpcom.ac_if.if_name, sc->arpcom.ac_if.if_name, status);
-#endif
-
-#if 1
- /* Ack interrupts FIRST in case we receive more during the ISR. */
- ie_ack(sc, status & IE_ST_WHENCE);
-#endif
-
- i82586_start_cmd(sc, status & IE_ST_WHENCE, 0, 0, ASYNC_OPTION);
-
- if (status & (IE_ST_FR | IE_ST_RNR))
- if (i82586_rint(sc, status) != 0) {
- reset = 1;
- break;
- }
-
- if (status & IE_ST_CX)
- if (i82586_tint(sc, status) != 0) {
- reset = 1;
- break;
- }
-
-#if I82586_DEBUG
- if ((status & IE_ST_CNA) && (sc->sc_debug & IED_CNA))
- printf("%s: cna; status=0x%x\n", sc->arpcom.ac_if.if_name, status);
-#endif
-
-#if 0
- if (sc->intrhook)
- (sc->intrhook)(sc, INTR_LOOP);
-#endif
-
-#if 1
- /*
- * Interrupt ACK was posted asynchronously; wait for
- * completion here before reading SCB status again.
- *
- * If ACK fails, try to reset the chip, in hopes that
- * it helps.
- */
- if (i82586_cmd_wait(sc) != 0) {
- reset = 1;
- break;
- }
-#endif
-
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- status = sc->ie_bus_read16(sc, off);
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_INTS_LOOPS, status);
-#endif
- }
-
- if (reset) {
-#if I82586_DEBUG
- printf("%s: intr reset; status=0x%x\n", sc->arpcom.ac_if.if_name, status);
-#endif
- i82586_cmd_wait(sc);
- i82586_reset(sc, 1);
- }
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_INTS_OUT, status);
-#endif
-
- if (sc->intrhook)
- (sc->intrhook)(sc, INTR_EXIT);
- }
-}
-
-/*
- * Process a received-frame interrupt.
- */
-int
-i82586_rint(struct ie_softc *sc, int scbstatus)
-{
- static int timesthru = 1024;
- int i, status, off;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_RX_INT, scbstatus);
-
- if (sc->sc_debug & IED_RINT)
- printf("%s: rint: status 0x%x\n",
- sc->arpcom.ac_if.if_name, scbstatus);
-#endif
-
- for (;;) {
- int drop = 0;
-
- i = sc->rfhead;
- off = IE_RFRAME_STATUS(sc->rframes, i);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- status = sc->ie_bus_read16(sc, off);
-
-#if I82586_DEBUG
- if (sc->sc_debug & IED_RINT)
- printf("%s: rint: frame(%d) status 0x%x\n",
- sc->arpcom.ac_if.if_name, i, status);
-#endif
- if ((status & IE_FD_COMPLETE) == 0) {
- if ((status & IE_FD_OK) != 0) {
- printf("%s: rint: weird: ",
- sc->arpcom.ac_if.if_name);
- i82586_rx_errors(sc, i, status);
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_RX_ERR, status);
-#endif
- break;
- }
- if (--timesthru == 0) {
- /* Account the accumulated errors */
- i82586_count_errors(sc);
- timesthru = 1024;
- }
- break;
- } else if ((status & IE_FD_OK) == 0) {
- /*
- * If the chip is configured to automatically
- * discard bad frames, the only reason we can
- * get here is an "out-of-resource" condition.
- */
- i82586_rx_errors(sc, i, status);
- drop = 1;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_RX_DROP, status);
-#endif
- }
-
-#if I82586_DEBUG
- if ((status & IE_FD_BUSY) != 0)
- printf("%s: rint: frame(%d) busy; status=0x%x\n",
- sc->arpcom.ac_if.if_name, i, status);
-#endif
-
- /*
- * Advance the RFD list, since we're done with
- * this descriptor.
- */
-
- /* Clear frame status */
- sc->ie_bus_write16(sc, off, 0);
-
- /* Put fence at this frame (the head) */
- off = IE_RFRAME_LAST(sc->rframes, i);
- sc->ie_bus_write16(sc, off, IE_FD_EOL|IE_FD_SUSP);
-
- /* and clear RBD field */
- off = IE_RFRAME_BUFDESC(sc->rframes, i);
- sc->ie_bus_write16(sc, off, 0xffff);
-
- /* Remove fence from current tail */
- off = IE_RFRAME_LAST(sc->rframes, sc->rftail);
- sc->ie_bus_write16(sc, off, 0);
-
- if (++sc->rftail == sc->nframes)
- sc->rftail = 0;
- if (++sc->rfhead == sc->nframes)
- sc->rfhead = 0;
-
- /* Pull the frame off the board */
- if (drop) {
- i82586_drop_frames(sc);
- if ((status & IE_FD_RNR) != 0)
- sc->rnr_expect = 1;
- sc->arpcom.ac_if.if_ierrors++;
- } else if (ie_readframe(sc, i) != 0)
- return (1);
- }
-
- if ((scbstatus & IE_ST_RNR) != 0) {
-
- /*
- * Receiver went "Not Ready". We try to figure out
- * whether this was an expected event based on past
- * frame status values.
- */
-
- if ((scbstatus & IE_RUS_SUSPEND) != 0) {
- /*
- * We use the "suspend on last frame" flag.
- * Send a RU RESUME command in response, since
- * we should have dealt with all completed frames
- * by now.
- */
- printf("RINT: SUSPENDED; scbstatus=0x%x\n",
- scbstatus);
- if (i82586_start_cmd(sc, IE_RUC_RESUME, 0, 0, 0) == 0)
- return (0);
- printf("%s: RU RESUME command timed out\n",
- sc->arpcom.ac_if.if_name);
- return (1); /* Ask for a reset */
- }
-
- if (sc->rnr_expect != 0) {
- /*
- * The RNR condition was announced in the previously
- * completed frame. Assume the receive ring is Ok,
- * so restart the receiver without further delay.
- */
- i82586_start_transceiver(sc);
- sc->rnr_expect = 0;
- return (0);
-
- } else if ((scbstatus & IE_RUS_NOSPACE) != 0) {
- /*
- * We saw no previous IF_FD_RNR flag.
- * We check our ring invariants and, if ok,
- * just restart the receiver at the current
- * point in the ring.
- */
- if (i82586_chk_rx_ring(sc) != 0)
- return (1);
-
- i82586_start_transceiver(sc);
- sc->arpcom.ac_if.if_ierrors++;
- return (0);
- } else
- printf("%s: receiver not ready; scbstatus=0x%x\n",
- sc->arpcom.ac_if.if_name, scbstatus);
-
- sc->arpcom.ac_if.if_ierrors++;
- return (1); /* Ask for a reset */
- }
-
- return (0);
-}
-
-/*
- * Process a command-complete interrupt. These are only generated by the
- * transmission of frames. This routine is deceptively simple, since most
- * of the real work is done by i82586_start().
- */
-int
-i82586_tint(struct ie_softc *sc, int scbstatus)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int status;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_INT, sc->xmit_busy);
-#endif
-
-#if I82586_DEBUG
- if (sc->xmit_busy <= 0) {
- printf("i82586_tint: (%d), WEIRD: xmit_busy=%d, xctail=%d, xchead=%d\n",
- sc->trace_flow_in / 2, sc->xmit_busy, sc->xctail, sc->xchead);
- I82586_TRACE(sc, I82586_TX_BAD, sc->xctail);
- return (0);
- }
-#endif
-
- ifp->if_timer = 0;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- status = sc->ie_bus_read16(sc, IE_CMD_XMIT_STATUS(sc->xmit_cmds,
- sc->xctail));
-
-#if I82586_DEBUG
- if (sc->sc_debug & IED_TINT)
- printf("%s: tint: SCB status 0x%x; xmit status 0x%x\n",
- sc->arpcom.ac_if.if_name, scbstatus, status);
-#endif
-
- if ((status & IE_STAT_COMPL) == 0 || (status & IE_STAT_BUSY)) {
- printf("i82586_tint: (%d) command still busy; status=0x%x; tail=%d\n",
- sc->trace_flow_in / 2, status, sc->xctail);
- printf("iestatus = 0x%x\n", scbstatus);
-/* sc->sc_debug = IED_ALL; */
- }
-
- if (status & IE_STAT_OK) {
- ifp->if_opackets++;
- ifp->if_collisions += (status & IE_XS_MAXCOLL);
- } else {
- ifp->if_oerrors++;
- /*
- * Check SQE and DEFERRED?
- * What if more than one bit is set?
- */
- if (status & IE_STAT_ABORT)
- printf("%s: send aborted\n", sc->arpcom.ac_if.if_name);
- else if (status & IE_XS_NOCARRIER)
- printf("%s: no carrier\n", sc->arpcom.ac_if.if_name);
- else if (status & IE_XS_LOSTCTS)
- printf("%s: lost CTS\n", sc->arpcom.ac_if.if_name);
- else if (status & IE_XS_UNDERRUN)
- printf("%s: DMA underrun\n", sc->arpcom.ac_if.if_name);
- else if (status & IE_XS_EXCMAX) {
- printf("%s: too many collisions\n",
- sc->arpcom.ac_if.if_name);
- sc->arpcom.ac_if.if_collisions += 16;
- }
- }
-
- /*
- * If multicast addresses were added or deleted while transmitting,
- * ie_mc_reset() set the want_mcsetup flag indicating that we
- * should do it.
- */
- if (sc->want_mcsetup) {
- ie_mc_setup(sc, IE_XBUF_ADDR(sc, sc->xctail));
- sc->want_mcsetup = 0;
- }
-
- /* Done with the buffer. */
- sc->xmit_busy--;
- sc->xctail = (sc->xctail + 1) % NTXBUF;
-
- /* Start the next packet, if any, transmitting. */
- if (sc->xmit_busy > 0)
- iexmit(sc);
-
- i82586_start_tx(sc);
- return (0);
-}
-
-/*
- * Get a range of receive buffer descriptors that represent one packet.
- */
-static int
-i82586_get_rbd_list(struct ie_softc *sc, u_int16_t *start, u_int16_t *end, int *pktlen)
-{
- int off, rbbase = sc->rbds;
- int rbindex, count = 0;
- int plen = 0;
- int rbdstatus;
-
- *start = rbindex = sc->rbhead;
-
- do {
- off = IE_RBD_STATUS(rbbase, rbindex);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- rbdstatus = sc->ie_bus_read16(sc, off);
- if ((rbdstatus & IE_RBD_USED) == 0) {
- /*
- * This means we are somehow out of sync. So, we
- * reset the adapter.
- */
-#if I82586_DEBUG
- print_rbd(sc, rbindex);
-#endif
- printf("%s: receive descriptors out of sync at %d\n",
- sc->arpcom.ac_if.if_name, rbindex);
- return (0);
- }
- plen += (rbdstatus & IE_RBD_CNTMASK);
-
- if (++rbindex == sc->nrxbuf)
- rbindex = 0;
-
- ++count;
- } while ((rbdstatus & IE_RBD_LAST) == 0);
- *end = rbindex;
- *pktlen = plen;
- return (count);
-}
-
-
-/*
- * Release a range of receive buffer descriptors after we've copied the packet.
- */
-static void
-i82586_release_rbd_list(struct ie_softc *sc, u_int16_t start, u_int16_t end)
-{
- int off, rbbase = sc->rbds;
- int rbindex = start;
-
- do {
- /* Clear buffer status */
- off = IE_RBD_STATUS(rbbase, rbindex);
- sc->ie_bus_write16(sc, off, 0);
- if (++rbindex == sc->nrxbuf)
- rbindex = 0;
- } while (rbindex != end);
-
- /* Mark EOL at new tail */
- rbindex = ((rbindex == 0) ? sc->nrxbuf : rbindex) - 1;
- off = IE_RBD_BUFLEN(rbbase, rbindex);
- sc->ie_bus_write16(sc, off, IE_RBUF_SIZE|IE_RBD_EOL);
-
- /* Remove EOL from current tail */
- off = IE_RBD_BUFLEN(rbbase, sc->rbtail);
- sc->ie_bus_write16(sc, off, IE_RBUF_SIZE);
-
- /* New head & tail pointer */
-/* hmm, why have both? head is always (tail + 1) % NRXBUF */
- sc->rbhead = end;
- sc->rbtail = rbindex;
-}
-
-/*
- * Drop the packet at the head of the RX buffer ring.
- * Called if the frame descriptor reports an error on this packet.
- * Returns 1 if the buffer descriptor ring appears to be corrupt;
- * and 0 otherwise.
- */
-static int
-i82586_drop_frames(struct ie_softc *sc)
-{
- u_int16_t bstart, bend;
- int pktlen;
-
- if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0)
- return (1);
- i82586_release_rbd_list(sc, bstart, bend);
- return (0);
-}
-
-/*
- * Check the RX frame & buffer descriptor lists for our invariants,
- * i.e.: EOL bit set iff. it is pointed at by the r*tail pointer.
- *
- * Called when the receive unit has stopped unexpectedly.
- * Returns 1 if an inconsistency is detected; 0 otherwise.
- *
- * The Receive Unit is expected to be NOT RUNNING.
- */
-static int
-i82586_chk_rx_ring(struct ie_softc *sc)
-{
- int n, off, val;
-
- for (n = 0; n < sc->nrxbuf; n++) {
- off = IE_RBD_BUFLEN(sc->rbds, n);
- val = sc->ie_bus_read16(sc, off);
- if ((n == sc->rbtail) ^ ((val & IE_RBD_EOL) != 0)) {
- /* `rbtail' and EOL flag out of sync */
- printf("%s: rx buffer descriptors out of sync at %d\n",
- sc->arpcom.ac_if.if_name, n);
- return (1);
- }
-
- /* Take the opportunity to clear the status fields here ? */
- }
-
- for (n = 0; n < sc->nframes; n++) {
- off = IE_RFRAME_LAST(sc->rframes, n);
- val = sc->ie_bus_read16(sc, off);
- if ((n == sc->rftail) ^ ((val & (IE_FD_EOL|IE_FD_SUSP)) != 0)) {
- /* `rftail' and EOL flag out of sync */
- printf("%s: rx frame list out of sync at %d\n",
- sc->arpcom.ac_if.if_name, n);
- return (1);
- }
- }
-
- return (0);
-}
-
-
-/*
- * Read frame NUM from unit UNIT (pre-cached as IE).
- *
- * This routine reads the RFD at NUM, and copies in the buffers from the list
- * of RBD, then rotates the RBD list so that the receiver doesn't start
- * complaining. Trailers are DROPPED---there's no point in wasting time
- * on confusing code to deal with them. Hopefully, this machine will
- * never ARP for trailers anyway.
- */
-static int
-ie_readframe(struct ie_softc *sc, int num) /* frame number to read */
-{
- struct ether_header *eh;
- struct mbuf *m;
- u_int16_t bstart, bend;
- int pktlen;
-
- if (i82586_get_rbd_list(sc, &bstart, &bend, &pktlen) == 0) {
- sc->arpcom.ac_if.if_ierrors++;
- return (1);
- }
-
- m = ieget(sc, bstart, pktlen);
- i82586_release_rbd_list(sc, bstart, bend);
-
- if (m == 0) {
- sc->arpcom.ac_if.if_ierrors++;
- return (0);
- }
-
- /*
- * Remove the mac header. This is different from the NetBSD
- * stack.
- */
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof (struct ether_header);
- m->m_len -= sizeof (struct ether_header);
- m->m_pkthdr.len -= sizeof (struct ether_header);
-
-#if I82586_DEBUG
- if (sc->sc_debug & IED_READFRAME) {
-
- printf("%s: frame from ether %s type 0x%x len %d\n",
- sc->arpcom.ac_if.if_name,
- ether_sprintf(eh->ether_shost),
- (u_int)ntohs(eh->ether_type),
- pktlen);
- }
-#endif
-
-#if NBPFILTER > 0
- /* Check for a BPF filter; if so, hand it up. */
- if (sc->arpcom.ac_if.if_bpf != 0)
- /* Pass it up. */
- bpf_mtap(sc->arpcom.ac_if.if_bpf, m);
-#endif /* NBPFILTER > 0 */
-
- /*
- * Finally pass this packet up to higher layers.
- */
- ether_input (&sc->arpcom.ac_if, eh, m);
- sc->arpcom.ac_if.if_ipackets++;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_RX_OK, sc->arpcom.ac_if.if_ipackets);
-#endif
-
- return (0);
-}
-
-/*
- * Start transmission on an interface.
- */
-void
-i82586_start(struct ifnet *ifp)
-{
- struct ie_softc *sc = ifp->if_softc;
-
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
- return;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_REQ, sc->xmit_busy);
-#endif
-
- rtems_bsdnet_event_send (sc->tx_task, i82586_TX_EVENT);
-}
-
-static void
-i82586_tx_task(void *arg)
-{
- struct ie_softc *sc = arg;
- rtems_event_set events;
-
- for (;;) {
- rtems_bsdnet_event_receive (i82586_TX_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- 0, &events);
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_EVT, sc->xmit_busy);
-
- if (sc->sc_debug)
- printf ("%s: =======\n", sc->arpcom.ac_if.if_name);
-#endif
-
- i82586_start_tx(sc);
- }
-}
-
-static void
-i82586_start_tx(struct ie_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m0, *m;
- int buffer, head, xbase;
- u_short len;
- int s;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_START_TX, sc->xmit_busy);
-#endif
-
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
- {
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_ACTIVE, ifp->if_snd.ifq_len);
-#endif
- return;
- }
-
- for (;;) {
- if (sc->xmit_busy == NTXBUF) {
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
-
- head = sc->xchead;
- xbase = sc->xbds;
-
- IF_DEQUEUE(&ifp->if_snd, m0);
- if (m0 == 0)
- break;
-
- /* We need to use m->m_pkthdr.len, so require the header */
- if ((m0->m_flags & M_PKTHDR) == 0)
- panic("i82586_start: no header mbuf");
-
-#if NBPFILTER > 0
- /* Tap off here if there is a BPF listener. */
- if (ifp->if_bpf)
- bpf_mtap(ifp->if_bpf, m0);
-#endif
-
-#if I82586_DEBUG
- if (sc->sc_debug & IED_ENQ)
- printf("%s: fill buffer %d\n", sc->arpcom.ac_if.if_name,
- sc->xchead);
-#endif
-
- if (m0->m_pkthdr.len > IE_TBUF_SIZE)
- printf("%s: tbuf overflow\n", sc->arpcom.ac_if.if_name);
-
- buffer = IE_XBUF_ADDR(sc, head);
- for (m = m0; m != 0; m = m->m_next) {
- (sc->memcopyout)(sc, mtod(m,caddr_t), buffer, m->m_len);
- buffer += m->m_len;
- }
-
- len = max(m0->m_pkthdr.len, ETHER_MIN_LEN);
- m_freem(m0);
-
- /*
- * Setup the transmit buffer descriptor here, while we
- * know the packet's length.
- */
- sc->ie_bus_write16(sc, IE_XBD_FLAGS(xbase, head),
- len | IE_TBD_EOL);
- sc->ie_bus_write16(sc, IE_XBD_NEXT(xbase, head), 0xffff);
- sc->ie_bus_write24(sc, IE_XBD_BUF(xbase, head),
- IE_XBUF_ADDR(sc, head));
-
- if (++head == NTXBUF)
- head = 0;
- sc->xchead = head;
-
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_TX_START, sc->xmit_busy);
-#endif
-
- s = splnet();
- /* Start the first packet transmitting. */
- if (sc->xmit_busy == 0)
- iexmit(sc);
-
- sc->xmit_busy++;
-
- splx(s);
- }
-}
-
-/*
- * Probe IE's ram setup [ Move all this into MD front-end!? ]
- * Use only if SCP and ISCP represent offsets into shared ram space.
- */
-int
-i82586_proberam(struct ie_softc *sc)
-{
- int result, off;
-
- /* Put in 16-bit mode */
- off = IE_SCP_BUS_USE(sc->scp);
- sc->ie_bus_write16(sc, off, 0);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
-
- /* Set the ISCP `busy' bit */
- off = IE_ISCP_BUSY(sc->iscp);
- sc->ie_bus_write16(sc, off, 1);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_WRITE);
-
- if (sc->hwreset)
- (sc->hwreset)(sc, CHIP_PROBE);
-
- (sc->chan_attn) (sc, CHIP_PROBE);
-
- delay(100); /* wait a while... */
-
- /* Read back the ISCP `busy' bit; it should be clear by now */
- off = IE_ISCP_BUSY(sc->iscp);
- IE_BUS_BARRIER(sc, off, 2, BUS_SPACE_BARRIER_READ);
- result = sc->ie_bus_read16(sc, off) == 0;
-
- /* Acknowledge any interrupts we may have caused. */
- ie_ack(sc, IE_ST_WHENCE);
-
- return (result);
-}
-
-void
-i82586_reset(struct ie_softc *sc, int hard)
-{
- int s = splnet();
-
- if (hard)
- printf("%s: reset\n", sc->arpcom.ac_if.if_name);
-
- /* Clear OACTIVE in case we're called from watchdog (frozen xmit). */
- sc->arpcom.ac_if.if_timer = 0;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-
- /*
- * Stop i82586 dead in its tracks.
- */
- if (i82586_start_cmd(sc, IE_RUC_ABORT | IE_CUC_ABORT, 0, 0, 0))
- printf("%s: abort commands timed out\n", sc->arpcom.ac_if.if_name);
-
- /*
- * This can really slow down the i82586_reset() on some cards, but it's
- * necessary to unwedge other ones (eg, the Sun VME ones) from certain
- * lockups.
- */
- if (hard && sc->hwreset)
- (sc->hwreset)(sc, CARD_RESET);
-
- delay(100);
- ie_ack(sc, IE_ST_WHENCE);
-
- if ((sc->arpcom.ac_if.if_flags & IFF_UP) != 0) {
- i82586_init(&sc->arpcom.ac_if);
- }
-
- splx(s);
-}
-
-static void
-setup_simple_command(struct ie_softc *sc, int cmd, int cmdbuf)
-{
- /* Setup a simple command */
- sc->ie_bus_write16(sc, IE_CMD_COMMON_STATUS(cmdbuf), 0);
- sc->ie_bus_write16(sc, IE_CMD_COMMON_CMD(cmdbuf), cmd | IE_CMD_LAST);
- sc->ie_bus_write16(sc, IE_CMD_COMMON_LINK(cmdbuf), 0xffff);
-
- /* Assign the command buffer to the SCB command list */
- sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb), cmdbuf);
-}
-
-/*
- * Run the time-domain reflectometer.
- */
-static void
-ie_run_tdr(struct ie_softc *sc, int cmd)
-{
- uint32_t result;
-
- setup_simple_command(sc, IE_CMD_TDR, cmd);
- sc->ie_bus_write16(sc, IE_CMD_TDR_TIME(cmd), 0);
-
- if (i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0) ||
- (sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd)) & IE_STAT_OK) == 0)
- result = 0x10000; /* XXX */
- else
- result = sc->ie_bus_read16(sc, IE_CMD_TDR_TIME(cmd));
-
- /* Squash any pending interrupts */
- ie_ack(sc, IE_ST_WHENCE);
-
- if (result & IE_TDR_SUCCESS)
- return;
-
- if (result & 0x10000)
- printf("%s: TDR command failed\n", sc->arpcom.ac_if.if_name);
- else if (result & IE_TDR_XCVR)
- printf("%s: transceiver problem\n", sc->arpcom.ac_if.if_name);
- else if (result & IE_TDR_OPEN)
- printf("%s: TDR detected incorrect termination %" PRId32 " clocks away\n",
- sc->arpcom.ac_if.if_name, result & IE_TDR_TIME);
- else if (result & IE_TDR_SHORT)
- printf("%s: TDR detected a short circuit %" PRId32 " clocks away\n",
- sc->arpcom.ac_if.if_name, result & IE_TDR_TIME);
- else
- printf("%s: TDR returned unknown status 0x%" PRIx32 "\n",
- sc->arpcom.ac_if.if_name, result);
-}
-
-
-/*
- * i82586_setup_bufs: set up the buffers
- *
- * We have a block of KVA at sc->buf_area which is of size sc->buf_area_sz.
- * this is to be used for the buffers. The chip indexs its control data
- * structures with 16 bit offsets, and it indexes actual buffers with
- * 24 bit addresses. So we should allocate control buffers first so that
- * we don't overflow the 16 bit offset field. The number of transmit
- * buffers is fixed at compile time.
- *
- */
-static void
-i82586_setup_bufs(struct ie_softc *sc)
-{
- int ptr = sc->buf_area; /* memory pool */
- int n, r;
-
- /*
- * step 0: zero memory and figure out how many recv buffers and
- * frames we can have.
- */
- ptr = (ptr + 3) & ~3; /* set alignment and stick with it */
-
-
- /*
- * step 1: lay out data structures in the shared-memory area
- */
-
- /* The no-op commands; used if "nop-chaining" is in effect */
- sc->nop_cmds = ptr;
- ptr += NTXBUF * IE_CMD_NOP_SZ;
-
- /* The transmit commands */
- sc->xmit_cmds = ptr;
- ptr += NTXBUF * IE_CMD_XMIT_SZ;
-
- /* The transmit buffers descriptors */
- sc->xbds = ptr;
- ptr += NTXBUF * IE_XBD_SZ;
-
- /* The transmit buffers */
- sc->xbufs = ptr;
- ptr += NTXBUF * IE_TBUF_SIZE;
-
- ptr = (ptr + 3) & ~3; /* re-align.. just in case */
-
- /* Compute free space for RECV stuff */
- n = sc->buf_area_sz - (ptr - sc->buf_area);
-
- /* Compute size of one RECV frame */
- r = IE_RFRAME_SZ + ((IE_RBD_SZ + IE_RBUF_SIZE) * B_PER_F);
-
- sc->nframes = n / r;
-
- if (sc->nframes <= 0)
- panic("ie: bogus buffer calc\n");
-
- sc->nrxbuf = sc->nframes * B_PER_F;
-
- /* The receice frame descriptors */
- sc->rframes = ptr;
- ptr += sc->nframes * IE_RFRAME_SZ;
-
- /* The receive buffer descriptors */
- sc->rbds = ptr;
- ptr += sc->nrxbuf * IE_RBD_SZ;
-
- /* The receive buffers */
- sc->rbufs = ptr;
- ptr += sc->nrxbuf * IE_RBUF_SIZE;
-
-#if I82586_DEBUG
- printf("%s: %d frames %d bufs\n", sc->arpcom.ac_if.if_name, sc->nframes,
- sc->nrxbuf);
-#endif
-
- /*
- * step 2: link together the recv frames and set EOL on last one
- */
- for (n = 0; n < sc->nframes; n++) {
- int m = (n == sc->nframes - 1) ? 0 : n + 1;
-
- /* Clear status */
- sc->ie_bus_write16(sc, IE_RFRAME_STATUS(sc->rframes,n), 0);
-
- /* RBD link = NULL */
- sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,n),
- 0xffff);
-
- /* Make a circular list */
- sc->ie_bus_write16(sc, IE_RFRAME_NEXT(sc->rframes,n),
- IE_RFRAME_ADDR(sc->rframes,m));
-
- /* Mark last as EOL */
- sc->ie_bus_write16(sc, IE_RFRAME_LAST(sc->rframes,n),
- ((m==0)? (IE_FD_EOL|IE_FD_SUSP) : 0));
- }
-
- /*
- * step 3: link the RBDs and set EOL on last one
- */
- for (n = 0; n < sc->nrxbuf; n++) {
- int m = (n == sc->nrxbuf - 1) ? 0 : n + 1;
-
- /* Clear status */
- sc->ie_bus_write16(sc, IE_RBD_STATUS(sc->rbds,n), 0);
-
- /* Make a circular list */
- sc->ie_bus_write16(sc, IE_RBD_NEXT(sc->rbds,n),
- IE_RBD_ADDR(sc->rbds,m));
-
- /* Link to data buffers */
- sc->ie_bus_write24(sc, IE_RBD_BUFADDR(sc->rbds, n),
- IE_RBUF_ADDR(sc, n));
- sc->ie_bus_write16(sc, IE_RBD_BUFLEN(sc->rbds,n),
- IE_RBUF_SIZE | ((m==0)?IE_RBD_EOL:0));
- }
-
- /*
- * step 4: all xmit no-op commands loopback onto themselves
- */
- for (n = 0; n < NTXBUF; n++) {
- sc->ie_bus_write16(sc, IE_CMD_NOP_STATUS(sc->nop_cmds, n), 0);
-
- sc->ie_bus_write16(sc, IE_CMD_NOP_CMD(sc->nop_cmds, n),
- IE_CMD_NOP);
-
- sc->ie_bus_write16(sc, IE_CMD_NOP_LINK(sc->nop_cmds, n),
- IE_CMD_NOP_ADDR(sc->nop_cmds, n));
- }
-
-
- /*
- * step 6: set the head and tail pointers on receive to keep track of
- * the order in which RFDs and RBDs are used.
- */
-
- /* Pointers to last packet sent and next available transmit buffer. */
- sc->xchead = sc->xctail = 0;
-
- /* Clear transmit-busy flag and set number of free transmit buffers. */
- sc->xmit_busy = 0;
-
- /*
- * Pointers to first and last receive frame.
- * The RFD pointed to by rftail is the only one that has EOL set.
- */
- sc->rfhead = 0;
- sc->rftail = sc->nframes - 1;
-
- /*
- * Pointers to first and last receive descriptor buffer.
- * The RBD pointed to by rbtail is the only one that has EOL set.
- */
- sc->rbhead = 0;
- sc->rbtail = sc->nrxbuf - 1;
-
-/* link in recv frames * and buffer into the scb. */
-#if I82586_DEBUG
- printf("%s: reserved %d bytes\n",
- sc->arpcom.ac_if.if_name, ptr - sc->buf_area);
-#endif
-}
-
-static int
-ie_cfg_setup(struct ie_softc *sc, int cmd, int promiscuous, int manchester)
-{
- int cmdresult, status;
- u_int8_t buf[IE_CMD_CFG_SZ]; /* XXX malloc? */
-
- *IE_CMD_CFG_CNT(buf) = 0x0c;
- *IE_CMD_CFG_FIFO(buf) = 8;
- *IE_CMD_CFG_SAVEBAD(buf) = 0x40;
- *IE_CMD_CFG_ADDRLEN(buf) = 0x2e;
- *IE_CMD_CFG_PRIORITY(buf) = 0;
- *IE_CMD_CFG_IFS(buf) = 0x60;
- *IE_CMD_CFG_SLOT_LOW(buf) = 0;
- *IE_CMD_CFG_SLOT_HIGH(buf) = 0xf2;
- *IE_CMD_CFG_PROMISC(buf) = (!!promiscuous) | (manchester << 2);
- *IE_CMD_CFG_CRSCDT(buf) = 0;
- *IE_CMD_CFG_MINLEN(buf) = 64;
- *IE_CMD_CFG_JUNK(buf) = 0xff;
- sc->memcopyout(sc, buf, cmd, IE_CMD_CFG_SZ);
- setup_simple_command(sc, IE_CMD_CONFIG, cmd);
- IE_BUS_BARRIER(sc, cmd, IE_CMD_CFG_SZ, BUS_SPACE_BARRIER_WRITE);
-
- cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmd, IE_STAT_COMPL, 0);
- status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmd));
- if (cmdresult != 0) {
- printf("%s: configure command timed out; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
- if ((status & IE_STAT_OK) == 0) {
- printf("%s: configure command failed; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
-
- /* Squash any pending interrupts */
- ie_ack(sc, IE_ST_WHENCE);
- return (1);
-}
-
-static int
-ie_ia_setup(struct ie_softc *sc, int cmdbuf)
-{
- int cmdresult, status;
-
- setup_simple_command(sc, IE_CMD_IASETUP, cmdbuf);
-
- (sc->memcopyout)(sc, sc->arpcom.ac_enaddr,
- IE_CMD_IAS_EADDR(cmdbuf), ETHER_ADDR_LEN);
-
- cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
- status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
- if (cmdresult != 0) {
- printf("%s: individual address command timed out; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
- if ((status & IE_STAT_OK) == 0) {
- printf("%s: individual address command failed; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
-
- /* Squash any pending interrupts */
- ie_ack(sc, IE_ST_WHENCE);
- return (1);
-}
-
-/*
- * Run the multicast setup command.
- * Called at splnet().
- */
-static int
-ie_mc_setup(struct ie_softc *sc, int cmdbuf)
-{
- int cmdresult, status;
-
- if (sc->mcast_count == 0)
- return (1);
-
- setup_simple_command(sc, IE_CMD_MCAST, cmdbuf);
-
- (sc->memcopyout)(sc, (caddr_t)sc->mcast_addrs,
- IE_CMD_MCAST_MADDR(cmdbuf),
- sc->mcast_count * ETHER_ADDR_LEN);
-
- sc->ie_bus_write16(sc, IE_CMD_MCAST_BYTES(cmdbuf),
- sc->mcast_count * ETHER_ADDR_LEN);
-
- /* Start the command */
- cmdresult = i82586_start_cmd(sc, IE_CUC_START, cmdbuf, IE_STAT_COMPL, 0);
- status = sc->ie_bus_read16(sc, IE_CMD_COMMON_STATUS(cmdbuf));
- if (cmdresult != 0) {
- printf("%s: multicast setup command timed out; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
- if ((status & IE_STAT_OK) == 0) {
- printf("%s: multicast setup command failed; status %x\n",
- sc->arpcom.ac_if.if_name, status);
- return (0);
- }
-
- /* Squash any pending interrupts */
- ie_ack(sc, IE_ST_WHENCE);
- return (1);
-}
-
-/*
- * This routine takes the environment generated by check_ie_present() and adds
- * to it all the other structures we need to operate the adapter. This
- * includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, starting
- * the receiver unit, and clearing interrupts.
- *
- * THIS ROUTINE MUST BE CALLED AT splnet() OR HIGHER.
- */
-void
-i82586_init(void *arg)
-{
- struct ie_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int cmd;
-
- sc->async_cmd_inprogress = 0;
- sc->xmit_busy = 0;
-
-#if I82586_DEBUG
- memset(sc->trace_flow, 0, sizeof(sc->trace_flow));
- sc->trace_flow_wrap = 0;
-#endif
- sc->trace_flow_in = 0;
-
- cmd = sc->buf_area;
-
-#if I82586_DEBUG
- printf ("%s: sc_debug at 0x%08x\n", sc->arpcom.ac_if.if_name, (unsigned int) &sc->sc_debug);
-#endif
-
- /*
- * Send the configure command first.
- */
- if (ie_cfg_setup(sc, cmd, sc->promisc, 0) == 0)
- return;
-
- /*
- * Send the Individual Address Setup command.
- */
- if (ie_ia_setup(sc, cmd) == 0)
- return;
-
- /*
- * Run the time-domain reflectometer.
- */
- ie_run_tdr(sc, cmd);
-
- /*
- * Set the multi-cast filter, if any
- */
- if (ie_mc_setup(sc, cmd) == 0)
- return;
-
- /*
- * If no tasks exist, create them. Need to add something to allow
- * different names for the different devices.
- */
- if (sc->intr_task == 0)
- sc->intr_task = rtems_bsdnet_newproc ("IEi0", 2048, i82586_intr_task, sc);
- if (sc->tx_task == 0)
- sc->tx_task = rtems_bsdnet_newproc ("IEt0", 2048, i82586_tx_task, sc);
-
-
- /*
- * Acknowledge any interrupts we have generated thus far.
- */
- ie_ack(sc, IE_ST_WHENCE);
-
- /*
- * Set up the transmit and recv buffers.
- */
- i82586_setup_bufs(sc);
-
- if (sc->hwinit)
- (sc->hwinit)(sc);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- if (NTXBUF < 2)
- sc->do_xmitnopchain = 0;
-
- i82586_start_transceiver(sc);
-}
-
-/*
- * Start the RU and possibly the CU unit
- */
-static void
-i82586_start_transceiver(struct ie_softc *sc)
-{
-#if I82586_DEBUG
- I82586_TRACE(sc, I82586_RX_START, 0);
-#endif
-
- /*
- * Start RU at current position in frame & RBD lists.
- */
- sc->ie_bus_write16(sc, IE_RFRAME_BUFDESC(sc->rframes,sc->rfhead),
- IE_RBD_ADDR(sc->rbds, sc->rbhead));
-
- sc->ie_bus_write16(sc, IE_SCB_RCVLST(sc->scb),
- IE_RFRAME_ADDR(sc->rframes,sc->rfhead));
-
- if (sc->do_xmitnopchain) {
- /* Stop transmit command chain */
- if (i82586_start_cmd(sc, IE_CUC_SUSPEND|IE_RUC_SUSPEND, 0, 0, 0))
- printf("%s: CU/RU stop command timed out\n",
- sc->arpcom.ac_if.if_name);
-
- /* Start the receiver & transmitter chain */
- /* sc->scb->ie_command_list =
- IEADDR(sc->nop_cmds[(sc->xctail+NTXBUF-1) % NTXBUF]);*/
- sc->ie_bus_write16(sc, IE_SCB_CMDLST(sc->scb),
- IE_CMD_NOP_ADDR(
- sc->nop_cmds,
- (sc->xctail + NTXBUF - 1) % NTXBUF));
-
- if (i82586_start_cmd(sc, IE_CUC_START|IE_RUC_START, 0, 0, 0))
- printf("%s: CU/RU command timed out\n",
- sc->arpcom.ac_if.if_name);
- } else {
- if (i82586_start_cmd(sc, IE_RUC_START, 0, 0, 0))
- printf("%s: RU command timed out\n",
- sc->arpcom.ac_if.if_name);
- }
-}
-
-void
-i82586_stop(struct ifnet *ifp, int disable)
-{
- struct ie_softc *sc = ifp->if_softc;
-
- if (i82586_start_cmd(sc, IE_RUC_SUSPEND | IE_CUC_SUSPEND, 0, 0, 0))
- printf("%s: iestop: disable commands timed out\n",
- sc->arpcom.ac_if.if_name);
-}
-
-int
-i82586_ioctl(struct ifnet *ifp, ioctl_command_t cmd, caddr_t data)
-{
- struct ie_softc *sc = ifp->if_softc;
-/* struct ifreq *ifr = (struct ifreq *)data; */
- int s;
- int error = 0;
-
- s = splnet();
- switch(cmd) {
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- break;
- case SIO_RTEMS_SHOW_STATS:
-#if I82586_DEBUG
- print_softie(sc);
-#endif
- break;
- default:
- error = ether_ioctl(ifp, cmd, data);
- if (error == ENETRESET) {
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- ie_mc_reset(sc);
- error = 0;
- }
- break;
- }
-#if I82586_DEBUG
- if (cmd == SIOCSIFFLAGS)
- sc->sc_debug = (ifp->if_flags & IFF_DEBUG) ? IED_ALL : 0;
-#endif
- splx(s);
- return (error);
-}
-
-static void
-ie_mc_reset(struct ie_softc *sc)
-{
- struct ether_multi *enm;
- struct ether_multistep step;
- int size;
-
- /*
- * Step through the list of addresses.
- */
- again:
- size = 0;
- sc->mcast_count = 0;
- ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
- while (enm) {
- size += 6;
- if (sc->mcast_count >= IE_MAXMCAST ||
- memcmp(enm->enm_addrlo, enm->enm_addrhi, 6) != 0) {
- sc->arpcom.ac_if.if_flags |= IFF_ALLMULTI;
- i82586_ioctl(&sc->arpcom.ac_if,
- SIOCSIFFLAGS, (void *)0);
- return;
- }
- ETHER_NEXT_MULTI(step, enm);
- }
-
- if (size > sc->mcast_addrs_size) {
- /* Need to allocate more space */
- if (sc->mcast_addrs_size)
- free(sc->mcast_addrs, M_IPMADDR);
- sc->mcast_addrs = (char *)
- malloc(size, M_IPMADDR, M_WAITOK);
- sc->mcast_addrs_size = size;
- }
-
- /*
- * We've got the space; now copy the addresses
- */
- ETHER_FIRST_MULTI(step, &sc->arpcom, enm);
- while (enm) {
- if (sc->mcast_count >= IE_MAXMCAST)
- goto again; /* Just in case */
-
- memcpy(&sc->mcast_addrs[sc->mcast_count], enm->enm_addrlo, 6);
- sc->mcast_count++;
- ETHER_NEXT_MULTI(step, enm);
- }
- sc->want_mcsetup = 1;
-}
-
-/*
- * Media change callback.
- */
-int
-i82586_mediachange(struct ifnet *ifp)
-{
- struct ie_softc *sc = ifp->if_softc;
-
- if (sc->sc_mediachange)
- return ((*sc->sc_mediachange)(sc));
- return (0);
-}
-
-/*
- * Media status callback.
- */
-void
-i82586_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct ie_softc *sc = ifp->if_softc;
-
- if (sc->sc_mediastatus)
- (*sc->sc_mediastatus)(sc, ifmr);
-}
-
-#if I82586_DEBUG
-static void
-print_softie(struct ie_softc *sc)
-{
- static char *trace_labels[] = {
- "INTS_REQ",
- "INTS_IN",
- "INTS_LOOPS",
- "INTS_OUT",
- "RX_INT",
- "RX_DROP",
- "RX_ERR",
- "RX_OK",
- "RX_START",
- "START_TX",
- "TX_START",
- "TX_INT",
- "TX_REQ",
- "TX_EVT",
- "TX_EMIT",
- "TX_BAD",
- "TX_ACTIVE",
- "TRACE_CNT"
- };
-
- int i;
-
- printf("i82586 %s:\n", sc->arpcom.ac_if.if_name);
-
- printf(" iobase=%p\n", sc->sc_iobase);
-
- printf(" scp=0x%08x\t\tiscp=0x%08x\t\tscb=0x%08x\n",
- sc->scp, sc->iscp, sc->scb);
- printf(" buf_area=0x%08x\tbuf_area_sz=0x%08x\n",
- sc->buf_area, sc->buf_area_sz);
- printf(" rframes=0x%08x\trbds=0x%08x\t\trbufs=0x%08x\n",
- sc->rframes, sc->rbds, sc->rbufs);
- printf(" nop_cmds=0x%08x\txmit_cmds=0x%08x\n",
- sc->nop_cmds, sc->xmit_cmds);
- printf(" xbds=0x%08x\txbufs=0x%08x\n\n",
- sc->xbds, sc->xbufs);
- printf(" rfhead=%d\trftail=%d\n",
- sc->rfhead, sc->rftail);
- printf(" rbhead=%d\trbtail=%d\n",
- sc->rbhead, sc->rbtail);
- printf(" nframes=%d\tnrxbuf=%d\trnr_expect=%d\n",
- sc->nframes, sc->nrxbuf, sc->rnr_expect);
- printf(" xchead=%d\txctail=%d\n",
- sc->xchead, sc->xctail);
- printf(" xmit_busy=%d\txmit_req=%d\tdo_xmitnopchain=%d\n",
- sc->xmit_busy, sc->xmit_req, sc->do_xmitnopchain);
- printf(" promisc=%d\tasync_cmd_inprogress=%d\n\n",
- sc->promisc, sc->async_cmd_inprogress);
-
- {
- int cnt;
- int in;
- int lfdone = 0;
- char *tabs;
-
- if (!sc->trace_flow_wrap) {
- cnt = sc->trace_flow_in;
- in = 0;
- }
- else {
- cnt = I82586_TRACE_FLOW;
- in = sc->trace_flow_in;
- }
-
- sc->trace_flow_in = sc->trace_flow_wrap = 0;
-
- cnt /= 2;
-
- for (i = 0; i < cnt; i++) {
- if (!lfdone) {
- switch (sc->trace_flow[in]) {
- case I82586_INTS_REQ:
- case I82586_INTS_IN:
- printf("\n");
- }
- }
-
- lfdone = 0;
-
- if (strlen(trace_labels[sc->trace_flow[in]]) < 8)
- tabs = "\t\t";
- else
- tabs = "\t";
-
- printf(" %d\t%s%s0x%08x (%d)\n",
- i, trace_labels[sc->trace_flow[in]], tabs,
- sc->trace_flow[in + 1], sc->trace_flow[in + 1]);
-
- switch (sc->trace_flow[in]) {
- case I82586_INTS_REQ:
- case I82586_INTS_OUT:
- lfdone = 1;
- printf("\n");
- }
-
- in += 2;
-
- if (in >= I82586_TRACE_FLOW)
- in = 0;
- }
- }
-}
-
-static void
-print_rbd(struct ie_softc *sc, int n)
-{
- printf("RBD at %08x:\n status %04x, next %04x, buffer %lx\n"
- "length/EOL %04x\n", IE_RBD_ADDR(sc->rbds,n),
- sc->ie_bus_read16(sc, IE_RBD_STATUS(sc->rbds,n)),
- sc->ie_bus_read16(sc, IE_RBD_NEXT(sc->rbds,n)),
- (u_long)0,/*bus_space_read_4(sc->bt, sc->bh, IE_RBD_BUFADDR(sc->rbds,n)),-* XXX */
- sc->ie_bus_read16(sc, IE_RBD_BUFLEN(sc->rbds,n)));
-}
-
-#endif
diff --git a/c/src/libchip/network/i82586reg.h b/c/src/libchip/network/i82586reg.h
deleted file mode 100644
index e093aff68f..0000000000
--- a/c/src/libchip/network/i82586reg.h
+++ /dev/null
@@ -1,448 +0,0 @@
-/* $NetBSD: i82586reg.h,v 1.7 1998/02/28 01:07:45 pk Exp $ */
-
-/*-
- * Copyright (c) 1998 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Paul Kranenburg.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the NetBSD
- * Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*-
- * Copyright (c) 1992, University of Vermont and State Agricultural College.
- * Copyright (c) 1992, Garrett A. Wollman.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * Vermont and State Agricultural College and Garrett A. Wollman.
- * 4. Neither the name of the University nor the name of the author
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHOR BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * Intel 82586 Ethernet chip
- * Register, bit, and structure definitions.
- *
- * Written by GAW with reference to the Clarkson Packet Driver code for this
- * chip written by Russ Nelson and others.
- */
-
-/*
- * NOTE, the structure definitions in here are for reference only.
- * We use integer offsets exclusively to access the i82586 data structures.
- */
-
-
-#if 0
-/*
- * This is the master configuration block.
- * It tells the hardware where all the rest of the stuff is.
- */
-struct __ie_sys_conf_ptr {
- u_int16_t mbz; /* must be zero */
- u_int8_t ie_bus_use; /* true if 8-bit only */
- u_int8_t mbz2[5]; /* must be zero */
- u_int32_t ie_iscp_ptr; /* 24-bit physaddr of ISCP */
-};
-#endif
-#define IE_SCP_SZ 12
-#define IE_SCP_BUS_USE(base) ((base) + 2)
-#define IE_SCP_ISCP(base) ((base) + 8)
-
-/*
- * Note that this is wired in hardware; the SCP is always located here, no
- * matter what.
- */
-#define IE_SCP_ADDR 0xfffff4
-
-#if 0
-/*
- * The tells the hardware where all the rest of the stuff is, too.
- * FIXME: some of these should be re-commented after we figure out their
- * REAL function.
- */
-struct __ie_int_sys_conf_ptr {
- u_int8_t ie_busy; // zeroed after init
- u_int8_t mbz;
- u_int16_t ie_scb_offset; // 16-bit physaddr of next struct
- caddr_t ie_base; // 24-bit physaddr for all 16-bit vars
-};
-#endif
-#define IE_ISCP_SZ 8
-#define IE_ISCP_BUSY(base) ((base) + 0)
-#define IE_ISCP_SCB(base) ((base) + 2)
-#define IE_ISCP_BASE(base) ((base) + 4)
-
-#if 0
-/*
- * This FINALLY tells the hardware what to do and where to put it.
- */
-struct __ie_sys_ctl_block {
- u_int16_t ie_status; // status word
- u_int16_t ie_command; // command word
- u_int16_t ie_command_list; // 16-pointer to command block list
- u_int16_t ie_recv_list; // 16-pointer to receive frame list
- u_int16_t ie_err_crc; // CRC errors
- u_int16_t ie_err_align; // Alignment errors
- u_int16_t ie_err_resource; // Resource errors
- u_int16_t ie_err_overrun; // Overrun errors
-};
-#endif
-#define IE_SCB_SZ 16
-#define IE_SCB_STATUS(base) ((base) + 0)
-#define IE_SCB_CMD(base) ((base) + 2)
-#define IE_SCB_CMDLST(base) ((base) + 4)
-#define IE_SCB_RCVLST(base) ((base) + 6)
-#define IE_SCB_ERRCRC(base) ((base) + 8)
-#define IE_SCB_ERRALN(base) ((base) + 10)
-#define IE_SCB_ERRRES(base) ((base) + 12)
-#define IE_SCB_ERROVR(base) ((base) + 14)
-
-/* Command values */
-#define IE_RUC_MASK 0x0070 /* mask for RU command */
-#define IE_RUC_NOP 0 /* for completeness */
-#define IE_RUC_START 0x0010 /* start receive unit command */
-#define IE_RUC_RESUME 0x0020 /* resume a suspended receiver command */
-#define IE_RUC_SUSPEND 0x0030 /* suspend receiver command */
-#define IE_RUC_ABORT 0x0040 /* abort current receive operation */
-
-#define IE_CUC_MASK 0x0700 /* mask for CU command */
-#define IE_CUC_NOP 0 /* included for completeness */
-#define IE_CUC_START 0x0100 /* do-command command */
-#define IE_CUC_RESUME 0x0200 /* resume a suspended cmd list */
-#define IE_CUC_SUSPEND 0x0300 /* suspend current command */
-#define IE_CUC_ABORT 0x0400 /* abort current command */
-
-#define IE_ACK_COMMAND 0xf000 /* mask for ACK command */
-#define IE_ACK_CX 0x8000 /* ack IE_ST_CX */
-#define IE_ACK_FR 0x4000 /* ack IE_ST_FR */
-#define IE_ACK_CNA 0x2000 /* ack IE_ST_CNA */
-#define IE_ACK_RNR 0x1000 /* ack IE_ST_RNR */
-
-#define IE_ACTION_COMMAND(x) (((x) & IE_CUC_MASK) == IE_CUC_START)
- /* is this command an action command? */
-
-/* Status values */
-#define IE_ST_WHENCE 0xf000 /* mask for cause of interrupt */
-#define IE_ST_CX 0x8000 /* command with I bit completed */
-#define IE_ST_FR 0x4000 /* frame received */
-#define IE_ST_CNA 0x2000 /* all commands completed */
-#define IE_ST_RNR 0x1000 /* receive not ready */
-
-#define IE_CUS_MASK 0x0700 /* mask for command unit status */
-#define IE_CUS_ACTIVE 0x0200 /* command unit is active */
-#define IE_CUS_SUSPEND 0x0100 /* command unit is suspended */
-
-#define IE_RUS_MASK 0x0070 /* mask for receiver unit status */
-#define IE_RUS_SUSPEND 0x0010 /* receiver is suspended */
-#define IE_RUS_NOSPACE 0x0020 /* receiver has no resources */
-#define IE_RUS_READY 0x0040 /* receiver is ready */
-
-#if 0
-/*
- * This is filled in partially by the chip, partially by us.
- */
-struct __ie_recv_frame_desc {
- u_int16_t ie_fd_status; // status for this frame
- u_int16_t ie_fd_last; // end of frame list flag
- u_int16_t ie_fd_next; // 16-pointer to next RFD
- u_int16_t ie_fd_buf_desc; // 16-pointer to list of buffer descs
- struct __ie_en_addr dest; // destination ether
- struct __ie_en_addr src; // source ether
- u_int16_t ie_length; // 802 length/Ether type
- u_short mbz; // must be zero
-};
-#endif
-#define IE_RFRAME_SZ 24
-#define IE_RFRAME_ADDR(base,i) ((base) + (i) * IE_RFRAME_SZ)
-#define IE_RFRAME_STATUS(b,i) (IE_RFRAME_ADDR(b,i) + 0)
-#define IE_RFRAME_LAST(b,i) (IE_RFRAME_ADDR(b,i) + 2)
-#define IE_RFRAME_NEXT(b,i) (IE_RFRAME_ADDR(b,i) + 4)
-#define IE_RFRAME_BUFDESC(b,i) (IE_RFRAME_ADDR(b,i) + 6)
-#define IE_RFRAME_EDST(b,i) (IE_RFRAME_ADDR(b,i) + 8)
-#define IE_RFRAME_ESRC(b,i) (IE_RFRAME_ADDR(b,i) + 14)
-#define IE_RFRAME_ELEN(b,i) (IE_RFRAME_ADDR(b,i) + 20)
-
-/* "last" bits */
-#define IE_FD_EOL 0x8000 /* last rfd in list */
-#define IE_FD_SUSP 0x4000 /* suspend RU after receipt */
-
-/* status field bits */
-#define IE_FD_COMPLETE 0x8000 /* frame is complete */
-#define IE_FD_BUSY 0x4000 /* frame is busy */
-#define IE_FD_OK 0x2000 /* frame is ok */
-#define IE_FD_CRC 0x0800 /* CRC error */
-#define IE_FD_ALGN 0x0400 /* Alignment error */
-#define IE_FD_RNR 0x0200 /* receiver out of resources here */
-#define IE_FD_OVR 0x0100 /* DMA overrun */
-#define IE_FD_SHORT 0x0080 /* Short frame */
-#define IE_FD_NOEOF 0x0040 /* no EOF (?) */
-#define IE_FD_ERRMASK /* all error bits */ \
- (IE_FD_CRC|IE_FD_ALGN|IE_FD_RNR|IE_FD_OVR|IE_FD_SHORT|IE_FD_NOEOF)
-#define IE_FD_STATUSBITS \
- "\20\20COMPLT\17BUSY\16OK\14CRC\13ALGN\12RNR\11OVR\10SHORT\7NOEOF"
-
-#if 0
-/*
- * linked list of buffers...
- */
-struct __ie_recv_buf_desc {
- u_int16_t ie_rbd_status; // status for this buffer
- u_int16_t ie_rbd_next; // 16-pointer to next RBD
- caddr_t ie_rbd_buffer; // 24-pointer to buffer for this RBD
- u_int16_t ie_rbd_length; // length of the buffer
- u_int16_t mbz; // must be zero
-};
-#endif
-#define IE_RBD_SZ 12
-#define IE_RBD_ADDR(base,i) ((base) + (i) * IE_RBD_SZ)
-#define IE_RBD_STATUS(b,i) (IE_RBD_ADDR(b,i) + 0)
-#define IE_RBD_NEXT(b,i) (IE_RBD_ADDR(b,i) + 2)
-#define IE_RBD_BUFADDR(b,i) (IE_RBD_ADDR(b,i) + 4)
-#define IE_RBD_BUFLEN(b,i) (IE_RBD_ADDR(b,i) + 8)
-
-/* RBD status fields */
-#define IE_RBD_LAST 0x8000 /* last buffer */
-#define IE_RBD_USED 0x4000 /* this buffer has data */
-#define IE_RBD_CNTMASK 0x3fff /* byte count of buffer data */
-
-/* RDB `End Of List' flag; encoded in `buffer length' field */
-#define IE_RBD_EOL 0x8000 /* last buffer */
-
-
-#if 0
-/*
- * All commands share this in common.
- */
-struct __ie_cmd_common {
- u_int16_t ie_cmd_status; // status of this command
- u_int16_t ie_cmd_cmd; // command word
- u_int16_t ie_cmd_link; // link to next command
-};
-#endif
-#define IE_CMD_COMMON_SZ 6
-#define IE_CMD_COMMON_STATUS(base) ((base) + 0)
-#define IE_CMD_COMMON_CMD(base) ((base) + 2)
-#define IE_CMD_COMMON_LINK(base) ((base) + 4)
-
-#define IE_STAT_COMPL 0x8000 /* command is completed */
-#define IE_STAT_BUSY 0x4000 /* command is running now */
-#define IE_STAT_OK 0x2000 /* command completed successfully */
-#define IE_STAT_ABORT 0x1000 /* command was aborted */
-
-#define IE_CMD_NOP 0x0000 /* NOP */
-#define IE_CMD_IASETUP 0x0001 /* initial address setup */
-#define IE_CMD_CONFIG 0x0002 /* configure command */
-#define IE_CMD_MCAST 0x0003 /* multicast setup command */
-#define IE_CMD_XMIT 0x0004 /* transmit command */
-#define IE_CMD_TDR 0x0005 /* time-domain reflectometer command */
-#define IE_CMD_DUMP 0x0006 /* dump command */
-#define IE_CMD_DIAGNOSE 0x0007 /* diagnostics command */
-
-#define IE_CMD_LAST 0x8000 /* this is the last command in the list */
-#define IE_CMD_SUSPEND 0x4000 /* suspend CU after this command */
-#define IE_CMD_INTR 0x2000 /* post an interrupt after completion */
-
-/*
- * No-op commands; just like COMMON but "indexable"
- */
-#define IE_CMD_NOP_SZ IE_CMD_COMMON_SZ
-#define IE_CMD_NOP_ADDR(base,i) ((base) + (i) * IE_CMD_NOP_SZ)
-#define IE_CMD_NOP_STATUS(b,i) (IE_CMD_NOP_ADDR(b,i) + 0)
-#define IE_CMD_NOP_CMD(b,i) (IE_CMD_NOP_ADDR(b,i) + 2)
-#define IE_CMD_NOP_LINK(b,i) (IE_CMD_NOP_ADDR(b,i) + 4)
-
-
-#if 0
-/*
- * This is the command to transmit a frame.
- */
-struct __ie_xmit_cmd {
- struct __ie_cmd_common com; // common part
-#define __ie_xmit_status com.ie_cmd_status
-
- u_int16_t ie_xmit_desc; // pointer to buffer descriptor
- struct __ie_en_addr ie_xmit_addr; // destination address
- u_int16_t ie_xmit_length; // 802.3 length/Ether type field
-};
-#endif
-#define IE_CMD_XMIT_SZ (IE_CMD_COMMON_SZ + 10)
-#define IE_CMD_XMIT_ADDR(base,i) ((base) + (i) * IE_CMD_XMIT_SZ)
-#define IE_CMD_XMIT_STATUS(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + 0) /* == CMD_COMMON_STATUS */
-#define IE_CMD_XMIT_CMD(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + 2) /* == CMD_COMMON_CMD */
-#define IE_CMD_XMIT_LINK(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + 4) /* == CMD_COMMON_LINK */
-#define IE_CMD_XMIT_DESC(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + IE_CMD_COMMON_SZ + 0)
-#define IE_CMD_XMIT_EADDR(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + IE_CMD_COMMON_SZ + 2)
-#define IE_CMD_XMIT_LEN(b,i) \
- (IE_CMD_XMIT_ADDR(b,i) + IE_CMD_COMMON_SZ + 8)
-
-#define IE_XS_MAXCOLL 0x000f /* number of collisions during transmit */
-#define IE_XS_EXCMAX 0x0020 /* exceeded maximum number of collisions */
-#define IE_XS_SQE 0x0040 /* SQE positive */
-#define IE_XS_DEFERRED 0x0080 /* transmission deferred */
-#define IE_XS_UNDERRUN 0x0100 /* DMA underrun */
-#define IE_XS_LOSTCTS 0x0200 /* Lost CTS */
-#define IE_XS_NOCARRIER 0x0400 /* No Carrier */
-#define IE_XS_LATECOLL 0x0800 /* Late collision */
-
-#if 0
-/*
- * This is a buffer descriptor for a frame to be transmitted.
- */
-struct __ie_xmit_buf {
- u_int16_t ie_xmit_flags; // see below
- u_int16_t ie_xmit_next; // 16-pointer to next desc
- caddr_t ie_xmit_buf; // 24-pointer to the actual buffer
-};
-#endif
-#define IE_XBD_SZ 8
-#define IE_XBD_ADDR(base,i) ((base) + (i) * IE_XBD_SZ)
-#define IE_XBD_FLAGS(b,i) (IE_XBD_ADDR(b,i) + 0)
-#define IE_XBD_NEXT(b,i) (IE_XBD_ADDR(b,i) + 2)
-#define IE_XBD_BUF(b,i) (IE_XBD_ADDR(b,i) + 4)
-
-#define IE_TBD_EOL 0x8000 /* this TBD is the last one */
-#define IE_TBD_CNTMASK 0x3fff /* The rest of the `flags' word
- is actually the length. */
-
-
-#if 0
-/*
- * Multicast setup command.
- */
-struct __ie_mcast_cmd {
- struct __ie_cmd_common com; // common part
-#define ie_mcast_status com.ie_cmd_status
-
- // size (in bytes) of multicast addresses
- u_short ie_mcast_bytes;
- struct __ie_en_addr ie_mcast_addrs[IE_MAXMCAST + 1];// space for them
-};
-#endif
-#define IE_CMD_MCAST_SZ (IE_CMD_COMMON_SZ + 2 /* + XXX */)
-#define IE_CMD_MCAST_BYTES(base) ((base) + IE_CMD_COMMON_SZ + 0)
-#define IE_CMD_MCAST_MADDR(base) ((base) + IE_CMD_COMMON_SZ + 2)
-
-#if 0
-/*
- * Time Domain Reflectometer command.
- */
-struct __ie_tdr_cmd {
- struct __ie_cmd_common com; // common part
-#define ie_tdr_status com.ie_cmd_status
- u_short ie_tdr_time; // error bits and time
-};
-#endif
-#define IE_CMD_TDR_SZ (IE_CMD_COMMON_SZ + 2)
-#define IE_CMD_TDR_TIME(base) ((base) + IE_CMD_COMMON_SZ + 0)
-
-#define IE_TDR_SUCCESS 0x8000 /* TDR succeeded without error */
-#define IE_TDR_XCVR 0x4000 /* detected a transceiver problem */
-#define IE_TDR_OPEN 0x2000 /* detected an incorrect termination ("open") */
-#define IE_TDR_SHORT 0x1000 /* TDR detected a short circuit */
-#define IE_TDR_TIME 0x07ff /* mask for reflection time */
-
-#if 0
-/*
- * Initial Address Setup command
- */
-struct __ie_iasetup_cmd {
- struct __ie_cmd_common com;
-#define ie_iasetup_status com.ie_cmd_status
- struct __ie_en_addr ie_address;
-};
-#endif
-#define IE_CMD_IAS_SZ (IE_CMD_COMMON_SZ + 6)
-#define IE_CMD_IAS_EADDR(base) ((base) + IE_CMD_COMMON_SZ + 0)
-
-#if 0
-/*
- * Configuration command
- */
-struct __ie_config_cmd {
- struct __ie_cmd_common com; // common part
-#define ie_config_status com.ie_cmd_status
-
- u_int8_t ie_config_count; // byte count (0x0c)
- u_int8_t ie_fifo; // fifo (8)
- u_int8_t ie_save_bad; // save bad frames (0x40)
- u_int8_t ie_addr_len; // address length (0x2e) (AL-LOC == 1)
- u_int8_t ie_priority; // priority and backoff (0x0)
- u_int8_t ie_ifs; // inter-frame spacing (0x60)
- u_int8_t ie_slot_low; // slot time, LSB (0x0)
- u_int8_t ie_slot_high; // slot time, MSN, and retries (0xf2)
- u_int8_t ie_promisc; // 1 if promiscuous, else 0
- u_int8_t ie_crs_cdt; // CSMA/CD parameters (0x0)
- u_int8_t ie_min_len; // min frame length (0x40)
- u_int8_t ie_junk; // stuff for 82596 (0xff)
-};
-#endif
-#define IE_CMD_CFG_SZ (IE_CMD_COMMON_SZ + 12)
-#define IE_CMD_CFG_CNT(base) ((base) + IE_CMD_COMMON_SZ + 0)
-#define IE_CMD_CFG_FIFO(base) ((base) + IE_CMD_COMMON_SZ + 1)
-#define IE_CMD_CFG_SAVEBAD(base) ((base) + IE_CMD_COMMON_SZ + 2)
-#define IE_CMD_CFG_ADDRLEN(base) ((base) + IE_CMD_COMMON_SZ + 3)
-#define IE_CMD_CFG_PRIORITY(base) ((base) + IE_CMD_COMMON_SZ + 4)
-#define IE_CMD_CFG_IFS(base) ((base) + IE_CMD_COMMON_SZ + 5)
-#define IE_CMD_CFG_SLOT_LOW(base) ((base) + IE_CMD_COMMON_SZ + 6)
-#define IE_CMD_CFG_SLOT_HIGH(base) ((base) + IE_CMD_COMMON_SZ + 7)
-#define IE_CMD_CFG_PROMISC(base) ((base) + IE_CMD_COMMON_SZ + 8)
-#define IE_CMD_CFG_CRSCDT(base) ((base) + IE_CMD_COMMON_SZ + 9)
-#define IE_CMD_CFG_MINLEN(base) ((base) + IE_CMD_COMMON_SZ + 10)
-#define IE_CMD_CFG_JUNK(base) ((base) + IE_CMD_COMMON_SZ + 11)
diff --git a/c/src/libchip/network/if_dc.c b/c/src/libchip/network/if_dc.c
deleted file mode 100644
index e822a7c533..0000000000
--- a/c/src/libchip/network/if_dc.c
+++ /dev/null
@@ -1,3849 +0,0 @@
-/*
- * Ported from FreeBSD --> RTEMS, december 03.
- * Daron Chabot <daron@nucleus.usask.ca>
- * -- only tested with i386 bsp.
- * -- supports *one* card (until the PCI & IRQ APIs get sorted out ;-))
- *
- *
- * Copyright (c) 1997, 1998, 1999
- * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Bill Paul.
- * 4. Neither the name of the author nor the names of any co-contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pci/if_dc.c,v 1.9.2.41 2003/03/05 18:42:33 njl Exp $
- */
-
-/*
- * DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143
- * series chips and several workalikes including the following:
- *
- * Macronix 98713/98715/98725/98727/98732 PMAC (www.macronix.com)
- * Macronix/Lite-On 82c115 PNIC II (www.macronix.com)
- * Lite-On 82c168/82c169 PNIC (www.litecom.com)
- * ASIX Electronics AX88140A (www.asix.com.tw)
- * ASIX Electronics AX88141 (www.asix.com.tw)
- * ADMtek AL981 (www.admtek.com.tw)
- * ADMtek AN985 (www.admtek.com.tw)
- * Davicom DM9100, DM9102, DM9102A (www.davicom8.com)
- * Accton EN1217 (www.accton.com)
- * Conexant LANfinity (www.conexant.com)
- *
- * Datasheets for the 21143 are available at developer.intel.com.
- * Datasheets for the clone parts can be found at their respective sites.
- * (Except for the PNIC; see www.freebsd.org/~wpaul/PNIC/pnic.ps.gz.)
- * The PNIC II is essentially a Macronix 98715A chip; the only difference
- * worth noting is that its multicast hash table is only 128 bits wide
- * instead of 512.
- *
- * Written by Bill Paul <wpaul@ee.columbia.edu>
- * Electrical Engineering Department
- * Columbia University, New York City
- */
-
-/*
- * The Intel 21143 is the successor to the DEC 21140. It is basically
- * the same as the 21140 but with a few new features. The 21143 supports
- * three kinds of media attachments:
- *
- * o MII port, for 10Mbps and 100Mbps support and NWAY
- * autonegotiation provided by an external PHY.
- * o SYM port, for symbol mode 100Mbps support.
- * o 10baseT port.
- * o AUI/BNC port.
- *
- * The 100Mbps SYM port and 10baseT port can be used together in
- * combination with the internal NWAY support to create a 10/100
- * autosensing configuration.
- *
- * Note that not all tulip workalikes are handled in this driver: we only
- * deal with those which are relatively well behaved. The Winbond is
- * handled separately due to its different register offsets and the
- * special handling needed for its various bugs. The PNIC is handled
- * here, but I'm not thrilled about it.
- *
- * All of the workalike chips use some form of MII transceiver support
- * with the exception of the Macronix chips, which also have a SYM port.
- * The ASIX AX88140A is also documented to have a SYM port, but all
- * the cards I've seen use an MII transceiver, probably because the
- * AX88140A doesn't support internal NWAY.
- */
-
-/*
- * This driver only supports architectures with the new style
- * exception processing. The following checks try to keep this
- * from being compiled on systems which can't support this driver.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#if defined(DRIVER_SUPPORTED)
- #undef DRIVER_SUPPORTED
-#endif
-
-#if defined(__i386__)
- #define DRIVER_SUPPORTED
-#endif
-
-#if defined(__PPC__)
- #define DRIVER_SUPPORTED
-#endif
-
-#include <bsp.h>
-
-#if !defined(PCI_DRAM_OFFSET)
- #undef DRIVER_SUPPORTED
-#endif
-
-#if defined(DRIVER_SUPPORTED) /* this covers the file "globally"... */
-#include <rtems/pci.h>
-
-#include <rtems/error.h>
-#include <errno.h>
-#include <rtems/rtems_bsdnet.h>
-
-#include <net/if_types.h>
-
-#include <sys/param.h>
-#include <sys/sockio.h>
-#include <sys/socket.h>
-#include <sys/mbuf.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-#include <sys/malloc.h>
-#include <sys/systm.h>
-#include <bsp.h>
-
-/* moved to cpukit/include/rtems in CVS current ! */
-/*#include "if_media.h" */
-/*#include "pci.h" */
-#include <net/if_media.h>
-#include <rtems/pci.h>
-/*
-#include <sys/kernel.h>
-#include <sys/sysctl.h>
-*/
-
-#include <vm/vm.h> /* for vtophys */
-
-
-#define vtophys(p) (uintptr_t)(p)
-
-/*
-#include <net/if_arp.h>
-#include <net/if_vlan_var.h>
-#include <net/bpf.h>
-*/
-
-#if 0
-#include <vm/pmap.h> /* for vtophys */
-#include <machine/clock.h> /* for DELAY */
-#include <machine/bus_pio.h>
-#include <machine/bus_memio.h>
-#include <machine/bus.h>
-#include <machine/resource.h>
-#include <sys/bus.h>
-#include <sys/rman.h>
-#endif
-#include <dev/mii/mii.h>
-#if 0
-#include <dev/mii/miivar.h>
-
-#include <pci/pcireg.h>
-#include <pci/pcivar.h>
-#endif
-
-/* NOTE: use mem space mapping (for now ...)
-#define DC_USEIOSPACE
-*/
-
-#ifdef __alpha__
-#define SRM_MEDIA
-#endif
-
-#include <bsp/irq.h>
-
-
-#include <libchip/if_dcreg.h>
-
-
-#define DRIVER_PREFIX "tl"
-#define NDRIVER 1
-#define IRQ_EVENT RTEMS_EVENT_13 /* Ha ... */
-static struct dc_softc dc_softc_devs[NDRIVER];
-
-#define UNUSED
-
-#if 0
-/* "controller miibus0" required. See GENERIC if you get errors here. */
-#include "miibus_if.h"
-
-
-
-#ifndef lint
-static const char rcsid[] =
- "$FreeBSD: src/sys/pci/if_dc.c,v 1.9.2.41 2003/03/05 18:42:33 njl Exp $";
-#endif
-
-#endif
-
-
-/*
- * Various supported device vendors/types and their names.
- * NOTE:
- * -----
- * Only the "ADMtek AN985" has been tested under RTEMS !!!
- */
-static struct dc_type dc_devs[] = {
- { DC_VENDORID_DEC, DC_DEVICEID_21143,
- "Intel 21143 10/100BaseTX", 0 },
- { DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009,
- "Davicom DM9009 10/100BaseTX", 0 },
- { DC_VENDORID_DAVICOM, DC_DEVICEID_DM9100,
- "Davicom DM9100 10/100BaseTX", 0 },
- { DC_VENDORID_DAVICOM, DC_DEVICEID_DM9102,
- "Davicom DM9102 10/100BaseTX", 0 },
- { DC_VENDORID_DAVICOM, DC_DEVICEID_DM9102,
- "Davicom DM9102A 10/100BaseTX", 0 },
- { DC_VENDORID_ADMTEK, DC_DEVICEID_AL981,
- "ADMtek AL981 10/100BaseTX", 0 },
- { DC_VENDORID_ADMTEK, DC_DEVICEID_AN985,
- "ADMtek AN985 10/100BaseTX", 0 },
- { DC_VENDORID_ASIX, DC_DEVICEID_AX88140A,
- "ASIX AX88140A 10/100BaseTX", 0 },
- { DC_VENDORID_ASIX, DC_DEVICEID_AX88140A,
- "ASIX AX88141 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_98713,
- "Macronix 98713 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_98713,
- "Macronix 98713A 10/100BaseTX", 0 },
- { DC_VENDORID_CP, DC_DEVICEID_98713_CP,
- "Compex RL100-TX 10/100BaseTX", 0 },
- { DC_VENDORID_CP, DC_DEVICEID_98713_CP,
- "Compex RL100-TX 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_987x5,
- "Macronix 98715/98715A 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_987x5,
- "Macronix 98715AEC-C 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_987x5,
- "Macronix 98725 10/100BaseTX", 0 },
- { DC_VENDORID_MX, DC_DEVICEID_98727,
- "Macronix 98727/98732 10/100BaseTX", 0 },
- { DC_VENDORID_LO, DC_DEVICEID_82C115,
- "LC82C115 PNIC II 10/100BaseTX", 0 },
- { DC_VENDORID_LO, DC_DEVICEID_82C168,
- "82c168 PNIC 10/100BaseTX", 0 },
- { DC_VENDORID_LO, DC_DEVICEID_82C168,
- "82c169 PNIC 10/100BaseTX", 0 },
- { DC_VENDORID_ACCTON, DC_DEVICEID_EN1217,
- "Accton EN1217 10/100BaseTX", 0 },
- { DC_VENDORID_ACCTON, DC_DEVICEID_EN2242,
- "Accton EN2242 MiniPCI 10/100BaseTX", 0 },
- { DC_VENDORID_CONEXANT, DC_DEVICEID_RS7112,
- "Conexant LANfinity MiniPCI 10/100BaseTX", 0 },
- { 0, 0, NULL, 0 }
-};
-
-#if 0
-static int dc_probe __P((device_t));
-static int dc_attach __P((device_t));
-static int dc_detach __P((device_t));
-static int dc_suspend __P((device_t));
-static int dc_resume __P((device_t));
-static void dc_shutdown __P((device_t));
-static void dc_acpi __P((device_t));
-#endif
-
-static struct dc_type *dc_devtype(int);
-static int dc_newbuf(struct dc_softc *, int, struct mbuf *);
-static int dc_encap(struct dc_softc *, struct mbuf *,
- u_int32_t *);
-static int dc_coal(struct dc_softc *, struct mbuf **);
-static void dc_pnic_rx_bug_war(struct dc_softc *, int);
-static int dc_rx_resync(struct dc_softc *);
-static void dc_rxeof(struct dc_softc *);
-static void dc_txeof(struct dc_softc *);
-/*static void dc_tick((void *));*/
-static void dc_tx_underrun(struct dc_softc *);
-static void dc_intr(void *);
-static void dc_daemon(void *);
-static void dc_start(struct ifnet *);
-static int dc_ioctl(struct ifnet *, ioctl_command_t, caddr_t);
-static void dc_init(void *);
-static void dc_stop(struct dc_softc *);
-static void dc_watchdog(struct ifnet *);
-#if 0
-static int dc_ifmedia_upd __P((struct ifnet *));
-static void dc_ifmedia_sts __P((struct ifnet *, struct ifmediareq *));
-#endif
-
-static void dc_delay(struct dc_softc *);
-static void dc_eeprom_idle(struct dc_softc *);
-static void dc_eeprom_putbyte(struct dc_softc *, int);
-static void dc_eeprom_getword(struct dc_softc *, int, u_int16_t *);
-static void dc_eeprom_getword_pnic(struct dc_softc *, int, u_int16_t *);
-static void dc_eeprom_width(struct dc_softc *);
-static void dc_read_eeprom(struct dc_softc *, caddr_t, int,int, int);
-
-#if 0
-static void dc_mii_writebit __P((struct dc_softc *, int));
-static int dc_mii_readbit __P((struct dc_softc *));
-static void dc_mii_sync __P((struct dc_softc *));
-static void dc_mii_send __P((struct dc_softc *, u_int32_t, int));
-static int dc_mii_readreg __P((struct dc_softc *, struct dc_mii_frame *));
-static int dc_mii_writereg __P((struct dc_softc *, struct dc_mii_frame *));
-static int dc_miibus_readreg __P((device_t, int, int));
-static int dc_miibus_writereg __P((device_t, int, int, int));
-static void dc_miibus_statchg __P((device_t));
-static void dc_miibus_mediainit __P((device_t));
-#endif
-
-static void dc_setcfg(struct dc_softc *, int);
-static u_int32_t dc_crc_le(struct dc_softc *, caddr_t);
-#ifndef UNUSED
-static u_int32_t dc_crc_be(caddr_t);
-#endif
-static void dc_setfilt_21143(struct dc_softc *);
-static void dc_setfilt_asix(struct dc_softc *);
-static void dc_setfilt_admtek(struct dc_softc *);
-static void dc_setfilt(struct dc_softc *);
-static void dc_reset(struct dc_softc *);
-static int dc_list_rx_init(struct dc_softc *);
-static int dc_list_tx_init(struct dc_softc *);
-static void dc_read_srom(struct dc_softc *, int);
-static void dc_parse_21143_srom(struct dc_softc *);
-static void dc_apply_fixup(struct dc_softc *, int);
-
-#if 0
-static void dc_decode_leaf_sia __P((struct dc_softc *,
- struct dc_eblock_sia *));
-static void dc_decode_leaf_mii __P((struct dc_softc *,
- struct dc_eblock_mii *));
-static void dc_decode_leaf_sym __P((struct dc_softc *,
- struct dc_eblock_sym *));
-#endif
-
-
-#ifdef DC_USEIOSPACE
-#define DC_RES SYS_RES_IOPORT
-#define DC_RID DC_PCI_CFBIO
-#else
-#define DC_RES SYS_RES_MEMORY
-#define DC_RID DC_PCI_CFBMA
-#endif
-
-#if 0
-static device_method_t dc_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, dc_probe),
- DEVMETHOD(device_attach, dc_attach),
- DEVMETHOD(device_detach, dc_detach),
- DEVMETHOD(device_suspend, dc_suspend),
- DEVMETHOD(device_resume, dc_resume),
- DEVMETHOD(device_shutdown, dc_shutdown),
-
- /* bus interface */
- DEVMETHOD(bus_print_child, bus_generic_print_child),
- DEVMETHOD(bus_driver_added, bus_generic_driver_added),
-
- /* MII interface */
- DEVMETHOD(miibus_readreg, dc_miibus_readreg),
- DEVMETHOD(miibus_writereg, dc_miibus_writereg),
- DEVMETHOD(miibus_statchg, dc_miibus_statchg),
- DEVMETHOD(miibus_mediainit, dc_miibus_mediainit),
-
- { 0, 0 }
-};
-
-static driver_t dc_driver = {
- "dc",
- dc_methods,
- sizeof(struct dc_softc)
-};
-
-static devclass_t dc_devclass;
-#endif
-
-
-#ifdef __i386__
-static int dc_quick=1;
-#if 0
-SYSCTL_INT(_hw, OID_AUTO, dc_quick, CTLFLAG_RW,
- &dc_quick,0,"do not mdevget in dc driver");
-#endif
-#endif
-
-#if 0
-DRIVER_MODULE(if_dc, pci, dc_driver, dc_devclass, 0, 0);
-DRIVER_MODULE(miibus, dc, miibus_driver, miibus_devclass, 0, 0);
-#endif
-
-
-#define DC_SETBIT(sc, reg, x) \
- CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) | (x))
-
-#define DC_CLRBIT(sc, reg, x) \
- CSR_WRITE_4(sc, reg, CSR_READ_4(sc, reg) & ~(x))
-
-#define SIO_SET(x) DC_SETBIT(sc, DC_SIO, (x))
-#define SIO_CLR(x) DC_CLRBIT(sc, DC_SIO, (x))
-
-
-/* XXX Fixme: rtems_bsp_delay( ) for the pc386 BSP (at least)
- * needs work... see pc386/include/bsp.h.
- * I have "a" solution, utilizing the 2nd i8254 timer,
- * if anyone is interested (first timer is used for clock_tick ISR)...
- */
-#ifdef __i386__
-extern void Wait_X_ms( unsigned int );
-#define DELAY(n) Wait_X_ms( (unsigned int)((n)/100) )
-#else
-#define DELAY(n) rtems_bsp_delay(n)
-#endif
-
-
-static void dc_delay(sc)
- struct dc_softc *sc;
-{
- int idx;
-
- for (idx = (300 / 33) + 1; idx > 0; idx--)
- CSR_READ_4(sc, DC_BUSCTL);
-}
-
-static void dc_eeprom_width(sc)
- struct dc_softc *sc;
-{
- int i;
-
- /* Force EEPROM to idle state. */
- dc_eeprom_idle(sc);
-
- /* Enter EEPROM access mode. */
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
- dc_delay(sc);
-
- for (i = 3; i--;) {
- if (6 & (1 << i))
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
- else
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- for (i = 1; i <= 12; i++) {
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- if (!(CSR_READ_4(sc, DC_SIO) & DC_SIO_EE_DATAOUT)) {
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- break;
- }
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- /* Turn off EEPROM access mode. */
- dc_eeprom_idle(sc);
-
- if (i < 4 || i > 12)
- sc->dc_romwidth = 6;
- else
- sc->dc_romwidth = i;
-
- /* Enter EEPROM access mode. */
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
- dc_delay(sc);
-
- /* Turn off EEPROM access mode. */
- dc_eeprom_idle(sc);
-}
-
-static void dc_eeprom_idle(sc)
- struct dc_softc *sc;
-{
- register int i;
-
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
- dc_delay(sc);
-
- for (i = 0; i < 25; i++) {
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CS);
- dc_delay(sc);
- CSR_WRITE_4(sc, DC_SIO, 0x00000000);
-
- return;
-}
-
-/*
- * Send a read command and address to the EEPROM, check for ACK.
- */
-static void dc_eeprom_putbyte(sc, addr)
- struct dc_softc *sc;
- int addr;
-{
- register int d, i;
-
- d = DC_EECMD_READ >> 6;
- for (i = 3; i--; ) {
- if (d & (1 << i))
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
- else
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_DATAIN);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- /*
- * Feed in each bit and strobe the clock.
- */
- for (i = sc->dc_romwidth; i--;) {
- if (addr & (1 << i)) {
- SIO_SET(DC_SIO_EE_DATAIN);
- } else {
- SIO_CLR(DC_SIO_EE_DATAIN);
- }
- dc_delay(sc);
- SIO_SET(DC_SIO_EE_CLK);
- dc_delay(sc);
- SIO_CLR(DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- return;
-}
-
-/*
- * Read a word of data stored in the EEPROM at address 'addr.'
- * The PNIC 82c168/82c169 has its own non-standard way to read
- * the EEPROM.
- */
-static void dc_eeprom_getword_pnic(sc, addr, dest)
- struct dc_softc *sc;
- int addr;
- u_int16_t *dest;
-{
- register int i;
- u_int32_t r;
-
- CSR_WRITE_4(sc, DC_PN_SIOCTL, DC_PN_EEOPCODE_READ|addr);
-
- for (i = 0; i < DC_TIMEOUT; i++) {
- DELAY(1);
- r = CSR_READ_4(sc, DC_SIO);
- if (!(r & DC_PN_SIOCTL_BUSY)) {
- *dest = (u_int16_t)(r & 0xFFFF);
- return;
- }
- }
-
- return;
-}
-
-/*
- * Read a word of data stored in the EEPROM at address 'addr.'
- */
-static void dc_eeprom_getword(sc, addr, dest)
- struct dc_softc *sc;
- int addr;
- u_int16_t *dest;
-{
- register int i;
- u_int16_t word = 0;
-
- /* Force EEPROM to idle state. */
- dc_eeprom_idle(sc);
-
- /* Enter EEPROM access mode. */
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_EESEL);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_ROMCTL_READ);
- dc_delay(sc);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_EE_CLK);
- dc_delay(sc);
- DC_SETBIT(sc, DC_SIO, DC_SIO_EE_CS);
- dc_delay(sc);
-
- /*
- * Send address of word we want to read.
- */
- dc_eeprom_putbyte(sc, addr);
-
- /*
- * Start reading bits from EEPROM.
- */
- for (i = 0x8000; i; i >>= 1) {
- SIO_SET(DC_SIO_EE_CLK);
- dc_delay(sc);
- if (CSR_READ_4(sc, DC_SIO) & DC_SIO_EE_DATAOUT)
- word |= i;
- dc_delay(sc);
- SIO_CLR(DC_SIO_EE_CLK);
- dc_delay(sc);
- }
-
- /* Turn off EEPROM access mode. */
- dc_eeprom_idle(sc);
-
- *dest = word;
-
- return;
-}
-
-/*
- * Read a sequence of words from the EEPROM.
- */
-static void dc_read_eeprom(sc, dest, off, cnt, swap)
- struct dc_softc *sc;
- caddr_t dest;
- int off;
- int cnt;
- int swap;
-{
- int i;
- u_int16_t word = 0, *ptr;
-
- for (i = 0; i < cnt; i++) {
- if (DC_IS_PNIC(sc))
- dc_eeprom_getword_pnic(sc, off + i, &word);
- else
- dc_eeprom_getword(sc, off + i, &word);
- ptr = (u_int16_t *)(dest + (i * 2));
- if (swap)
- *ptr = ntohs(word);
- else
- *ptr = word;
- }
-
- return;
-}
-
-
-#if 0
-/*
- * The following two routines are taken from the Macronix 98713
- * Application Notes pp.19-21.
- */
-/*
- * Write a bit to the MII bus.
- */
-static void dc_mii_writebit(sc, bit)
- struct dc_softc *sc;
- int bit;
-{
- if (bit)
- CSR_WRITE_4(sc, DC_SIO,
- DC_SIO_ROMCTL_WRITE|DC_SIO_MII_DATAOUT);
- else
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE);
-
- DC_SETBIT(sc, DC_SIO, DC_SIO_MII_CLK);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_MII_CLK);
-
- return;
-}
-
-/*
- * Read a bit from the MII bus.
- */
-static int dc_mii_readbit(sc)
- struct dc_softc *sc;
-{
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_READ|DC_SIO_MII_DIR);
- CSR_READ_4(sc, DC_SIO);
- DC_SETBIT(sc, DC_SIO, DC_SIO_MII_CLK);
- DC_CLRBIT(sc, DC_SIO, DC_SIO_MII_CLK);
- if (CSR_READ_4(sc, DC_SIO) & DC_SIO_MII_DATAIN)
- return(1);
-
- return(0);
-}
-
-/*
- * Sync the PHYs by setting data bit and strobing the clock 32 times.
- */
-static void dc_mii_sync(sc)
- struct dc_softc *sc;
-{
- register int i;
-
- CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE);
-
- for (i = 0; i < 32; i++)
- dc_mii_writebit(sc, 1);
-
- return;
-}
-
-/*
- * Clock a series of bits through the MII.
- */
-static void dc_mii_send(sc, bits, cnt)
- struct dc_softc *sc;
- u_int32_t bits;
- int cnt;
-{
- int i;
-
- for (i = (0x1 << (cnt - 1)); i; i >>= 1)
- dc_mii_writebit(sc, bits & i);
-}
-
-/*
- * Read an PHY register through the MII.
- */
-static int dc_mii_readreg(sc, frame)
- struct dc_softc *sc;
- struct dc_mii_frame *frame;
-
-{
- int i, ack, s;
-
-
- /*
- * Set up frame for RX.
- */
- frame->mii_stdelim = DC_MII_STARTDELIM;
- frame->mii_opcode = DC_MII_READOP;
- frame->mii_turnaround = 0;
- frame->mii_data = 0;
-
- /*
- * Sync the PHYs.
- */
- dc_mii_sync(sc);
-
- /*
- * Send command/address info.
- */
- dc_mii_send(sc, frame->mii_stdelim, 2);
- dc_mii_send(sc, frame->mii_opcode, 2);
- dc_mii_send(sc, frame->mii_phyaddr, 5);
- dc_mii_send(sc, frame->mii_regaddr, 5);
-
-#ifdef notdef
- /* Idle bit */
- dc_mii_writebit(sc, 1);
- dc_mii_writebit(sc, 0);
-#endif
-
- /* Check for ack */
- ack = dc_mii_readbit(sc);
-
- /*
- * Now try reading data bits. If the ack failed, we still
- * need to clock through 16 cycles to keep the PHY(s) in sync.
- */
- if (ack) {
- for(i = 0; i < 16; i++) {
- dc_mii_readbit(sc);
- }
- goto fail;
- }
-
- for (i = 0x8000; i; i >>= 1) {
- if (!ack) {
- if (dc_mii_readbit(sc))
- frame->mii_data |= i;
- }
- }
-
-fail:
-
- dc_mii_writebit(sc, 0);
- dc_mii_writebit(sc, 0);
-
-
- if (ack)
- return(1);
- return(0);
-}
-
-/*
- * Write to a PHY register through the MII.
- */
-static int dc_mii_writereg(sc, frame)
- struct dc_softc *sc;
- struct dc_mii_frame *frame;
-
-{
- int s;
-
- /*
- * Set up frame for TX.
- */
-
- frame->mii_stdelim = DC_MII_STARTDELIM;
- frame->mii_opcode = DC_MII_WRITEOP;
- frame->mii_turnaround = DC_MII_TURNAROUND;
-
- /*
- * Sync the PHYs.
- */
- dc_mii_sync(sc);
-
- dc_mii_send(sc, frame->mii_stdelim, 2);
- dc_mii_send(sc, frame->mii_opcode, 2);
- dc_mii_send(sc, frame->mii_phyaddr, 5);
- dc_mii_send(sc, frame->mii_regaddr, 5);
- dc_mii_send(sc, frame->mii_turnaround, 2);
- dc_mii_send(sc, frame->mii_data, 16);
-
- /* Idle bit. */
- dc_mii_writebit(sc, 0);
- dc_mii_writebit(sc, 0);
-
-
- return(0);
-}
-
-static int dc_miibus_readreg(dev, phy, reg)
- device_t dev;
- int phy, reg;
-{
- struct dc_mii_frame frame;
- struct dc_softc *sc;
- int i, rval, phy_reg = 0;
-
- sc = device_get_softc(dev);
- bzero((char *)&frame, sizeof(frame));
-
- /*
- * Note: both the AL981 and AN985 have internal PHYs,
- * however the AL981 provides direct access to the PHY
- * registers while the AN985 uses a serial MII interface.
- * The AN985's MII interface is also buggy in that you
- * can read from any MII address (0 to 31), but only address 1
- * behaves normally. To deal with both cases, we pretend
- * that the PHY is at MII address 1.
- */
- if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR)
- return(0);
-
- /*
- * Note: the ukphy probes of the RS7112 report a PHY at
- * MII address 0 (possibly HomePNA?) and 1 (ethernet)
- * so we only respond to correct one.
- */
- if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR)
- return(0);
-
- if (sc->dc_pmode != DC_PMODE_MII) {
- if (phy == (MII_NPHY - 1)) {
- switch(reg) {
- case MII_BMSR:
- /*
- * Fake something to make the probe
- * code think there's a PHY here.
- */
- return(BMSR_MEDIAMASK);
- break;
- case MII_PHYIDR1:
- if (DC_IS_PNIC(sc))
- return(DC_VENDORID_LO);
- return(DC_VENDORID_DEC);
- break;
- case MII_PHYIDR2:
- if (DC_IS_PNIC(sc))
- return(DC_DEVICEID_82C168);
- return(DC_DEVICEID_21143);
- break;
- default:
- return(0);
- break;
- }
- } else
- return(0);
- }
-
- if (DC_IS_PNIC(sc)) {
- CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_READ |
- (phy << 23) | (reg << 18));
- for (i = 0; i < DC_TIMEOUT; i++) {
- DELAY(1);
- rval = CSR_READ_4(sc, DC_PN_MII);
- if (!(rval & DC_PN_MII_BUSY)) {
- rval &= 0xFFFF;
- return(rval == 0xFFFF ? 0 : rval);
- }
- }
- return(0);
- }
-
- if (DC_IS_COMET(sc)) {
- switch(reg) {
- case MII_BMCR:
- phy_reg = DC_AL_BMCR;
- break;
- case MII_BMSR:
- phy_reg = DC_AL_BMSR;
- break;
- case MII_PHYIDR1:
- phy_reg = DC_AL_VENID;
- break;
- case MII_PHYIDR2:
- phy_reg = DC_AL_DEVID;
- break;
- case MII_ANAR:
- phy_reg = DC_AL_ANAR;
- break;
- case MII_ANLPAR:
- phy_reg = DC_AL_LPAR;
- break;
- case MII_ANER:
- phy_reg = DC_AL_ANER;
- break;
- default:
- printk("dc%d: phy_read: bad phy register %x\n",
- sc->dc_unit, reg);
- return(0);
- break;
- }
-
- rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF;
-
- if (rval == 0xFFFF)
- return(0);
- return(rval);
- }
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- if (sc->dc_type == DC_TYPE_98713) {
- phy_reg = CSR_READ_4(sc, DC_NETCFG);
- CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL);
- }
- dc_mii_readreg(sc, &frame);
- if (sc->dc_type == DC_TYPE_98713)
- CSR_WRITE_4(sc, DC_NETCFG, phy_reg);
-
- return(frame.mii_data);
-}
-
-static int dc_miibus_writereg(dev, phy, reg, data)
- device_t dev;
- int phy, reg, data;
-{
- struct dc_softc *sc;
- struct dc_mii_frame frame;
- int i, phy_reg = 0;
-
- sc = device_get_softc(dev);
- bzero((char *)&frame, sizeof(frame));
-
- if (DC_IS_ADMTEK(sc) && phy != DC_ADMTEK_PHYADDR)
- return(0);
-
- if (DC_IS_CONEXANT(sc) && phy != DC_CONEXANT_PHYADDR)
- return(0);
-
- if (DC_IS_PNIC(sc)) {
- CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE |
- (phy << 23) | (reg << 10) | data);
- for (i = 0; i < DC_TIMEOUT; i++) {
- if (!(CSR_READ_4(sc, DC_PN_MII) & DC_PN_MII_BUSY))
- break;
- }
- return(0);
- }
-
- if (DC_IS_COMET(sc)) {
- switch(reg) {
- case MII_BMCR:
- phy_reg = DC_AL_BMCR;
- break;
- case MII_BMSR:
- phy_reg = DC_AL_BMSR;
- break;
- case MII_PHYIDR1:
- phy_reg = DC_AL_VENID;
- break;
- case MII_PHYIDR2:
- phy_reg = DC_AL_DEVID;
- break;
- case MII_ANAR:
- phy_reg = DC_AL_ANAR;
- break;
- case MII_ANLPAR:
- phy_reg = DC_AL_LPAR;
- break;
- case MII_ANER:
- phy_reg = DC_AL_ANER;
- break;
- default:
- printk("dc%d: phy_write: bad phy register %x\n",
- sc->dc_unit, reg);
- return(0);
- break;
- }
-
- CSR_WRITE_4(sc, phy_reg, data);
- return(0);
- }
-
- frame.mii_phyaddr = phy;
- frame.mii_regaddr = reg;
- frame.mii_data = data;
-
- if (sc->dc_type == DC_TYPE_98713) {
- phy_reg = CSR_READ_4(sc, DC_NETCFG);
- CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL);
- }
- dc_mii_writereg(sc, &frame);
- if (sc->dc_type == DC_TYPE_98713)
- CSR_WRITE_4(sc, DC_NETCFG, phy_reg);
-
- return(0);
-}
-
-static void dc_miibus_statchg(dev)
- device_t dev;
-{
- struct dc_softc *sc;
- struct mii_data *mii;
- struct ifmedia *ifm;
-
- sc = device_get_softc(dev);
- if (DC_IS_ADMTEK(sc))
- return;
-
- mii = device_get_softc(sc->dc_miibus);
- ifm = &mii->mii_media;
- if (DC_IS_DAVICOM(sc) &&
- IFM_SUBTYPE(ifm->ifm_media) == IFM_homePNA) {
- dc_setcfg(sc, ifm->ifm_media);
- sc->dc_if_media = ifm->ifm_media;
- } else {
- dc_setcfg(sc, mii->mii_media_active);
- sc->dc_if_media = mii->mii_media_active;
- }
-
- return;
-}
-
-/*
- * Special support for DM9102A cards with HomePNA PHYs. Note:
- * with the Davicom DM9102A/DM9801 eval board that I have, it seems
- * to be impossible to talk to the management interface of the DM9801
- * PHY (its MDIO pin is not connected to anything). Consequently,
- * the driver has to just 'know' about the additional mode and deal
- * with it itself. *sigh*
- */
-static void dc_miibus_mediainit(dev)
- device_t dev;
-{
- struct dc_softc *sc;
- struct mii_data *mii;
- struct ifmedia *ifm;
- int rev;
-
- rev = pci_read_config(dev, DC_PCI_CFRV, 4) & 0xFF;
-
- sc = device_get_softc(dev);
- mii = device_get_softc(sc->dc_miibus);
- ifm = &mii->mii_media;
-
- if (DC_IS_DAVICOM(sc) && rev >= DC_REVISION_DM9102A)
- ifmedia_add(ifm, IFM_ETHER|IFM_homePNA, 0, NULL);
-
- return;
-}
-#endif
-
-#define DC_POLY 0xEDB88320
-#define DC_BITS_512 9
-#define DC_BITS_128 7
-#define DC_BITS_64 6
-
-static u_int32_t dc_crc_le(sc, addr)
- struct dc_softc *sc;
- caddr_t addr;
-{
- u_int32_t idx, bit, data, crc;
-
- /* Compute CRC for the address value. */
- crc = 0xFFFFFFFF; /* initial value */
-
- for (idx = 0; idx < 6; idx++) {
- for (data = *addr++, bit = 0; bit < 8; bit++, data >>= 1)
- crc = (crc >> 1) ^ (((crc ^ data) & 1) ? DC_POLY : 0);
- }
-
- /*
- * The hash table on the PNIC II and the MX98715AEC-C/D/E
- * chips is only 128 bits wide.
- */
- if (sc->dc_flags & DC_128BIT_HASH)
- return (crc & ((1 << DC_BITS_128) - 1));
-
- /* The hash table on the MX98715BEC is only 64 bits wide. */
- if (sc->dc_flags & DC_64BIT_HASH)
- return (crc & ((1 << DC_BITS_64) - 1));
-
- return (crc & ((1 << DC_BITS_512) - 1));
-}
-
-#ifndef UNUSED
-/*
- * Calculate CRC of a multicast group address, return the lower 6 bits.
- */
-static u_int32_t dc_crc_be(addr)
- caddr_t addr;
-{
- u_int32_t crc, carry;
- int i, j;
- u_int8_t c;
-
- /* Compute CRC for the address value. */
- crc = 0xFFFFFFFF; /* initial value */
-
- for (i = 0; i < 6; i++) {
- c = *(addr + i);
- for (j = 0; j < 8; j++) {
- carry = ((crc & 0x80000000) ? 1 : 0) ^ (c & 0x01);
- crc <<= 1;
- c >>= 1;
- if (carry)
- crc = (crc ^ 0x04c11db6) | carry;
- }
- }
-
- /* return the filter bit position */
- return((crc >> 26) & 0x0000003F);
-}
-#endif
-
-/*
- * 21143-style RX filter setup routine. Filter programming is done by
- * downloading a special setup frame into the TX engine. 21143, Macronix,
- * PNIC, PNIC II and Davicom chips are programmed this way.
- *
- * We always program the chip using 'hash perfect' mode, i.e. one perfect
- * address (our node address) and a 512-bit hash filter for multicast
- * frames. We also sneak the broadcast address into the hash filter since
- * we need that too.
- */
-void dc_setfilt_21143(sc)
- struct dc_softc *sc;
-{
- struct dc_desc *sframe;
- u_int32_t h, *sp;
- /*struct ifmultiaddr *ifma;*/
- struct ifnet *ifp;
- int i;
- u_int16_t *ac_enaddr;
-
- ifp = &sc->arpcom.ac_if;
-
- i = sc->dc_cdata.dc_tx_prod;
- DC_INC(sc->dc_cdata.dc_tx_prod, DC_TX_LIST_CNT);
- sc->dc_cdata.dc_tx_cnt++;
- sframe = &sc->dc_ldata->dc_tx_list[i];
- sp = (u_int32_t *)&sc->dc_cdata.dc_sbuf;
- bzero((char *)sp, DC_SFRAME_LEN);
-
- sframe->dc_data = vtophys(&sc->dc_cdata.dc_sbuf);
- sframe->dc_ctl = DC_SFRAME_LEN | DC_TXCTL_SETUP | DC_TXCTL_TLINK |
- DC_FILTER_HASHPERF | DC_TXCTL_FINT;
-
- sc->dc_cdata.dc_tx_chain[i] = (struct mbuf *)&sc->dc_cdata.dc_sbuf;
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
-
- if (ifp->if_flags & IFF_ALLMULTI)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
-#if 0
- for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
- ifma = ifma->ifma_link.le_next) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = dc_crc_le(sc,
- LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- sp[h >> 4] |= 1 << (h & 0xF);
- }
-#endif
-
- if (ifp->if_flags & IFF_BROADCAST) {
- h = dc_crc_le(sc, (caddr_t)&etherbroadcastaddr);
- sp[h >> 4] |= 1 << (h & 0xF);
- }
-
- /* Set our MAC address */
- ac_enaddr = (u_int16_t *)sc->arpcom.ac_enaddr;
- sp[39] = ac_enaddr[0];
- sp[40] = ac_enaddr[1];
- sp[41] = ac_enaddr[2];
-
- sframe->dc_status = DC_TXSTAT_OWN;
- CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
-
- /*
- * The PNIC takes an exceedingly long time to process its
- * setup frame; wait 10ms after posting the setup frame
- * before proceeding, just so it has time to swallow its
- * medicine.
- */
- DELAY(10000);
-
- ifp->if_timer = 5;
-
- return;
-}
-
-void dc_setfilt_admtek(sc)
- struct dc_softc *sc;
-{
- struct ifnet *ifp;
-#if 0
- int h = 0;
- u_int32_t hashes[2] = { 0, 0 };
- struct ifmultiaddr *ifma;
-#endif
- u_int32_t *ac_enaddr;
-
- ifp = &sc->arpcom.ac_if;
-
- /* Init our MAC address */
- ac_enaddr = (u_int32_t *)&sc->arpcom.ac_enaddr[0];
- CSR_WRITE_4(sc, DC_AL_PAR0, *ac_enaddr);
- ac_enaddr = (u_int32_t *)&sc->arpcom.ac_enaddr[4];
- CSR_WRITE_4(sc, DC_AL_PAR1, *ac_enaddr);
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
-
- if (ifp->if_flags & IFF_ALLMULTI)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
-
- /* first, zot all the existing hash bits */
- CSR_WRITE_4(sc, DC_AL_MAR0, 0);
- CSR_WRITE_4(sc, DC_AL_MAR1, 0);
-
-#if 0
- /*
- * If we're already in promisc or allmulti mode, we
- * don't have to bother programming the multicast filter.
- */
- if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
- return;
-
- /* now program new ones */
- for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
- ifma = ifma->ifma_link.le_next) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = dc_crc_be(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- }
-
- CSR_WRITE_4(sc, DC_AL_MAR0, hashes[0]);
- CSR_WRITE_4(sc, DC_AL_MAR1, hashes[1]);
-#endif
- return;
-}
-
-void dc_setfilt_asix(sc)
- struct dc_softc *sc;
-{
- struct ifnet *ifp;
-#if 0
- int h = 0;
- u_int32_t hashes[2] = { 0, 0 };
- struct ifmultiaddr *ifma;
-#endif
- u_int32_t *ac_enaddr;
-
- ifp = &sc->arpcom.ac_if;
-
- /* Init our MAC address */
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR0);
- ac_enaddr = (u_int32_t *)&sc->arpcom.ac_enaddr[0];
- CSR_WRITE_4(sc, DC_AX_FILTDATA, *ac_enaddr);
-
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_PAR1);
-
- ac_enaddr = (u_int32_t *)&sc->arpcom.ac_enaddr[4];
- CSR_WRITE_4(sc, DC_AX_FILTDATA, *ac_enaddr);
-
- /* If we want promiscuous mode, set the allframes bit. */
- if (ifp->if_flags & IFF_PROMISC)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_PROMISC);
-
- if (ifp->if_flags & IFF_ALLMULTI)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_RX_ALLMULTI);
-
- /*
- * The ASIX chip has a special bit to enable reception
- * of broadcast frames.
- */
- if (ifp->if_flags & IFF_BROADCAST)
- DC_SETBIT(sc, DC_NETCFG, DC_AX_NETCFG_RX_BROAD);
- else
- DC_CLRBIT(sc, DC_NETCFG, DC_AX_NETCFG_RX_BROAD);
-
- /* first, zot all the existing hash bits */
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0);
- CSR_WRITE_4(sc, DC_AX_FILTDATA, 0);
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR1);
- CSR_WRITE_4(sc, DC_AX_FILTDATA, 0);
-
-#if 0
- /*
- * If we're already in promisc or allmulti mode, we
- * don't have to bother programming the multicast filter.
- */
- if (ifp->if_flags & (IFF_PROMISC|IFF_ALLMULTI))
- return;
-
- /* now program new ones */
- for (ifma = ifp->if_multiaddrs.lh_first; ifma != NULL;
- ifma = ifma->ifma_link.le_next) {
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- h = dc_crc_be(LLADDR((struct sockaddr_dl *)ifma->ifma_addr));
- if (h < 32)
- hashes[0] |= (1 << h);
- else
- hashes[1] |= (1 << (h - 32));
- }
-
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR0);
- CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[0]);
- CSR_WRITE_4(sc, DC_AX_FILTIDX, DC_AX_FILTIDX_MAR1);
- CSR_WRITE_4(sc, DC_AX_FILTDATA, hashes[1]);
-#endif
- return;
-}
-
-static void dc_setfilt(sc)
- struct dc_softc *sc;
-{
- if (DC_IS_INTEL(sc) || DC_IS_MACRONIX(sc) || DC_IS_PNIC(sc) ||
- DC_IS_PNICII(sc) || DC_IS_DAVICOM(sc) || DC_IS_CONEXANT(sc))
- dc_setfilt_21143(sc);
-
- if (DC_IS_ASIX(sc))
- dc_setfilt_asix(sc);
-
- if (DC_IS_ADMTEK(sc))
- dc_setfilt_admtek(sc);
-
- return;
-}
-
-/*
- * In order to fiddle with the
- * 'full-duplex' and '100Mbps' bits in the netconfig register, we
- * first have to put the transmit and/or receive logic in the idle state.
- */
-static void dc_setcfg(sc, media)
- struct dc_softc *sc;
- int media;
-{
- int i, restart = 0;
- u_int32_t isr;
-
- if (IFM_SUBTYPE(media) == IFM_NONE)
- return;
-
- if (CSR_READ_4(sc, DC_NETCFG) & (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON)) {
- restart = 1;
- DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_TX_ON|DC_NETCFG_RX_ON));
-
- for (i = 0; i < DC_TIMEOUT; i++) {
- isr = CSR_READ_4(sc, DC_ISR);
- if (isr & DC_ISR_TX_IDLE ||
- (isr & DC_ISR_RX_STATE) == DC_RXSTATE_STOPPED)
- break;
- DELAY(10);
- }
-
- if (i == DC_TIMEOUT)
- printk("dc%d: failed to force tx and "
- "rx to idle state\n", sc->dc_unit);
- }
-
- if (IFM_SUBTYPE(media) == IFM_100_TX) {
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_SPEEDSEL);
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_HEARTBEAT);
- if (sc->dc_pmode == DC_PMODE_MII) {
- int watchdogreg;
-
- if (DC_IS_INTEL(sc)) {
- /* there's a write enable bit here that reads as 1 */
- watchdogreg = CSR_READ_4(sc, DC_WATCHDOG);
- watchdogreg &= ~DC_WDOG_CTLWREN;
- watchdogreg |= DC_WDOG_JABBERDIS;
- CSR_WRITE_4(sc, DC_WATCHDOG, watchdogreg);
- } else {
- DC_SETBIT(sc, DC_WATCHDOG, DC_WDOG_JABBERDIS);
- }
- DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
- DC_NETCFG_PORTSEL|DC_NETCFG_SCRAMBLER));
- if (sc->dc_type == DC_TYPE_98713)
- DC_SETBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
- DC_NETCFG_SCRAMBLER));
- if (!DC_IS_DAVICOM(sc))
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc, IFM_AUTO);
- } else {
- if (DC_IS_PNIC(sc)) {
- DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_SPEEDSEL);
- DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_100TX_LOOP);
- DC_SETBIT(sc, DC_PN_NWAY, DC_PN_NWAY_SPEEDSEL);
- }
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc,
- (media & IFM_GMASK) == IFM_FDX ?
- IFM_100_TX|IFM_FDX : IFM_100_TX);
- }
- }
-
- if (IFM_SUBTYPE(media) == IFM_10_T) {
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_SPEEDSEL);
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_HEARTBEAT);
- if (sc->dc_pmode == DC_PMODE_MII) {
- int watchdogreg;
-
- /* there's a write enable bit here that reads as 1 */
- if (DC_IS_INTEL(sc)) {
- watchdogreg = CSR_READ_4(sc, DC_WATCHDOG);
- watchdogreg &= ~DC_WDOG_CTLWREN;
- watchdogreg |= DC_WDOG_JABBERDIS;
- CSR_WRITE_4(sc, DC_WATCHDOG, watchdogreg);
- } else {
- DC_SETBIT(sc, DC_WATCHDOG, DC_WDOG_JABBERDIS);
- }
- DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_PCS|
- DC_NETCFG_PORTSEL|DC_NETCFG_SCRAMBLER));
- if (sc->dc_type == DC_TYPE_98713)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
- if (!DC_IS_DAVICOM(sc))
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
- if (DC_IS_INTEL(sc))
- dc_apply_fixup(sc, IFM_AUTO);
- } else {
- if (DC_IS_PNIC(sc)) {
- DC_PN_GPIO_CLRBIT(sc, DC_PN_GPIO_SPEEDSEL);
- DC_PN_GPIO_SETBIT(sc, DC_PN_GPIO_100TX_LOOP);
- DC_CLRBIT(sc, DC_PN_NWAY, DC_PN_NWAY_SPEEDSEL);
- }
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PCS);
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_SCRAMBLER);
- if (DC_IS_INTEL(sc)) {
- DC_CLRBIT(sc, DC_SIARESET, DC_SIA_RESET);
- DC_CLRBIT(sc, DC_10BTCTRL, 0xFFFF);
- if ((media & IFM_GMASK) == IFM_FDX)
- DC_SETBIT(sc, DC_10BTCTRL, 0x7F3D);
- else
- DC_SETBIT(sc, DC_10BTCTRL, 0x7F3F);
- DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
- DC_CLRBIT(sc, DC_10BTCTRL,
- DC_TCTL_AUTONEGENBL);
- dc_apply_fixup(sc,
- (media & IFM_GMASK) == IFM_FDX ?
- IFM_10_T|IFM_FDX : IFM_10_T);
- DELAY(20000);
- }
- }
- }
-
-#if 0
- /*
- * If this is a Davicom DM9102A card with a DM9801 HomePNA
- * PHY and we want HomePNA mode, set the portsel bit to turn
- * on the external MII port.
- */
- if (DC_IS_DAVICOM(sc)) {
- if (IFM_SUBTYPE(media) == IFM_homePNA) {
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- sc->dc_link = 1;
- } else {
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_PORTSEL);
- }
- }
-#endif
-
- if ((media & IFM_GMASK) == IFM_FDX) {
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
- if (sc->dc_pmode == DC_PMODE_SYM && DC_IS_PNIC(sc))
- DC_SETBIT(sc, DC_PN_NWAY, DC_PN_NWAY_DUPLEX);
- } else {
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_FULLDUPLEX);
- if (sc->dc_pmode == DC_PMODE_SYM && DC_IS_PNIC(sc))
- DC_CLRBIT(sc, DC_PN_NWAY, DC_PN_NWAY_DUPLEX);
- }
-
- if (restart)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON|DC_NETCFG_RX_ON);
-
- return;
-}
-
-static void dc_reset(sc)
- struct dc_softc *sc;
-{
- register int i;
-
- DC_SETBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
-
- for (i = 0; i < DC_TIMEOUT; i++) {
- DELAY(10);
- if (!(CSR_READ_4(sc, DC_BUSCTL) & DC_BUSCTL_RESET))
- break;
- }
-
- if (DC_IS_ASIX(sc) || DC_IS_ADMTEK(sc) || DC_IS_CONEXANT(sc)) {
- DELAY(10000);
- DC_CLRBIT(sc, DC_BUSCTL, DC_BUSCTL_RESET);
- i = 0;
- }
-
- if (i == DC_TIMEOUT)
- printk("dc%d: reset never completed!\n", sc->dc_unit);
-
- /* Wait a little while for the chip to get its brains in order. */
- DELAY(1000);
-
- CSR_WRITE_4(sc, DC_IMR, 0x00000000);
- CSR_WRITE_4(sc, DC_BUSCTL, 0x00000000);
- CSR_WRITE_4(sc, DC_NETCFG, 0x00000000);
-
- /*
- * Bring the SIA out of reset. In some cases, it looks
- * like failing to unreset the SIA soon enough gets it
- * into a state where it will never come out of reset
- * until we reset the whole chip again.
- */
- if (DC_IS_INTEL(sc)) {
- DC_SETBIT(sc, DC_SIARESET, DC_SIA_RESET);
- CSR_WRITE_4(sc, DC_10BTCTRL, 0);
- CSR_WRITE_4(sc, DC_WATCHDOG, 0);
- }
-
- return;
-}
-
-static
-struct dc_type *dc_devtype( int unitnum )
-{
- struct dc_type *t;
- uint32_t rev;
- int rc;
-
-
- t = dc_devs;
-
- while(t->dc_name != NULL) {
- rc = pci_find_device(t->dc_vid, t->dc_did, \
- (unitnum - 1), &t->dc_bus, &t->dc_dev, &t->dc_fun);
- if (rc == PCIB_ERR_SUCCESS) {
- /* Check the PCI revision */
- /*pcib_conf_read32(t->dc_devsig, DC_PCI_CFRV, &rev); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFRV, &rev);
- rev &= 0xFF;
-
- if (t->dc_did == DC_DEVICEID_98713 &&
- rev >= DC_REVISION_98713A)
- t++;
- if (t->dc_did == DC_DEVICEID_98713_CP &&
- rev >= DC_REVISION_98713A)
- t++;
- if (t->dc_did == DC_DEVICEID_987x5 &&
- rev >= DC_REVISION_98715AEC_C)
- t++;
- if (t->dc_did == DC_DEVICEID_987x5 &&
- rev >= DC_REVISION_98725)
- t++;
- if (t->dc_did == DC_DEVICEID_AX88140A &&
- rev >= DC_REVISION_88141)
- t++;
- if (t->dc_did == DC_DEVICEID_82C168 &&
- rev >= DC_REVISION_82C169)
- t++;
- if (t->dc_did == DC_DEVICEID_DM9102 &&
- rev >= DC_REVISION_DM9102A)
- t++;
- return(t);
- }
- t++;
- }
-
- return(NULL);
-}
-
-#if 0
-/*
- * Probe for a 21143 or clone chip. Check the PCI vendor and device
- * IDs against our list and return a device name if we find a match.
- * We do a little bit of extra work to identify the exact type of
- * chip. The MX98713 and MX98713A have the same PCI vendor/device ID,
- * but different revision IDs. The same is true for 98715/98715A
- * chips and the 98725, as well as the ASIX and ADMtek chips. In some
- * cases, the exact chip revision affects driver behavior.
- */
-static int dc_probe(dev)
- device_t dev;
-{
- struct dc_type *t;
-
- t = dc_devtype(dev);
-
- if (t != NULL) {
- device_set_desc(dev, t->dc_name);
- return(0);
- }
-
- return(ENXIO);
-}
-
-
-static void dc_acpi(dev)
- device_t dev;
-{
- u_int32_t r, cptr;
- int unit;
-
- unit = device_get_unit(dev);
-
- /* Find the location of the capabilities block */
- cptr = pci_read_config(dev, DC_PCI_CCAP, 4) & 0xFF;
-
- r = pci_read_config(dev, cptr, 4) & 0xFF;
- if (r == 0x01) {
-
- r = pci_read_config(dev, cptr + 4, 4);
- if (r & DC_PSTATE_D3) {
- u_int32_t iobase, membase, irq;
-
- /* Save important PCI config data. */
- iobase = pci_read_config(dev, DC_PCI_CFBIO, 4);
- membase = pci_read_config(dev, DC_PCI_CFBMA, 4);
- irq = pci_read_config(dev, DC_PCI_CFIT, 4);
-
- /* Reset the power state. */
- printk("dc%d: chip is in D%d power mode "
- "-- setting to D0\n", unit, r & DC_PSTATE_D3);
- r &= 0xFFFFFFFC;
- pci_write_config(dev, cptr + 4, r, 4);
-
- /* Restore PCI config data. */
- pci_write_config(dev, DC_PCI_CFBIO, iobase, 4);
- pci_write_config(dev, DC_PCI_CFBMA, membase, 4);
- pci_write_config(dev, DC_PCI_CFIT, irq, 4);
- }
- }
- return;
-}
-#endif
-
-
-static void dc_apply_fixup(sc, media)
- struct dc_softc *sc;
- int media;
-{
- struct dc_mediainfo *m;
- u_int8_t *p;
- int i;
- u_int32_t reg;
-
- m = sc->dc_mi;
-
- while (m != NULL) {
- if (m->dc_media == media)
- break;
- m = m->dc_next;
- }
-
- if (m == NULL)
- return;
-
- for (i = 0, p = m->dc_reset_ptr; i < m->dc_reset_len; i++, p += 2) {
- reg = (p[0] | (p[1] << 8)) << 16;
- CSR_WRITE_4(sc, DC_WATCHDOG, reg);
- }
-
- for (i = 0, p = m->dc_gp_ptr; i < m->dc_gp_len; i++, p += 2) {
- reg = (p[0] | (p[1] << 8)) << 16;
- CSR_WRITE_4(sc, DC_WATCHDOG, reg);
- }
-
- return;
-}
-
-#if 0
-static void dc_decode_leaf_sia(sc, l)
- struct dc_softc *sc;
- struct dc_eblock_sia *l;
-{
- struct dc_mediainfo *m;
-
- m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
- bzero(m, sizeof(struct dc_mediainfo));
- if (l->dc_sia_code == DC_SIA_CODE_10BT)
- m->dc_media = IFM_10_T;
-
- if (l->dc_sia_code == DC_SIA_CODE_10BT_FDX)
- m->dc_media = IFM_10_T|IFM_FDX;
-
- if (l->dc_sia_code == DC_SIA_CODE_10B2)
- m->dc_media = IFM_10_2;
-
- if (l->dc_sia_code == DC_SIA_CODE_10B5)
- m->dc_media = IFM_10_5;
-
- m->dc_gp_len = 2;
- m->dc_gp_ptr = (u_int8_t *)&l->dc_sia_gpio_ctl;
-
- m->dc_next = sc->dc_mi;
- sc->dc_mi = m;
-
- sc->dc_pmode = DC_PMODE_SIA;
-
- return;
-}
-
-static void dc_decode_leaf_sym(sc, l)
- struct dc_softc *sc;
- struct dc_eblock_sym *l;
-{
- struct dc_mediainfo *m;
-
- m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
- bzero(m, sizeof(struct dc_mediainfo));
- if (l->dc_sym_code == DC_SYM_CODE_100BT)
- m->dc_media = IFM_100_TX;
-
- if (l->dc_sym_code == DC_SYM_CODE_100BT_FDX)
- m->dc_media = IFM_100_TX|IFM_FDX;
-
- m->dc_gp_len = 2;
- m->dc_gp_ptr = (u_int8_t *)&l->dc_sym_gpio_ctl;
-
- m->dc_next = sc->dc_mi;
- sc->dc_mi = m;
-
- sc->dc_pmode = DC_PMODE_SYM;
-
- return;
-}
-
-static void dc_decode_leaf_mii(sc, l)
- struct dc_softc *sc;
- struct dc_eblock_mii *l;
-{
- u_int8_t *p;
- struct dc_mediainfo *m;
-
- m = malloc(sizeof(struct dc_mediainfo), M_DEVBUF, M_NOWAIT);
- bzero(m, sizeof(struct dc_mediainfo));
- /* We abuse IFM_AUTO to represent MII. */
- m->dc_media = IFM_AUTO;
- m->dc_gp_len = l->dc_gpr_len;
-
- p = (u_int8_t *)l;
- p += sizeof(struct dc_eblock_mii);
- m->dc_gp_ptr = p;
- p += 2 * l->dc_gpr_len;
- m->dc_reset_len = *p;
- p++;
- m->dc_reset_ptr = p;
-
- m->dc_next = sc->dc_mi;
- sc->dc_mi = m;
-
- return;
-}
-#endif
-
-static void dc_read_srom(sc, bits)
- struct dc_softc *sc;
- int bits;
-{
- int size;
-
- size = 2 << bits;
- sc->dc_srom = malloc(size, M_DEVBUF, M_NOWAIT);
- dc_read_eeprom(sc, (caddr_t)sc->dc_srom, 0, (size / 2), 0);
-}
-
-static void dc_parse_21143_srom(sc)
- struct dc_softc *sc;
-{
- struct dc_leaf_hdr *lhdr;
- struct dc_eblock_hdr *hdr;
- int i, loff;
- char *ptr;
-
- loff = sc->dc_srom[27];
- lhdr = (struct dc_leaf_hdr *)&(sc->dc_srom[loff]);
-
- ptr = (char *)lhdr;
- ptr += sizeof(struct dc_leaf_hdr) - 1;
- for (i = 0; i < lhdr->dc_mcnt; i++) {
- hdr = (struct dc_eblock_hdr *)ptr;
- switch(hdr->dc_type) {
-#if 0
- case DC_EBLOCK_MII:
- dc_decode_leaf_mii(sc, (struct dc_eblock_mii *)hdr);
- break;
- case DC_EBLOCK_SIA:
- dc_decode_leaf_sia(sc, (struct dc_eblock_sia *)hdr);
- break;
- case DC_EBLOCK_SYM:
- dc_decode_leaf_sym(sc, (struct dc_eblock_sym *)hdr);
- break;
-#endif
- default:
- /* Don't care. Yet. */
- break;
- }
- ptr += (hdr->dc_len & 0x7F);
- ptr++;
- }
-
- return;
-}
-
-
-static void
-nop(const rtems_irq_connect_data* unused)
-{
-}
-
-/*
- * Attach the interface. Allocate softc structures, do ifmedia
- * setup and ethernet/BPF attach.
- */
-int
-rtems_dc_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- int rc;
- u_char eaddr[ETHER_ADDR_LEN];
-
- char *unitName;
- int unitNumber;
-
- uint32_t command;
- struct dc_softc *sc;
- struct ifnet *ifp;
- struct dc_type *t;
- uint32_t revision;
- int error = 0, mac_offset;
- uint32_t value;
-
- /*
- * Get the instance number for the board we're going to configure
- * from the user.
- */
- unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName);
- if( unitNumber < 0) {
- return 0;
- }
- if( strcmp(unitName, DRIVER_PREFIX) ) {
- printk("dec2114x : unit name '%s' not %s\n", \
- unitName, DRIVER_PREFIX );
- return 0;
- }
-
- sc = &dc_softc_devs[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
-
- if(ifp->if_softc != NULL) {
- printk("dec2114x[%d]: unit number already in use.\n", \
- unitNumber);
- return (0);
- }
- memset(sc, 0, sizeof(struct dc_softc));
-
- /*unit = device_get_unit(dev);*/
- sc->dc_unit = unitNumber;
- sc->dc_name = unitName;
-
- /*
- * Handle power management nonsense.
- *
- dc_acpi(dev);
- */
-
- /* Scan for dec2114x cards in pci config space */
- if( (sc->dc_info = dc_devtype(unitNumber)) == NULL) {
- printk("Can't find any dec2114x NICs in PCI space.\n");
- return 0;
- }
- t = sc->dc_info;
-
-
- /*
- * Map control/status registers.
- */
- /*sig = sc->dc_info->dc_devsig; */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- PCI_COMMAND, &command);
- /*pcib_conf_read32(sig, PCI_COMMAND, &command); */
- command |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
- pci_write_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- PCI_COMMAND, command);
- /*pcib_conf_write32(sig, PCI_COMMAND, command); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- PCI_COMMAND, &command);
- /*pcib_conf_read32(sig, PCI_COMMAND, &command); */
-
-#ifdef DC_USEIOSPACE
- if (!(command & PCI_COMMAND_IO)) {
- printk("dc%d: failed to enable I/O ports!\n", sc->dc_unit);
- error = ENXIO;
- goto fail;
- }
-#else
- if (!(command & PCI_COMMAND_MEMORY)) {
- printk("dc%d: failed to enable memory mapping!\n", sc->dc_unit);
- error = ENXIO;
- goto fail;
- }
-#endif
-
-#if 0
- rid = DC_RID;
- sc->dc_res = bus_alloc_resource(dev, DC_RES, &rid,
- 0, ~0, 1, RF_ACTIVE);
-
- if (sc->dc_res == NULL) {
- printk("dc%d: couldn't map ports/memory\n", unit);
- error = ENXIO;
- goto fail;
- }
- sc->dc_btag = rman_get_bustag(sc->dc_res);
- sc->dc_bhandle = rman_get_bushandle(sc->dc_res);
-#endif
-
- /* sc->membase is the address of the card's CSRs !!! */
- /*pcib_conf_read32(sig, DC_PCI_CFBMA, &value); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFBMA, &value);
- sc->membase = value;
-
- /* Allocate interrupt */
- memset(&sc->irqInfo, 0, sizeof(rtems_irq_connect_data));
- /*pcib_conf_read32(sig, DC_PCI_CFIT, &value); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFIT, &value);
-
- sc->irqInfo.name = value & 0xFF;
- sc->irqInfo.hdl = (rtems_irq_hdl)dc_intr;
- sc->irqInfo.handle = (void *)sc; /* new parameter */
- sc->irqInfo.on = nop;
- sc->irqInfo.off = nop;
- sc->irqInfo.isOn = NULL;
-
-#ifdef BSP_SHARED_HANDLER_SUPPORT
- rc = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
-#else
- rc = BSP_install_rtems_irq_handler( &sc->irqInfo );
-#endif
- if(!rc) {
- rtems_panic("Can't install dec2114x irq handler.\n");
- }
-
-
-#if 0
- rid = 0;
- sc->dc_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE);
-
- if (sc->dc_irq == NULL) {
- printk("dc%d: couldn't map interrupt\n", unit);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- error = ENXIO;
- goto fail;
- }
-
- error = bus_setup_intr(dev, sc->dc_irq, INTR_TYPE_NET,
- dc_intr, sc, &sc->dc_intrhand);
-
- if (error) {
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- printk("dc%d: couldn't set up irq\n", unit);
- goto fail;
- }
-#endif
-
-
- /* Need this info to decide on a chip type.
- sc->dc_info = dc_devtype(dev);
- */
- /*pcib_conf_read32(sig, DC_PCI_CFRV, &revision); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFRV, &revision);
- revision &= 0x000000FF;
-
- /* Get the eeprom width, but PNIC has diff eeprom */
- if (sc->dc_info->dc_did != DC_DEVICEID_82C168)
- dc_eeprom_width(sc);
-
- switch(sc->dc_info->dc_did) {
- case DC_DEVICEID_21143:
- sc->dc_type = DC_TYPE_21143;
- sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
- sc->dc_flags |= DC_REDUCED_MII_POLL;
- /* Save EEPROM contents so we can parse them later. */
- dc_read_srom(sc, sc->dc_romwidth);
- break;
- case DC_DEVICEID_DM9009:
- case DC_DEVICEID_DM9100:
- case DC_DEVICEID_DM9102:
- sc->dc_type = DC_TYPE_DM9102;
- sc->dc_flags |= DC_TX_COALESCE|DC_TX_INTR_ALWAYS;
- sc->dc_flags |= DC_REDUCED_MII_POLL|DC_TX_STORENFWD;
- sc->dc_pmode = DC_PMODE_MII;
- /* Increase the latency timer value. */
- /*pcib_conf_read32(sig, DC_PCI_CFLT, &command); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFLT, &command);
- command &= 0xFFFF00FF;
- command |= 0x00008000;
- /*pcib_conf_write32(sig, DC_PCI_CFLT, command); */
- pci_write_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFLT, command);
- break;
- case DC_DEVICEID_AL981:
- sc->dc_type = DC_TYPE_AL981;
- sc->dc_flags |= DC_TX_USE_TX_INTR;
- sc->dc_flags |= DC_TX_ADMTEK_WAR;
- sc->dc_pmode = DC_PMODE_MII;
- dc_read_srom(sc, sc->dc_romwidth);
- break;
- case DC_DEVICEID_AN985:
- case DC_DEVICEID_EN2242:
- sc->dc_type = DC_TYPE_AN985;
- sc->dc_flags |= DC_TX_USE_TX_INTR;
- sc->dc_flags |= DC_TX_ADMTEK_WAR;
- sc->dc_pmode = DC_PMODE_MII;
- dc_read_srom(sc, sc->dc_romwidth);
- break;
- case DC_DEVICEID_98713:
- case DC_DEVICEID_98713_CP:
- if (revision < DC_REVISION_98713A) {
- sc->dc_type = DC_TYPE_98713;
- }
- if (revision >= DC_REVISION_98713A) {
- sc->dc_type = DC_TYPE_98713A;
- sc->dc_flags |= DC_21143_NWAY;
- }
- sc->dc_flags |= DC_REDUCED_MII_POLL;
- sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
- break;
- case DC_DEVICEID_987x5:
- case DC_DEVICEID_EN1217:
- /*
- * Macronix MX98715AEC-C/D/E parts have only a
- * 128-bit hash table. We need to deal with these
- * in the same manner as the PNIC II so that we
- * get the right number of bits out of the
- * CRC routine.
- */
- if (revision >= DC_REVISION_98715AEC_C &&
- revision < DC_REVISION_98725)
- sc->dc_flags |= DC_128BIT_HASH;
- sc->dc_type = DC_TYPE_987x5;
- sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
- sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
- break;
- case DC_DEVICEID_98727:
- sc->dc_type = DC_TYPE_987x5;
- sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
- sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
- break;
- case DC_DEVICEID_82C115:
- sc->dc_type = DC_TYPE_PNICII;
- sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR|DC_128BIT_HASH;
- sc->dc_flags |= DC_REDUCED_MII_POLL|DC_21143_NWAY;
- break;
- case DC_DEVICEID_82C168:
- sc->dc_type = DC_TYPE_PNIC;
- sc->dc_flags |= DC_TX_STORENFWD|DC_TX_INTR_ALWAYS;
- sc->dc_flags |= DC_PNIC_RX_BUG_WAR;
- sc->dc_pnic_rx_buf = malloc(DC_RXLEN * 5, M_DEVBUF, M_NOWAIT);
- if (revision < DC_REVISION_82C169)
- sc->dc_pmode = DC_PMODE_SYM;
- break;
- case DC_DEVICEID_AX88140A:
- sc->dc_type = DC_TYPE_ASIX;
- sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_INTR_FIRSTFRAG;
- sc->dc_flags |= DC_REDUCED_MII_POLL;
- sc->dc_pmode = DC_PMODE_MII;
- break;
- case DC_DEVICEID_RS7112:
- sc->dc_type = DC_TYPE_CONEXANT;
- sc->dc_flags |= DC_TX_INTR_ALWAYS;
- sc->dc_flags |= DC_REDUCED_MII_POLL;
- sc->dc_pmode = DC_PMODE_MII;
- dc_read_srom(sc, sc->dc_romwidth);
- break;
- default:
- printk("dc%d: unknown device: %x\n", sc->dc_unit,
- sc->dc_info->dc_did);
- break;
- }
-
- /* Save the cache line size. */
- if (DC_IS_DAVICOM(sc)) {
- sc->dc_cachesize = 0;
- }
- else {
- /*pcib_conf_read32(sig, DC_PCI_CFLT, &value); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFLT, &value);
- sc->dc_cachesize = (u_int8_t)(value & 0xFF);
- }
-
- /* Reset the adapter. */
- dc_reset(sc);
-
- /* Take 21143 out of snooze mode */
- if (DC_IS_INTEL(sc)) {
- /*pcib_conf_read32(sig, DC_PCI_CFDD, &command); */
- pci_read_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFDD, &command);
- command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
- /*pcib_conf_write32(sig, DC_PCI_CFDD, command); */
- pci_write_config_dword(t->dc_bus,t->dc_dev,t->dc_fun,\
- DC_PCI_CFDD, command);
- }
-
-
- /*
- * Try to learn something about the supported media.
- * We know that ASIX and ADMtek and Davicom devices
- * will *always* be using MII media, so that's a no-brainer.
- * The tricky ones are the Macronix/PNIC II and the
- * Intel 21143.
- */
- if (DC_IS_INTEL(sc))
- dc_parse_21143_srom(sc);
- else if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
- if (sc->dc_type == DC_TYPE_98713)
- sc->dc_pmode = DC_PMODE_MII;
- else
- sc->dc_pmode = DC_PMODE_SYM;
- } else if (!sc->dc_pmode)
- sc->dc_pmode = DC_PMODE_MII;
-
- /*
- * Get station address from the EEPROM.
- */
- switch(sc->dc_type) {
- case DC_TYPE_98713:
- case DC_TYPE_98713A:
- case DC_TYPE_987x5:
- case DC_TYPE_PNICII:
- dc_read_eeprom(sc, (caddr_t)&mac_offset,
- (DC_EE_NODEADDR_OFFSET / 2), 1, 0);
- dc_read_eeprom(sc, (caddr_t)&eaddr, (mac_offset / 2), 3, 0);
- break;
- case DC_TYPE_PNIC:
- dc_read_eeprom(sc, (caddr_t)&eaddr, 0, 3, 1);
- break;
- case DC_TYPE_DM9102:
- case DC_TYPE_21143:
- case DC_TYPE_ASIX:
- dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
- break;
- case DC_TYPE_AL981:
- case DC_TYPE_AN985:
- bcopy(&sc->dc_srom[DC_AL_EE_NODEADDR], (caddr_t)&eaddr,
- ETHER_ADDR_LEN);
- dc_read_eeprom(sc, (caddr_t)&eaddr, DC_AL_EE_NODEADDR, 3, 0);
- break;
- case DC_TYPE_CONEXANT:
- bcopy(sc->dc_srom + DC_CONEXANT_EE_NODEADDR, &eaddr, 6);
- break;
- default:
- dc_read_eeprom(sc, (caddr_t)&eaddr, DC_EE_NODEADDR, 3, 0);
- break;
- }
-
- /*
- * A 21143 or clone chip was detected. Inform the world.
- */
- bcopy(eaddr, (char *)&sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
- printk("dc%d: MAC address -- %02x:%02x:%02x:%02x:%02x:%02x\n", \
- sc->dc_unit,sc->arpcom.ac_enaddr[0], \
- sc->arpcom.ac_enaddr[1], sc->arpcom.ac_enaddr[2], \
- sc->arpcom.ac_enaddr[3], sc->arpcom.ac_enaddr[4], \
- sc->arpcom.ac_enaddr[5]);
-
-
- sc->dc_ldata = malloc(sizeof(struct dc_list_data), M_DEVBUF, M_NOWAIT);
-
- if (sc->dc_ldata == NULL) {
- printk("dc%d: no memory for list buffers!\n", sc->dc_unit);
- if (sc->dc_pnic_rx_buf != NULL)
- free(sc->dc_pnic_rx_buf, M_DEVBUF);
-#if 0
- bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
-#endif
- error = ENXIO;
- goto fail;
- }
-
- bzero(sc->dc_ldata, sizeof(struct dc_list_data));
-
- ifp = &sc->arpcom.ac_if;
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber; /*sc->dc_unit;*/
- ifp->if_name = unitName; /*sc->dc_name;*/
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX; /* | IFF_MULTICAST;*/
- ifp->if_ioctl = dc_ioctl;
- ifp->if_output = ether_output;
- ifp->if_start = dc_start;
- ifp->if_watchdog = dc_watchdog;
- ifp->if_init = dc_init;
- ifp->if_baudrate = 100000000;
- ifp->if_snd.ifq_maxlen = DC_TX_LIST_CNT - 1;
-
-#if 0
- /*
- * Do MII setup. If this is a 21143, check for a PHY on the
- * MII bus after applying any necessary fixups to twiddle the
- * GPIO bits. If we don't end up finding a PHY, restore the
- * old selection (SIA only or SIA/SYM) and attach the dcphy
- * driver instead.
- */
- if (DC_IS_INTEL(sc)) {
- dc_apply_fixup(sc, IFM_AUTO);
- tmp = sc->dc_pmode;
- sc->dc_pmode = DC_PMODE_MII;
- }
-
- error = mii_phy_probe(dev, &sc->dc_miibus,
- dc_ifmedia_upd, dc_ifmedia_sts);
-
- if (error && DC_IS_INTEL(sc)) {
- sc->dc_pmode = tmp;
- if (sc->dc_pmode != DC_PMODE_SIA)
- sc->dc_pmode = DC_PMODE_SYM;
- sc->dc_flags |= DC_21143_NWAY;
- mii_phy_probe(dev, &sc->dc_miibus,
- dc_ifmedia_upd, dc_ifmedia_sts);
- /*
- * For non-MII cards, we need to have the 21143
- * drive the LEDs. Except there are some systems
- * like the NEC VersaPro NoteBook PC which have no
- * LEDs, and twiddling these bits has adverse effects
- * on them. (I.e. you suddenly can't get a link.)
- */
- if (pci_read_config(dev, DC_PCI_CSID, 4) != 0x80281033)
- sc->dc_flags |= DC_TULIP_LEDS;
- error = 0;
- }
-
- if (error) {
- printk("dc%d: MII without any PHY!\n", sc->dc_unit);
- contigfree(sc->dc_ldata, sizeof(struct dc_list_data),
- M_DEVBUF);
- if (sc->dc_pnic_rx_buf != NULL)
- free(sc->dc_pnic_rx_buf, M_DEVBUF);
- bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
- error = ENXIO;
- goto fail;
- }
-#endif
-
- /*
- * Call MI attach routine.
- */
- if_attach(ifp);
- ether_ifattach(ifp);
- /*callout_handle_init(&sc->dc_stat_ch);*/
-
- if (DC_IS_ADMTEK(sc)) {
- /*
- * Set automatic TX underrun recovery for the ADMtek chips
- */
- DC_SETBIT(sc, DC_AL_CR, DC_AL_CR_ATUR);
- }
-
- if(sc->daemontid == 0) {
- sc->daemontid = rtems_bsdnet_newproc("decD",4096, \
- dc_daemon,(void *)sc);
- printk("dec[%d]: daemon process started\n", sc->dc_unit);
- }
-
- /*
- * Tell the upper layer(s) we support long frames.
- *
- ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
- */
-
-#ifdef SRM_MEDIA /* only defined if __alpha__ is defined... */
- sc->dc_srm_media = 0;
-
- /* Remember the SRM console media setting */
- if (DC_IS_INTEL(sc)) {
- command = pci_read_config(dev, DC_PCI_CFDD, 4);
- command &= ~(DC_CFDD_SNOOZE_MODE|DC_CFDD_SLEEP_MODE);
- switch ((command >> 8) & 0xff) {
- case 3:
- sc->dc_srm_media = IFM_10_T;
- break;
- case 4:
- sc->dc_srm_media = IFM_10_T | IFM_FDX;
- break;
- case 5:
- sc->dc_srm_media = IFM_100_TX;
- break;
- case 6:
- sc->dc_srm_media = IFM_100_TX | IFM_FDX;
- break;
- }
- if (sc->dc_srm_media)
- sc->dc_srm_media |= IFM_ACTIVE | IFM_ETHER;
- }
-#endif
-
-
-fail:
-
- return (1); /*(error);*/
-}
-
-#if 0
-static int dc_detach(dev)
- device_t dev;
-{
- struct dc_softc *sc;
- struct ifnet *ifp;
- int s;
- struct dc_mediainfo *m;
-
-
- sc = device_get_softc(dev);
- ifp = &sc->arpcom.ac_if;
-
- dc_stop(sc);
- ether_ifdetach(ifp, ETHER_BPF_SUPPORTED);
-
- bus_generic_detach(dev);
- device_delete_child(dev, sc->dc_miibus);
-
- bus_teardown_intr(dev, sc->dc_irq, sc->dc_intrhand);
- bus_release_resource(dev, SYS_RES_IRQ, 0, sc->dc_irq);
- bus_release_resource(dev, DC_RES, DC_RID, sc->dc_res);
-
- contigfree(sc->dc_ldata, sizeof(struct dc_list_data), M_DEVBUF);
- if (sc->dc_pnic_rx_buf != NULL)
- free(sc->dc_pnic_rx_buf, M_DEVBUF);
-
- while(sc->dc_mi != NULL) {
- m = sc->dc_mi->dc_next;
- free(sc->dc_mi, M_DEVBUF);
- sc->dc_mi = m;
- }
- free(sc->dc_srom, M_DEVBUF);
-
-
- return(0);
-}
-#endif
-
-
-/*
- * Initialize the transmit descriptors.
- */
-static int dc_list_tx_init(sc)
- struct dc_softc *sc;
-{
- struct dc_chain_data *cd;
- struct dc_list_data *ld;
- int i;
-
- cd = &sc->dc_cdata;
- ld = sc->dc_ldata;
- for (i = 0; i < DC_TX_LIST_CNT; i++) {
- if (i == (DC_TX_LIST_CNT - 1)) {
- ld->dc_tx_list[i].dc_next =
- vtophys(&ld->dc_tx_list[0]);
- } else {
- ld->dc_tx_list[i].dc_next =
- vtophys(&ld->dc_tx_list[i + 1]);
- }
- cd->dc_tx_chain[i] = NULL;
- ld->dc_tx_list[i].dc_data = 0;
- ld->dc_tx_list[i].dc_ctl = 0;
- }
-
- cd->dc_tx_prod = cd->dc_tx_cons = cd->dc_tx_cnt = 0;
-
- return(0);
-}
-
-
-/*
- * Initialize the RX descriptors and allocate mbufs for them. Note that
- * we arrange the descriptors in a closed ring, so that the last descriptor
- * points back to the first.
- */
-static int dc_list_rx_init(sc)
- struct dc_softc *sc;
-{
- struct dc_chain_data *cd;
- struct dc_list_data *ld;
- int i;
-
- cd = &sc->dc_cdata;
- ld = sc->dc_ldata;
-
- for (i = 0; i < DC_RX_LIST_CNT; i++) {
- if (dc_newbuf(sc, i, NULL) == ENOBUFS)
- return(ENOBUFS);
- if (i == (DC_RX_LIST_CNT - 1)) {
- ld->dc_rx_list[i].dc_next =
- vtophys(&ld->dc_rx_list[0]);
- } else {
- ld->dc_rx_list[i].dc_next =
- vtophys(&ld->dc_rx_list[i + 1]);
- }
- }
-
- cd->dc_rx_prod = 0;
-
- return(0);
-}
-
-/*
- * Initialize an RX descriptor and attach an MBUF cluster.
- */
-static int dc_newbuf(sc, i, m)
- struct dc_softc *sc;
- int i;
- struct mbuf *m;
-{
- struct mbuf *m_new = NULL;
- struct dc_desc *c;
-
- c = &sc->dc_ldata->dc_rx_list[i];
-
- if (m == NULL) {
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
- return(ENOBUFS);
-
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- m_freem(m_new);
- return(ENOBUFS);
- }
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- } else {
- m_new = m;
- m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
- m_new->m_data = m_new->m_ext.ext_buf;
- }
-
- m_adj(m_new, sizeof(u_int64_t));
-
- /*
- * If this is a PNIC chip, zero the buffer. This is part
- * of the workaround for the receive bug in the 82c168 and
- * 82c169 chips.
- */
- if (sc->dc_flags & DC_PNIC_RX_BUG_WAR)
- bzero((char *)mtod(m_new, char *), m_new->m_len);
-
- sc->dc_cdata.dc_rx_chain[i] = m_new;
- c->dc_data = vtophys(mtod(m_new, caddr_t));
- c->dc_ctl = DC_RXCTL_RLINK | DC_RXLEN;
- c->dc_status = DC_RXSTAT_OWN;
-
- return(0);
-}
-
-/*
- * Grrrrr.
- * The PNIC chip has a terrible bug in it that manifests itself during
- * periods of heavy activity. The exact mode of failure if difficult to
- * pinpoint: sometimes it only happens in promiscuous mode, sometimes it
- * will happen on slow machines. The bug is that sometimes instead of
- * uploading one complete frame during reception, it uploads what looks
- * like the entire contents of its FIFO memory. The frame we want is at
- * the end of the whole mess, but we never know exactly how much data has
- * been uploaded, so salvaging the frame is hard.
- *
- * There is only one way to do it reliably, and it's disgusting.
- * Here's what we know:
- *
- * - We know there will always be somewhere between one and three extra
- * descriptors uploaded.
- *
- * - We know the desired received frame will always be at the end of the
- * total data upload.
- *
- * - We know the size of the desired received frame because it will be
- * provided in the length field of the status word in the last descriptor.
- *
- * Here's what we do:
- *
- * - When we allocate buffers for the receive ring, we bzero() them.
- * This means that we know that the buffer contents should be all
- * zeros, except for data uploaded by the chip.
- *
- * - We also force the PNIC chip to upload frames that include the
- * ethernet CRC at the end.
- *
- * - We gather all of the bogus frame data into a single buffer.
- *
- * - We then position a pointer at the end of this buffer and scan
- * backwards until we encounter the first non-zero byte of data.
- * This is the end of the received frame. We know we will encounter
- * some data at the end of the frame because the CRC will always be
- * there, so even if the sender transmits a packet of all zeros,
- * we won't be fooled.
- *
- * - We know the size of the actual received frame, so we subtract
- * that value from the current pointer location. This brings us
- * to the start of the actual received packet.
- *
- * - We copy this into an mbuf and pass it on, along with the actual
- * frame length.
- *
- * The performance hit is tremendous, but it beats dropping frames all
- * the time.
- */
-
-#define DC_WHOLEFRAME (DC_RXSTAT_FIRSTFRAG|DC_RXSTAT_LASTFRAG)
-static void dc_pnic_rx_bug_war(sc, idx)
- struct dc_softc *sc;
- int idx;
-{
- struct dc_desc *cur_rx;
- struct dc_desc *c = NULL;
- struct mbuf *m = NULL;
- unsigned char *ptr;
- int i, total_len;
- u_int32_t rxstat = 0;
-
- i = sc->dc_pnic_rx_bug_save;
- cur_rx = &sc->dc_ldata->dc_rx_list[idx];
- ptr = sc->dc_pnic_rx_buf;
- bzero(ptr, sizeof(DC_RXLEN * 5));
-
- /* Copy all the bytes from the bogus buffers. */
- while (1) {
- c = &sc->dc_ldata->dc_rx_list[i];
- rxstat = c->dc_status;
- m = sc->dc_cdata.dc_rx_chain[i];
- bcopy(mtod(m, char *), ptr, DC_RXLEN);
- ptr += DC_RXLEN;
- /* If this is the last buffer, break out. */
- if (i == idx || rxstat & DC_RXSTAT_LASTFRAG)
- break;
- dc_newbuf(sc, i, m);
- DC_INC(i, DC_RX_LIST_CNT);
- }
-
- /* Find the length of the actual receive frame. */
- total_len = DC_RXBYTES(rxstat);
-
- /* Scan backwards until we hit a non-zero byte. */
- while(*ptr == 0x00)
- ptr--;
-#if 0
- /* Round off. */
- if ((uintptr_t)(ptr) & 0x3)
- ptr -= 1;
-#endif
-
- /* Now find the start of the frame. */
- ptr -= total_len;
- if (ptr < sc->dc_pnic_rx_buf)
- ptr = sc->dc_pnic_rx_buf;
-
- /*
- * Now copy the salvaged frame to the last mbuf and fake up
- * the status word to make it look like a successful
- * frame reception.
- */
- dc_newbuf(sc, i, m);
- bcopy(ptr, mtod(m, char *), total_len);
- cur_rx->dc_status = rxstat | DC_RXSTAT_FIRSTFRAG;
-
- return;
-}
-
-/*
- * This routine searches the RX ring for dirty descriptors in the
- * event that the rxeof routine falls out of sync with the chip's
- * current descriptor pointer. This may happen sometimes as a result
- * of a "no RX buffer available" condition that happens when the chip
- * consumes all of the RX buffers before the driver has a chance to
- * process the RX ring. This routine may need to be called more than
- * once to bring the driver back in sync with the chip, however we
- * should still be getting RX DONE interrupts to drive the search
- * for new packets in the RX ring, so we should catch up eventually.
- */
-static int dc_rx_resync(sc)
- struct dc_softc *sc;
-{
- int i, pos;
- struct dc_desc *cur_rx;
-
- pos = sc->dc_cdata.dc_rx_prod;
-
- for (i = 0; i < DC_RX_LIST_CNT; i++) {
- cur_rx = &sc->dc_ldata->dc_rx_list[pos];
- if (!(cur_rx->dc_status & DC_RXSTAT_OWN))
- break;
- DC_INC(pos, DC_RX_LIST_CNT);
- }
-
- /* If the ring really is empty, then just return. */
- if (i == DC_RX_LIST_CNT)
- return(0);
-
- /* We've fallen behing the chip: catch it. */
- sc->dc_cdata.dc_rx_prod = pos;
-
- return(EAGAIN);
-}
-
-/*
- * A frame has been uploaded: pass the resulting mbuf chain up to
- * the higher level protocols.
- */
-static void dc_rxeof(sc)
- struct dc_softc *sc;
-{
- struct ether_header *eh;
- struct mbuf *m;
- struct ifnet *ifp;
- struct dc_desc *cur_rx;
- int i, total_len = 0;
- u_int32_t rxstat;
-
- ifp = &sc->arpcom.ac_if;
- i = sc->dc_cdata.dc_rx_prod;
-
- while(!(sc->dc_ldata->dc_rx_list[i].dc_status & DC_RXSTAT_OWN)) {
-
-#ifdef DEVICE_POLLING
- if (ifp->if_ipending & IFF_POLLING) {
- if (sc->rxcycles <= 0)
- break;
- sc->rxcycles--;
- }
-#endif /* DEVICE_POLLING */
- cur_rx = &sc->dc_ldata->dc_rx_list[i];
- rxstat = cur_rx->dc_status;
- m = sc->dc_cdata.dc_rx_chain[i];
- total_len = DC_RXBYTES(rxstat);
-
- if (sc->dc_flags & DC_PNIC_RX_BUG_WAR) {
- if ((rxstat & DC_WHOLEFRAME) != DC_WHOLEFRAME) {
- if (rxstat & DC_RXSTAT_FIRSTFRAG)
- sc->dc_pnic_rx_bug_save = i;
- if ((rxstat & DC_RXSTAT_LASTFRAG) == 0) {
- DC_INC(i, DC_RX_LIST_CNT);
- continue;
- }
- dc_pnic_rx_bug_war(sc, i);
- rxstat = cur_rx->dc_status;
- total_len = DC_RXBYTES(rxstat);
- }
- }
-
- sc->dc_cdata.dc_rx_chain[i] = NULL;
-
- /*
- * If an error occurs, update stats, clear the
- * status word and leave the mbuf cluster in place:
- * it should simply get re-used next time this descriptor
- * comes up in the ring. However, don't report long
- * frames as errors since they could be vlans
- */
- if ((rxstat & DC_RXSTAT_RXERR)){
- if (!(rxstat & DC_RXSTAT_GIANT) ||
- (rxstat & (DC_RXSTAT_CRCERR | DC_RXSTAT_DRIBBLE |
- DC_RXSTAT_MIIERE | DC_RXSTAT_COLLSEEN |
- DC_RXSTAT_RUNT | DC_RXSTAT_DE))) {
- ifp->if_ierrors++;
- if (rxstat & DC_RXSTAT_COLLSEEN)
- ifp->if_collisions++;
- dc_newbuf(sc, i, m);
- if (rxstat & DC_RXSTAT_CRCERR) {
- DC_INC(i, DC_RX_LIST_CNT);
- continue;
- } else {
- dc_init(sc);
- return;
- }
- }
- }
-
- /* No errors; receive the packet. */
- total_len -= ETHER_CRC_LEN;
-
-#ifdef __i386__
- /*
- * On the x86 we do not have alignment problems, so try to
- * allocate a new buffer for the receive ring, and pass up
- * the one where the packet is already, saving the expensive
- * copy done in m_devget().
- * If we are on an architecture with alignment problems, or
- * if the allocation fails, then use m_devget and leave the
- * existing buffer in the receive ring.
- */
- if (dc_quick && dc_newbuf(sc, i, NULL) == 0) {
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = total_len;
- DC_INC(i, DC_RX_LIST_CNT);
- } else
-#endif
- {
- struct mbuf *m0;
-
- m0 = m_devget(mtod(m, char *) - ETHER_ALIGN,
- total_len + ETHER_ALIGN, 0, ifp, NULL);
- dc_newbuf(sc, i, m);
- DC_INC(i, DC_RX_LIST_CNT);
- if (m0 == NULL) {
- ifp->if_ierrors++;
- continue;
- }
- m_adj(m0, ETHER_ALIGN);
- m = m0;
- }
-
- ifp->if_ipackets++;
- eh = mtod(m, struct ether_header *);
-
- /* Remove header from mbuf and pass it on. */
- m_adj(m, sizeof(struct ether_header));
- ether_input(ifp, eh, m);
- }
-
- sc->dc_cdata.dc_rx_prod = i;
-}
-
-/*
- * A frame was downloaded to the chip. It's safe for us to clean up
- * the list buffers.
- */
-
-static void
-dc_txeof(sc)
- struct dc_softc *sc;
-{
- struct dc_desc *cur_tx = NULL;
- struct ifnet *ifp;
- int idx;
-
- ifp = &sc->arpcom.ac_if;
-
- /*
- * Go through our tx list and free mbufs for those
- * frames that have been transmitted.
- */
- idx = sc->dc_cdata.dc_tx_cons;
- while(idx != sc->dc_cdata.dc_tx_prod) {
- u_int32_t txstat;
-
- cur_tx = &sc->dc_ldata->dc_tx_list[idx];
- txstat = cur_tx->dc_status;
-
- if (txstat & DC_TXSTAT_OWN)
- break;
-
- if (!(cur_tx->dc_ctl & DC_TXCTL_LASTFRAG) ||
- cur_tx->dc_ctl & DC_TXCTL_SETUP) {
- if (cur_tx->dc_ctl & DC_TXCTL_SETUP) {
- /*
- * Yes, the PNIC is so brain damaged
- * that it will sometimes generate a TX
- * underrun error while DMAing the RX
- * filter setup frame. If we detect this,
- * we have to send the setup frame again,
- * or else the filter won't be programmed
- * correctly.
- */
- if (DC_IS_PNIC(sc)) {
- if (txstat & DC_TXSTAT_ERRSUM)
- dc_setfilt(sc);
- }
- sc->dc_cdata.dc_tx_chain[idx] = NULL;
- }
- sc->dc_cdata.dc_tx_cnt--;
- DC_INC(idx, DC_TX_LIST_CNT);
- continue;
- }
-
- if (DC_IS_CONEXANT(sc)) {
- /*
- * For some reason Conexant chips like
- * setting the CARRLOST flag even when
- * the carrier is there. In CURRENT we
- * have the same problem for Xircom
- * cards !
- */
- if (/*sc->dc_type == DC_TYPE_21143 &&*/
- sc->dc_pmode == DC_PMODE_MII &&
- ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM|
- DC_TXSTAT_NOCARRIER)))
- txstat &= ~DC_TXSTAT_ERRSUM;
- } else {
- if (/*sc->dc_type == DC_TYPE_21143 &&*/
- sc->dc_pmode == DC_PMODE_MII &&
- ((txstat & 0xFFFF) & ~(DC_TXSTAT_ERRSUM|
- DC_TXSTAT_NOCARRIER|DC_TXSTAT_CARRLOST)))
- txstat &= ~DC_TXSTAT_ERRSUM;
- }
-
- if (txstat & DC_TXSTAT_ERRSUM) {
- ifp->if_oerrors++;
- if (txstat & DC_TXSTAT_EXCESSCOLL)
- ifp->if_collisions++;
- if (txstat & DC_TXSTAT_LATECOLL)
- ifp->if_collisions++;
- if (!(txstat & DC_TXSTAT_UNDERRUN)) {
- dc_init(sc);
- return;
- }
- }
-
- ifp->if_collisions += (txstat & DC_TXSTAT_COLLCNT) >> 3;
-
- ifp->if_opackets++;
- if (sc->dc_cdata.dc_tx_chain[idx] != NULL) {
- m_freem(sc->dc_cdata.dc_tx_chain[idx]);
- sc->dc_cdata.dc_tx_chain[idx] = NULL;
- }
-
- sc->dc_cdata.dc_tx_cnt--;
- DC_INC(idx, DC_TX_LIST_CNT);
- }
-
- if (idx != sc->dc_cdata.dc_tx_cons) {
- /* some buffers have been freed */
- sc->dc_cdata.dc_tx_cons = idx;
- ifp->if_flags &= ~IFF_OACTIVE;
- }
- ifp->if_timer = (sc->dc_cdata.dc_tx_cnt == 0) ? 0 : 5;
-
- return;
-}
-
-
-#if 0
-static void dc_tick(xsc)
- void *xsc;
-{
- struct dc_softc *sc;
- /*struct mii_data *mii;*/
- struct ifnet *ifp;
- int s;
- u_int32_t r;
-
-
- sc = xsc;
- ifp = &sc->arpcom.ac_if;
- mii = device_get_softc(sc->dc_miibus);
-
- if (sc->dc_flags & DC_REDUCED_MII_POLL) {
- if (sc->dc_flags & DC_21143_NWAY) {
- r = CSR_READ_4(sc, DC_10BTSTAT);
- if (IFM_SUBTYPE(mii->mii_media_active) ==
- IFM_100_TX && (r & DC_TSTAT_LS100)) {
- sc->dc_link = 0;
- mii_mediachg(mii);
- }
- if (IFM_SUBTYPE(mii->mii_media_active) ==
- IFM_10_T && (r & DC_TSTAT_LS10)) {
- sc->dc_link = 0;
- mii_mediachg(mii);
- }
- if (sc->dc_link == 0)
- mii_tick(mii);
- } else {
- r = CSR_READ_4(sc, DC_ISR);
- if ((r & DC_ISR_RX_STATE) == DC_RXSTATE_WAIT &&
- sc->dc_cdata.dc_tx_cnt == 0)
- mii_tick(mii);
- if (!(mii->mii_media_status & IFM_ACTIVE))
- sc->dc_link = 0;
- }
- } else
- mii_tick(mii);
-
- /*
- * When the init routine completes, we expect to be able to send
- * packets right away, and in fact the network code will send a
- * gratuitous ARP the moment the init routine marks the interface
- * as running. However, even though the MAC may have been initialized,
- * there may be a delay of a few seconds before the PHY completes
- * autonegotiation and the link is brought up. Any transmissions
- * made during that delay will be lost. Dealing with this is tricky:
- * we can't just pause in the init routine while waiting for the
- * PHY to come ready since that would bring the whole system to
- * a screeching halt for several seconds.
- *
- * What we do here is prevent the TX start routine from sending
- * any packets until a link has been established. After the
- * interface has been initialized, the tick routine will poll
- * the state of the PHY until the IFM_ACTIVE flag is set. Until
- * that time, packets will stay in the send queue, and once the
- * link comes up, they will be flushed out to the wire.
- */
- if (!sc->dc_link) {
- mii_pollstat(mii);
- if (mii->mii_media_status & IFM_ACTIVE &&
- IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
- sc->dc_link++;
- if (ifp->if_snd.ifq_head != NULL)
- dc_start(ifp);
- }
- }
-
- if (sc->dc_flags & DC_21143_NWAY && !sc->dc_link)
- sc->dc_stat_ch = timeout(dc_tick, sc, hz/10);
- else
- sc->dc_stat_ch = timeout(dc_tick, sc, hz);
-
- return;
-}
-#endif
-
-/*
- * A transmit underrun has occurred. Back off the transmit threshold,
- * or switch to store and forward mode if we have to.
- */
-static void dc_tx_underrun(sc)
- struct dc_softc *sc;
-{
- u_int32_t isr;
- int i;
-
- if (DC_IS_DAVICOM(sc))
- dc_init(sc);
-
- if (DC_IS_INTEL(sc)) {
- /*
- * The real 21143 requires that the transmitter be idle
- * in order to change the transmit threshold or store
- * and forward state.
- */
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
-
- for (i = 0; i < DC_TIMEOUT; i++) {
- isr = CSR_READ_4(sc, DC_ISR);
- if (isr & DC_ISR_TX_IDLE)
- break;
- DELAY(10);
- }
- if (i == DC_TIMEOUT) {
- printk("dc%d: failed to force tx to idle state\n",
- sc->dc_unit);
- dc_init(sc);
- }
- }
-
- printk("dc%d: TX underrun -- ", sc->dc_unit);
- sc->dc_txthresh += DC_TXTHRESH_INC;
- if (sc->dc_txthresh > DC_TXTHRESH_MAX) {
- printk("using store and forward mode\n");
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
- } else {
- printk("increasing TX threshold\n");
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH);
- DC_SETBIT(sc, DC_NETCFG, sc->dc_txthresh);
- }
-
- if (DC_IS_INTEL(sc))
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
-
- return;
-}
-
-#ifdef DEVICE_POLLING
-static poll_handler_t dc_poll;
-
-static void
-dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
-{
- struct dc_softc *sc = ifp->if_softc;
-
- if (cmd == POLL_DEREGISTER) { /* final call, enable interrupts */
- /* Re-enable interrupts. */
- CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
- return;
- }
- sc->rxcycles = count;
- dc_rxeof(sc);
- dc_txeof(sc);
- if (ifp->if_snd.ifq_head != NULL && !(ifp->if_flags & IFF_OACTIVE))
- dc_start(ifp);
-
- if (cmd == POLL_AND_CHECK_STATUS) { /* also check status register */
- u_int32_t status;
-
- status = CSR_READ_4(sc, DC_ISR);
- status &= (DC_ISR_RX_WATDOGTIMEO|DC_ISR_RX_NOBUF|
- DC_ISR_TX_NOBUF|DC_ISR_TX_IDLE|DC_ISR_TX_UNDERRUN|
- DC_ISR_BUS_ERR);
- if (!status)
- return ;
- /* ack what we have */
- CSR_WRITE_4(sc, DC_ISR, status);
-
- if (status & (DC_ISR_RX_WATDOGTIMEO|DC_ISR_RX_NOBUF) ) {
- u_int32_t r = CSR_READ_4(sc, DC_FRAMESDISCARDED);
- ifp->if_ierrors += (r & 0xffff) + ((r >> 17) & 0x7ff);
-
- if (dc_rx_resync(sc))
- dc_rxeof(sc);
- }
- /* restart transmit unit if necessary */
- if (status & DC_ISR_TX_IDLE && sc->dc_cdata.dc_tx_cnt)
- CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
-
- if (status & DC_ISR_TX_UNDERRUN)
- dc_tx_underrun(sc);
-
- if (status & DC_ISR_BUS_ERR) {
- printk("dc_poll: dc%d bus error\n", sc->dc_unit);
- dc_reset(sc);
- dc_init(sc);
- }
- }
-}
-#endif /* DEVICE_POLLING */
-
-static void
-dc_intr(void* arg)
-{
- /* Need to make this work for multiple devices ... eventually */
- struct dc_softc *sc = (struct dc_softc *)arg;
-
-
- /* Disable interrupts. */
- CSR_WRITE_4(sc, DC_IMR, 0x00000000);
-
- rtems_bsdnet_event_send(sc->daemontid, IRQ_EVENT);
-#if 0
- if (sc->suspended) {
- return;
- }
-
- ifp = &sc->arpcom.ac_if;
-
-#ifdef DEVICE_POLLING
- if (ifp->if_ipending & IFF_POLLING)
- return;
- if (ether_poll_register(dc_poll, ifp)) { /* ok, disable interrupts */
- CSR_WRITE_4(sc, DC_IMR, 0x00000000);
- return;
- }
-#endif /* DEVICE_POLLING */
- if ( (CSR_READ_4(sc, DC_ISR) & DC_INTRS) == 0)
- return ;
-
- /* Suppress unwanted interrupts */
- if (!(ifp->if_flags & IFF_UP)) {
- if (CSR_READ_4(sc, DC_ISR) & DC_INTRS)
- dc_stop(sc);
- return;
- }
-#endif
-}
-
-
-static void
-dc_daemon(void * arg)
-{
- struct dc_softc *sc = (struct dc_softc *)arg;
- struct ifnet *ifp;
- u_int32_t status;
- rtems_event_set events;
-
-
- for(;;) {
- rtems_bsdnet_event_receive(RTEMS_ALL_EVENTS, \
- RTEMS_WAIT | RTEMS_EVENT_ANY, \
- RTEMS_NO_TIMEOUT,
- &events);
-
-
- ifp = &sc->arpcom.ac_if;
-
- while((status = CSR_READ_4(sc, DC_ISR)) & DC_INTRS) {
-
- CSR_WRITE_4(sc, DC_ISR, status);
-
- if (status & DC_ISR_RX_OK) {
- int curpkts;
- curpkts = ifp->if_ipackets;
- dc_rxeof(sc);
- if (curpkts == ifp->if_ipackets) {
- while(dc_rx_resync(sc))
- dc_rxeof(sc);
- }
- }
-
- if (status & (DC_ISR_TX_OK|DC_ISR_TX_NOBUF))
- dc_txeof(sc);
-
- if (status & DC_ISR_TX_IDLE) {
- dc_txeof(sc);
- if (sc->dc_cdata.dc_tx_cnt) {
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
- CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
- }
- }
-
- if (status & DC_ISR_TX_UNDERRUN)
- dc_tx_underrun(sc);
-
- if ((status & DC_ISR_RX_WATDOGTIMEO)
- || (status & DC_ISR_RX_NOBUF)) {
- int curpkts;
- curpkts = ifp->if_ipackets;
- dc_rxeof(sc);
- if (curpkts == ifp->if_ipackets) {
- while(dc_rx_resync(sc))
- dc_rxeof(sc);
- }
- }
-
- if (status & DC_ISR_BUS_ERR) {
- dc_reset(sc);
- dc_init(sc);
- }
- }
-
- /* Make atomic !!! */
- /* Re-enable interrupts. */
- CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
-
- if (ifp->if_snd.ifq_head != NULL)
- dc_start(ifp);
- }
-
-}
-
-
-/*
- * Encapsulate an mbuf chain in a descriptor by coupling the mbuf data
- * pointers to the fragment pointers.
- */
-static int dc_encap(sc, m_head, txidx)
- struct dc_softc *sc;
- struct mbuf *m_head;
- u_int32_t *txidx;
-{
- struct dc_desc *f = NULL;
- struct mbuf *m;
- int frag, cur, cnt = 0;
-
- /*
- * Start packing the mbufs in this chain into
- * the fragment pointers. Stop when we run out
- * of fragments or hit the end of the mbuf chain.
- */
- m = m_head;
- cur = frag = *txidx;
-
- for (m = m_head; m != NULL; m = m->m_next) {
- if (m->m_len != 0) {
- if (sc->dc_flags & DC_TX_ADMTEK_WAR) {
- if (*txidx != sc->dc_cdata.dc_tx_prod &&
- frag == (DC_TX_LIST_CNT - 1))
- return(ENOBUFS);
- }
- if ((DC_TX_LIST_CNT -
- (sc->dc_cdata.dc_tx_cnt + cnt)) < 5)
- return(ENOBUFS);
-
- f = &sc->dc_ldata->dc_tx_list[frag];
- f->dc_ctl = DC_TXCTL_TLINK | m->m_len;
- if (cnt == 0) {
- f->dc_status = 0;
- f->dc_ctl |= DC_TXCTL_FIRSTFRAG;
- } else
- f->dc_status = DC_TXSTAT_OWN;
- f->dc_data = vtophys(mtod(m, vm_offset_t));
- cur = frag;
- DC_INC(frag, DC_TX_LIST_CNT);
- cnt++;
- }
- }
-
- if (m != NULL)
- return(ENOBUFS);
-
- sc->dc_cdata.dc_tx_cnt += cnt;
- sc->dc_cdata.dc_tx_chain[cur] = m_head;
- sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_LASTFRAG;
- if (sc->dc_flags & DC_TX_INTR_FIRSTFRAG)
- sc->dc_ldata->dc_tx_list[*txidx].dc_ctl |= DC_TXCTL_FINT;
- if (sc->dc_flags & DC_TX_INTR_ALWAYS)
- sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
- if (sc->dc_flags & DC_TX_USE_TX_INTR && sc->dc_cdata.dc_tx_cnt > 64)
- sc->dc_ldata->dc_tx_list[cur].dc_ctl |= DC_TXCTL_FINT;
- sc->dc_ldata->dc_tx_list[*txidx].dc_status = DC_TXSTAT_OWN;
- *txidx = frag;
-
- return(0);
-}
-
-/*
- * Coalesce an mbuf chain into a single mbuf cluster buffer.
- * Needed for some really badly behaved chips that just can't
- * do scatter/gather correctly.
- */
-static int dc_coal(sc, m_head)
- struct dc_softc *sc;
- struct mbuf **m_head;
-{
- struct mbuf *m_new, *m;
-
- m = *m_head;
- MGETHDR(m_new, M_DONTWAIT, MT_DATA);
- if (m_new == NULL)
- return(ENOBUFS);
- if (m->m_pkthdr.len > MHLEN) {
- MCLGET(m_new, M_DONTWAIT);
- if (!(m_new->m_flags & M_EXT)) {
- m_freem(m_new);
- return(ENOBUFS);
- }
- }
- m_copydata(m, 0, m->m_pkthdr.len, mtod(m_new, caddr_t));
- m_new->m_pkthdr.len = m_new->m_len = m->m_pkthdr.len;
- m_freem(m);
- *m_head = m_new;
-
- return(0);
-}
-
-/*
- * Main transmit routine. To avoid having to do mbuf copies, we put pointers
- * to the mbuf data regions directly in the transmit lists. We also save a
- * copy of the pointers since the transmit list fragment pointers are
- * physical addresses.
- */
-
-static void dc_start(ifp)
- struct ifnet *ifp;
-{
- struct dc_softc *sc;
- struct mbuf *m_head = NULL;
- u_int32_t idx;
-
- sc = ifp->if_softc;
-#if 0
- if (!sc->dc_link && ifp->if_snd.ifq_len < 10)
- return;
-#endif
- if (ifp->if_flags & IFF_OACTIVE)
- return;
-
- idx = sc->dc_cdata.dc_tx_prod;
-
- while(sc->dc_cdata.dc_tx_chain[idx] == NULL) {
- IF_DEQUEUE(&ifp->if_snd, m_head);
- if (m_head == NULL)
- break;
-
- if (sc->dc_flags & DC_TX_COALESCE &&
- m_head->m_next != NULL) {
- /* only coalesce if have >1 mbufs */
- if (dc_coal(sc, &m_head)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
- }
-
- if (dc_encap(sc, m_head, &idx)) {
- IF_PREPEND(&ifp->if_snd, m_head);
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
-#if 0
- /*
- * If there's a BPF listener, bounce a copy of this frame
- * to him.
- */
- if (ifp->if_bpf)
- bpf_mtap(ifp, m_head);
-#endif
- if (sc->dc_flags & DC_TX_ONE) {
- ifp->if_flags |= IFF_OACTIVE;
- break;
- }
- }
-
- /* Transmit */
- sc->dc_cdata.dc_tx_prod = idx;
- if (!(sc->dc_flags & DC_TX_POLL))
- CSR_WRITE_4(sc, DC_TXSTART, 0xFFFFFFFF);
-
- /*
- * Set a timeout in case the chip goes out to lunch.
- */
- ifp->if_timer = 5;
-
- return;
-}
-
-static void dc_init(xsc)
- void *xsc;
-{
- struct dc_softc *sc = xsc;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- /*struct mii_data *mii;*/
-
-
- /*mii = device_get_softc(sc->dc_miibus);*/
-
- /*
- * Cancel pending I/O and free all RX/TX buffers.
- */
- dc_stop(sc);
- dc_reset(sc);
-
- /*
- * Set cache alignment and burst length.
- */
- if (DC_IS_ASIX(sc) || DC_IS_DAVICOM(sc))
- CSR_WRITE_4(sc, DC_BUSCTL, 0);
- else
- CSR_WRITE_4(sc, DC_BUSCTL, DC_BUSCTL_MRME|DC_BUSCTL_MRLE);
- /*
- * Evenly share the bus between receive and transmit process.
- */
- if (DC_IS_INTEL(sc))
- DC_SETBIT(sc, DC_BUSCTL, DC_BUSCTL_ARBITRATION);
- if (DC_IS_DAVICOM(sc) || DC_IS_INTEL(sc)) {
- DC_SETBIT(sc, DC_BUSCTL, DC_BURSTLEN_USECA);
- } else {
- DC_SETBIT(sc, DC_BUSCTL, DC_BURSTLEN_16LONG);
- }
- if (sc->dc_flags & DC_TX_POLL)
- DC_SETBIT(sc, DC_BUSCTL, DC_TXPOLL_1);
- switch(sc->dc_cachesize) {
- case 32:
- DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_32LONG);
- break;
- case 16:
- DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_16LONG);
- break;
- case 8:
- DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_8LONG);
- break;
- case 0:
- default:
- DC_SETBIT(sc, DC_BUSCTL, DC_CACHEALIGN_NONE);
- break;
- }
-
- if (sc->dc_flags & DC_TX_STORENFWD)
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
- else {
- if (sc->dc_txthresh > DC_TXTHRESH_MAX) {
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
- } else {
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_STORENFWD);
- DC_SETBIT(sc, DC_NETCFG, sc->dc_txthresh);
- }
- }
-
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_NO_RXCRC);
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_BACKOFF);
-
- if (DC_IS_MACRONIX(sc) || DC_IS_PNICII(sc)) {
- /*
- * The app notes for the 98713 and 98715A say that
- * in order to have the chips operate properly, a magic
- * number must be written to CSR16. Macronix does not
- * document the meaning of these bits so there's no way
- * to know exactly what they do. The 98713 has a magic
- * number all its own; the rest all use a different one.
- */
- DC_CLRBIT(sc, DC_MX_MAGICPACKET, 0xFFFF0000);
- if (sc->dc_type == DC_TYPE_98713)
- DC_SETBIT(sc, DC_MX_MAGICPACKET, DC_MX_MAGIC_98713);
- else
- DC_SETBIT(sc, DC_MX_MAGICPACKET, DC_MX_MAGIC_98715);
- }
-
- DC_CLRBIT(sc, DC_NETCFG, DC_NETCFG_TX_THRESH);
- DC_SETBIT(sc, DC_NETCFG, DC_TXTHRESH_MIN);
-
- /* Init circular RX list. */
- if (dc_list_rx_init(sc) == ENOBUFS) {
- printk("dc%d: initialization failed: no "
- "memory for rx buffers\n", sc->dc_unit);
- dc_stop(sc);
- return;
- }
-
- /*
- * Init tx descriptors.
- */
- dc_list_tx_init(sc);
-
- /*
- * Load the address of the RX list.
- */
- CSR_WRITE_4(sc, DC_RXADDR, vtophys(&sc->dc_ldata->dc_rx_list[0]));
- CSR_WRITE_4(sc, DC_TXADDR, vtophys(&sc->dc_ldata->dc_tx_list[0]));
-
- /*
- * Enable interrupts.
- */
-#ifdef DEVICE_POLLING
- /*
- * ... but only if we are not polling, and make sure they are off in
- * the case of polling. Some cards (e.g. fxp) turn interrupts on
- * after a reset.
- */
- if (ifp->if_ipending & IFF_POLLING)
- CSR_WRITE_4(sc, DC_IMR, 0x00000000);
- else
-#endif
- /* Enable interrupts */
- CSR_WRITE_4(sc, DC_IMR, DC_INTRS);
- CSR_WRITE_4(sc, DC_ISR, 0xFFFFFFFF);
-
- /* Enable transmitter. */
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_TX_ON);
-
- /*
- * If this is an Intel 21143 and we're not using the
- * MII port, program the LED control pins so we get
- * link and activity indications.
- */
- if (sc->dc_flags & DC_TULIP_LEDS) {
- CSR_WRITE_4(sc, DC_WATCHDOG,
- DC_WDOG_CTLWREN|DC_WDOG_LINK|DC_WDOG_ACTIVITY);
- CSR_WRITE_4(sc, DC_WATCHDOG, 0);
- }
-
- /*
- * Load the RX/multicast filter. We do this sort of late
- * because the filter programming scheme on the 21143 and
- * some clones requires DMAing a setup frame via the TX
- * engine, and we need the transmitter enabled for that.
- */
- dc_setfilt(sc);
-
- /* Enable receiver. */
- DC_SETBIT(sc, DC_NETCFG, DC_NETCFG_RX_ON);
- CSR_WRITE_4(sc, DC_RXSTART, 0xFFFFFFFF);
-
- /*mii_mediachg(mii);*/
- dc_setcfg(sc, sc->dc_if_media);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
-
-#if 0
-
- /* Don't start the ticker if this is a homePNA link. */
- if (IFM_SUBTYPE(mii->mii_media.ifm_media) == IFM_homePNA)
- sc->dc_link = 1;
- else {
- if (sc->dc_flags & DC_21143_NWAY)
- sc->dc_stat_ch = timeout(dc_tick, sc, hz/10);
- else
- sc->dc_stat_ch = timeout(dc_tick, sc, hz);
- }
-
-#ifdef SRM_MEDIA
- if(sc->dc_srm_media) {
- struct ifreq ifr;
-
- ifr.ifr_media = sc->dc_srm_media;
- ifmedia_ioctl(ifp, &ifr, &mii->mii_media, SIOCSIFMEDIA);
- sc->dc_srm_media = 0;
- }
-#endif
-#endif /* end if (0) */
- return;
-}
-
-
-#if 0
-/*
- * Set media options.
- */
-static int dc_ifmedia_upd(ifp)
- struct ifnet *ifp;
-{
- struct dc_softc *sc;
- struct mii_data *mii;
- struct ifmedia *ifm;
-
- sc = ifp->if_softc;
- mii = device_get_softc(sc->dc_miibus);
- mii_mediachg(mii);
- ifm = &mii->mii_media;
-
- if (DC_IS_DAVICOM(sc) &&
- IFM_SUBTYPE(ifm->ifm_media) == IFM_homePNA)
- dc_setcfg(sc, ifm->ifm_media);
- else
- sc->dc_link = 0;
-
- return(0);
-}
-
-/*
- * Report current media status.
- */
-static void dc_ifmedia_sts(ifp, ifmr)
- struct ifnet *ifp;
- struct ifmediareq *ifmr;
-{
- struct dc_softc *sc;
- struct mii_data *mii;
- struct ifmedia *ifm;
-
- sc = ifp->if_softc;
- mii = device_get_softc(sc->dc_miibus);
- mii_pollstat(mii);
- ifm = &mii->mii_media;
- if (DC_IS_DAVICOM(sc)) {
- if (IFM_SUBTYPE(ifm->ifm_media) == IFM_homePNA) {
- ifmr->ifm_active = ifm->ifm_media;
- ifmr->ifm_status = 0;
- return;
- }
- }
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-
- return;
-}
-#endif
-
-
-static int dc_ioctl(ifp, command, data)
- struct ifnet *ifp;
- ioctl_command_t command;
- caddr_t data;
-{
- struct dc_softc *sc = ifp->if_softc;
- /*struct ifreq *ifr = (struct ifreq *) data;
- struct mii_data *mii;*/
- int error = 0;
-
-
- switch(command) {
- case SIOCSIFADDR:
- case SIOCGIFADDR:
- case SIOCSIFMTU:
- error = ether_ioctl(ifp, command, data);
- break;
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_UP) {
- int need_setfilt = (ifp->if_flags ^ sc->dc_if_flags) &
- (IFF_PROMISC | IFF_ALLMULTI);
- if (ifp->if_flags & IFF_RUNNING) {
- if (need_setfilt)
- dc_setfilt(sc);
- } else {
- sc->dc_txthresh = 0;
- dc_init(sc);
- }
- } else {
- if (ifp->if_flags & IFF_RUNNING)
- dc_stop(sc);
- }
- sc->dc_if_flags = ifp->if_flags;
- error = 0;
- break;
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- dc_setfilt(sc);
- error = 0;
- break;
-#if 0
- case SIOCGIFMEDIA:
- case SIOCSIFMEDIA:
- mii = device_get_softc(sc->dc_miibus);
- error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
-#ifdef SRM_MEDIA
- if (sc->dc_srm_media)
- sc->dc_srm_media = 0;
-#endif
- break;
-#endif
- default:
- error = EINVAL;
- break;
- }
-
-
- return(error);
-}
-
-static void dc_watchdog(ifp)
- struct ifnet *ifp;
-{
- struct dc_softc *sc;
-
- sc = ifp->if_softc;
-
- ifp->if_oerrors++;
- printk("dc%d: watchdog timeout\n", sc->dc_unit);
-
- dc_stop(sc);
- dc_reset(sc);
- dc_init(sc);
-
- if (ifp->if_snd.ifq_head != NULL)
- dc_start(ifp);
-
- return;
-}
-
-/*
- * Stop the adapter and free any mbufs allocated to the
- * RX and TX lists.
- */
-static void dc_stop(sc)
- struct dc_softc *sc;
-{
- register int i;
- struct ifnet *ifp;
-
- ifp = &sc->arpcom.ac_if;
- ifp->if_timer = 0;
-
- /*untimeout(dc_tick, sc, sc->dc_stat_ch);*/
-
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
-#ifdef DEVICE_POLLING
- ether_poll_deregister(ifp);
-#endif
-
- DC_CLRBIT(sc, DC_NETCFG, (DC_NETCFG_RX_ON|DC_NETCFG_TX_ON));
- CSR_WRITE_4(sc, DC_IMR, 0x00000000);
- CSR_WRITE_4(sc, DC_TXADDR, 0x00000000);
- CSR_WRITE_4(sc, DC_RXADDR, 0x00000000);
- sc->dc_link = 0;
-
- /*
- * Free data in the RX lists.
- */
- for (i = 0; i < DC_RX_LIST_CNT; i++) {
- if (sc->dc_cdata.dc_rx_chain[i] != NULL) {
- m_freem(sc->dc_cdata.dc_rx_chain[i]);
- sc->dc_cdata.dc_rx_chain[i] = NULL;
- }
- }
- bzero((char *)&sc->dc_ldata->dc_rx_list,
- sizeof(sc->dc_ldata->dc_rx_list));
-
- /*
- * Free the TX list buffers.
- */
- for (i = 0; i < DC_TX_LIST_CNT; i++) {
- if (sc->dc_cdata.dc_tx_chain[i] != NULL) {
- if (sc->dc_ldata->dc_tx_list[i].dc_ctl &
- DC_TXCTL_SETUP) {
- sc->dc_cdata.dc_tx_chain[i] = NULL;
- continue;
- }
- m_freem(sc->dc_cdata.dc_tx_chain[i]);
- sc->dc_cdata.dc_tx_chain[i] = NULL;
- }
- }
-
- bzero((char *)&sc->dc_ldata->dc_tx_list,
- sizeof(sc->dc_ldata->dc_tx_list));
-
- return;
-}
-
-
-#if 0
-/*
- * Stop all chip I/O so that the kernel's probe routines don't
- * get confused by errant DMAs when rebooting.
- */
-static void dc_shutdown(dev)
- device_t dev;
-{
- struct dc_softc *sc;
-
- sc = device_get_softc(dev);
-
- dc_stop(sc);
-
- return;
-}
-
-/*
- * Device suspend routine. Stop the interface and save some PCI
- * settings in case the BIOS doesn't restore them properly on
- * resume.
- */
-static int dc_suspend(dev)
- device_t dev;
-{
- register int i;
- int s;
- struct dc_softc *sc;
-
-
- sc = device_get_softc(dev);
-
- dc_stop(sc);
-
- for (i = 0; i < 5; i++)
- sc->saved_maps[i] = pci_read_config(dev, PCIR_MAPS + i * 4, 4);
- sc->saved_biosaddr = pci_read_config(dev, PCIR_BIOS, 4);
- sc->saved_intline = pci_read_config(dev, PCIR_INTLINE, 1);
- sc->saved_cachelnsz = pci_read_config(dev, PCIR_CACHELNSZ, 1);
- sc->saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
-
- sc->suspended = 1;
-
- return (0);
-}
-
-/*
- * Device resume routine. Restore some PCI settings in case the BIOS
- * doesn't, re-enable busmastering, and restart the interface if
- * appropriate.
- */
-static int dc_resume(dev)
- device_t dev;
-{
- register int i;
- int s;
- struct dc_softc *sc;
- struct ifnet *ifp;
-
-
- sc = device_get_softc(dev);
- ifp = &sc->arpcom.ac_if;
-
- dc_acpi(dev);
-
- /* better way to do this? */
- for (i = 0; i < 5; i++)
- pci_write_config(dev, PCIR_MAPS + i * 4, sc->saved_maps[i], 4);
- pci_write_config(dev, PCIR_BIOS, sc->saved_biosaddr, 4);
- pci_write_config(dev, PCIR_INTLINE, sc->saved_intline, 1);
- pci_write_config(dev, PCIR_CACHELNSZ, sc->saved_cachelnsz, 1);
- pci_write_config(dev, PCIR_LATTIMER, sc->saved_lattimer, 1);
-
- /* reenable busmastering */
- pci_enable_busmaster(dev);
- pci_enable_io(dev, DC_RES);
-
- /* reinitialize interface if necessary */
- if (ifp->if_flags & IFF_UP)
- dc_init(sc);
-
- sc->suspended = 0;
-
- return (0);
-}
-#endif
-
-#endif /* end if supported */
diff --git a/c/src/libchip/network/if_fxp.c b/c/src/libchip/network/if_fxp.c
deleted file mode 100644
index 2fe9a5c403..0000000000
--- a/c/src/libchip/network/if_fxp.c
+++ /dev/null
@@ -1,2339 +0,0 @@
-/*-
- * Copyright (c) 1995, David Greenman
- * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice unmodified, this list of conditions, and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/dev/fxp/if_fxp.c,v 1.118 2001/09/05 23:33:58 brooks Exp $
- */
-
-/*
- * Intel EtherExpress Pro/100B PCI Fast Ethernet driver
- */
-
-/*
- * RTEMS Revision Preliminary History
- *
- * July XXX, 2002 W. Eric Norum <eric.norum@usask.ca>
- * Placed in RTEMS CVS repository. All further modifications will be
- * noted in the CVS log and not in this comment.
- *
- * July 11, 2002 W. Eric Norum <eric.norum@usask.ca>
- * Minor modifications to get driver working with NIC on VersaLogic
- * Bobcat PC-104 single-board computer. The Bobcat has no video
- * driver so printf/printk calls are directed to COM2:. This
- * arrangement seems to require delays after the printk calls or
- * else things lock up. Perhaps the RTEMS pc386 console code
- * should be modified to insert these delays itself.
- *
- * June 27, 2002 W. Eric Norum <eric.norum@usask.ca>
- * Obtained from Thomas Doerfler <Thomas.Doerfler@imd-systems.de>.
- * A big thank-you to Thomas for making this available.
- *
- * October 01, 2001 Thomas Doerfler <Thomas.Doerfler@imd-systems.de>
- * Original RTEMS modifications.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#if defined(__i386__)
-
-/*#define DEBUG_OUT 0*/
-
-#include <rtems.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <bsp.h>
-#include <inttypes.h>
-
-#include <errno.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 <sys/malloc.h>
-#include <sys/systm.h>
-#include <bsp.h>
-#include <bsp/irq.h>
-#include <bsp/irq-generic.h>
-#include <rtems/pci.h>
-
-#ifdef NS
-#include <netns/ns.h>
-#include <netns/ns_if.h>
-#endif
-
-#include <net/bpf.h>
-
-#include <vm/vm.h> /* for vtophys */
-
-#include <net/if_types.h>
-
-#include "if_fxpreg.h"
-#include <libchip/if_fxpvar.h>
-
-/*
- * some adaptation replacements for RTEMS
- */
-static rtems_interval fxp_ticksPerSecond;
-#define device_printf(device,format,args...) printk(format,## args)
-#define DELAY(n) rtems_task_wake_after(((n)*fxp_ticksPerSecond/1000000)+1)
-#ifdef DEBUG_OUT
-#define DBGLVL_PRINTK(LVL,format, args...) \
-if (DEBUG_OUT >= (LVL)) { \
- printk(format, ## args); \
-}
-#else
-#define DBGLVL_PRINTK(LVL,format, args...)
-#endif
-
-/*
- * RTEMS event used by interrupt handler to signal driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/*
- * remapping between PCI device and CPU memmory address view...
- */
-#if defined(__i386)
-#define vtophys(p) (u_int32_t)(p)
-#else
-#define vtophys(p) vtophys(p)
-#endif
-
-#define NFXPDRIVER 1
-static struct fxp_softc fxp_softc[NFXPDRIVER];
-static bool fxp_is_verbose = true;
-/*
- * NOTE! On the Alpha, we have an alignment constraint. The
- * card DMAs the packet immediately following the RFA. However,
- * the first thing in the packet is a 14-byte Ethernet header.
- * This means that the packet is misaligned. To compensate,
- * we actually offset the RFA 2 bytes into the cluster. This
- * alignes the packet after the Ethernet header at a 32-bit
- * boundary. HOWEVER! This means that the RFA is misaligned!
- */
-#define RFA_ALIGNMENT_FUDGE 2
-
-/*
- * Set initial transmit threshold at 64 (512 bytes). This is
- * increased by 64 (512 bytes) at a time, to maximum of 192
- * (1536 bytes), if an underrun occurs.
- */
-static int tx_threshold = 64;
-
-/*
- * The configuration byte map has several undefined fields which
- * must be one or must be zero. Set up a template for these bits
- * only, (assuming a 82557 chip) leaving the actual configuration
- * to fxp_init.
- *
- * See struct fxp_cb_config for the bit definitions.
- */
-static u_char fxp_cb_config_template[] = {
- 0x0, 0x0, /* cb_status */
- 0x0, 0x0, /* cb_command */
- 0x0, 0x0, 0x0, 0x0, /* link_addr */
- 0x0, /* 0 */
- 0x0, /* 1 */
- 0x0, /* 2 */
- 0x0, /* 3 */
- 0x0, /* 4 */
- 0x0, /* 5 */
- 0x32, /* 6 */
- 0x0, /* 7 */
- 0x0, /* 8 */
- 0x0, /* 9 */
- 0x6, /* 10 */
- 0x0, /* 11 */
- 0x0, /* 12 */
- 0x0, /* 13 */
- 0xf2, /* 14 */
- 0x48, /* 15 */
- 0x0, /* 16 */
- 0x40, /* 17 */
- 0xf0, /* 18 */
- 0x0, /* 19 */
- 0x3f, /* 20 */
- 0x5 /* 21 */
-};
-
-struct fxp_ident {
- u_int16_t devid;
- char *name;
- int warn;
-};
-
-#define UNTESTED 1
-
-/*
- * Claim various Intel PCI device identifiers for this driver. The
- * sub-vendor and sub-device field are extensively used to identify
- * particular variants, but we don't currently differentiate between
- * them.
- */
-static struct fxp_ident fxp_ident_table[] = {
- { 0x1229, "Intel Pro 10/100B/100+ Ethernet", 0 },
- { 0x2449, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1209, "Intel Embedded 10/100 Ethernet", 0 },
- { 0x1029, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1030, "Intel Pro/100 Ethernet", 0 },
- { 0x1031, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1032, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1033, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1034, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1035, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1036, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1037, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x1038, "Intel Pro/100 Ethernet", UNTESTED },
- { 0x103B, "Intel Pro/100 Ethernet (82801BD PRO/100 VM (LOM))", 0 },
- { 0, NULL, 0 }
-};
-
-#if 0
-static int fxp_probe(device_t dev);
-static int fxp_attach(device_t dev);
-static int fxp_detach(device_t dev);
-static int fxp_shutdown(device_t dev);
-#endif
-int fxp_output (struct ifnet *,
- struct mbuf *, struct sockaddr *, struct rtentry *);
-
-
-static void fxp_intr(void *arg);
-static void fxp_init(void *xsc);
-static void fxp_tick(void *xsc);
-static void fxp_start(struct ifnet *ifp);
-static void fxp_stop(struct fxp_softc *sc);
-static void fxp_release(struct fxp_softc *sc);
-static int fxp_ioctl(struct ifnet *ifp, ioctl_command_t command,
- caddr_t data);
-static void fxp_watchdog(struct ifnet *ifp);
-static int fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm);
-static void fxp_mc_setup(struct fxp_softc *sc);
-static u_int16_t fxp_eeprom_getword(struct fxp_softc *sc, int offset,
- int autosize);
-static void fxp_eeprom_putword(struct fxp_softc *sc, int offset,
- u_int16_t data);
-static void fxp_autosize_eeprom(struct fxp_softc *sc);
-static void fxp_read_eeprom(struct fxp_softc *sc, u_short *data,
- int offset, int words);
-static void fxp_write_eeprom(struct fxp_softc *sc, u_short *data,
- int offset, int words);
-#ifdef NOTUSED
-static int fxp_ifmedia_upd(struct ifnet *ifp);
-static void fxp_ifmedia_sts(struct ifnet *ifp,
- struct ifmediareq *ifmr);
-static int fxp_serial_ifmedia_upd(struct ifnet *ifp);
-static void fxp_serial_ifmedia_sts(struct ifnet *ifp,
- struct ifmediareq *ifmr);
-static volatile int fxp_miibus_readreg(device_t dev, int phy, int reg);
-static void fxp_miibus_writereg(device_t dev, int phy, int reg,
- int value);
-#endif
-static __inline void fxp_lwcopy(volatile u_int32_t *src,
- volatile u_int32_t *dst);
-static __inline void fxp_scb_wait(struct fxp_softc *sc);
-static __inline void fxp_scb_cmd(struct fxp_softc *sc, int cmd);
-static __inline void fxp_dma_wait(volatile u_int16_t *status,
- struct fxp_softc *sc);
-
-/*
- * Inline function to copy a 16-bit aligned 32-bit quantity.
- */
-static __inline void
-fxp_lwcopy(volatile u_int32_t *src, volatile u_int32_t *dst)
-{
-#ifdef __i386__
- *dst = *src;
-#else
- volatile u_int16_t *a = (volatile u_int16_t*)src;
- volatile u_int16_t *b = (volatile u_int16_t*)dst;
-
- b[0] = a[0];
- b[1] = a[1];
-#endif
-}
-
-/*
- * inline access functions to pci space registers
- */
-static __inline u_int8_t fxp_csr_read_1(struct fxp_softc *sc,int reg) {
- u_int8_t val;
- if (sc->pci_regs_are_io) {
- inport_byte(sc->pci_regs_base + reg,val);
- }
- else {
- val = *(volatile u_int8_t*)(sc->pci_regs_base+reg);
- }
- return val;
-}
-static __inline u_int32_t fxp_csr_read_2(struct fxp_softc *sc,int reg) {
- u_int16_t val;
- if (sc->pci_regs_are_io) {
- inport_word(sc->pci_regs_base + reg,val);
- }
- else {
- val = *(volatile u_int16_t*)(sc->pci_regs_base+reg);
- }
- return val;
-}
-static __inline u_int32_t fxp_csr_read_4(struct fxp_softc *sc,int reg) {
- u_int32_t val;
- if (sc->pci_regs_are_io) {
- inport_long(sc->pci_regs_base + reg,val);
- }
- else {
- val = *(volatile u_int32_t*)(sc->pci_regs_base+reg);
- }
- return val;
-}
-
-/*
- * Wait for the previous command to be accepted (but not necessarily
- * completed).
- */
-static __inline void
-fxp_scb_wait(struct fxp_softc *sc)
-{
- int i = 10000;
-
- while (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) && --i)
- DELAY(2);
- if (i == 0)
- device_printf(sc->dev, "SCB timeout: 0x%d 0x%d"
- "0x%d" PRIx32 "0x%" PRIx32 "\n",
- CSR_READ_1(sc, FXP_CSR_SCB_COMMAND),
- CSR_READ_1(sc, FXP_CSR_SCB_STATACK),
- CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS),
- CSR_READ_2(sc, FXP_CSR_FLOWCONTROL));
-}
-
-static __inline void
-fxp_scb_cmd(struct fxp_softc *sc, int cmd)
-{
-
- if (cmd == FXP_SCB_COMMAND_CU_RESUME && sc->cu_resume_bug) {
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, FXP_CB_COMMAND_NOP);
- fxp_scb_wait(sc);
- }
- CSR_WRITE_1(sc, FXP_CSR_SCB_COMMAND, cmd);
-}
-
-static __inline void
-fxp_dma_wait(volatile u_int16_t *status, struct fxp_softc *sc)
-{
- int i = 10000;
-
- while (!(*status & FXP_CB_STATUS_C) && --i)
- DELAY(2);
- if (i == 0)
- device_printf(sc->dev, "DMA timeout\n");
-}
-
-
-#define FXP_PCI_CONF_ACCESSOR(_confop, _baseop, _type) \
- \
- static inline int _confop ( \
- struct fxp_softc *sc, \
- int offset, \
- _type data ) \
- { \
- _baseop( \
- sc->pci_bus, \
- sc->pci_dev, \
- sc->pci_fun, \
- offset, \
- data \
- ); \
- return PCIB_ERR_SUCCESS; \
- }
-
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read8, pci_read_config_byte, uint8_t * );
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read16, pci_read_config_word, uint16_t * );
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_read32, pci_read_config_dword, uint32_t * );
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write8, pci_write_config_byte, uint8_t );
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write16, pci_write_config_word, uint16_t );
-FXP_PCI_CONF_ACCESSOR( fxp_pci_conf_write32, pci_write_config_dword, uint32_t );
-
-static __inline unsigned int fxp_pci_get_vendor(struct fxp_softc *sc) {
- u_int16_t vendor;
- fxp_pci_conf_read16(sc, PCI_VENDOR_ID, &vendor);
- return vendor;
-}
-
-static __inline unsigned int fxp_pci_get_device(struct fxp_softc *sc) {
- u_int16_t device;
- fxp_pci_conf_read16(sc, PCI_DEVICE_ID, &device);
- return device;
-}
-
-static __inline unsigned int fxp_pci_get_subvendor(struct fxp_softc *sc) {
- u_int16_t subvendor;
- fxp_pci_conf_read16(sc, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
- return subvendor;
-}
-
-static __inline unsigned int fxp_pci_get_subdevice(struct fxp_softc *sc) {
- u_int16_t subdevice;
- fxp_pci_conf_read16(sc, PCI_SUBSYSTEM_ID, &subdevice);
- return subdevice;
-}
-
-static __inline unsigned int fxp_pci_get_revid(struct fxp_softc *sc) {
- u_int8_t revid;
- fxp_pci_conf_read8(sc, PCI_REVISION_ID, &revid);
- return revid;
-}
-
-/* Prototype to avoid warning. This must be a global symbol. */
-int rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching);
-
-int
-rtems_fxp_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
-{
- int error = 0;
- struct fxp_softc *sc;
- struct ifnet *ifp;
- uint16_t val16;
- uint32_t val32;
- uint16_t data;
- int i;
- int s;
- int unitNumber;
- char *unitName;
- u_int16_t dev_id;
- u_int8_t interrupt;
- int mtu;
-
- /*
- * Set up some timing values
- */
- fxp_ticksPerSecond = rtems_clock_get_ticks_per_second();
- DBGLVL_PRINTK(1,"fxp_attach called\n");
-
- /*
- * Parse driver name
- */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber <= 0) || (unitNumber > NFXPDRIVER)) {
- device_printf(dev,"Bad FXP unit number.\n");
- return 0;
- }
- sc = &fxp_softc[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- device_printf(dev,"FXP Driver already in use.\n");
- return 0;
- }
-
- memset(sc, 0, sizeof(*sc));
-#ifdef NOTUSED
- sc->dev = dev;
- callout_handle_init(&sc->stat_ch);
- mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_DEF | MTX_RECURSE);
-#endif
- s = splimp();
-
- /*
- * find device on pci bus
- */
- { int j; int pbus, pdev, pfun;
-
- for (j=0; fxp_ident_table[j].devid; j++ ) {
- i = pci_find_device( 0x8086, fxp_ident_table[j].devid,
- unitNumber-1, &pbus, &pdev, &pfun );
- sc->pci_bus = pbus;
- sc->pci_dev = pdev;
- sc->pci_fun = pfun;
- DBGLVL_PRINTK(2,"fxp_attach: find_devid returned %d ,"
- "pci bus %d dev %d fun %d \n",
- i, sc->pci_bus, sc->pci_dev, sc->pci_fun);
- if (PCIB_ERR_SUCCESS == i) {
- if ( UNTESTED == fxp_ident_table[j].warn ) {
- device_printf(dev,
-"WARNING: this chip version has NOT been reported to work under RTEMS yet.\n");
- device_printf(dev,
-" If it works OK, report it as tested in 'c/src/libchip/network/if_fxp.c'\n");
- }
- break;
- }
- }
- }
-
- /*
- * FIXME: add search for more device types...
- */
- if (i != PCIB_ERR_SUCCESS) {
- device_printf(dev, "could not find 82559ER device\n");
- return 0;
- }
-
-
- /*
- * Enable bus mastering. Enable memory space too, in case
- * BIOS/Prom forgot about it.
- */
- fxp_pci_conf_read16(sc, PCI_COMMAND,&val16);
- val16 |= (PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER);
- fxp_pci_conf_write16(sc, PCI_COMMAND, val16);
- DBGLVL_PRINTK(3,"fxp_attach: PCI_COMMAND_write = 0x%x\n",val16);
- fxp_pci_conf_read16(sc, PCI_COMMAND,&val16);
- DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read = 0x%x\n",val16);
-
- /*
- * Figure out which we should try first - memory mapping or i/o mapping?
- * We default to memory mapping. Then we accept an override from the
- * command line. Then we check to see which one is enabled.
- */
-#ifdef NOTUSED
- m1 = PCI_COMMAND_MEMORY;
- m2 = PCI_COMMAND_IO;
- prefer_iomap = 0;
- if (resource_int_value(device_get_name(dev), device_get_unit(dev),
- "prefer_iomap", &prefer_iomap) == 0 && prefer_iomap != 0) {
- m1 = PCI_COMMAND_IO;
- m2 = PCI_COMMAND_MEMORY;
- }
-
- if (val & m1) {
- sc->rtp = ((m1 == PCI_COMMAND_MEMORY)
- ? SYS_RES_MEMORY : SYS_RES_IOPORT);
- sc->rgd = ((m1 == PCI_COMMAND_MEMORY)
- ? FXP_PCI_MMBA : FXP_PCI_IOBA);
- sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd,
- 0, ~0, 1, RF_ACTIVE);
- }
- if (sc->mem == NULL && (val & m2)) {
- sc->rtp = ((m2 == PCI_COMMAND_MEMORY)
- ? SYS_RES_MEMORY : SYS_RES_IOPORT);
- sc->rgd = ((m2 == PCI_COMMAND_MEMORY)
- ? FXP_PCI_MMBA : FXP_PCI_IOBA);
- sc->mem = bus_alloc_resource(dev, sc->rtp, &sc->rgd,
- 0, ~0, 1, RF_ACTIVE);
- }
-
- if (!sc->mem) {
- device_printf(dev, "could not map device registers\n");
- error = ENXIO;
- goto fail;
- }
- if (fxp_is_verbose) {
- device_printf(dev, "using %s space register mapping\n",
- sc->rtp == SYS_RES_MEMORY? "memory" : "I/O");
- }
-
- sc->sc_st = rman_get_bustag(sc->mem);
- sc->sc_sh = rman_get_bushandle(sc->mem);
-
- /*
- * Allocate our interrupt.
- */
- rid = 0;
- sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE);
- if (sc->irq == NULL) {
- device_printf(dev, "could not map interrupt\n");
- error = ENXIO;
- goto fail;
- }
-
- error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET,
- fxp_intr, sc, &sc->ih);
- if (error) {
- device_printf(dev, "could not setup irq\n");
- goto fail;
- }
-#endif
-
- /*
- * get mapping and base address of registers
- */
- fxp_pci_conf_read16(sc, PCI_COMMAND,&val16);
- DBGLVL_PRINTK(4,"fxp_attach: PCI_COMMAND_read = 0x%x\n",val16);
- if((val16 & PCI_COMMAND_IO) != 0) {
- sc->pci_regs_are_io = true;
- fxp_pci_conf_read32(sc, PCI_BASE_ADDRESS_1, &val32);
- sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_IO_MASK;
- }
- else {
- sc->pci_regs_are_io = false;
- fxp_pci_conf_read32(sc, PCI_BASE_ADDRESS_0, &val32);
- sc->pci_regs_base = val32 & PCI_BASE_ADDRESS_MEM_MASK;
- }
- DBGLVL_PRINTK(3,"fxp_attach: CSR registers are mapped in %s space"
- " at address 0x%x\n",
- sc->pci_regs_are_io ? "I/O" : "MEM",
- sc->pci_regs_base);
-
- /*
- * get interrupt level to be used
- */
- fxp_pci_conf_read8(sc, PCI_INTERRUPT_LINE, &interrupt);
- DBGLVL_PRINTK(3,"fxp_attach: interrupt = 0x%x\n",interrupt);
- sc->irq_num = interrupt;
- /*
- * Reset to a stable state.
- CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
- */
- CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
- DELAY(10);
-
- sc->cbl_base = malloc(sizeof(struct fxp_cb_tx) * FXP_NTXCB,
- M_DEVBUF, M_NOWAIT);
- DBGLVL_PRINTK(3,"fxp_attach: sc->cbl_base = 0x%x\n",sc->cbl_base);
- if (sc->cbl_base == NULL)
- goto failmem;
- else
- memset(sc->cbl_base, 0, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
-
- sc->fxp_stats = malloc(sizeof(struct fxp_stats), M_DEVBUF,
- M_NOWAIT);
- DBGLVL_PRINTK(3,"fxp_attach: sc->fxp_stats = 0x%x\n",sc->fxp_stats);
- if (sc->fxp_stats == NULL)
- goto failmem;
- else
- memset(sc->fxp_stats, 0, sizeof(struct fxp_stats));
-
- sc->mcsp = malloc(sizeof(struct fxp_cb_mcs), M_DEVBUF, M_NOWAIT);
- DBGLVL_PRINTK(3,"fxp_attach: sc->mcsp = 0x%x\n",sc->mcsp);
- if (sc->mcsp == NULL)
- goto failmem;
-
- /*
- * Pre-allocate our receive buffers.
- */
- for (i = 0; i < FXP_NRFABUFS; i++) {
- if (fxp_add_rfabuf(sc, NULL) != 0) {
- goto failmem;
- }
- }
-
- /*
- * Find out how large of an SEEPROM we have.
- */
- DBGLVL_PRINTK(3,"fxp_attach: calling fxp_autosize_eeprom\n");
- fxp_autosize_eeprom(sc);
-
- /*
- * Determine whether we must use the 503 serial interface.
- */
- fxp_read_eeprom(sc, &data, 6, 1);
- if ((data & FXP_PHY_DEVICE_MASK) != 0 &&
- (data & FXP_PHY_SERIAL_ONLY))
- sc->flags |= FXP_FLAG_SERIAL_MEDIA;
-
- /*
- * Find out the basic controller type; we currently only
- * differentiate between a 82557 and greater.
- */
- fxp_read_eeprom(sc, &data, 5, 1);
- if ((data >> 8) == 1)
- sc->chip = FXP_CHIP_82557;
- DBGLVL_PRINTK(3,"fxp_attach: sc->chip = %d\n",sc->chip);
-
- /*
- * Enable workarounds for certain chip revision deficiencies.
- *
- * Systems based on the ICH2/ICH2-M chip from Intel have a defect
- * where the chip can cause a PCI protocol violation if it receives
- * a CU_RESUME command when it is entering the IDLE state. The
- * workaround is to disable Dynamic Standby Mode, so the chip never
- * deasserts CLKRUN#, and always remains in an active state.
- *
- * See Intel 82801BA/82801BAM Specification Update, Errata #30.
- */
-#ifdef NOTUSED
- i = fxp_pci_get_device(dev);
-#else
- fxp_pci_conf_read16(sc, PCI_DEVICE_ID, &dev_id);
- DBGLVL_PRINTK(3,"fxp_attach: device id = 0x%x\n",dev_id);
-#endif
- if (dev_id == 0x2449 || (dev_id > 0x1030 && dev_id < 0x1039)) {
- device_printf(dev, "*** See Intel 82801BA/82801BAM Specification Update, Errata #30. ***\n");
- fxp_read_eeprom(sc, &data, 10, 1);
- if (data & 0x02) { /* STB enable */
- u_int16_t cksum;
- int i;
-
- device_printf(dev,
- "*** DISABLING DYNAMIC STANDBY MODE IN EEPROM ***\n");
- data &= ~0x02;
- fxp_write_eeprom(sc, &data, 10, 1);
- device_printf(dev, "New EEPROM ID: 0x%x\n", data);
- cksum = 0;
- for (i = 0; i < (1 << sc->eeprom_size) - 1; i++) {
- fxp_read_eeprom(sc, &data, i, 1);
- cksum += data;
- }
- i = (1 << sc->eeprom_size) - 1;
- cksum = 0xBABA - cksum;
- fxp_read_eeprom(sc, &data, i, 1);
- fxp_write_eeprom(sc, &cksum, i, 1);
- device_printf(dev,
- "EEPROM checksum @ 0x%x: 0x%x -> 0x%x\n",
- i, data, cksum);
- /*
- * We need to do a full PCI reset here. A software
- * reset to the port doesn't cut it, but let's try
- * anyway.
- */
- CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SOFTWARE_RESET);
- DELAY(50);
- device_printf(dev,
- "*** PLEASE REBOOT THE SYSTEM NOW FOR CORRECT OPERATION ***\n");
-#if 1
- /*
- * If the user elects to continue, try the software
- * workaround, as it is better than nothing.
- */
- sc->flags |= FXP_FLAG_CU_RESUME_BUG;
-#endif
- }
- }
-
- /*
- * If we are not a 82557 chip, we can enable extended features.
- */
- if (sc->chip != FXP_CHIP_82557) {
- u_int8_t tmp_val;
- /*
- * If MWI is enabled in the PCI configuration, and there
- * is a valid cacheline size (8 or 16 dwords), then tell
- * the board to turn on MWI.
- */
- fxp_pci_conf_read8(sc, PCI_CACHE_LINE_SIZE, &tmp_val);
- DBGLVL_PRINTK(3,"fxp_attach: CACHE_LINE_SIZE = %d\n",tmp_val);
- if (val16 & PCI_COMMAND_MEMORY &&
- tmp_val != 0)
- sc->flags |= FXP_FLAG_MWI_ENABLE;
-
- /* turn on the extended TxCB feature */
- sc->flags |= FXP_FLAG_EXT_TXCB;
-
- /* enable reception of long frames for VLAN */
- sc->flags |= FXP_FLAG_LONG_PKT_EN;
- DBGLVL_PRINTK(3,"fxp_attach: sc->flags = 0x%x\n",
- sc->flags);
- }
-
- /*
- * Read MAC address.
- */
- fxp_read_eeprom(sc, (u_int16_t*)sc->arpcom.ac_enaddr, 0, 3);
- if (fxp_is_verbose) {
- device_printf(dev, "Ethernet address %x:%x:%x:%x:%x:%x %s \n",
- ((u_int8_t*)sc->arpcom.ac_enaddr)[0],
- ((u_int8_t*)sc->arpcom.ac_enaddr)[1],
- ((u_int8_t*)sc->arpcom.ac_enaddr)[2],
- ((u_int8_t*)sc->arpcom.ac_enaddr)[3],
- ((u_int8_t*)sc->arpcom.ac_enaddr)[4],
- ((u_int8_t*)sc->arpcom.ac_enaddr)[5],
- sc->flags & FXP_FLAG_SERIAL_MEDIA ? ", 10Mbps" : "");
- device_printf(dev, "PCI IDs: 0x%x 0x%x 0x%x 0x%x 0x%x\n",
- fxp_pci_get_vendor(sc), fxp_pci_get_device(sc),
- fxp_pci_get_subvendor(sc), fxp_pci_get_subdevice(sc),
- fxp_pci_get_revid(sc));
- device_printf(dev, "Chip Type: %d\n", sc->chip);
- }
-
-#ifdef NOTUSED /* do not set up interface at all... */
- /*
- * If this is only a 10Mbps device, then there is no MII, and
- * the PHY will use a serial interface instead.
- *
- * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
- * doesn't have a programming interface of any sort. The
- * media is sensed automatically based on how the link partner
- * is configured. This is, in essence, manual configuration.
- */
- if (sc->flags & FXP_FLAG_SERIAL_MEDIA) {
- ifmedia_init(&sc->sc_media, 0, fxp_serial_ifmedia_upd,
- fxp_serial_ifmedia_sts);
- ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL);
- ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL);
- } else {
- if (mii_phy_probe(dev, &sc->miibus, fxp_ifmedia_upd,
- fxp_ifmedia_sts)) {
- device_printf(dev, "MII without any PHY!\n");
- error = ENXIO;
- goto fail;
- }
- }
-#endif
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_baudrate = 100000000;
- ifp->if_init = fxp_init;
- ifp->if_ioctl = fxp_ioctl;
- ifp->if_start = fxp_start;
- ifp->if_output = ether_output;
- ifp->if_watchdog = fxp_watchdog;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX /*| IFF_MULTICAST*/;
- if (ifp->if_snd.ifq_maxlen == 0)
- ifp->if_snd.ifq_maxlen = ifqmaxlen;
-
- /*
- * Attach the interface.
- */
- DBGLVL_PRINTK(3,"fxp_attach: calling if_attach\n");
- if_attach (ifp);
- DBGLVL_PRINTK(3,"fxp_attach: calling ether_if_attach\n");
- ether_ifattach(ifp);
- DBGLVL_PRINTK(3,"fxp_attach: return from ether_if_attach\n");
-
-#ifdef NOTUSED
- /*
- * Tell the upper layer(s) we support long frames.
- */
- ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header);
-#endif
- /*
- * Let the system queue as many packets as we have available
- * TX descriptors.
- */
- ifp->if_snd.ifq_maxlen = FXP_NTXCB - 1;
-
- splx(s);
- return (0);
-
-failmem:
- device_printf(dev, "Failed to malloc memory\n");
- error = ENOMEM;
-#ifdef NOTUSED
-fail:
-#endif
- splx(s);
- fxp_release(sc);
- return (error);
-}
-
-/*
- * release all resources
- */
-static void
-fxp_release(struct fxp_softc *sc)
-{
-
-#ifdef NOTUSED
- bus_generic_detach(sc->dev);
- if (sc->miibus)
- device_delete_child(sc->dev, sc->miibus);
-#endif
- if (sc->cbl_base)
- free(sc->cbl_base, M_DEVBUF);
- if (sc->fxp_stats)
- free(sc->fxp_stats, M_DEVBUF);
- if (sc->mcsp)
- free(sc->mcsp, M_DEVBUF);
- if (sc->rfa_headm)
- m_freem(sc->rfa_headm);
-
-#ifdef NOTUSED
- if (sc->ih)
- bus_teardown_intr(sc->dev, sc->irq, sc->ih);
- if (sc->irq)
- bus_release_resource(sc->dev, SYS_RES_IRQ, 0, sc->irq);
- if (sc->mem)
- bus_release_resource(sc->dev, sc->rtp, sc->rgd, sc->mem);
- mtx_destroy(&sc->sc_mtx);
-#endif
-}
-
-#if NOTUSED
-/*
- * Detach interface.
- */
-static int
-fxp_detach(device_t dev)
-{
- struct fxp_softc *sc = device_get_softc(dev);
- int s;
-
- /* disable interrupts */
- CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
-
- s = splimp();
-
- /*
- * Stop DMA and drop transmit queue.
- */
- fxp_stop(sc);
-
- /*
- * Close down routes etc.
- */
- ether_ifdetach(&sc->arpcom.ac_if, ETHER_BPF_SUPPORTED);
-
- /*
- * Free all media structures.
- */
- ifmedia_removeall(&sc->sc_media);
-
- splx(s);
-
- /* Release our allocated resources. */
- fxp_release(sc);
-
- return (0);
-}
-
-/*
- * Device shutdown routine. Called at system shutdown after sync. The
- * main purpose of this routine is to shut off receiver DMA so that
- * kernel memory doesn't get clobbered during warmboot.
- */
-static int
-fxp_shutdown(device_t dev)
-{
- /*
- * Make sure that DMA is disabled prior to reboot. Not doing
- * do could allow DMA to corrupt kernel memory during the
- * reboot before the driver initializes.
- */
- fxp_stop((struct fxp_softc *) device_get_softc(dev));
- return (0);
-}
-#endif
-
-/*
- * Show interface statistics
- */
-static void
-fxp_stats(struct fxp_softc *sc)
-{
- struct ifnet *ifp = &sc->sc_if;
-
- printf (" Output packets:%-8" PRIu64, ifp->if_opackets);
- printf (" Collisions:%-8" PRIu64, ifp->if_collisions);
- printf (" Output errors:%-8" PRIu64 "\n", ifp->if_oerrors);
- printf (" Input packets:%-8" PRIu64, ifp->if_ipackets);
- printf (" Input errors:%-8" PRIu64 "\n", ifp->if_ierrors);
-}
-
-static void
-fxp_eeprom_shiftin(struct fxp_softc *sc, int data, int length)
-{
- u_int16_t reg;
- int x;
-
- /*
- * Shift in data.
- */
- for (x = 1 << (length - 1); x; x >>= 1) {
- if (data & x)
- reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
- else
- reg = FXP_EEPROM_EECS;
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
- DELAY(1);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
- DELAY(1);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
- DELAY(1);
- }
-}
-
-/*
- * Read from the serial EEPROM. Basically, you manually shift in
- * the read opcode (one bit at a time) and then shift in the address,
- * and then you shift out the data (all of this one bit at a time).
- * The word size is 16 bits, so you have to provide the address for
- * every 16 bits of data.
- */
-static u_int16_t
-fxp_eeprom_getword(struct fxp_softc *sc, int offset, int autosize)
-{
- u_int16_t reg, data;
- int x;
-
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
- /*
- * Shift in read opcode.
- */
- fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_READ, 3);
- /*
- * Shift in address.
- */
- data = 0;
- for (x = 1 << (sc->eeprom_size - 1); x; x >>= 1) {
- if (offset & x)
- reg = FXP_EEPROM_EECS | FXP_EEPROM_EEDI;
- else
- reg = FXP_EEPROM_EECS;
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
- DELAY(1);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
- DELAY(1);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
- DELAY(1);
- reg = CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO;
- data++;
- if (autosize && reg == 0) {
- sc->eeprom_size = data;
- break;
- }
- }
- /*
- * Shift out data.
- */
- data = 0;
- reg = FXP_EEPROM_EECS;
- for (x = 1 << 15; x; x >>= 1) {
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg | FXP_EEPROM_EESK);
- DELAY(1);
- if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
- data |= x;
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, reg);
- DELAY(1);
- }
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
- DELAY(1);
-
- return (data);
-}
-
-static void
-fxp_eeprom_putword(struct fxp_softc *sc, int offset, u_int16_t data)
-{
- int i;
-
- /*
- * Erase/write enable.
- */
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
- fxp_eeprom_shiftin(sc, 0x4, 3);
- fxp_eeprom_shiftin(sc, 0x03 << (sc->eeprom_size - 2), sc->eeprom_size);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
- DELAY(1);
- /*
- * Shift in write opcode, address, data.
- */
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
- fxp_eeprom_shiftin(sc, FXP_EEPROM_OPC_WRITE, 3);
- fxp_eeprom_shiftin(sc, offset, sc->eeprom_size);
- fxp_eeprom_shiftin(sc, data, 16);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
- DELAY(1);
- /*
- * Wait for EEPROM to finish up.
- */
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
- DELAY(1);
- for (i = 0; i < 1000; i++) {
- if (CSR_READ_2(sc, FXP_CSR_EEPROMCONTROL) & FXP_EEPROM_EEDO)
- break;
- DELAY(50);
- }
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
- DELAY(1);
- /*
- * Erase/write disable.
- */
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, FXP_EEPROM_EECS);
- fxp_eeprom_shiftin(sc, 0x4, 3);
- fxp_eeprom_shiftin(sc, 0, sc->eeprom_size);
- CSR_WRITE_2(sc, FXP_CSR_EEPROMCONTROL, 0);
- DELAY(1);
-}
-
-/*
- * From NetBSD:
- *
- * Figure out EEPROM size.
- *
- * 559's can have either 64-word or 256-word EEPROMs, the 558
- * datasheet only talks about 64-word EEPROMs, and the 557 datasheet
- * talks about the existance of 16 to 256 word EEPROMs.
- *
- * The only known sizes are 64 and 256, where the 256 version is used
- * by CardBus cards to store CIS information.
- *
- * The address is shifted in msb-to-lsb, and after the last
- * address-bit the EEPROM is supposed to output a `dummy zero' bit,
- * after which follows the actual data. We try to detect this zero, by
- * probing the data-out bit in the EEPROM control register just after
- * having shifted in a bit. If the bit is zero, we assume we've
- * shifted enough address bits. The data-out should be tri-state,
- * before this, which should translate to a logical one.
- */
-static void
-fxp_autosize_eeprom(struct fxp_softc *sc)
-{
-
- /* guess maximum size of 256 words */
- sc->eeprom_size = 8;
-
- /* autosize */
- (void) fxp_eeprom_getword(sc, 0, 1);
-}
-
-static void
-fxp_read_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
-{
- int i;
-
- for (i = 0; i < words; i++) {
- data[i] = fxp_eeprom_getword(sc, offset + i, 0);
- DBGLVL_PRINTK(4,"fxp_eeprom_read(off=0x%x)=0x%x\n",
- offset+i,data[i]);
- }
-}
-
-static void
-fxp_write_eeprom(struct fxp_softc *sc, u_short *data, int offset, int words)
-{
- int i;
-
- for (i = 0; i < words; i++)
- fxp_eeprom_putword(sc, offset + i, data[i]);
- DBGLVL_PRINTK(4,"fxp_eeprom_write(off=0x%x,0x%x)\n",
- offset+i,data[i]);
-}
-
-/*
- * Start packet transmission on the interface.
- */
-static void
-fxp_start(struct ifnet *ifp)
-{
- struct fxp_softc *sc = ifp->if_softc;
- struct fxp_cb_tx *txp;
-
- DBGLVL_PRINTK(3,"fxp_start called\n");
-
- /*
- * See if we need to suspend xmit until the multicast filter
- * has been reprogrammed (which can only be done at the head
- * of the command chain).
- */
- if (sc->need_mcsetup) {
- DBGLVL_PRINTK(3,"fxp_start need_mcsetup\n");
- return;
- }
-
- txp = NULL;
-
- /*
- * We're finished if there is nothing more to add to the list or if
- * we're all filled up with buffers to transmit.
- * NOTE: One TxCB is reserved to guarantee that fxp_mc_setup() can add
- * a NOP command when needed.
- */
- while (ifp->if_snd.ifq_head != NULL && sc->tx_queued < FXP_NTXCB - 1) {
- struct mbuf *m, *mb_head;
- int segment;
-
- /*
- * Grab a packet to transmit.
- */
- IF_DEQUEUE(&ifp->if_snd, mb_head);
-
- /*
- * Get pointer to next available tx desc.
- */
- txp = sc->cbl_last->next;
-
- /*
- * Go through each of the mbufs in the chain and initialize
- * the transmit buffer descriptors with the physical address
- * and size of the mbuf.
- */
-tbdinit:
- for (m = mb_head, segment = 0; m != NULL; m = m->m_next) {
- if (m->m_len != 0) {
- if (segment == FXP_NTXSEG)
- break;
- txp->tbd[segment].tb_addr =
- vtophys(mtod(m, vm_offset_t));
- txp->tbd[segment].tb_size = m->m_len;
- segment++;
- }
- }
- if (m != NULL) {
- struct mbuf *mn;
-
- /*
- * We ran out of segments. We have to recopy this
- * mbuf chain first. Bail out if we can't get the
- * new buffers.
- */
- MGETHDR(mn, M_DONTWAIT, MT_DATA);
- if (mn == NULL) {
- m_freem(mb_head);
- break;
- }
- if (mb_head->m_pkthdr.len > MHLEN) {
- MCLGET(mn, M_DONTWAIT);
- if ((mn->m_flags & M_EXT) == 0) {
- m_freem(mn);
- m_freem(mb_head);
- break;
- }
- }
- m_copydata(mb_head, 0, mb_head->m_pkthdr.len,
- mtod(mn, caddr_t));
- mn->m_pkthdr.len = mn->m_len = mb_head->m_pkthdr.len;
- m_freem(mb_head);
- mb_head = mn;
- goto tbdinit;
- }
-
- txp->tbd_number = segment;
- txp->mb_head = mb_head;
- txp->cb_status = 0;
- if (sc->tx_queued != FXP_CXINT_THRESH - 1) {
- txp->cb_command =
- FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF |
- FXP_CB_COMMAND_S;
- } else {
- txp->cb_command =
- FXP_CB_COMMAND_XMIT | FXP_CB_COMMAND_SF |
- FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
- /*
- * Set a 5 second timer just in case we don't hear
- * from the card again.
- */
- ifp->if_timer = 5;
- }
- txp->tx_threshold = tx_threshold;
-
- /*
- * Advance the end of list forward.
- */
-
-#ifdef __alpha__
- /*
- * On platforms which can't access memory in 16-bit
- * granularities, we must prevent the card from DMA'ing
- * up the status while we update the command field.
- * This could cause us to overwrite the completion status.
- */
- atomic_clear_short(&sc->cbl_last->cb_command,
- FXP_CB_COMMAND_S);
-#else
- sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
-#endif /*__alpha__*/
- sc->cbl_last = txp;
-
- /*
- * Advance the beginning of the list forward if there are
- * no other packets queued (when nothing is queued, cbl_first
- * sits on the last TxCB that was sent out).
- */
- if (sc->tx_queued == 0)
- sc->cbl_first = txp;
-
- sc->tx_queued++;
-
-#ifdef NOTUSED
- /*
- * Pass packet to bpf if there is a listener.
- */
- if (ifp->if_bpf)
- bpf_mtap(ifp, mb_head);
-#endif
- }
-
- /*
- * We're finished. If we added to the list, issue a RESUME to get DMA
- * going again if suspended.
- */
- if (txp != NULL) {
- fxp_scb_wait(sc);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
- }
-
- /*
- * reenable interrupts
- */
- RTEMS_COMPILER_MEMORY_BARRIER();
- CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0);
- bsp_interrupt_vector_enable(sc->irq_num);
- RTEMS_COMPILER_MEMORY_BARRIER();
-}
-
-/*
- * Process interface interrupts.
- */
-static void fxp_intr(void *arg)
-{
- /*
- * Obtain device state
- */
- struct fxp_softc *sc = (struct fxp_softc *)arg;
-
- /*
- * disable interrupts
- */
- CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, FXP_SCB_INTR_DISABLE);
- /*
- * send event to deamon
- */
- rtems_bsdnet_event_send (sc->daemonTid, INTERRUPT_EVENT);
-}
-
-static void fxp_daemon(void *xsc)
-{
- struct fxp_softc *sc = xsc;
- struct ifnet *ifp = &sc->sc_if;
- u_int8_t statack;
- rtems_event_set events;
-
-#ifdef NOTUSED
- if (sc->suspended) {
- return;
- }
-#endif
- for (;;) {
-
- DBGLVL_PRINTK(4,"fxp_daemon waiting for event, INTRCNTL 0x%02x\n",
- CSR_READ_1(sc, FXP_CSR_SCB_INTRCNTL));
- /*
- * wait for event to receive from interrupt function
- */
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- while ((statack = CSR_READ_1(sc, FXP_CSR_SCB_STATACK)) != 0) {
- DBGLVL_PRINTK(4,"fxp_daemon: processing event, statack = 0x%x\n",
- statack);
-#ifdef NOTUSED
- /*
- * It should not be possible to have all bits set; the
- * FXP_SCB_INTR_SWI bit always returns 0 on a read. If
- * all bits are set, this may indicate that the card has
- * been physically ejected, so ignore it.
- */
- if (statack == 0xff)
- return;
-#endif
-
- /*
- * First ACK all the interrupts in this pass.
- */
- CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, statack);
-
- /*
- * Free any finished transmit mbuf chains.
- *
- * Handle the CNA event likt a CXTNO event. It used to
- * be that this event (control unit not ready) was not
- * encountered, but it is now with the SMPng modifications.
- * The exact sequence of events that occur when the interface
- * is brought up are different now, and if this event
- * goes unhandled, the configuration/rxfilter setup sequence
- * can stall for several seconds. The result is that no
- * packets go out onto the wire for about 5 to 10 seconds
- * after the interface is ifconfig'ed for the first time.
- */
- if (statack & (FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA)) {
- struct fxp_cb_tx *txp;
-
- for (txp = sc->cbl_first; sc->tx_queued &&
- (txp->cb_status & FXP_CB_STATUS_C) != 0;
- txp = txp->next) {
- if (txp->mb_head != NULL) {
- m_freem(txp->mb_head);
- txp->mb_head = NULL;
- }
- sc->tx_queued--;
- }
- sc->cbl_first = txp;
- ifp->if_timer = 0;
- if (sc->tx_queued == 0) {
- if (sc->need_mcsetup)
- fxp_mc_setup(sc);
- }
- /*
- * Try to start more packets transmitting.
- */
- if (ifp->if_snd.ifq_head != NULL)
- fxp_start(ifp);
- }
- /*
- * Process receiver interrupts. If a no-resource (RNR)
- * condition exists, get whatever packets we can and
- * re-start the receiver.
- */
- if (statack & (FXP_SCB_STATACK_FR | FXP_SCB_STATACK_RNR)) {
- struct mbuf *m;
- struct fxp_rfa *rfa;
-rcvloop:
- m = sc->rfa_headm;
- rfa = (struct fxp_rfa *)(m->m_ext.ext_buf +
- RFA_ALIGNMENT_FUDGE);
-
- if (rfa->rfa_status & FXP_RFA_STATUS_C) {
- /*
- * Remove first packet from the chain.
- */
- sc->rfa_headm = m->m_next;
- m->m_next = NULL;
-
- /*
- * Add a new buffer to the receive chain.
- * If this fails, the old buffer is recycled
- * instead.
- */
- if (fxp_add_rfabuf(sc, m) == 0) {
- struct ether_header *eh;
- int total_len;
-
- total_len = rfa->actual_size &
- (MCLBYTES - 1);
- if (total_len <
- sizeof(struct ether_header)) {
- m_freem(m);
- goto rcvloop;
- }
-
- /*
- * Drop the packet if it has CRC
- * errors. This test is only needed
- * when doing 802.1q VLAN on the 82557
- * chip.
- */
- if (rfa->rfa_status &
- FXP_RFA_STATUS_CRC) {
- m_freem(m);
- goto rcvloop;
- }
-
- m->m_pkthdr.rcvif = ifp;
- m->m_pkthdr.len = m->m_len = total_len;
- eh = mtod(m, struct ether_header *);
- m->m_data +=
- sizeof(struct ether_header);
- m->m_len -=
- sizeof(struct ether_header);
- m->m_pkthdr.len = m->m_len;
- ether_input(ifp, eh, m);
- }
- goto rcvloop;
- }
- if (statack & FXP_SCB_STATACK_RNR) {
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
- vtophys(sc->rfa_headm->m_ext.ext_buf) +
- RFA_ALIGNMENT_FUDGE);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
- }
- }
- }
- /*
- * reenable interrupts
- */
- RTEMS_COMPILER_MEMORY_BARRIER();
- CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL,0);
- RTEMS_COMPILER_MEMORY_BARRIER();
- }
-}
-
-/*
- * Update packet in/out/collision statistics. The i82557 doesn't
- * allow you to access these counters without doing a fairly
- * expensive DMA to get _all_ of the statistics it maintains, so
- * we do this operation here only once per second. The statistics
- * counters in the kernel are updated from the previous dump-stats
- * DMA and then a new dump-stats DMA is started. The on-chip
- * counters are zeroed when the DMA completes. If we can't start
- * the DMA immediately, we don't wait - we just prepare to read
- * them again next time.
- */
-static void
-fxp_tick(void *xsc)
-{
- struct fxp_softc *sc = xsc;
- struct ifnet *ifp = &sc->sc_if;
- struct fxp_stats *sp = sc->fxp_stats;
- struct fxp_cb_tx *txp;
- int s;
-
- DBGLVL_PRINTK(4,"fxp_tick called\n");
-
- ifp->if_opackets += sp->tx_good;
- ifp->if_collisions += sp->tx_total_collisions;
- if (sp->rx_good) {
- ifp->if_ipackets += sp->rx_good;
- sc->rx_idle_secs = 0;
- } else {
- /*
- * Receiver's been idle for another second.
- */
- sc->rx_idle_secs++;
- }
- ifp->if_ierrors +=
- sp->rx_crc_errors +
- sp->rx_alignment_errors +
- sp->rx_rnr_errors +
- sp->rx_overrun_errors;
- /*
- * If any transmit underruns occured, bump up the transmit
- * threshold by another 512 bytes (64 * 8).
- */
- if (sp->tx_underruns) {
- ifp->if_oerrors += sp->tx_underruns;
- if (tx_threshold < 192)
- tx_threshold += 64;
- }
- s = splimp();
- /*
- * Release any xmit buffers that have completed DMA. This isn't
- * strictly necessary to do here, but it's advantagous for mbufs
- * with external storage to be released in a timely manner rather
- * than being defered for a potentially long time. This limits
- * the delay to a maximum of one second.
- */
- for (txp = sc->cbl_first; sc->tx_queued &&
- (txp->cb_status & FXP_CB_STATUS_C) != 0;
- txp = txp->next) {
- if (txp->mb_head != NULL) {
- m_freem(txp->mb_head);
- txp->mb_head = NULL;
- }
- sc->tx_queued--;
- }
- sc->cbl_first = txp;
- /*
- * If we haven't received any packets in FXP_MAC_RX_IDLE seconds,
- * then assume the receiver has locked up and attempt to clear
- * the condition by reprogramming the multicast filter. This is
- * a work-around for a bug in the 82557 where the receiver locks
- * up if it gets certain types of garbage in the syncronization
- * bits prior to the packet header. This bug is supposed to only
- * occur in 10Mbps mode, but has been seen to occur in 100Mbps
- * mode as well (perhaps due to a 10/100 speed transition).
- */
- if (sc->rx_idle_secs > FXP_MAX_RX_IDLE) {
- sc->rx_idle_secs = 0;
- fxp_mc_setup(sc);
- }
- /*
- * If there is no pending command, start another stats
- * dump. Otherwise punt for now.
- */
- if (CSR_READ_1(sc, FXP_CSR_SCB_COMMAND) == 0) {
- /*
- * Start another stats dump.
- */
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMPRESET);
- } else {
- /*
- * A previous command is still waiting to be accepted.
- * Just zero our copy of the stats and wait for the
- * next timer event to update them.
- */
- sp->tx_good = 0;
- sp->tx_underruns = 0;
- sp->tx_total_collisions = 0;
-
- sp->rx_good = 0;
- sp->rx_crc_errors = 0;
- sp->rx_alignment_errors = 0;
- sp->rx_rnr_errors = 0;
- sp->rx_overrun_errors = 0;
- }
-#ifdef NOTUSED
- if (sc->miibus != NULL)
- mii_tick(device_get_softc(sc->miibus));
-#endif
- splx(s);
- /*
- * Schedule another timeout one second from now.
- */
- if (sc->stat_ch == fxp_timeout_running) {
- timeout(fxp_tick, sc, hz);
- }
- else if (sc->stat_ch == fxp_timeout_stop_rq) {
- sc->stat_ch = fxp_timeout_stopped;
- }
-}
-
-/*
- * Stop the interface. Cancels the statistics updater and resets
- * the interface.
- */
-static void
-fxp_stop(struct fxp_softc *sc)
-{
- struct ifnet *ifp = &sc->sc_if;
- struct fxp_cb_tx *txp;
- int i;
-
- DBGLVL_PRINTK(2,"fxp_stop called\n");
-
- ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
- ifp->if_timer = 0;
-
- /*
- * stop stats updater.
- */
- if (sc->stat_ch == fxp_timeout_running) {
- DBGLVL_PRINTK(3,"fxp_stop: trying to stop stat update tick\n");
- sc->stat_ch = fxp_timeout_stop_rq;
- while(sc->stat_ch != fxp_timeout_stopped) {
- rtems_bsdnet_semaphore_release();
- rtems_task_wake_after(fxp_ticksPerSecond);
- rtems_bsdnet_semaphore_obtain();
- }
- DBGLVL_PRINTK(3,"fxp_stop: stat update tick stopped\n");
- }
- /*
- * Issue software reset
- */
- DBGLVL_PRINTK(3,"fxp_stop: issue software reset\n");
- CSR_WRITE_4(sc, FXP_CSR_PORT, FXP_PORT_SELECTIVE_RESET);
- DELAY(10);
-
- /*
- * Release any xmit buffers.
- */
- DBGLVL_PRINTK(3,"fxp_stop: releasing xmit buffers\n");
- txp = sc->cbl_base;
- if (txp != NULL) {
- for (i = 0; i < FXP_NTXCB; i++) {
- if (txp[i].mb_head != NULL) {
- m_freem(txp[i].mb_head);
- txp[i].mb_head = NULL;
- }
- }
- }
- sc->tx_queued = 0;
-
- /*
- * Free all the receive buffers then reallocate/reinitialize
- */
- DBGLVL_PRINTK(3,"fxp_stop: free and reinit all receive buffers\n");
- if (sc->rfa_headm != NULL)
- m_freem(sc->rfa_headm);
- sc->rfa_headm = NULL;
- sc->rfa_tailm = NULL;
- for (i = 0; i < FXP_NRFABUFS; i++) {
- if (fxp_add_rfabuf(sc, NULL) != 0) {
- /*
- * This "can't happen" - we're at splimp()
- * and we just freed all the buffers we need
- * above.
- */
- panic("fxp_stop: no buffers!");
- }
- }
- DBGLVL_PRINTK(2,"fxp_stop: finished\n");
-}
-
-/*
- * Watchdog/transmission transmit timeout handler. Called when a
- * transmission is started on the interface, but no interrupt is
- * received before the timeout. This usually indicates that the
- * card has wedged for some reason.
- */
-static void
-fxp_watchdog(struct ifnet *ifp)
-{
- struct fxp_softc *sc = ifp->if_softc;
-
- device_printf(sc->dev, "device timeout\n");
- ifp->if_oerrors++;
-
- fxp_init(sc);
-}
-
-static void
-fxp_init(void *xsc)
-{
- struct fxp_softc *sc = xsc;
- struct ifnet *ifp = &sc->sc_if;
- struct fxp_cb_config *cbp;
- struct fxp_cb_ias *cb_ias;
- struct fxp_cb_tx *txp;
- int i, prm, s;
- rtems_status_code statcode;
-
-rtems_task_wake_after(100);
- DBGLVL_PRINTK(2,"fxp_init called\n");
-
- s = splimp();
- /*
- * Cancel any pending I/O
- */
- /*
- * E. Norum 2004-10-11
- * Add line suggested by "Eugene Denisov" <dea@sendmail.ru>.
- * Prevents lockup at initialization.
- */
- sc->stat_ch = fxp_timeout_stopped;
- fxp_stop(sc);
-
- prm = (ifp->if_flags & IFF_PROMISC) ? 1 : 0;
-
- DBGLVL_PRINTK(5,"fxp_init: Initializing base of CBL and RFA memory\n");
- /*
- * Initialize base of CBL and RFA memory. Loading with zero
- * sets it up for regular linear addressing.
- */
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, 0);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_BASE);
-
- fxp_scb_wait(sc);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_BASE);
-
- /*
- * Initialize base of dump-stats buffer.
- */
- DBGLVL_PRINTK(5,"fxp_init: Initializing base of dump-stats buffer\n");
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(sc->fxp_stats));
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_DUMP_ADR);
-
- /*
- * We temporarily use memory that contains the TxCB list to
- * construct the config CB. The TxCB list memory is rebuilt
- * later.
- */
- cbp = (struct fxp_cb_config *) sc->cbl_base;
- DBGLVL_PRINTK(5,"fxp_init: cbp = 0x%x\n",cbp);
-
- /*
- * This memcpy is kind of disgusting, but there are a bunch of must be
- * zero and must be one bits in this structure and this is the easiest
- * way to initialize them all to proper values.
- */
- memcpy( (void *)(u_int32_t*)(volatile void *)&cbp->cb_status,
- fxp_cb_config_template,
- sizeof(fxp_cb_config_template));
-
- cbp->cb_status = 0;
- cbp->cb_command = FXP_CB_COMMAND_CONFIG | FXP_CB_COMMAND_EL;
- cbp->link_addr = -1; /* (no) next command */
- cbp->byte_count = 22; /* (22) bytes to config */
- cbp->rx_fifo_limit = 8; /* rx fifo threshold (32 bytes) */
- cbp->tx_fifo_limit = 0; /* tx fifo threshold (0 bytes) */
- cbp->adaptive_ifs = 0; /* (no) adaptive interframe spacing */
- cbp->mwi_enable = sc->flags & FXP_FLAG_MWI_ENABLE ? 1 : 0;
- cbp->type_enable = 0; /* actually reserved */
- cbp->read_align_en = sc->flags & FXP_FLAG_READ_ALIGN ? 1 : 0;
- cbp->end_wr_on_cl = sc->flags & FXP_FLAG_WRITE_ALIGN ? 1 : 0;
- cbp->rx_dma_bytecount = 0; /* (no) rx DMA max */
- cbp->tx_dma_bytecount = 0; /* (no) tx DMA max */
- cbp->dma_mbce = 0; /* (disable) dma max counters */
- cbp->late_scb = 0; /* (don't) defer SCB update */
- cbp->direct_dma_dis = 1; /* disable direct rcv dma mode */
- cbp->tno_int_or_tco_en =0; /* (disable) tx not okay interrupt */
- cbp->ci_int = 1; /* interrupt on CU idle */
- cbp->ext_txcb_dis = sc->flags & FXP_FLAG_EXT_TXCB ? 0 : 1;
- cbp->ext_stats_dis = 1; /* disable extended counters */
- cbp->keep_overrun_rx = 0; /* don't pass overrun frames to host */
- cbp->save_bf = sc->chip == FXP_CHIP_82557 ? 1 : prm;
- cbp->disc_short_rx = !prm; /* discard short packets */
- cbp->underrun_retry = 1; /* retry mode (once) on DMA underrun */
- cbp->two_frames = 0; /* do not limit FIFO to 2 frames */
- cbp->dyn_tbd = 0; /* (no) dynamic TBD mode */
- cbp->mediatype = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 0 : 1;
- cbp->csma_dis = 0; /* (don't) disable link */
- cbp->tcp_udp_cksum = 0; /* (don't) enable checksum */
- cbp->vlan_tco = 0; /* (don't) enable vlan wakeup */
- cbp->link_wake_en = 0; /* (don't) assert PME# on link change */
- cbp->arp_wake_en = 0; /* (don't) assert PME# on arp */
- cbp->mc_wake_en = 0; /* (don't) enable PME# on mcmatch */
- cbp->nsai = 1; /* (don't) disable source addr insert */
- cbp->preamble_length = 2; /* (7 byte) preamble */
- cbp->loopback = 0; /* (don't) loopback */
- cbp->linear_priority = 0; /* (normal CSMA/CD operation) */
- cbp->linear_pri_mode = 0; /* (wait after xmit only) */
- cbp->interfrm_spacing = 6; /* (96 bits of) interframe spacing */
- cbp->promiscuous = prm; /* promiscuous mode */
- cbp->bcast_disable = 0; /* (don't) disable broadcasts */
- cbp->wait_after_win = 0; /* (don't) enable modified backoff alg*/
- cbp->ignore_ul = 0; /* consider U/L bit in IA matching */
- cbp->crc16_en = 0; /* (don't) enable crc-16 algorithm */
- cbp->crscdt = sc->flags & FXP_FLAG_SERIAL_MEDIA ? 1 : 0;
-
- cbp->stripping = !prm; /* truncate rx packet to byte count */
- cbp->padding = 1; /* (do) pad short tx packets */
- cbp->rcv_crc_xfer = 0; /* (don't) xfer CRC to host */
- cbp->long_rx_en = sc->flags & FXP_FLAG_LONG_PKT_EN ? 1 : 0;
- cbp->ia_wake_en = 0; /* (don't) wake up on address match */
- cbp->magic_pkt_dis = 0; /* (don't) disable magic packet */
- /* must set wake_en in PMCSR also */
- cbp->force_fdx = 0; /* (don't) force full duplex */
- cbp->fdx_pin_en = 1; /* (enable) FDX# pin */
- cbp->multi_ia = 0; /* (don't) accept multiple IAs */
- cbp->mc_all = sc->flags & FXP_FLAG_ALL_MCAST ? 1 : 0;
-
- DBGLVL_PRINTK(5,"fxp_init: cbp initialized\n");
- if (sc->chip == FXP_CHIP_82557) {
- /*
- * The 82557 has no hardware flow control, the values
- * below are the defaults for the chip.
- */
- cbp->fc_delay_lsb = 0;
- cbp->fc_delay_msb = 0x40;
- cbp->pri_fc_thresh = 3;
- cbp->tx_fc_dis = 0;
- cbp->rx_fc_restop = 0;
- cbp->rx_fc_restart = 0;
- cbp->fc_filter = 0;
- cbp->pri_fc_loc = 1;
- } else {
- cbp->fc_delay_lsb = 0x1f;
- cbp->fc_delay_msb = 0x01;
- cbp->pri_fc_thresh = 3;
- cbp->tx_fc_dis = 0; /* enable transmit FC */
- cbp->rx_fc_restop = 1; /* enable FC restop frames */
- cbp->rx_fc_restart = 1; /* enable FC restart frames */
- cbp->fc_filter = !prm; /* drop FC frames to host */
- cbp->pri_fc_loc = 1; /* FC pri location (byte31) */
- }
-
- /*
- * Start the config command/DMA.
- */
- DBGLVL_PRINTK(5,"fxp_init: starting config command/DMA\n");
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&cbp->cb_status));
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
- /* ...and wait for it to complete. */
- fxp_dma_wait(&cbp->cb_status, sc);
-
- /*
- * Now initialize the station address. Temporarily use the TxCB
- * memory area like we did above for the config CB.
- */
- DBGLVL_PRINTK(5,"fxp_init: initialize station address\n");
- cb_ias = (struct fxp_cb_ias *) sc->cbl_base;
- cb_ias->cb_status = 0;
- cb_ias->cb_command = FXP_CB_COMMAND_IAS | FXP_CB_COMMAND_EL;
- cb_ias->link_addr = -1;
- memcpy((void *)(u_int32_t*)(volatile void *)cb_ias->macaddr,
- sc->arpcom.ac_enaddr,
- sizeof(sc->arpcom.ac_enaddr));
-
- /*
- * Start the IAS (Individual Address Setup) command/DMA.
- */
- DBGLVL_PRINTK(5,"fxp_init: start IAS command/DMA\n");
- fxp_scb_wait(sc);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
- /* ...and wait for it to complete. */
- fxp_dma_wait(&cb_ias->cb_status, sc);
-
- /*
- * Initialize transmit control block (TxCB) list.
- */
-
- DBGLVL_PRINTK(5,"fxp_init: initialize TxCB list\n");
- txp = sc->cbl_base;
- memset(txp, 0, sizeof(struct fxp_cb_tx) * FXP_NTXCB);
- for (i = 0; i < FXP_NTXCB; i++) {
- txp[i].cb_status = FXP_CB_STATUS_C | FXP_CB_STATUS_OK;
- txp[i].cb_command = FXP_CB_COMMAND_NOP;
- txp[i].link_addr =
- vtophys(&txp[(i + 1) & FXP_TXCB_MASK].cb_status);
- if (sc->flags & FXP_FLAG_EXT_TXCB)
- txp[i].tbd_array_addr = vtophys(&txp[i].tbd[2]);
- else
- txp[i].tbd_array_addr = vtophys(&txp[i].tbd[0]);
- txp[i].next = &txp[(i + 1) & FXP_TXCB_MASK];
- }
- /*
- * Set the suspend flag on the first TxCB and start the control
- * unit. It will execute the NOP and then suspend.
- */
- DBGLVL_PRINTK(5,"fxp_init: setup suspend flag\n");
- txp->cb_command = FXP_CB_COMMAND_NOP | FXP_CB_COMMAND_S;
- sc->cbl_first = sc->cbl_last = txp;
- sc->tx_queued = 1;
-
- fxp_scb_wait(sc);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
-
- /*
- * Initialize receiver buffer area - RFA.
- */
- DBGLVL_PRINTK(5,"fxp_init: initialize RFA\n");
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL,
- vtophys(sc->rfa_headm->m_ext.ext_buf) + RFA_ALIGNMENT_FUDGE);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START);
-
-#ifdef NOTUSED
- /*
- * Set current media.
- */
- if (sc->miibus != NULL)
- mii_mediachg(device_get_softc(sc->miibus));
-#endif
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- if (sc->daemonTid == 0) {
- /*
- * Start driver task
- */
- sc->daemonTid = rtems_bsdnet_newproc ("FXPd", 4096, fxp_daemon, sc);
-
- /*
- * Set up interrupts
- */
- statcode = rtems_interrupt_handler_install(
- sc->irq_num,
- "fxp_intr",
- RTEMS_INTERRUPT_SHARED,
- fxp_intr,
- sc
- );
-
- if ( statcode != RTEMS_SUCCESSFUL ) {
- rtems_panic ("Can't attach fxp interrupt handler for irq %d\n",
- sc->irq_num);
- }
- }
-
- /*
- * Enable interrupts.
- */
- CSR_WRITE_1(sc, FXP_CSR_SCB_INTRCNTL, 0);
- splx(s);
-
- /*
- * Start stats updater.
- */
- sc->stat_ch = fxp_timeout_running;
- DBGLVL_PRINTK(2,"fxp_init: stats updater timeout called with hz=%d\n", hz);
- timeout(fxp_tick, sc, hz);
- DBGLVL_PRINTK(2,"fxp_init finished\n");
-}
-
-#ifdef NOTUSED
-static int
-fxp_serial_ifmedia_upd(struct ifnet *ifp)
-{
-
- return (0);
-}
-
-static void
-fxp_serial_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
-
- ifmr->ifm_active = IFM_ETHER|IFM_MANUAL;
-}
-
-/*
- * Change media according to request.
- */
-static int
-fxp_ifmedia_upd(struct ifnet *ifp)
-{
- struct fxp_softc *sc = ifp->if_softc;
- struct mii_data *mii;
-
- mii = device_get_softc(sc->miibus);
- mii_mediachg(mii);
- return (0);
-}
-
-/*
- * Notify the world which media we're using.
- */
-static void
-fxp_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
-{
- struct fxp_softc *sc = ifp->if_softc;
- struct mii_data *mii;
-
- mii = device_get_softc(sc->miibus);
- mii_pollstat(mii);
- ifmr->ifm_active = mii->mii_media_active;
- ifmr->ifm_status = mii->mii_media_status;
-
- if (ifmr->ifm_status & IFM_10_T && sc->flags & FXP_FLAG_CU_RESUME_BUG)
- sc->cu_resume_bug = 1;
- else
- sc->cu_resume_bug = 0;
-}
-#endif
-
-/*
- * Add a buffer to the end of the RFA buffer list.
- * Return 0 if successful, 1 for failure. A failure results in
- * adding the 'oldm' (if non-NULL) on to the end of the list -
- * tossing out its old contents and recycling it.
- * The RFA struct is stuck at the beginning of mbuf cluster and the
- * data pointer is fixed up to point just past it.
- */
-static int
-fxp_add_rfabuf(struct fxp_softc *sc, struct mbuf *oldm)
-{
- u_int32_t v;
- struct mbuf *m;
- struct fxp_rfa *rfa, *p_rfa;
-
- DBGLVL_PRINTK(4,"fxp_add_rfabuf called\n");
-
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m != NULL) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0) {
- m_freem(m);
- if (oldm == NULL)
- return 1;
- m = oldm;
- m->m_data = m->m_ext.ext_buf;
- }
- } else {
- if (oldm == NULL)
- return 1;
- m = oldm;
- m->m_data = m->m_ext.ext_buf;
- }
-
- /*
- * Move the data pointer up so that the incoming data packet
- * will be 32-bit aligned.
- */
- m->m_data += RFA_ALIGNMENT_FUDGE;
-
- /*
- * Get a pointer to the base of the mbuf cluster and move
- * data start past it.
- */
- rfa = mtod(m, struct fxp_rfa *);
- m->m_data += sizeof(struct fxp_rfa);
- rfa->size = (u_int16_t)(MCLBYTES - sizeof(struct fxp_rfa) - RFA_ALIGNMENT_FUDGE);
-
- /*
- * Initialize the rest of the RFA. Note that since the RFA
- * is misaligned, we cannot store values directly. Instead,
- * we use an optimized, inline copy.
- */
-
- rfa->rfa_status = 0;
- rfa->rfa_control = FXP_RFA_CONTROL_EL;
- rfa->actual_size = 0;
-
- v = -1;
- fxp_lwcopy(&v, (volatile u_int32_t*) rfa->link_addr);
- fxp_lwcopy(&v, (volatile u_int32_t*) rfa->rbd_addr);
-
- /*
- * If there are other buffers already on the list, attach this
- * one to the end by fixing up the tail to point to this one.
- */
- if (sc->rfa_headm != NULL) {
- p_rfa = (struct fxp_rfa *) (sc->rfa_tailm->m_ext.ext_buf +
- RFA_ALIGNMENT_FUDGE);
- sc->rfa_tailm->m_next = m;
- v = vtophys(rfa);
- fxp_lwcopy(&v, (volatile u_int32_t*) p_rfa->link_addr);
- p_rfa->rfa_control = 0;
- } else {
- sc->rfa_headm = m;
- }
- sc->rfa_tailm = m;
-
- return (m == oldm);
-}
-
-#ifdef NOTUSED
-static volatile int
-fxp_miibus_readreg(device_t dev, int phy, int reg)
-{
- struct fxp_softc *sc = device_get_softc(dev);
- int count = 10000;
- int value;
-
- CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
- (FXP_MDI_READ << 26) | (reg << 16) | (phy << 21));
-
- while (((value = CSR_READ_4(sc, FXP_CSR_MDICONTROL)) & 0x10000000) == 0
- && count--)
- DELAY(10);
-
- if (count <= 0)
- device_printf(dev, "fxp_miibus_readreg: timed out\n");
-
- return (value & 0xffff);
-}
-
-static void
-fxp_miibus_writereg(device_t dev, int phy, int reg, int value)
-{
- struct fxp_softc *sc = device_get_softc(dev);
- int count = 10000;
-
- CSR_WRITE_4(sc, FXP_CSR_MDICONTROL,
- (FXP_MDI_WRITE << 26) | (reg << 16) | (phy << 21) |
- (value & 0xffff));
-
- while ((CSR_READ_4(sc, FXP_CSR_MDICONTROL) & 0x10000000) == 0 &&
- count--)
- DELAY(10);
-
- if (count <= 0)
- device_printf(dev, "fxp_miibus_writereg: timed out\n");
-}
-#endif
-
-static int
-fxp_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct fxp_softc *sc = ifp->if_softc;
-#ifdef NOTUSED
- struct ifreq *ifr = (struct ifreq *)data;
- struct mii_data *mii;
-#endif
- int s, error = 0;
-
- DBGLVL_PRINTK(2,"fxp_ioctl called\n");
-
- s = splimp();
-
- switch (command) {
- case SIOCSIFADDR:
- case SIOCGIFADDR:
- case SIOCSIFMTU:
- error = ether_ioctl(ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- if (ifp->if_flags & IFF_ALLMULTI)
- sc->flags |= FXP_FLAG_ALL_MCAST;
- else
- sc->flags &= ~FXP_FLAG_ALL_MCAST;
-
- /*
- * If interface is marked up and not running, then start it.
- * If it is marked down and running, stop it.
- * XXX If it's up then re-initialize it. This is so flags
- * such as IFF_PROMISC are handled.
- */
- if (ifp->if_flags & IFF_UP) {
- fxp_init(sc);
- } else {
- if (ifp->if_flags & IFF_RUNNING)
- fxp_stop(sc);
- }
- break;
-
- case SIOCADDMULTI:
- case SIOCDELMULTI:
- if (ifp->if_flags & IFF_ALLMULTI)
- sc->flags |= FXP_FLAG_ALL_MCAST;
- else
- sc->flags &= ~FXP_FLAG_ALL_MCAST;
- /*
- * Multicast list has changed; set the hardware filter
- * accordingly.
- */
- if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0)
- fxp_mc_setup(sc);
- /*
- * fxp_mc_setup() can set FXP_FLAG_ALL_MCAST, so check it
- * again rather than else {}.
- */
- if (sc->flags & FXP_FLAG_ALL_MCAST)
- fxp_init(sc);
- error = 0;
- break;
-
-#ifdef NOTUSED
- case SIOCSIFMEDIA:
- case SIOCGIFMEDIA:
- if (sc->miibus != NULL) {
- mii = device_get_softc(sc->miibus);
- error = ifmedia_ioctl(ifp, ifr,
- &mii->mii_media, command);
- } else {
- error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, command);
- }
- break;
-#endif
-
- case SIO_RTEMS_SHOW_STATS:
- fxp_stats(sc);
- break;
-
- default:
- error = EINVAL;
- }
- splx(s);
- return (error);
-}
-
-/*
- * Program the multicast filter.
- *
- * We have an artificial restriction that the multicast setup command
- * must be the first command in the chain, so we take steps to ensure
- * this. By requiring this, it allows us to keep up the performance of
- * the pre-initialized command ring (esp. link pointers) by not actually
- * inserting the mcsetup command in the ring - i.e. its link pointer
- * points to the TxCB ring, but the mcsetup descriptor itself is not part
- * of it. We then can do 'CU_START' on the mcsetup descriptor and have it
- * lead into the regular TxCB ring when it completes.
- *
- * This function must be called at splimp.
- */
-static void
-fxp_mc_setup(struct fxp_softc *sc)
-{
- struct fxp_cb_mcs *mcsp = sc->mcsp;
- struct ifnet *ifp = &sc->sc_if;
-#ifdef NOTUSED
- struct ifmultiaddr *ifma;
-#endif
- int nmcasts;
- int count;
-
- DBGLVL_PRINTK(2,"fxp_mc_setup called\n");
-
- /*
- * If there are queued commands, we must wait until they are all
- * completed. If we are already waiting, then add a NOP command
- * with interrupt option so that we're notified when all commands
- * have been completed - fxp_start() ensures that no additional
- * TX commands will be added when need_mcsetup is true.
- */
- if (sc->tx_queued) {
- struct fxp_cb_tx *txp;
-
- /*
- * need_mcsetup will be true if we are already waiting for the
- * NOP command to be completed (see below). In this case, bail.
- */
- if (sc->need_mcsetup)
- return;
- sc->need_mcsetup = 1;
-
- /*
- * Add a NOP command with interrupt so that we are notified when all
- * TX commands have been processed.
- */
- txp = sc->cbl_last->next;
- txp->mb_head = NULL;
- txp->cb_status = 0;
- txp->cb_command = FXP_CB_COMMAND_NOP |
- FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
- /*
- * Advance the end of list forward.
- */
- sc->cbl_last->cb_command &= ~FXP_CB_COMMAND_S;
- sc->cbl_last = txp;
- sc->tx_queued++;
- /*
- * Issue a resume in case the CU has just suspended.
- */
- fxp_scb_wait(sc);
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_RESUME);
- /*
- * Set a 5 second timer just in case we don't hear from the
- * card again.
- */
- ifp->if_timer = 5;
-
- return;
- }
- sc->need_mcsetup = 0;
-
- /*
- * Initialize multicast setup descriptor.
- */
- mcsp->next = sc->cbl_base;
- mcsp->mb_head = NULL;
- mcsp->cb_status = 0;
- mcsp->cb_command = FXP_CB_COMMAND_MCAS |
- FXP_CB_COMMAND_S | FXP_CB_COMMAND_I;
- mcsp->link_addr = vtophys(&sc->cbl_base->cb_status);
-
- nmcasts = 0;
-#ifdef NOTUSED /* FIXME: Multicast not supported? */
- if ((sc->flags & FXP_FLAG_ALL_MCAST) == 0) {
-#if __FreeBSD_version < 500000
- LIST_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-#else
- TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
-#endif
- if (ifma->ifma_addr->sa_family != AF_LINK)
- continue;
- if (nmcasts >= MAXMCADDR) {
- sc->flags |= FXP_FLAG_ALL_MCAST;
- nmcasts = 0;
- break;
- }
- memcpy((void *)(uintptr_t)(volatile void *)
- &sc->mcsp->mc_addr[nmcasts][0],
- LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 6);
- nmcasts++;
- }
- }
-#endif
- mcsp->mc_cnt = nmcasts * 6;
- sc->cbl_first = sc->cbl_last = (struct fxp_cb_tx *) mcsp;
- sc->tx_queued = 1;
-
- /*
- * Wait until command unit is not active. This should never
- * be the case when nothing is queued, but make sure anyway.
- */
- count = 100;
- while ((CSR_READ_1(sc, FXP_CSR_SCB_RUSCUS) >> 6) ==
- FXP_SCB_CUS_ACTIVE && --count)
- DELAY(10);
- if (count == 0) {
- device_printf(sc->dev, "command queue timeout\n");
- return;
- }
-
- /*
- * Start the multicast setup command.
- */
- fxp_scb_wait(sc);
- CSR_WRITE_4(sc, FXP_CSR_SCB_GENERAL, vtophys(&mcsp->cb_status));
- fxp_scb_cmd(sc, FXP_SCB_COMMAND_CU_START);
-
- ifp->if_timer = 2;
- return;
- }
-
-#endif /* defined(__i386__) */
diff --git a/c/src/libchip/network/if_fxpreg.h b/c/src/libchip/network/if_fxpreg.h
deleted file mode 100644
index 9bf4e59ff5..0000000000
--- a/c/src/libchip/network/if_fxpreg.h
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (c) 1995, David Greenman
- * Copyright (c) 2001 Jonathan Lemon <jlemon@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice unmodified, this list of conditions, and the following
- * disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/dev/fxp/if_fxpreg.h,v 1.23.2.4 2001/08/31 02:17:02 jlemon Exp $
- */
-
-#define FXP_VENDORID_INTEL 0x8086
-
-#define FXP_PCI_MMBA 0x10
-#define FXP_PCI_IOBA 0x14
-
-/*
- * Control/status registers.
- */
-#define FXP_CSR_SCB_RUSCUS 0 /* scb_rus/scb_cus (1 byte) */
-#define FXP_CSR_SCB_STATACK 1 /* scb_statack (1 byte) */
-#define FXP_CSR_SCB_COMMAND 2 /* scb_command (1 byte) */
-#define FXP_CSR_SCB_INTRCNTL 3 /* scb_intrcntl (1 byte) */
-#define FXP_CSR_SCB_GENERAL 4 /* scb_general (4 bytes) */
-#define FXP_CSR_PORT 8 /* port (4 bytes) */
-#define FXP_CSR_FLASHCONTROL 12 /* flash control (2 bytes) */
-#define FXP_CSR_EEPROMCONTROL 14 /* eeprom control (2 bytes) */
-#define FXP_CSR_MDICONTROL 16 /* mdi control (4 bytes) */
-#define FXP_CSR_FLOWCONTROL 0x19 /* flow control (2 bytes) */
-#define FXP_CSR_GENCONTROL 0x1C /* general control (1 byte) */
-
-/*
- * FOR REFERENCE ONLY, the old definition of FXP_CSR_SCB_RUSCUS:
- *
- * volatile u_int8_t :2,
- * scb_rus:4,
- * scb_cus:2;
- */
-
-#define FXP_PORT_SOFTWARE_RESET 0
-#define FXP_PORT_SELFTEST 1
-#define FXP_PORT_SELECTIVE_RESET 2
-#define FXP_PORT_DUMP 3
-
-#define FXP_SCB_RUS_IDLE 0
-#define FXP_SCB_RUS_SUSPENDED 1
-#define FXP_SCB_RUS_NORESOURCES 2
-#define FXP_SCB_RUS_READY 4
-#define FXP_SCB_RUS_SUSP_NORBDS 9
-#define FXP_SCB_RUS_NORES_NORBDS 10
-#define FXP_SCB_RUS_READY_NORBDS 12
-
-#define FXP_SCB_CUS_IDLE 0
-#define FXP_SCB_CUS_SUSPENDED 1
-#define FXP_SCB_CUS_ACTIVE 2
-
-#define FXP_SCB_INTR_DISABLE 0x01 /* Disable all interrupts */
-#define FXP_SCB_INTR_SWI 0x02 /* Generate SWI */
-#define FXP_SCB_INTMASK_FCP 0x04
-#define FXP_SCB_INTMASK_ER 0x08
-#define FXP_SCB_INTMASK_RNR 0x10
-#define FXP_SCB_INTMASK_CNA 0x20
-#define FXP_SCB_INTMASK_FR 0x40
-#define FXP_SCB_INTMASK_CXTNO 0x80
-
-#define FXP_SCB_STATACK_FCP 0x01 /* Flow Control Pause */
-#define FXP_SCB_STATACK_ER 0x02 /* Early Receive */
-#define FXP_SCB_STATACK_SWI 0x04
-#define FXP_SCB_STATACK_MDI 0x08
-#define FXP_SCB_STATACK_RNR 0x10
-#define FXP_SCB_STATACK_CNA 0x20
-#define FXP_SCB_STATACK_FR 0x40
-#define FXP_SCB_STATACK_CXTNO 0x80
-
-#define FXP_SCB_COMMAND_CU_NOP 0x00
-#define FXP_SCB_COMMAND_CU_START 0x10
-#define FXP_SCB_COMMAND_CU_RESUME 0x20
-#define FXP_SCB_COMMAND_CU_DUMP_ADR 0x40
-#define FXP_SCB_COMMAND_CU_DUMP 0x50
-#define FXP_SCB_COMMAND_CU_BASE 0x60
-#define FXP_SCB_COMMAND_CU_DUMPRESET 0x70
-
-#define FXP_SCB_COMMAND_RU_NOP 0
-#define FXP_SCB_COMMAND_RU_START 1
-#define FXP_SCB_COMMAND_RU_RESUME 2
-#define FXP_SCB_COMMAND_RU_ABORT 4
-#define FXP_SCB_COMMAND_RU_LOADHDS 5
-#define FXP_SCB_COMMAND_RU_BASE 6
-#define FXP_SCB_COMMAND_RU_RBDRESUME 7
-
-/*
- * Command block definitions
- */
-struct fxp_cb_nop {
- void *fill[2];
- volatile u_int16_t cb_status;
- volatile u_int16_t cb_command;
- volatile u_int32_t link_addr;
-};
-struct fxp_cb_ias {
- void *fill[2];
- volatile u_int16_t cb_status;
- volatile u_int16_t cb_command;
- volatile u_int32_t link_addr;
- volatile u_int8_t macaddr[6];
-};
-/* I hate bit-fields :-( */
-struct fxp_cb_config {
- void *fill[2];
- volatile u_int16_t cb_status;
- volatile u_int16_t cb_command;
- volatile u_int32_t link_addr;
- volatile u_int byte_count:6,
- :2;
- volatile u_int rx_fifo_limit:4,
- tx_fifo_limit:3,
- :1;
- volatile u_int8_t adaptive_ifs;
- volatile u_int mwi_enable:1, /* 8,9 */
- type_enable:1, /* 8,9 */
- read_align_en:1, /* 8,9 */
- end_wr_on_cl:1, /* 8,9 */
- :4;
- volatile u_int rx_dma_bytecount:7,
- :1;
- volatile u_int tx_dma_bytecount:7,
- dma_mbce:1;
- volatile u_int late_scb:1, /* 7 */
- direct_dma_dis:1, /* 8,9 */
- tno_int_or_tco_en:1, /* 7,9 */
- ci_int:1,
- ext_txcb_dis:1, /* 8,9 */
- ext_stats_dis:1, /* 8,9 */
- keep_overrun_rx:1,
- save_bf:1;
- volatile u_int disc_short_rx:1,
- underrun_retry:2,
- :3,
- two_frames:1, /* 8,9 */
- dyn_tbd:1; /* 8,9 */
- volatile u_int mediatype:1, /* 7 */
- :6,
- csma_dis:1; /* 8,9 */
- volatile u_int tcp_udp_cksum:1, /* 9 */
- :3,
- vlan_tco:1, /* 8,9 */
- link_wake_en:1, /* 8,9 */
- arp_wake_en:1, /* 8 */
- mc_wake_en:1; /* 8 */
- volatile u_int :3,
- nsai:1,
- preamble_length:2,
- loopback:2;
- volatile u_int linear_priority:3, /* 7 */
- :5;
- volatile u_int linear_pri_mode:1, /* 7 */
- :3,
- interfrm_spacing:4;
- volatile u_int :8;
- volatile u_int :8;
- volatile u_int promiscuous:1,
- bcast_disable:1,
- wait_after_win:1, /* 8,9 */
- :1,
- ignore_ul:1, /* 8,9 */
- crc16_en:1, /* 9 */
- :1,
- crscdt:1;
- volatile u_int fc_delay_lsb:8; /* 8,9 */
- volatile u_int fc_delay_msb:8; /* 8,9 */
- volatile u_int stripping:1,
- padding:1,
- rcv_crc_xfer:1,
- long_rx_en:1, /* 8,9 */
- pri_fc_thresh:3, /* 8,9 */
- :1;
- volatile u_int ia_wake_en:1, /* 8 */
- magic_pkt_dis:1, /* 8,9,!9ER */
- tx_fc_dis:1, /* 8,9 */
- rx_fc_restop:1, /* 8,9 */
- rx_fc_restart:1, /* 8,9 */
- fc_filter:1, /* 8,9 */
- force_fdx:1,
- fdx_pin_en:1;
- volatile u_int :5,
- pri_fc_loc:1, /* 8,9 */
- multi_ia:1,
- :1;
- volatile u_int :3,
- mc_all:1,
- :4;
-};
-
-#define MAXMCADDR 80
-struct fxp_cb_mcs {
- struct fxp_cb_tx *next;
- struct mbuf *mb_head;
- volatile u_int16_t cb_status;
- volatile u_int16_t cb_command;
- volatile u_int32_t link_addr;
- volatile u_int16_t mc_cnt;
- volatile u_int8_t mc_addr[MAXMCADDR][6];
-};
-
-/*
- * Number of DMA segments in a TxCB. Note that this is carefully
- * chosen to make the total struct size an even power of two. It's
- * critical that no TxCB be split across a page boundry since
- * no attempt is made to allocate physically contiguous memory.
- *
- */
-#ifdef __alpha__ /* XXX - should be conditional on pointer size */
-#define FXP_NTXSEG 28
-#else
-#define FXP_NTXSEG 29
-#endif
-
-struct fxp_tbd {
- volatile u_int32_t tb_addr;
- volatile u_int32_t tb_size;
-};
-struct fxp_cb_tx {
- struct fxp_cb_tx *next;
- struct mbuf *mb_head;
- volatile u_int16_t cb_status;
- volatile u_int16_t cb_command;
- volatile u_int32_t link_addr;
- volatile u_int32_t tbd_array_addr;
- volatile u_int16_t byte_count;
- volatile u_int8_t tx_threshold;
- volatile u_int8_t tbd_number;
- /*
- * The following structure isn't actually part of the TxCB,
- * unless the extended TxCB feature is being used. In this
- * case, the first two elements of the structure below are
- * fetched along with the TxCB.
- */
- volatile struct fxp_tbd tbd[FXP_NTXSEG];
-};
-
-/*
- * Control Block (CB) definitions
- */
-
-/* status */
-#define FXP_CB_STATUS_OK 0x2000
-#define FXP_CB_STATUS_C 0x8000
-/* commands */
-#define FXP_CB_COMMAND_NOP 0x0
-#define FXP_CB_COMMAND_IAS 0x1
-#define FXP_CB_COMMAND_CONFIG 0x2
-#define FXP_CB_COMMAND_MCAS 0x3
-#define FXP_CB_COMMAND_XMIT 0x4
-#define FXP_CB_COMMAND_RESRV 0x5
-#define FXP_CB_COMMAND_DUMP 0x6
-#define FXP_CB_COMMAND_DIAG 0x7
-/* command flags */
-#define FXP_CB_COMMAND_SF 0x0008 /* simple/flexible mode */
-#define FXP_CB_COMMAND_I 0x2000 /* generate interrupt on completion */
-#define FXP_CB_COMMAND_S 0x4000 /* suspend on completion */
-#define FXP_CB_COMMAND_EL 0x8000 /* end of list */
-
-/*
- * RFA definitions
- */
-
-struct fxp_rfa {
- volatile u_int16_t rfa_status;
- volatile u_int16_t rfa_control;
- volatile u_int8_t link_addr[4];
- volatile u_int8_t rbd_addr[4];
- volatile u_int16_t actual_size;
- volatile u_int16_t size;
-};
-#define FXP_RFA_STATUS_RCOL 0x0001 /* receive collision */
-#define FXP_RFA_STATUS_IAMATCH 0x0002 /* 0 = matches station address */
-#define FXP_RFA_STATUS_S4 0x0010 /* receive error from PHY */
-#define FXP_RFA_STATUS_TL 0x0020 /* type/length */
-#define FXP_RFA_STATUS_FTS 0x0080 /* frame too short */
-#define FXP_RFA_STATUS_OVERRUN 0x0100 /* DMA overrun */
-#define FXP_RFA_STATUS_RNR 0x0200 /* no resources */
-#define FXP_RFA_STATUS_ALIGN 0x0400 /* alignment error */
-#define FXP_RFA_STATUS_CRC 0x0800 /* CRC error */
-#define FXP_RFA_STATUS_OK 0x2000 /* packet received okay */
-#define FXP_RFA_STATUS_C 0x8000 /* packet reception complete */
-#define FXP_RFA_CONTROL_SF 0x08 /* simple/flexible memory mode */
-#define FXP_RFA_CONTROL_H 0x10 /* header RFD */
-#define FXP_RFA_CONTROL_S 0x4000 /* suspend after reception */
-#define FXP_RFA_CONTROL_EL 0x8000 /* end of list */
-
-/*
- * Statistics dump area definitions
- */
-struct fxp_stats {
- volatile u_int32_t tx_good;
- volatile u_int32_t tx_maxcols;
- volatile u_int32_t tx_latecols;
- volatile u_int32_t tx_underruns;
- volatile u_int32_t tx_lostcrs;
- volatile u_int32_t tx_deffered;
- volatile u_int32_t tx_single_collisions;
- volatile u_int32_t tx_multiple_collisions;
- volatile u_int32_t tx_total_collisions;
- volatile u_int32_t rx_good;
- volatile u_int32_t rx_crc_errors;
- volatile u_int32_t rx_alignment_errors;
- volatile u_int32_t rx_rnr_errors;
- volatile u_int32_t rx_overrun_errors;
- volatile u_int32_t rx_cdt_errors;
- volatile u_int32_t rx_shortframes;
- volatile u_int32_t completion_status;
-};
-#define FXP_STATS_DUMP_COMPLETE 0xa005
-#define FXP_STATS_DR_COMPLETE 0xa007
-
-/*
- * Serial EEPROM control register bits
- */
-#define FXP_EEPROM_EESK 0x01 /* shift clock */
-#define FXP_EEPROM_EECS 0x02 /* chip select */
-#define FXP_EEPROM_EEDI 0x04 /* data in */
-#define FXP_EEPROM_EEDO 0x08 /* data out */
-
-/*
- * Serial EEPROM opcodes, including start bit
- */
-#define FXP_EEPROM_OPC_ERASE 0x4
-#define FXP_EEPROM_OPC_WRITE 0x5
-#define FXP_EEPROM_OPC_READ 0x6
-
-/*
- * Management Data Interface opcodes
- */
-#define FXP_MDI_WRITE 0x1
-#define FXP_MDI_READ 0x2
-
-/*
- * PHY device types
- */
-#define FXP_PHY_DEVICE_MASK 0x3f00
-#define FXP_PHY_SERIAL_ONLY 0x8000
-#define FXP_PHY_NONE 0
-#define FXP_PHY_82553A 1
-#define FXP_PHY_82553C 2
-#define FXP_PHY_82503 3
-#define FXP_PHY_DP83840 4
-#define FXP_PHY_80C240 5
-#define FXP_PHY_80C24 6
-#define FXP_PHY_82555 7
-#define FXP_PHY_DP83840A 10
-#define FXP_PHY_82555B 11
diff --git a/c/src/libchip/network/open_eth.c b/c/src/libchip/network/open_eth.c
deleted file mode 100644
index 88df0882cf..0000000000
--- a/c/src/libchip/network/open_eth.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * RTEMS driver for Opencores Ethernet Controller
- *
- * Weakly based on dec21140 rtems driver and open_eth linux driver
- * Written by Jiri Gaisler, Gaisler Research
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- *
- */
-
-/*
- * This driver current only supports architectures with the old style
- * exception processing. The following checks try to keep this
- * from being compiled on systems which can't support this driver.
- *
- * NOTE: The i386, ARM, and PowerPC use a different interrupt API than
- * that used by this driver.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#if defined(__i386__) || defined(__arm__) || defined(__PPC__)
- #define OPENETH_NOT_SUPPORTED
-#endif
-
-#if !defined(OPENETH_NOT_SUPPORTED)
-#include <bsp.h>
-#include <rtems.h>
-
-#include <bsp.h>
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <libchip/open_eth.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>
-
-#ifdef malloc
-#undef malloc
-#endif
-#ifdef free
-#undef free
-#endif
-
-extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
-
- /*
-#define OPEN_ETH_DEBUG
- */
-
-#ifdef CPU_U32_FIX
-extern void ipalign(struct mbuf *m);
-#endif
-
-/* message descriptor entry */
-struct MDTX
-{
- char *buf;
-};
-
-struct MDRX
-{
- struct mbuf *m;
-};
-
-/*
- * Number of OCs supported by this driver
- */
-#define NOCDRIVER 1
-
-/*
- * Receive buffer size -- Allow for a full ethernet packet including CRC
- */
-#define RBUF_SIZE 1536
-
-#define ET_MINLEN 64 /* minimum message length */
-
-/*
- * RTEMS event used by interrupt handler to signal driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/*
- * RTEMS event used to start transmit daemon.
- * This must not be the same as INTERRUPT_EVENT.
- */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
- /* event to send when tx buffers become available */
-#define OPEN_ETH_TX_WAIT_EVENT RTEMS_EVENT_3
-
- /* suspend when all TX descriptors exhausted */
- /*
-#define OETH_SUSPEND_NOTXBUF
- */
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/*
- * Per-device data
- */
-struct open_eth_softc
-{
-
- struct arpcom arpcom;
-
- oeth_regs *regs;
-
- int acceptBroadcast;
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- unsigned int tx_ptr;
- unsigned int rx_ptr;
- unsigned int txbufs;
- unsigned int rxbufs;
- struct MDTX *txdesc;
- struct MDRX *rxdesc;
- rtems_vector_number vector;
- unsigned int en100MHz;
-
- /*
- * Statistics
- */
- unsigned long rxInterrupts;
- unsigned long rxPackets;
- unsigned long rxLengthError;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxOverrun;
- unsigned long rxMiss;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txDeferred;
- unsigned long txHeartbeat;
- unsigned long txLateCollision;
- unsigned long txRetryLimit;
- unsigned long txUnderrun;
- unsigned long txLostCarrier;
- unsigned long txRawWait;
-};
-
-static struct open_eth_softc oc;
-
-/* OPEN_ETH interrupt handler */
-
-static rtems_isr
-open_eth_interrupt_handler (rtems_vector_number v)
-{
- uint32_t status;
-
- /* read and clear interrupt cause */
-
- status = oc.regs->int_src;
- oc.regs->int_src = status;
-
- /* Frame received? */
-
- if (status & (OETH_INT_RXF | OETH_INT_RXE))
- {
- oc.rxInterrupts++;
- rtems_bsdnet_event_send (oc.rxDaemonTid, INTERRUPT_EVENT);
- }
-#ifdef OETH_SUSPEND_NOTXBUF
- if (status & (OETH_INT_MASK_TXB | OETH_INT_MASK_TXC | OETH_INT_MASK_TXE))
- {
- oc.txInterrupts++;
- rtems_bsdnet_event_send (oc.txDaemonTid, OPEN_ETH_TX_WAIT_EVENT);
- }
-#endif
- /*
-#ifdef __leon__
- LEON_Clear_interrupt(v-0x10);
-#endif
- */
-}
-
-static uint32_t read_mii(uint32_t addr)
-{
- while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
- oc.regs->miiaddress = addr << 8;
- oc.regs->miicommand = OETH_MIICOMMAND_RSTAT;
- while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
- if (!(oc.regs->miistatus & OETH_MIISTATUS_NVALID))
- return(oc.regs->miirx_data);
- else {
- printf("open_eth: failed to read mii\n");
- return (0);
- }
-}
-
-static void write_mii(uint32_t addr, uint32_t data)
-{
- while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
- oc.regs->miiaddress = addr << 8;
- oc.regs->miitx_data = data;
- oc.regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
- while (oc.regs->miistatus & OETH_MIISTATUS_BUSY) {}
-}
-/*
- * Initialize the ethernet hardware
- */
-static void
-open_eth_initialize_hardware (struct open_eth_softc *sc)
-{
- struct mbuf *m;
- int i;
- int mii_cr = 0;
-
- oeth_regs *regs;
-
- regs = sc->regs;
-
- /* Reset the controller. */
-
- regs->ctrlmoder = 0;
- regs->moder = OETH_MODER_RST; /* Reset ON */
- regs->moder = 0; /* Reset OFF */
-
- /* reset PHY and wait for complettion */
- mii_cr = 0x3300;
- if (!sc->en100MHz) mii_cr = 0;
- write_mii(0, mii_cr | 0x8000);
- while (read_mii(0) & 0x8000) {}
- if (!sc->en100MHz) write_mii(0, 0);
- mii_cr = read_mii(0);
- printf("open_eth: driver attached, PHY config : 0x%04" PRIx32 "\n", read_mii(0));
-
-#ifdef OPEN_ETH_DEBUG
- printf("mii_cr: %04x\n", mii_cr);
- for (i=0;i<21;i++)
- printf("mii_reg %2d : 0x%04x\n", i, read_mii(i));
-#endif
-
- /* Setting TXBD base to sc->txbufs */
-
- regs->tx_bd_num = sc->txbufs;
-
- /* Initialize rx/tx pointers. */
-
- sc->rx_ptr = 0;
- sc->tx_ptr = 0;
-
- /* Set min/max packet length */
- regs->packet_len = 0x00400600;
-
- /* Set IPGT register to recomended value */
- regs->ipgt = 0x00000015;
-
- /* Set IPGR1 register to recomended value */
- regs->ipgr1 = 0x0000000c;
-
- /* Set IPGR2 register to recomended value */
- regs->ipgr2 = 0x00000012;
-
- /* Set COLLCONF register to recomended value */
- regs->collconf = 0x000f003f;
-
- /* initialize TX descriptors */
-
- sc->txdesc = calloc(sc->txbufs, sizeof(*sc->txdesc));
- for (i = 0; i < sc->txbufs; i++)
- {
- sc->regs->xd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
- sc->txdesc[i].buf = calloc(1, OETH_MAXBUF_LEN);
-#ifdef OPEN_ETH_DEBUG
- printf("TXBUF: %08x\n", (int) sc->txdesc[i].buf);
-#endif
- }
- sc->regs->xd[sc->txbufs - 1].len_status |= OETH_TX_BD_WRAP;
-
- /* allocate RX buffers */
-
- sc->rxdesc = calloc(sc->rxbufs, sizeof(*sc->rxdesc));
- for (i = 0; i < sc->rxbufs; i++)
- {
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- sc->rxdesc[i].m = m;
- sc->regs->xd[i + sc->txbufs].addr = mtod (m, uint32_t*);
- sc->regs->xd[i + sc->txbufs].len_status =
- OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ;
-#ifdef OPEN_ETH_DEBUG
- printf("RXBUF: %08x\n", (int) sc->rxdesc[i].m);
-#endif
- }
- sc->regs->xd[sc->rxbufs + sc->txbufs - 1].len_status |= OETH_RX_BD_WRAP;
-
-
- /* set ethernet address. */
-
- regs->mac_addr1 = sc->arpcom.ac_enaddr[0] << 8 | sc->arpcom.ac_enaddr[1];
-
- uint32_t mac_addr0;
- mac_addr0 = sc->arpcom.ac_enaddr[2];
- mac_addr0 <<= 8;
- mac_addr0 |= sc->arpcom.ac_enaddr[3];
- mac_addr0 <<= 8;
- mac_addr0 |= sc->arpcom.ac_enaddr[4];
- mac_addr0 <<= 8;
- mac_addr0 |= sc->arpcom.ac_enaddr[5];
-
- regs->mac_addr0 = mac_addr0;
-
- /* install interrupt vector */
- set_vector (open_eth_interrupt_handler, sc->vector, 1);
-
- /* clear all pending interrupts */
-
- regs->int_src = 0xffffffff;
-
- /* MAC mode register: PAD, IFG, CRCEN */
-
- regs->moder = OETH_MODER_PAD | OETH_MODER_CRCEN | ((mii_cr & 0x100) << 2);
-
- /* enable interrupts */
-
- regs->int_mask = OETH_INT_MASK_RXF | OETH_INT_MASK_RXE | OETH_INT_MASK_RXC;
-
-#ifdef OETH_SUSPEND_NOTXBUF
- regs->int_mask |= OETH_INT_MASK_TXB | OETH_INT_MASK_TXC | OETH_INT_MASK_TXE | OETH_INT_BUSY;*/
- sc->regs->xd[(sc->txbufs - 1)/2].len_status |= OETH_TX_BD_IRQ;
- sc->regs->xd[sc->txbufs - 1].len_status |= OETH_TX_BD_IRQ;
-#endif
-
- regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
-}
-
-static void
-open_eth_rxDaemon (void *arg)
-{
- struct ether_header *eh;
- struct open_eth_softc *dp = (struct open_eth_softc *) &oc;
- struct ifnet *ifp = &dp->arpcom.ac_if;
- struct mbuf *m;
- unsigned int len;
- uint32_t len_status;
- unsigned int bad;
- rtems_event_set events;
-
-
- for (;;)
- {
-
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
-#ifdef OPEN_ETH_DEBUG
- printf ("r\n");
-#endif
-
- while (!
- ((len_status =
- dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status) & OETH_RX_BD_EMPTY))
- {
- bad = 0;
- if (len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT))
- {
- dp->rxLengthError++;
- bad = 1;
- }
- if (len_status & OETH_RX_BD_DRIBBLE)
- {
- dp->rxNonOctet++;
- bad = 1;
- }
- if (len_status & OETH_RX_BD_CRCERR)
- {
- dp->rxBadCRC++;
- bad = 1;
- }
- if (len_status & OETH_RX_BD_OVERRUN)
- {
- dp->rxOverrun++;
- bad = 1;
- }
- if (len_status & OETH_RX_BD_MISS)
- {
- dp->rxMiss++;
- bad = 1;
- }
- if (len_status & OETH_RX_BD_LATECOL)
- {
- dp->rxCollision++;
- bad = 1;
- }
-
- if (!bad)
- {
- /* pass on the packet in the receive buffer */
- len = len_status >> 16;
- m = (struct mbuf *) (dp->rxdesc[dp->rx_ptr].m);
- m->m_len = m->m_pkthdr.len =
- len - 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
-
- ether_input (ifp, eh, m);
-
- /* get a new mbuf */
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- dp->rxdesc[dp->rx_ptr].m = m;
- dp->regs->xd[dp->rx_ptr + dp->txbufs].addr =
- (uint32_t*) mtod (m, void *);
- dp->rxPackets++;
- }
-
- dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status =
- (dp->regs->xd[dp->rx_ptr+dp->txbufs].len_status &
- ~OETH_TX_BD_STATS) | OETH_TX_BD_READY;
- dp->rx_ptr = (dp->rx_ptr + 1) % dp->rxbufs;
- }
- }
-}
-
-static int inside = 0;
-static void
-sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct open_eth_softc *dp = ifp->if_softc;
- unsigned char *temp;
- struct mbuf *n;
- uint32_t len, len_status;
-
- if (inside) printf ("error: sendpacket re-entered!!\n");
- inside = 1;
- /*
- * Waiting for Transmitter ready
- */
- n = m;
-
- while (dp->regs->xd[dp->tx_ptr].len_status & OETH_TX_BD_READY)
- {
-#ifdef OETH_SUSPEND_NOTXBUF
- rtems_event_set events;
- rtems_bsdnet_event_receive (OPEN_ETH_TX_WAIT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_MILLISECONDS_TO_TICKS(500), &events);
-#endif
- }
-
- len = 0;
- temp = (unsigned char *) dp->txdesc[dp->tx_ptr].buf;
- dp->regs->xd[dp->tx_ptr].addr = (uint32_t*) temp;
-
-#ifdef OPEN_ETH_DEBUG
- printf("TXD: 0x%08x\n", (int) m->m_data);
-#endif
- for (;;)
- {
-#ifdef OPEN_ETH_DEBUG
- int i;
- printf("MBUF: 0x%08x : ", (int) m->m_data);
- for (i=0;i<m->m_len;i++)
- printf("%x%x", (m->m_data[i] >> 4) & 0x0ff, m->m_data[i] & 0x0ff);
- printf("\n");
-#endif
- len += m->m_len;
- if (len <= RBUF_SIZE)
- memcpy ((void *) temp, (char *) m->m_data, m->m_len);
- temp += m->m_len;
- if ((m = m->m_next) == NULL)
- break;
- }
-
- m_freem (n);
-
- /* don't send long packets */
-
- if (len <= RBUF_SIZE) {
-
- /* Clear all of the status flags. */
- len_status = dp->regs->xd[dp->tx_ptr].len_status & ~OETH_TX_BD_STATS;
-
- /* If the frame is short, tell CPM to pad it. */
- if (len < ET_MINLEN) {
- len_status |= OETH_TX_BD_PAD;
- len = ET_MINLEN;
- }
- else
- len_status &= ~OETH_TX_BD_PAD;
-
- /* write buffer descriptor length and status */
- len_status &= 0x0000ffff;
- len_status |= (len << 16) | (OETH_TX_BD_READY | OETH_TX_BD_CRC);
- dp->regs->xd[dp->tx_ptr].len_status = len_status;
- dp->tx_ptr = (dp->tx_ptr + 1) % dp->txbufs;
-
- }
- inside = 0;
-}
-
-/*
- * Driver transmit daemon
- */
-static void
-open_eth_txDaemon (void *arg)
-{
- struct open_eth_softc *sc = (struct open_eth_softc *) arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for (;;)
- {
- /*
- * Wait for packet
- */
-
- rtems_bsdnet_event_receive (START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT, &events);
-#ifdef OPEN_ETH_DEBUG
- printf ("t\n");
-#endif
-
- /*
- * Send packets till queue is empty
- */
- for (;;)
- {
- /*
- * Get the next mbuf chain to transmit.
- */
- IF_DEQUEUE (&ifp->if_snd, m);
- if (!m)
- break;
- sendpacket (ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-
-static void
-open_eth_start (struct ifnet *ifp)
-{
- struct open_eth_softc *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/*
- * Initialize and start the device
- */
-static void
-open_eth_init (void *arg)
-{
- struct open_eth_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- if (sc->txDaemonTid == 0)
- {
-
- /*
- * Set up OPEN_ETH hardware
- */
- open_eth_initialize_hardware (sc);
-
- /*
- * Start driver tasks
- */
- sc->rxDaemonTid = rtems_bsdnet_newproc ("DCrx", 4096,
- open_eth_rxDaemon, sc);
- sc->txDaemonTid = rtems_bsdnet_newproc ("DCtx", 4096,
- open_eth_txDaemon, sc);
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
-}
-
-/*
- * Stop the device
- */
-static void
-open_eth_stop (struct open_eth_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- sc->regs->moder = 0; /* RX/TX OFF */
- sc->regs->moder = OETH_MODER_RST; /* Reset ON */
- sc->regs->moder = 0; /* Reset OFF */
-}
-
-
-/*
- * Show interface statistics
- */
-static void
-open_eth_stats (struct open_eth_softc *sc)
-{
- printf (" Rx Packets:%-8lu", sc->rxPackets);
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Length:%-8lu", sc->rxLengthError);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Overrun:%-8lu", sc->rxOverrun);
- printf (" Miss:%-8lu", sc->rxMiss);
- printf (" Collision:%-8lu\n", sc->rxCollision);
-
- printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
- printf (" Deferred:%-8lu", sc->txDeferred);
- printf (" Missed Hearbeat:%-8lu\n", sc->txHeartbeat);
- printf (" No Carrier:%-8lu", sc->txLostCarrier);
- printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
- printf (" Late Collision:%-8lu\n", sc->txLateCollision);
- printf (" Underrun:%-8lu", sc->txUnderrun);
- printf (" Raw output wait:%-8lu\n", sc->txRawWait);
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-open_eth_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct open_eth_softc *sc = 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:
- open_eth_stop (sc);
- break;
-
- case IFF_UP:
- open_eth_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- open_eth_stop (sc);
- open_eth_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- open_eth_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/*
- * Attach an OPEN_ETH driver to the system
- */
-int
-rtems_open_eth_driver_attach (struct rtems_bsdnet_ifconfig *config,
- open_eth_configuration_t * chip)
-{
- struct open_eth_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /* parse driver name */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- sc = &oc;
- ifp = &sc->arpcom.ac_if;
- memset (sc, 0, sizeof (*sc));
-
- if (config->hardware_address)
- {
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address,
- ETHER_ADDR_LEN);
- }
- else
- {
- memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
- }
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- sc->acceptBroadcast = !config->ignore_broadcast;
- sc->regs = chip->base_address;
- sc->vector = chip->vector;
- sc->txbufs = chip->txd_count;
- sc->rxbufs = chip->rxd_count;
- sc->en100MHz = chip->en100MHz;
-
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = open_eth_init;
- ifp->if_ioctl = open_eth_ioctl;
- ifp->if_start = open_eth_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;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
-
-#ifdef OPEN_ETH_DEBUG
- printf ("OPEN_ETH : driver has been attached\n");
-#endif
- return 1;
-};
-
-#endif /* OPENETH_NOT_SUPPORTED */
diff --git a/c/src/libchip/network/smc91111.c b/c/src/libchip/network/smc91111.c
deleted file mode 100644
index 45c87e8245..0000000000
--- a/c/src/libchip/network/smc91111.c
+++ /dev/null
@@ -1,1653 +0,0 @@
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <errno.h>
-
-#include <bsp.h>
-
-/*
- * This driver currently only supports SPARC with the old style
- * exception processing and the Phytec Phycore MPC5554.
- * This test keeps it from being compiled on systems which haven't been
- * tested.
- *
- */
-
-#if defined(HAS_SMC91111)
- #define SMC91111_SUPPORTED
-#endif
-
-#if defined(HAS_SMC91111)
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <inttypes.h>
-#include <rtems/error.h>
-#include <rtems/rtems_bsdnet.h>
-#include <rtems/irq-extension.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>
-
-#define SMC91111_INTERRUPT_EVENT RTEMS_EVENT_1 /* RTEMS event used by interrupt handler to signal driver tasks. This must not be any of the events used by the network task synchronization. */
-#define SMC91111_START_TRANSMIT_EVENT RTEMS_EVENT_2 /* RTEMS event used to start transmit/receive daemon. This must not be the same as INTERRUPT_EVENT. */
-#define SMC91111_TX_WAIT_EVENT RTEMS_EVENT_3 /* event to send when tx buffers become available */
-
-/* Set to perms of:
- 0 disables all debug output
- 1 for process debug output
- 2 for added data IO output: get_reg, put_reg
- 4 for packet allocation/free output
- 8 for only startup status, so we can tell we're installed OK
- 16 dump phy read/write
- 32 precise register dump
- 64 dump packets
-*/
-/*#define DEBUG (-1)*/
-/*#define DEBUG (-1 & ~(16))*/
-#define DEBUG (0)
-/*#define DEBUG (1)*/
-
-#include "smc91111config.h"
-#include <libchip/smc91111.h>
-
-#ifdef BSP_FEATURE_IRQ_EXTENSION
- #include <rtems/irq-extension.h>
-#endif
-
-struct lan91cxx_priv_data smc91111;
-
-int lan91cxx_hardware_init(struct lan91cxx_priv_data *cpd);
-static uint16_t lan91cxx_read_phy(struct lan91cxx_priv_data *cpd,
- uint8_t phyaddr, uint8_t phyreg);
-static void lan91cxx_write_phy(struct lan91cxx_priv_data *cpd,
- uint8_t phyaddr, uint8_t phyreg,
- uint16_t value);
-static void lan91cxx_start(struct ifnet *ifp);
-static void smc91111_start(struct ifnet *ifp);
-static int smc_probe(struct lan91cxx_priv_data *cpd);
-static void smc91111_stop(struct lan91cxx_priv_data *cpd);
-static void smc91111_init(void *arg);
-#ifndef BSP_FEATURE_IRQ_EXTENSION
-static void lan91cxx_finish_sent(struct lan91cxx_priv_data *cpd);
-#endif
-#if 0
-static int lan91cxx_phy_fixed(struct lan91cxx_priv_data *cpd);
-static void lan91cxx_phy_configure(struct lan91cxx_priv_data *cpd);
-#endif
-
-#define min(l,r) ((l) < (r) ? (l) : (r))
-#define max(l,r) ((l) > (r) ? (l) : (r))
-
-#ifndef BSP_FEATURE_IRQ_EXTENSION
-/* \ ------------- Interrupt ------------- \ */
-static void lan91cxx_interrupt_handler(void *arg)
-{
- struct lan91cxx_priv_data *cpd = arg;
- unsigned short irq, event;
- unsigned short oldbase;
- unsigned short oldpointer;
- INCR_STAT(cpd, interrupts);
- DEBUG_FUNCTION();
-
- HAL_READ_UINT16(cpd->base + (LAN91CXX_BS), oldbase);
- oldpointer = get_reg(cpd, LAN91CXX_POINTER);
-
- /* Get the (unmasked) requests */
- irq = get_reg(cpd, LAN91CXX_INTERRUPT);
- event = irq & (irq >> 8) & 0xff;
- if (0 == event)
- return;
-
- /*put_reg(cpd, LAN91CXX_INTERRUPT, irq ); */ /* ack interrupts */
-
- if (event & LAN91CXX_INTERRUPT_ERCV_INT) {
- db_printf("Early receive interrupt");
- } else if (event & LAN91CXX_INTERRUPT_EPH_INT) {
- db_printf("ethernet protocol handler failures");
- } else if (event & LAN91CXX_INTERRUPT_RX_OVRN_INT) {
- db_printf("receive overrun");
- } else if (event & LAN91CXX_INTERRUPT_ALLOC_INT) {
- db_printf("allocation interrupt");
- } else {
-
- if (event & LAN91CXX_INTERRUPT_TX_SET) {
- db_printf("#*tx irq\n");
- lan91cxx_finish_sent(cpd);
- put_reg(cpd, LAN91CXX_INTERRUPT,
- (irq & 0xff00) | LAN91CXX_INTERRUPT_TX_INT);
-
- /*rtems_bsdnet_event_send (cpd->txDaemonTid, SMC91111_INTERRUPT_EVENT); */
- /*put_reg(cpd, LAN91CXX_INTERRUPT, (irq & 0xff00) | LAN91CXX_INTERRUPT_TX_INT); */
- /*rtems_bsdnet_event_send (cpd->txDaemonTid, SMC91111_TX_WAIT_EVENT); */
- }
- if (event & LAN91CXX_INTERRUPT_RCV_INT) {
- db_printf("#*rx irq\n");
- rtems_bsdnet_event_send(cpd->rxDaemonTid,
- SMC91111_INTERRUPT_EVENT);
- }
- if (event &
- ~(LAN91CXX_INTERRUPT_TX_SET | LAN91CXX_INTERRUPT_RCV_INT))
- db_printf("Unknown interrupt\n");
- }
- db_printf("out %s\n", __FUNCTION__);
-
- put_reg(cpd, LAN91CXX_POINTER, oldpointer);
- HAL_WRITE_UINT16(cpd->base + (LAN91CXX_BS), oldbase);
-}
-#endif
-
-/* \ ------------- Rx receive ------------- \ */
-
- /**/
-/* This function is called as a result of the "readpacket()" call.*/
-/* Its job is to actually fetch data for a packet from the hardware once*/
-/* memory buffers have been allocated for the packet. Note that the buffers*/
-/* may come in pieces, using a mbuf list. */
-static void lan91cxx_recv(struct lan91cxx_priv_data *cpd, struct mbuf *m)
-{
- struct ifnet *ifp = &cpd->arpcom.ac_if;
- struct ether_header *eh;
- short mlen = 0, plen;
- char *start;
- rxd_t *data = NULL, val;
-#if DEBUG & 64
- rxd_t lp = 0;
-#else
- /* start is only read with debug enabled */
- (void)start;
-#endif
- struct mbuf *n;
- dbg_prefix = "<";
-
- DEBUG_FUNCTION();
- INCR_STAT(cpd, rx_deliver);
-
- /* ############ read packet ############ */
-
- put_reg(cpd, LAN91CXX_POINTER,
- (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
- LAN91CXX_POINTER_AUTO_INCR));
- val = get_data(cpd);
-
- /* packet length (minus header/footer) */
-#ifdef LAN91CXX_32BIT_RX
- val = CYG_LE32_TO_CPU(val);
- plen = (val >> 16) - 6;
-#else
- val = CYG_LE16_TO_CPU(val);
- plen = get_data(cpd);
- plen = CYG_LE16_TO_CPU(plen) - 6;
-#endif
-
- if ( cpd->c111_reva || LAN91CXX_RX_STATUS_IS_ODD(cpd, val) ) /* RevA Odd-bit BUG */
- plen++;
-
- for (n = m; n; n = n->m_next) {
-#ifdef LAN91CXX_32BIT_RX
- if (mlen == 2) {
-#if DEBUG & 64
- db_printf("Appending to last apacket\n");
-#endif
-
- val = get_data(cpd);
- *((unsigned short *)data) = (val >> 16) & 0xffff;
- plen -= 2;
- data = (rxd_t *) n->m_data;
- start = (char *)data;
- mlen = n->m_len;
- if ((data) && (mlen > 1)) {
- *(unsigned short *)data = (val & 0xffff);
- data = (rxd_t *)((unsigned short *)data + 1);
- plen -= 2;
- mlen -= 2;
- }
- } else {
- data = (rxd_t *) n->m_data;
- start = (char *)data;
- mlen = n->m_len;
- }
-#else
- data = (rxd_t *) n->m_data;
- start = (char *)data;
- mlen = n->m_len;
-#endif
-
- db1_printf("<[packet : mlen 0x%x, plen 0x%x]\n", mlen, plen);
-
- if (data) {
- while (mlen >= sizeof(*data)) {
-#ifdef LAN91CXX_32BIT_RX
- val = get_data(cpd);
- *(unsigned short *)data = (val >> 16) & 0xffff;
- data = (rxd_t *)((unsigned short *)data + 1);
- *(unsigned short *)data = (val & 0xffff);
- data = (rxd_t *)((unsigned short *)data + 1);
-#else
- *data++ = get_data(cpd);
-#endif
- mlen -= sizeof(*data);
- plen -= sizeof(*data);
- }
- } else { /* must actively discard ie. read it from the chip anyway. */
- while (mlen >= sizeof(*data)) {
- (void)get_data(cpd);
- mlen -= sizeof(*data);
- plen -= sizeof(*data);
- }
- }
-
-#if DEBUG & 64
- lp = 0;
- while (((int)start) < ((int)data)) {
- unsigned char a = *(start++);
- unsigned char b = *(start++);
- db64_printf("%02x %02x ", a, b);
- lp += 2;
- if (lp >= 16) {
- db64_printf("\n");
- lp = 0;
- }
- }
- db64_printf(" \n");
-#endif
- }
- val = get_data(cpd); /* Read control word (and potential data) unconditionally */
-#ifdef LAN91CXX_32BIT_RX
- if (plen & 2) {
- if (data && (mlen>1) ) {
- *(unsigned short *)data = (val >> 16) & 0xffff;
- data = (rxd_t *)((unsigned short *)data + 1);
- val <<= 16;
- mlen-=2;
- }
- }
- if ( (plen & 1) && data && (mlen>0) )
- *(unsigned char *)data = val >> 24;
-#else
- val = CYG_LE16_TO_CPU(val);
- cp = (unsigned char *)data;
-
- CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX, "Controlbyte is not for Rx");
- CYG_ASSERT((1 == mlen) == (0 != LAN91CXX_CONTROLBYTE_IS_ODD(cpd, val)),
- "Controlbyte does not match");
- if (data && (1 == mlen) && LAN91CXX_CONTROLBYTE_IS_ODD(cpd, val)) {
- cval = val & 0x00ff; /* last byte contains data */
- *cp = cval;
- }
-#endif
-
- val = get_reg(cpd, LAN91CXX_FIFO_PORTS);
- if (0x8000 & val) { /* Then the Rx FIFO is empty */
- db4_printf
- ("<+Rx packet NOT freed, stat is %x (expected %x)\n",
- val, cpd->rxpacket);
- } else {
- db4_printf("<+Rx packet freed %x (expected %x)\n",
- 0xff & (val >> 8), cpd->rxpacket);
- }
-
- CYG_ASSERT((0xff & (val >> 8)) == cpd->rxpacket,
- "Unexpected rx packet");
-
- /* ############ free packet ############ */
- /* Free packet */
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
-
- dbg_prefix = "";
-
- /* Remove the mac header. This is different from the NetBSD stack. */
- eh = mtod(m, struct ether_header *);
- m->m_data += sizeof(struct ether_header);
- m->m_len -= sizeof(struct ether_header);
- m->m_pkthdr.len -= sizeof(struct ether_header);
-
- ether_input(ifp, eh, m);
-
-}
-
-/* allocate mbuf chain */
-static struct mbuf *smc91111_allocmbufchain(int totlen, struct ifnet *ifp)
-{
-
- struct mbuf *m, *m0, *newm;
- int len;
-
- MGETHDR(m0, M_DONTWAIT, MT_DATA);
- if (m0 == 0)
- return (0);
- m0->m_pkthdr.rcvif = ifp;
- m0->m_pkthdr.len = totlen;
- len = MHLEN;
- m = m0;
-
- /* This loop goes through and allocates mbufs for all the data we will be copying in. */
- while (totlen > 0) {
- if (totlen >= MINCLSIZE) {
- MCLGET(m, M_DONTWAIT);
- if ((m->m_flags & M_EXT) == 0)
- goto bad;
- len = MCLBYTES;
- }
-
- if (m == m0) {
- caddr_t newdata = (caddr_t)
- ALIGN(m->m_data +
- sizeof(struct ether_header)) -
- sizeof(struct ether_header);
- len -= newdata - m->m_data;
- m->m_data = newdata;
- }
-
- m->m_len = len = min(totlen, len);
-
- totlen -= len;
- if (totlen > 0) {
- MGET(newm, M_DONTWAIT, MT_DATA);
- if (newm == 0)
- goto bad;
- len = MLEN;
- m = m->m_next = newm;
- }
- }
- return (m0);
-
- bad:
- m_freem(m0);
- return (0);
-}
-
-static int readpacket(struct lan91cxx_priv_data *cpd)
-{
- struct mbuf *m;
- unsigned short stat, complen;
- struct ifnet *ifp = &cpd->arpcom.ac_if;
-#ifdef LAN91CXX_32BIT_RX
- uint32_t val;
-#endif
-
- DEBUG_FUNCTION();
-
- /* ############ read packet nr ############ */
- stat = get_reg(cpd, LAN91CXX_FIFO_PORTS);
- db1_printf("+LAN91CXX_FIFO_PORTS: 0x%04x\n", stat);
-
- if (0x8000 & stat) {
- /* Then the Rx FIFO is empty */
- db4_printf("!RxEvent with empty fifo\n");
- return 0;
- }
-
- INCR_STAT(cpd, rx_count);
-
- db4_printf("+Rx packet allocated %x (previous %x)\n",
- 0xff & (stat >> 8), cpd->rxpacket);
-
- /* There is an Rx Packet ready */
- cpd->rxpacket = 0xff & (stat >> 8);
-
- /* ############ read packet header ############ */
- /* Read status and (word) length */
- put_reg(cpd, LAN91CXX_POINTER,
- (LAN91CXX_POINTER_RCV | LAN91CXX_POINTER_READ |
- LAN91CXX_POINTER_AUTO_INCR | 0x0000));
-#ifdef LAN91CXX_32BIT_RX
- val = get_data(cpd);
- val = CYG_LE32_TO_CPU(val);
- stat = val & 0xffff;
- complen = ((val >> 16) & 0xffff) - 6; /* minus header/footer words */
-#else
- stat = get_data(cpd);
- stat = CYG_LE16_TO_CPU(stat);
- complen = get_data(cpd);
- complen = CYG_LE16_TO_CPU(len) - 6; /* minus header/footer words */
-#endif
-
-#ifdef KEEP_STATISTICS
- if (stat & LAN91CXX_RX_STATUS_ALIGNERR)
- INCR_STAT(cpd, rx_align_errors);
- /*if ( stat & LAN91CXX_RX_STATUS_BCAST ) INCR_STAT( ); */
- if (stat & LAN91CXX_RX_STATUS_BADCRC)
- INCR_STAT(cpd, rx_crc_errors);
- if (stat & LAN91CXX_RX_STATUS_TOOLONG)
- INCR_STAT(cpd, rx_too_long_frames);
- if (stat & LAN91CXX_RX_STATUS_TOOSHORT)
- INCR_STAT(cpd, rx_short_frames);
- /*if ( stat & LAN91CXX_RX_STATUS_MCAST ) INCR_STAT( ); */
-#endif /* KEEP_STATISTICS */
-
- if ((stat & LAN91CXX_RX_STATUS_BAD) == 0) {
- INCR_STAT(cpd, rx_good);
- /* Then it's OK */
-
- if (cpd->c111_reva || LAN91CXX_RX_STATUS_IS_ODD(cpd, stat)) /* RevA Odd-bit BUG */
- complen++;
-
-#if DEBUG & 1
- db_printf("good rx - stat: 0x%04x, len: 0x%04x\n", stat,
- complen);
-#endif
- /* Check for bogusly short packets; can happen in promisc mode: */
- /* Asserted against and checked by upper layer driver. */
- if (complen > sizeof(struct ether_header)) {
- /* then it is acceptable; offer the data to the network stack */
-
- complen = ((complen + 3) & ~3);
-
- m = smc91111_allocmbufchain(complen, ifp);
- {
- struct mbuf *n = m;
- db_printf("mbuf-chain:");
- while (n) {
- db_printf("[%" PRIxPTR ":%x]",
- mtod(n, uintptr_t),
- (unsigned int)(n->m_len));
- n = n->m_next;
- }
- db_printf("\n");
- }
-
- if (m) {
- /* fetch packet data into mbuf chain */
- lan91cxx_recv(cpd, m);
- return 1;
- }
- }
- /*(sc->funs->eth_drv->recv)(sc, len); */
- }
-
- /* Not OK for one reason or another... */
- db1_printf("!bad rx: stat: 0x%04x, len: 0x%04x\n", stat, complen);
-
- /* ############ free packet ############ */
- /* Free packet */
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_remrel_rx_frame);
- return 1;
-
-}
-
-static void smc91111_rxDaemon(void *arg)
-{
- struct lan91cxx_priv_data *cpd = arg;
- rtems_event_set events;
- DEBUG_FUNCTION();
-
- for (;;) {
- rtems_bsdnet_event_receive(INTERRUPT_EVENT,
- RTEMS_WAIT | RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT, &events);
-
- /* read until read fifo is empty */
- while (!(get_reg(cpd, LAN91CXX_FIFO_PORTS) & 0x8000)) {
- readpacket(cpd);
- }
- }
-}
-
-/* \ ------------- Tx send ------------- \ */
-
-static void sendpacket(struct ifnet *ifp, struct mbuf *m)
-{
- struct lan91cxx_priv_data *cpd = ifp->if_softc;
- int i, len, plen, tcr, odd;
- struct mbuf *n = m;
- unsigned short *sdata = NULL;
- unsigned short ints, control;
- uint16_t packet, status;
- dbg_prefix = ">";
- DEBUG_FUNCTION();
-
- cpd->txbusy = 1;
-
- /* Worry about the TX engine stopping. */
- tcr = get_reg(cpd, LAN91CXX_TCR);
- if (0 == (LAN91CXX_TCR_TXENA & tcr)) {
- db1_printf("> ENGINE RESTART: tcr %x\n", tcr);
- tcr |= LAN91CXX_TCR_TXENA;
- put_reg(cpd, LAN91CXX_TCR, tcr);
- }
-
- /* ############ packet allocation ############ */
-
- /* Find packet length */
- plen = 0;
- while (n) {
- plen += n->m_len;
- n = n->m_next;
- }
-
- /* Alloc new TX packet */
- do {
- put_reg(cpd, LAN91CXX_MMU_COMMAND,
- LAN91CXX_MMU_alloc_for_tx | ((plen >> 8) & 0x07));
-
- i = 1024 * 1024;
- do {
- status = get_reg(cpd, LAN91CXX_INTERRUPT);
- } while (0 == (status & LAN91CXX_INTERRUPT_ALLOC_INT)
- && (--i > 0));
- if (i)
- packet = get_reg(cpd, LAN91CXX_PNR);
- else
- packet = 0xffff;
- db1_printf(">+allocated packet %04x\n", packet);
-
- packet = packet >> 8;
- if (packet & 0x80) {
- /* Hm.. Isn't this a dead end? */
- db1_printf("Allocation failed! Retrying...\n");
- continue;
- }
- } while (0);
-
- db4_printf(">+Tx packet allocated %x (previous %x)\n",
- packet, cpd->txpacket);
-
- cpd->txpacket = packet;
-
- /* ############ assemble packet data ############ */
-
- /* prepare send */
- put_reg(cpd, LAN91CXX_PNR, packet);
- /* Note: Check FIFO state here before continuing? */
- put_reg(cpd, LAN91CXX_POINTER, LAN91CXX_POINTER_AUTO_INCR | 0x0000);
- /* Pointer is now set, and the proper bank is selected for */
- /* data writes. */
-
- /* Prepare header: */
- put_data(cpd, CYG_CPU_TO_LE16(0)); /* reserve space for status word */
- /* packet length (includes status, byte-count and control shorts) */
- put_data(cpd, CYG_CPU_TO_LE16(0x7FE & (plen + 6))); /* Always even, always < 15xx(dec) */
-
- /* Put data into buffer */
- odd = 0;
- n = m;
- while (n) {
- sdata = (unsigned short *)n->m_data;
- len = n->m_len;
-
- CYG_ASSERT(sdata, "!No sg data pointer here");
-
- /* start on an odd offset?
- * If last byte also (1byte mbuf with different pointer should not occur)
- * let following code handle it
- */
- if ( ((unsigned int)sdata & 1) && (len>1) ){
- put_data8(cpd,*(unsigned char *)sdata);
- sdata = (unsigned short *)((unsigned int)sdata + 1);
- odd = ~odd;
- len--;
- }
-
- /* speed up copying a bit, never copy last word */
- while(len >= 17){
- put_data(cpd, *(sdata));
- put_data(cpd, *(sdata+1));
- put_data(cpd, *(sdata+2));
- put_data(cpd, *(sdata+3));
- put_data(cpd, *(sdata+4));
- put_data(cpd, *(sdata+5));
- put_data(cpd, *(sdata+6));
- put_data(cpd, *(sdata+7));
- sdata += 8;
- len -= 16;
- }
-
- /* copy word wise, skip last word */
- while (len >= 3) {
- put_data(cpd, *sdata++);
- len -= sizeof(*sdata);
- }
-
- /* one or two bytes left to put into fifo */
- if ( len > 1 ){
- /* the last 2bytes */
- if ( !odd || n->m_next ){
- put_data(cpd, *sdata++);
- len -= sizeof(*sdata);
- }else{
- /* write next byte, mark that we are not at an odd offset any more,
- * remaining byte will be written outside while together with control byte.
- */
- put_data8(cpd,*(unsigned char *)sdata);
- sdata = (unsigned short *)((unsigned int)sdata + 1);
- odd = 0;
- len--;
- /*break;*/
- }
- }else if ( (len>0) && (n->m_next) ){
- /* one byte left to write, and more bytes is comming in next mbuf */
- put_data8(cpd,*(unsigned char *)sdata);
- odd = ~odd;
- }
-
- n = n->m_next;
- }
-
- /* Lay down the control short unconditionally at the end. */
- /* (or it might use random memory contents) */
- control = 0;
- if ( len > 0 ){
- if ( !odd ) {
- /* Need to set ODD flag and insert the data */
- unsigned char onebyte = *(unsigned char *)sdata;
- control = onebyte;
- control |= LAN91CXX_CONTROLBYTE_ODD;
- }else{
- put_data8(cpd,*(unsigned char *)sdata);
- }
- }
- control |= LAN91CXX_CONTROLBYTE_CRC; /* Just in case... */
- put_data(cpd, CYG_CPU_TO_LE16(control));
-
- m_freem(m);
- CYG_ASSERT(sdata, "!No sg data pointer outside");
-
- /* ############ start transmit ############ */
-
- /* Ack TX empty int and unmask it. */
- ints = get_reg(cpd, LAN91CXX_INTERRUPT) & 0xff00;
- put_reg(cpd, LAN91CXX_INTERRUPT,
- ints | LAN91CXX_INTERRUPT_TX_EMPTY_INT);
- put_reg(cpd, LAN91CXX_INTERRUPT, ints | LAN91CXX_INTERRUPT_TX_INT_M); /* notify on error only (Autorelease) */
-
- /* Enqueue the packet */
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_enq_packet);
-
- ints = get_reg(cpd, LAN91CXX_INTERRUPT);
- db1_printf(">END: ints at TX: %04x\n", ints);
- dbg_prefix = "";
-}
-
-static void smc91111_txDaemon(void *arg)
-{
- struct lan91cxx_priv_data *cpd = arg;
- struct ifnet *ifp = &cpd->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
- DEBUG_FUNCTION();
-
- for (;;) {
- /*
- * Wait for packet
- */
-
- rtems_bsdnet_event_receive
- (SMC91111_START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT, &events);
-
- /*IF_DEQUEUE (&ifp->if_snd, m);
- if (m) {
- sendpacket (ifp, m);
- } */
-
- for (;;) {
- IF_DEQUEUE(&ifp->if_snd, m);
- if (!m)
- break;
- sendpacket(ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
-
- }
-
-}
-
-/* start transmit */
-static void smc91111_start(struct ifnet *ifp)
-{
- struct lan91cxx_priv_data *cpd = ifp->if_softc;
-
- if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
- return;
-
- rtems_bsdnet_event_send(cpd->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-
-}
-
-#ifndef BSP_FEATURE_IRQ_EXTENSION
-/* called after a tx error interrupt, freet the packet */
-static void lan91cxx_finish_sent(struct lan91cxx_priv_data *cpd)
-{
- unsigned short packet, tcr;
- int saved_packet;
-
- DEBUG_FUNCTION();
-
- INCR_STAT(cpd, tx_complete);
-
- saved_packet = get_reg(cpd, LAN91CXX_PNR);
-
- /* Ack and mask TX interrupt set */
- /*ints = get_reg(cpd, LAN91CXX_INTERRUPT) & 0xff00;
- ints |= LAN91CXX_INTERRUPT_TX_SET_ACK;
- ints &= ~LAN91CXX_INTERRUPT_TX_SET_M;
- put_reg(cpd, LAN91CXX_INTERRUPT, ints); */
-
- /* Get number of completed packet and read the status word */
- packet = get_reg(cpd, LAN91CXX_FIFO_PORTS);
- db1_printf("%s:START: fifo %04x \n", __FUNCTION__, packet);
-
- {
- unsigned short reg;
-
- reg = get_reg(cpd, LAN91CXX_EPH_STATUS);
-
- /* Covering each bit in turn... */
- if (reg & LAN91CXX_STATUS_TX_UNRN)
- INCR_STAT(cpd, tx_underrun);
- if (reg & LAN91CXX_STATUS_LOST_CARR)
- INCR_STAT(cpd, tx_carrier_loss);
- if (reg & LAN91CXX_STATUS_LATCOL)
- INCR_STAT(cpd, tx_late_collisions);
- if (reg & LAN91CXX_STATUS_TX_DEFR)
- INCR_STAT(cpd, tx_deferred);
- if (reg & LAN91CXX_STATUS_SQET)
- INCR_STAT(cpd, tx_sqetesterrors);
- if (reg & LAN91CXX_STATUS_16COL)
- INCR_STAT(cpd, tx_max_collisions);
- if (reg & LAN91CXX_STATUS_MUL_COL)
- INCR_STAT(cpd, tx_mult_collisions);
- if (reg & LAN91CXX_STATUS_SNGL_COL)
- INCR_STAT(cpd, tx_single_collisions);
- if (reg & LAN91CXX_STATUS_TX_SUC)
- INCR_STAT(cpd, tx_good);
-
- cpd->stats.tx_total_collisions =
- cpd->stats.tx_late_collisions +
- cpd->stats.tx_max_collisions +
- cpd->stats.tx_mult_collisions +
- cpd->stats.tx_single_collisions;
-
- /* We do not need to look in the Counter Register (LAN91CXX_COUNTER)
- because it just mimics the info we already have above. */
- }
-
- /* We do not really care about Tx failure. Ethernet is not a reliable
- medium. But we do care about the TX engine stopping. */
- tcr = get_reg(cpd, LAN91CXX_TCR);
- if (0 == (LAN91CXX_TCR_TXENA & tcr)) {
- db1_printf("%s: ENGINE RESTART: tcr %x \n", __FUNCTION__, tcr);
- tcr |= LAN91CXX_TCR_TXENA;
- put_reg(cpd, LAN91CXX_TCR, tcr);
- }
-
- packet &= 0xff;
-
- /* and then free the packet */
- put_reg(cpd, LAN91CXX_PNR, cpd->txpacket);
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_rel_packet);
-
- while (get_reg(cpd, LAN91CXX_MMU_COMMAND) & LAN91CXX_MMU_COMMAND_BUSY) ;
- /* Don't change Packet Number Reg until busy bit is cleared */
- /* Per LAN91C111 Spec, Page 50 */
- put_reg(cpd, LAN91CXX_PNR, saved_packet);
-
-}
-#endif
-
-/* \ ------------- Helpers ------------- \ */
-
-/*
- * Show interface statistics
- */
-static void smc91111_stats(struct lan91cxx_priv_data *priv)
-{
- printf("tx_good :%-8d\n", priv->stats.tx_good);
- printf("tx_max_collisions :%-8d\n", priv->stats.tx_max_collisions);
- printf("tx_late_collisions :%-8d\n", priv->stats.tx_late_collisions);
- printf("tx_underrun :%-8d\n", priv->stats.tx_underrun);
- printf("tx_carrier_loss :%-8d\n", priv->stats.tx_carrier_loss);
- printf("tx_deferred :%-8d\n", priv->stats.tx_deferred);
- printf("tx_sqetesterrors :%-8d\n", priv->stats.tx_sqetesterrors);
- printf("tx_single_collisions:%-8d\n", priv->stats.tx_single_collisions);
- printf("tx_mult_collisions :%-8d\n", priv->stats.tx_mult_collisions);
- printf("tx_total_collisions :%-8d\n", priv->stats.tx_total_collisions);
- printf("rx_good :%-8d\n", priv->stats.rx_good);
- printf("rx_crc_errors :%-8d\n", priv->stats.rx_crc_errors);
- printf("rx_align_errors :%-8d\n", priv->stats.rx_align_errors);
- printf("rx_resource_errors :%-8d\n", priv->stats.rx_resource_errors);
- printf("rx_overrun_errors :%-8d\n", priv->stats.rx_overrun_errors);
- printf("rx_collisions :%-8d\n", priv->stats.rx_collisions);
- printf("rx_short_frames :%-8d\n", priv->stats.rx_short_frames);
- printf("rx_too_long_frames :%-8d\n", priv->stats.rx_too_long_frames);
- printf("rx_symbol_errors :%-8d\n", priv->stats.rx_symbol_errors);
- printf("interrupts :%-8d\n", priv->stats.interrupts);
- printf("rx_count :%-8d\n", priv->stats.rx_count);
- printf("rx_deliver :%-8d\n", priv->stats.rx_deliver);
- printf("rx_resource :%-8d\n", priv->stats.rx_resource);
- printf("rx_restart :%-8d\n", priv->stats.rx_restart);
- printf("tx_count :%-8d\n", priv->stats.tx_count);
- printf("tx_complete :%-8d\n", priv->stats.tx_complete);
- printf("tx_dropped :%-8d\n", priv->stats.tx_dropped);
-}
-
-/*
- * Driver ioctl handler
- */
-static int smc91111_ioctl(struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct lan91cxx_priv_data *cpd = ifp->if_softc;
- int error = 0;
- DEBUG_FUNCTION();
-
- switch (command) {
- case SIOCGIFADDR:
- case SIOCSIFADDR:
- db_printf("SIOCSIFADDR\n");
- ether_ioctl(ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- db_printf("SIOCSIFFLAGS\n");
- switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
- case IFF_RUNNING:
- smc91111_stop(cpd);
- break;
-
- case IFF_UP:
- smc91111_init(cpd);
- break;
-
- case IFF_UP | IFF_RUNNING:
- smc91111_stop(cpd);
- smc91111_init(cpd);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- db_printf("SIO_RTEMS_SHOW_STATS\n");
- smc91111_stats(cpd);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
-
- return error;
-}
-
-/*
- * Attach an SMC91111 driver to the system
- */
-int _rtems_smc91111_driver_attach (struct rtems_bsdnet_ifconfig *config,
- struct scmv91111_configuration * chip)
-{
- struct ifnet *ifp;
- struct lan91cxx_priv_data *cpd;
- int unitNumber;
- char *unitName;
- int mtu;
- DEBUG_FUNCTION();
-
- /* parse driver name */
- if ((unitNumber = rtems_bsdnet_parse_driver_name(config, &unitName)) < 0) {
- db_printf("Unitnumber < 0: %d\n", unitNumber);
- return 0;
- }
-
- db_printf("Unitnumber: %d, baseaddr: 0x%p\n", unitNumber, chip->baseaddr);
-
- cpd = &smc91111;
- ifp = &cpd->arpcom.ac_if;
- memset(cpd, 0, sizeof(*cpd));
-
- cpd->config = *chip;
- cpd->base = chip->baseaddr;
-
- if (smc_probe(cpd)) {
- return 0;
- }
-
- if (config->hardware_address) {
- memcpy(cpd->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- } else {
-#ifdef SMC91111_ENADDR_IS_SETUP
- /* The address was put in the chip at reset time. Retrieve it. */
- int i;
- for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
- unsigned short r = get_reg(cpd, LAN91CXX_IA01 + i / 2);
- cpd->arpcom.ac_enaddr[i] = r;
- cpd->arpcom.ac_enaddr[i+1] = r >> 8;
- }
-#else
- /* dummy default address */
- cpd->arpcom.ac_enaddr[0] = 0x12;
- cpd->arpcom.ac_enaddr[1] = 0x13;
- cpd->arpcom.ac_enaddr[2] = 0x14;
- cpd->arpcom.ac_enaddr[3] = 0x15;
- cpd->arpcom.ac_enaddr[4] = 0x16;
- cpd->arpcom.ac_enaddr[5] = 0x17;
-#endif
- }
-
- cpd->enaddr[0] = cpd->arpcom.ac_enaddr[0];
- cpd->enaddr[1] = cpd->arpcom.ac_enaddr[1];
- cpd->enaddr[2] = cpd->arpcom.ac_enaddr[2];
- cpd->enaddr[3] = cpd->arpcom.ac_enaddr[3];
- cpd->enaddr[4] = cpd->arpcom.ac_enaddr[4];
- cpd->enaddr[5] = cpd->arpcom.ac_enaddr[5];
- cpd->rpc_cur_mode =
- LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK |
- LAN91CXX_RPCR_ANEG;
-
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = cpd;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = smc91111_init;
- ifp->if_ioctl = smc91111_ioctl;
- ifp->if_start = smc91111_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;
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
- ether_ifattach(ifp);
-
-#if DEBUG
- printf("SMC91111 : driver has been attached\n");
-#endif
-
- return 1;
-};
-
-/* \ ------------- Initialization ------------- \ */
-
-/*
- * Initialize and start the device
- */
-static void smc91111_init(void *arg)
-{
- struct lan91cxx_priv_data *cpd = arg;
- struct ifnet *ifp = &cpd->arpcom.ac_if;
- DEBUG_FUNCTION();
-
- if (cpd->txDaemonTid == 0) {
-
- lan91cxx_hardware_init(cpd);
- lan91cxx_start(ifp);
-
- cpd->rxDaemonTid = rtems_bsdnet_newproc("DCrx", 4096,
- smc91111_rxDaemon, cpd);
- cpd->txDaemonTid =
- rtems_bsdnet_newproc("DCtx", 4096, smc91111_txDaemon, cpd);
- } else {
- lan91cxx_start(ifp);
- }
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-}
-
-/*
- * Stop the device
- */
-static void smc91111_stop(struct lan91cxx_priv_data *cpd)
-{
- struct ifnet *ifp = &cpd->arpcom.ac_if;
- DEBUG_FUNCTION();
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /* Reset chip */
- put_reg(cpd, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
- put_reg(cpd, LAN91CXX_RCR, 0);
- cpd->txbusy = cpd->within_send = 0;
-
-}
-
-int lan91cxx_hardware_init(struct lan91cxx_priv_data *cpd)
-{
- unsigned short val;
- int i;
-
- DEBUG_FUNCTION();
-
- cpd->txbusy = cpd->within_send = 0;
-
- /* install interrupt vector */
-#ifdef BSP_FEATURE_IRQ_EXTENSION
- {
- rtems_status_code sc = RTEMS_SUCCESSFUL;
-
- sc = rtems_interrupt_handler_install(
- cpd->config.vector,
- cpd->config.info,
- cpd->config.options,
- cpd->config.interrupt_wrapper,
- cpd
- );
- if (sc != RTEMS_SUCCESSFUL) {
- printf("rtems_interrupt_handler_install returned %d.\n", sc);
- return 0;
- }
- }
-#else
- {
- int rc;
-
- db_printf("Install lan91cxx isr at vec/irq %" PRIu32 "\n", cpd->config.vector);
- rc = rtems_interrupt_handler_install(cpd->config.vector, "smc91cxx",
- RTEMS_INTERRUPT_SHARED, lan91cxx_interrupt_handler, cpd);
- if (rc != RTEMS_SUCCESSFUL)
- return 0;
- }
-#endif
-
- /* Reset chip */
- put_reg(cpd, LAN91CXX_RCR, LAN91CXX_RCR_SOFT_RST);
- put_reg(cpd, LAN91CXX_RCR, 0);
- HAL_DELAY_US(100000);
- put_reg(cpd, LAN91CXX_CONFIG, 0x9000);
- put_reg(cpd, LAN91CXX_RCR, 0);
- put_reg(cpd, LAN91CXX_TCR, 0);
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
-
- val = get_reg(cpd, LAN91CXX_EPH_STATUS);
- /* probe chip by reading the signature in BS register */
- val = get_banksel(cpd);
- db9_printf("LAN91CXX - supposed BankReg @ %x = %04x\n",
- (unsigned int)(cpd->base + LAN91CXX_BS), val);
-
- if ((0xff00 & val) != 0x3300) {
- printf("No 91Cxx signature");
- printf("smsc_lan91cxx_init: No 91Cxx signature found\n");
- return 0;
- }
-
- val = get_reg(cpd, LAN91CXX_REVISION);
-
- db9_printf("LAN91CXX - type: %01x, rev: %01x\n",
- (val >> 4) & 0xf, val & 0xf);
-
- /* Set RevA flag for LAN91C111 so we can cope with the odd-bit bug. */
- cpd->c111_reva = (val == 0x3390); /* 90=A, 91=B, 92=C */
-
- /* The controller may provide a function used to set up the ESA */
- if (cpd->config_enaddr)
- (*cpd->config_enaddr) (cpd);
-
- db9_printf("LAN91CXX - status: %04x\n", val);
- /* Use statically configured ESA from the private data */
- db9_printf
- ("LAN91CXX - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
- cpd->enaddr[0], cpd->enaddr[1], cpd->enaddr[2],
- cpd->enaddr[3], cpd->enaddr[4], cpd->enaddr[5]);
- /* Set up hardware address */
- for (i = 0; i < sizeof(cpd->enaddr); i += 2)
- put_reg(cpd, LAN91CXX_IA01 + i / 2,
- cpd->enaddr[i] | (cpd->enaddr[i + 1] << 8));
-
- return 1;
-}
-
-/*
- This function is called to "start up" the interface. It may be called
- multiple times, even when the hardware is already running. It will be
- called whenever something "hardware oriented" changes and should leave
- the hardware ready to send/receive packets.
-*/
-static void lan91cxx_start(struct ifnet *ifp)
-{
- struct lan91cxx_priv_data *cpd = ifp->if_softc;
-
- uint16_t intr;
- uint16_t phy_ctl;
- int delay;
- DEBUG_FUNCTION();
-
- HAL_DELAY_US(100000);
-
- /* 91C111 Errata. Internal PHY comes up disabled. Must enable here. */
- phy_ctl = lan91cxx_read_phy(cpd, 0, LAN91CXX_PHY_CTRL);
- phy_ctl &= ~LAN91CXX_PHY_CTRL_MII_DIS;
- lan91cxx_write_phy(cpd, 0, LAN91CXX_PHY_CTRL, phy_ctl);
-
- /* Start auto-negotiation */
- put_reg(cpd, LAN91CXX_RPCR,
- LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK |
- LAN91CXX_RPCR_ANEG);
- cpd->rpc_cur_mode =
- LAN91CXX_RPCR_LEDA_RX | LAN91CXX_RPCR_LEDB_LINK |
- LAN91CXX_RPCR_ANEG;
-
- /* wait for auto-negotiation to finish. */
- /* give it ~5 seconds before giving up (no cable?) */
- delay = 50;
- while (!(lan91cxx_read_phy(cpd, 0, LAN91CXX_PHY_STAT) & 0x20)) {
- if (--delay <= 0) {
- printf("Timeout autonegotiation\n");
- break;
- }
- HAL_DELAY_US(100000);
- }
-
- put_reg(cpd, LAN91CXX_MMU_COMMAND, LAN91CXX_MMU_reset_mmu);
-
- put_reg(cpd, LAN91CXX_INTERRUPT, 0); /* disable interrupts */
- intr = get_reg(cpd, LAN91CXX_INTERRUPT);
- put_reg(cpd, LAN91CXX_INTERRUPT, intr & /* ack old interrupts */
- (LAN91CXX_INTERRUPT_TX_INT |
- LAN91CXX_INTERRUPT_TX_EMPTY_INT |
- LAN91CXX_INTERRUPT_RX_OVRN_INT | LAN91CXX_INTERRUPT_ERCV_INT));
- put_reg(cpd, LAN91CXX_RCR,
- LAN91CXX_RCR_STRIP_CRC | LAN91CXX_RCR_RXEN |
- LAN91CXX_RCR_ALMUL);
- put_reg(cpd, LAN91CXX_TCR, LAN91CXX_TCR_TXENA | LAN91CXX_TCR_PAD_EN);
- put_reg(cpd, LAN91CXX_CONTROL, LAN91CXX_CONTROL_AUTO_RELEASE); /* */
- put_reg(cpd, LAN91CXX_INTERRUPT, /* enable interrupts */
- LAN91CXX_INTERRUPT_RCV_INT_M);
-
- if ((0
-#ifdef ETH_DRV_FLAGS_PROMISC_MODE
- != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
-#endif
- ) || (ifp->if_flags & IFF_PROMISC)
- ) {
- /* Then we select promiscuous mode. */
- unsigned short rcr;
- rcr = get_reg(cpd, LAN91CXX_RCR);
- rcr |= LAN91CXX_RCR_PRMS;
- put_reg(cpd, LAN91CXX_RCR, rcr);
- }
-}
-
-/* \ ------------- Probe ------------- \ */
-
-static const char *chip_ids[15] = {
- NULL, NULL, NULL,
- /* 3 */ "SMC91C90/91C92",
- /* 4 */ "SMC91C94",
- /* 5 */ "SMC91C95",
- /* 6 */ "SMC91C96",
- /* 7 */ "SMC91C100",
- /* 8 */ "SMC91C100FD",
- /* 9 */ "SMC91C11xFD",
- NULL, NULL,
- NULL, NULL, NULL
-};
-
-static int smc_probe(struct lan91cxx_priv_data *cpd)
-{
- unsigned short bank;
- unsigned short revision_register;
-
- DEBUG_FUNCTION();
-
- /* First, see if the high byte is 0x33 */
- HAL_READ_UINT16(cpd->base + (LAN91CXX_BS), bank);
- bank = CYG_LE16_TO_CPU(bank);
- if ((bank & 0xFF00) != 0x3300) {
- db_printf("<1>Smc probe bank check 1 failed.\n");
- return -ENODEV;
- }
- /* The above MIGHT indicate a device, but I need to write to further
- test this. */
- HAL_WRITE_UINT16(cpd->base + (LAN91CXX_BS), CYG_CPU_TO_LE16(0 >> 3));
- HAL_READ_UINT16(cpd->base + (LAN91CXX_BS), bank);
- bank = CYG_LE16_TO_CPU(bank);
- if ((bank & 0xFF00) != 0x3300) {
- db_printf("<1>Smc probe bank check 2 failed.\n");
- return -ENODEV;
- }
-#if SMC_DEBUG > 3
- {
- unsigned short bank16, bank16_0, bank16_1;
- HAL_READ_UINT16(cpd->base + (LAN91CXX_BS), bank16);
- bank = CYG_LE16_TO_CPU(bank);
- HAL_READ_UINT8(cpd->base + (LAN91CXX_BS), bank16_0);
- HAL_READ_UINT8(cpd->base + (LAN91CXX_BS + 1), bank16_1);
-
- db_printf
- ("smc_probe:Bank read as a 16 bit value:0x%04x\n", bank16);
- db_printf
- ("smc_probe:Bank read as an 8 bit value:0x%02x\n",
- bank16_0);
- db_printf
- ("smc_probe:Bank + 1 read as an 8 bit value:0x%02x\n",
- bank16_1);
- }
-#endif
-
- /* check if the revision register is something that I recognize.
- These might need to be added to later, as future revisions
- could be added. */
- revision_register = get_reg(cpd, LAN91CXX_REVISION);
- if (!chip_ids[(revision_register >> 4) & 0xF]) {
- /* I don't recognize this chip, so... */
- db_printf
- ("smc_probe: IO %" PRIxPTR ": Unrecognized revision register:"
- " %x, Contact author. \n", (uintptr_t)cpd->base,
- revision_register);
-
- return -ENODEV;
- }
- db_printf("LAN91CXX(0x%x) - type: %s, rev: %01x\n",
- revision_register,
- chip_ids[(revision_register >> 4) & 0xF],
- revision_register & 0xf);
-
- /* Set RevA flag for LAN91C111 so we can cope with the odd-bit bug. */
- if (revision_register == 0x3390) {
- db_printf("!Revision A\n");
- }
-
- return 0;
-}
-
-#if 0
-/* \ ------------- PHY read/write ------------- \ */
-/*Sets the PHY to a configuration as determined by the user*/
-static int lan91cxx_phy_fixed(struct lan91cxx_priv_data *cpd)
-{
- int my_fixed_caps;
- int cfg1;
-
- DEBUG_FUNCTION();
- db4_printf("lan91cxx_phy_fixed: full duplex: %d, speed: %d\n",
- cpd->config.ctl_rfduplx, cpd->config.ctl_rspeed);
-
- /* Enter Link Disable state */
- cfg1 = lan91cxx_read_phy(cpd, 0, LAN91CXX_PHY_CONFIG1);
- cfg1 |= PHY_CFG1_LNKDIS;
- lan91cxx_write_phy(cpd, 0, LAN91CXX_PHY_CONFIG1, cfg1);
-
- /* Set our fixed capabilities, Disable auto-negotiation */
- my_fixed_caps = 0;
-
- if (cpd->config.ctl_rfduplx)
- my_fixed_caps |= LAN91CXX_PHY_CTRL_DPLX;
-
- if (cpd->config.ctl_rspeed == 100)
- my_fixed_caps |= LAN91CXX_PHY_CTRL_SPEED;
-
- /* Write capabilities to the phy control register */
- lan91cxx_write_phy(cpd, 0, LAN91CXX_PHY_CTRL, my_fixed_caps);
-
- /* Re-Configure the Receive/Phy Control register */
- put_reg(cpd, LAN91CXX_RPCR, cpd->rpc_cur_mode);
-
- return (1);
-}
-#endif
-
-#if 0
-/*Configures the specified PHY using Autonegotiation. */
-static void lan91cxx_phy_configure(struct lan91cxx_priv_data *cpd)
-{
-
- unsigned int phyaddr;
- unsigned int my_phy_caps; /* My PHY capabilities */
- unsigned int my_ad_caps; /* My Advertised capabilities */
- unsigned int status = 0;
- int failed = 0, delay;
-
- DEBUG_FUNCTION();
-
- /* Set the blocking flag */
- cpd->autoneg_active = 1;
-
- /* Get the detected phy address */
- phyaddr = cpd->phyaddr;
-
- /* Reset the PHY, setting all other bits to zero */
- lan91cxx_write_phy(cpd, 0, PHY_CNTL_REG, PHY_CNTL_RST);
-
- /* Wait for the reset to complete, or time out */
- delay = 50;
- while (delay--) {
- if (!(lan91cxx_read_phy(cpd, 0, PHY_CNTL_REG)
- & PHY_CNTL_RST)) {
- break;
- }
- HAL_DELAY_US(100000);
- }
-
- if (delay < 1) {
- db_printf("smc91111:!PHY reset timed out\n");
- goto smc_phy_configure_exit;
- }
-
- /* Read PHY Register 18, Status Output */
- cpd->lastPhy18 = lan91cxx_read_phy(cpd, 0, PHY_INT_REG);
-
- /* Enable PHY Interrupts (for register 18) */
- /* Interrupts listed here are disabled */
- lan91cxx_write_phy(cpd, 0, PHY_MASK_REG,
- PHY_INT_LOSSSYNC | PHY_INT_CWRD | PHY_INT_SSD
- | PHY_INT_ESD | PHY_INT_RPOL | PHY_INT_JAB |
- PHY_INT_SPDDET | PHY_INT_DPLXDET);
-
- /* Configure the Receive/Phy Control register */
- put_reg(cpd, LAN91CXX_RPCR, cpd->rpc_cur_mode);
-
- /* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
- my_phy_caps = lan91cxx_read_phy(cpd, phyaddr, PHY_STAT_REG);
- my_ad_caps = PHY_AD_CSMA; /* I am CSMA capable */
-
- if (my_phy_caps & PHY_STAT_CAP_T4)
- my_ad_caps |= PHY_AD_T4;
-
- if (my_phy_caps & PHY_STAT_CAP_TXF)
- my_ad_caps |= PHY_AD_TX_FDX;
-
- if (my_phy_caps & PHY_STAT_CAP_TXH)
- my_ad_caps |= PHY_AD_TX_HDX;
-
- if (my_phy_caps & PHY_STAT_CAP_TF)
- my_ad_caps |= PHY_AD_10_FDX;
-
- if (my_phy_caps & PHY_STAT_CAP_TH)
- my_ad_caps |= PHY_AD_10_HDX;
-
- /* Disable capabilities not selected by our user */
- if (cpd->config.ctl_rspeed != 100) {
- my_ad_caps &= ~(PHY_AD_T4 | PHY_AD_TX_FDX | PHY_AD_TX_HDX);
- }
-
- if (!cpd->config.ctl_rfduplx) {
- my_ad_caps &= ~(PHY_AD_TX_FDX | PHY_AD_10_FDX);
- }
-
- /* Update our Auto-Neg Advertisement Register */
- lan91cxx_write_phy(cpd, 0, PHY_AD_REG, my_ad_caps);
-
- db4_printf("smc91111:phy caps=%x\n", my_phy_caps);
- db4_printf("smc91111:phy advertised caps=%x\n", my_ad_caps);
-
- /* If the user requested no auto neg, then go set his request */
- if (!(cpd->config.ctl_autoneg)) {
- lan91cxx_phy_fixed(cpd);
-
- goto smc_phy_configure_exit;
- }
-
- /* Restart auto-negotiation process in order to advertise my caps */
- lan91cxx_write_phy(cpd, 0, PHY_CNTL_REG,
- PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
-
- /* wait for auto-negotiation to finish. */
- /* give it ~5 seconds before giving up (no cable?) */
- delay = 50;
- while (!
- ((status =
- lan91cxx_read_phy(cpd, 0, LAN91CXX_PHY_STAT)) & 0x20)) {
- if (--delay <= 0) {
- printf("Timeout autonegotiation\n");
- failed = 1;
- break;
- }
-
- /* Restart auto-negotiation if remote fault */
- if (status & PHY_STAT_REM_FLT) {
- db_printf("smc91111:PHY remote fault detected\n");
-
- /* Restart auto-negotiation */
- db_printf("smc91111:PHY restarting auto-negotiation\n");
- lan91cxx_write_phy(cpd, 0, PHY_CNTL_REG,
- PHY_CNTL_ANEG_EN |
- PHY_CNTL_ANEG_RST |
- PHY_CNTL_SPEED | PHY_CNTL_DPLX);
- }
- HAL_DELAY_US(100000);
- }
-
- /* Fail if we detected an auto-negotiate remote fault */
- if (status & PHY_STAT_REM_FLT) {
- db_printf("smc91111:PHY remote fault detected\n");
- failed = 1;
- }
-
- /* The smc_phy_interrupt() routine will be called to update lastPhy18 */
-
- /* Set our sysctl parameters to match auto-negotiation results */
- if (cpd->lastPhy18 & PHY_INT_SPDDET) {
- db_printf("smc91111:PHY 100BaseT\n");
- cpd->rpc_cur_mode |= LAN91CXX_RPCR_SPEED;
- } else {
- db_printf("smc91111:PHY 10BaseT\n");
- cpd->rpc_cur_mode &= ~LAN91CXX_RPCR_SPEED;
- }
-
- if (cpd->lastPhy18 & PHY_INT_DPLXDET) {
- db_printf("smc91111:PHY Full Duplex\n");
- cpd->rpc_cur_mode |= LAN91CXX_RPCR_DPLX;
- } else {
- db_printf("smc91111:PHY Half Duplex\n");
- cpd->rpc_cur_mode &= ~LAN91CXX_RPCR_DPLX;
- }
-
- /* Re-Configure the Receive/Phy Control register */
- put_reg(cpd, LAN91CXX_RPCR, cpd->rpc_cur_mode);
-
- smc_phy_configure_exit:
-
- /* Exit auto-negotiation */
- cpd->autoneg_active = 0;
-}
-#endif
-
-static uint16_t
-lan91cxx_read_phy(struct lan91cxx_priv_data *cpd, uint8_t phyaddr,
- uint8_t phyreg)
-{
- int i, mask, input_idx, clk_idx = 0;
- uint16_t mii_reg, value;
- uint8_t bits[64];
-
- /* 32 consecutive ones on MDO to establish sync */
- for (i = 0; i < 32; ++i)
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
-
- /* Start code <01> */
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
-
- /* Read command <10> */
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
-
- /* Output the PHY address, msb first */
- for (mask = 0x10; mask; mask >>= 1) {
- if (phyaddr & mask)
- bits[clk_idx++] =
- LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- else
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- }
-
- /* Output the phy register number, msb first */
- for (mask = 0x10; mask; mask >>= 1) {
- if (phyreg & mask)
- bits[clk_idx++] =
- LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- else
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- }
-
- /* Tristate and turnaround (1 bit times) */
- bits[clk_idx++] = 0;
-
- /* Input starts at this bit time */
- input_idx = clk_idx;
-
- /* Will input 16 bits */
- for (i = 0; i < 16; ++i)
- bits[clk_idx++] = 0;
-
- /* Final clock bit */
- bits[clk_idx++] = 0;
-
- /* Get the current MII register value */
- mii_reg = get_reg(cpd, LAN91CXX_MGMT);
-
- /* Turn off all MII Interface bits */
- mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
- LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
- HAL_DELAY_US(50);
-
- /* Clock all 64 cycles */
- for (i = 0; i < sizeof(bits); ++i) {
- /* Clock Low - output data */
- put_reg(cpd, LAN91CXX_MGMT, mii_reg | bits[i]);
- HAL_DELAY_US(50);
-
- /* Clock Hi - input data */
- put_reg(cpd, LAN91CXX_MGMT,
- mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
- HAL_DELAY_US(50);
-
- bits[i] |= get_reg(cpd, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;
- }
-
- /* Return to idle state */
- put_reg(cpd, LAN91CXX_MGMT, mii_reg);
- HAL_DELAY_US(50);
-
- /* Recover input data */
- for (value = 0, i = 0; i < 16; ++i) {
- value <<= 1;
- if (bits[input_idx++] & LAN91CXX_MGMT_MDI)
- value |= 1;
- }
-
- db16_printf("phy_read : %d : %04x\n", phyreg, value);
- return value;
-}
-
-static void
-lan91cxx_write_phy(struct lan91cxx_priv_data *cpd, uint8_t phyaddr,
- uint8_t phyreg, uint16_t value)
-{
- int i, mask, clk_idx = 0;
- uint16_t mii_reg;
- uint8_t bits[65];
-
- /* 32 consecutive ones on MDO to establish sync */
- for (i = 0; i < 32; ++i)
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
-
- /* Start code <01> */
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
-
- /* Write command <01> */
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
-
- /* Output the PHY address, msb first */
- for (mask = 0x10; mask; mask >>= 1) {
- if (phyaddr & mask)
- bits[clk_idx++] =
- LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- else
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- }
-
- /* Output the phy register number, msb first */
- for (mask = 0x10; mask; mask >>= 1) {
- if (phyreg & mask)
- bits[clk_idx++] =
- LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- else
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- }
-
- /* Tristate and turnaround (2 bit times) */
- bits[clk_idx++] = 0;
- bits[clk_idx++] = 0;
-
- /* Write out 16 bits of data, msb first */
- for (mask = 0x8000; mask; mask >>= 1) {
- if (value & mask)
- bits[clk_idx++] =
- LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MDO;
- else
- bits[clk_idx++] = LAN91CXX_MGMT_MDOE;
- }
-
- /* Final clock bit (tristate) */
- bits[clk_idx++] = 0;
-
- /* Get the current MII register value */
- mii_reg = get_reg(cpd, LAN91CXX_MGMT);
-
- /* Turn off all MII Interface bits */
- mii_reg &= ~(LAN91CXX_MGMT_MDOE | LAN91CXX_MGMT_MCLK |
- LAN91CXX_MGMT_MDI | LAN91CXX_MGMT_MDO);
- HAL_DELAY_US(50);
-
- /* Clock all cycles */
- for (i = 0; i < sizeof(bits); ++i) {
- /* Clock Low - output data */
- put_reg(cpd, LAN91CXX_MGMT, mii_reg | bits[i]);
- HAL_DELAY_US(50);
-
- /* Clock Hi - input data */
- put_reg(cpd, LAN91CXX_MGMT,
- mii_reg | bits[i] | LAN91CXX_MGMT_MCLK);
- HAL_DELAY_US(50);
-
-/* bits[i] |= get_reg(cpd, LAN91CXX_MGMT) & LAN91CXX_MGMT_MDI;*/
- }
-
- /* Return to idle state */
- put_reg(cpd, LAN91CXX_MGMT, mii_reg);
- HAL_DELAY_US(50);
-
- db16_printf("phy_write: %d : %04x\n", phyreg, value);
-}
-
-#if 0
-void lan91cxx_print_bank(int bank){
- struct lan91cxx_priv_data *cpd = &smc91111;
- int regno;
- unsigned short regval[8];
- int i;
-
- if ( bank >= 4 )
- return;
- for(i=0; i<8; i++){
- regno=i+bank<<3;
- regval[i] = get_reg(cpd, regno);
- }
- printk("---- BANK %d ----\n\r",bank);
- for(i=0; i<8; i++){
- printk("0x%x: 0x%x\n\r",i,regval[i]);
- }
-
-}
-#endif
-
-#endif
diff --git a/c/src/libchip/network/smc91111config.h b/c/src/libchip/network/smc91111config.h
deleted file mode 100644
index 8340ca23bb..0000000000
--- a/c/src/libchip/network/smc91111config.h
+++ /dev/null
@@ -1,118 +0,0 @@
-#ifndef _SMC91111_CONFIG_H_
-#define _SMC91111_CONFIG_H_
-
-/*
- * RTEMS event used by interrupt handler to signal driver tasks.
- * This must not be any of the events used by the network task synchronization.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/*
- * RTEMS event used to start transmit daemon.
- * This must not be the same as INTERRUPT_EVENT.
- */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
- /* event to send when tx buffers become available */
-#define SMC91111_TX_WAIT_EVENT RTEMS_EVENT_3
-
-
-/* Number of OCs supported by this driver*/
-#define NOCDRIVER 1
-
-/* Receive buffer size -- Allow for a full ethernet packet including CRC */
-#define RBUF_SIZE 1536
-
-#define ET_MINLEN 64 /* minimum message length */
-
-#if (MCLBYTES < RBUF_SIZE)
-# error "Driver must have MCLBYTES > RBUF_SIZE"
-#endif
-
-/* ----------------- cygdriver params ----------------- */
-
-#define LAN91CXX_32BIT_RX
-#define LAN91CXX_IS_LAN91C111
-
-/* ----------------- compat layer ----------------- */
-
-#include <stdint.h>
-
-typedef uint32_t CYG_WORD;
-typedef uint8_t CYG_BYTE;
-typedef uint16_t CYG_WORD16;
-typedef uint32_t CYG_WORD32;
-
-#ifndef CYG_SWAP16
-# define CYG_SWAP16(_x_) \
- ({ uint16_t _x = (_x_); ((_x << 8) | (_x >> 8)); })
-#endif
-
-#ifndef CYG_SWAP32
-# define CYG_SWAP32(_x_) \
- ({ uint32_t _x = (_x_); \
- ((_x << 24) | \
- ((0x0000FF00UL & _x) << 8) | \
- ((0x00FF0000UL & _x) >> 8) | \
- (_x >> 24)); })
-#endif
-
-# define CYG_CPU_TO_BE16(_x_) (_x_)
-# define CYG_CPU_TO_BE32(_x_) (_x_)
-# define CYG_BE16_TO_CPU(_x_) (_x_)
-# define CYG_BE32_TO_CPU(_x_) (_x_)
-
-# define CYG_CPU_TO_LE16(_x_) CYG_SWAP16((_x_))
-# define CYG_CPU_TO_LE32(_x_) CYG_SWAP32((_x_))
-# define CYG_LE16_TO_CPU(_x_) CYG_SWAP16((_x_))
-# define CYG_LE32_TO_CPU(_x_) CYG_SWAP32((_x_))
-
-#define CYG_MACRO_START do {
-#define CYG_MACRO_END } while (0)
-#define HAL_IO_BARRIER() \
- __asm__ volatile ( "" : : : "memory" )
-
-#define HAL_READ_UINT8( _register_, _value_ ) \
- CYG_MACRO_START \
- ((_value_) = *((volatile CYG_BYTE *)(_register_))); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define HAL_WRITE_UINT8( _register_, _value_ ) \
- CYG_MACRO_START \
- (*((volatile CYG_BYTE *)(_register_)) = (_value_)); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define HAL_READ_UINT16( _register_, _value_ ) \
- CYG_MACRO_START \
- ((_value_) = *((volatile CYG_WORD16 *)(_register_))); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define HAL_WRITE_UINT16( _register_, _value_ ) \
- CYG_MACRO_START \
- (*((volatile CYG_WORD16 *)(_register_)) = (_value_)); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define HAL_READ_UINT32( _register_, _value_ ) \
- CYG_MACRO_START \
- ((_value_) = *((volatile CYG_WORD32 *)(_register_))); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define HAL_READ_UINT16( _register_, _value_ ) \
- CYG_MACRO_START \
- ((_value_) = *((volatile CYG_WORD16 *)(_register_))); \
- HAL_IO_BARRIER (); \
- CYG_MACRO_END
-
-#define CYG_ASSERT(c,p) do { if (!(c)) { while(1) { printf(p);} }; } while(0)
-
-#define HAL_DELAY_US(p) rtems_task_wake_after (RTEMS_MICROSECONDS_TO_TICKS (p))
-
-
-#endif /* _SMC_91111_CONFIG_H_ */
-
-
diff --git a/c/src/libchip/network/sonic.c b/c/src/libchip/network/sonic.c
deleted file mode 100644
index dc97008b8d..0000000000
--- a/c/src/libchip/network/sonic.c
+++ /dev/null
@@ -1,1685 +0,0 @@
-/*
- * RTEMS NETWORK DRIVER FOR NATIONAL DP83932 `SONIC'
- * SYSTEMS-ORIENTED NETWORK INTERFACE CONTROLLER
- *
- * REUSABLE CHIP DRIVER
- *
- * References:
- *
- * 1) DP83932C-20/25/33 MHz SONIC(TM) Systems-Oriented Network Interface
- * Controller data sheet. TL/F/10492, RRD-B30M105, National Semiconductor,
- * 1995.
- *
- * 2) Software Driver Programmer's Guide for the DP83932 SONIC(TM),
- * Application Note 746, Wesley Lee and Mike Lui, TL/F/11140,
- * RRD-B30M75, National Semiconductor, March, 1991.
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- *
- * This driver was originally written and tested on a DY-4 DMV177,
- * which had a 100 Mhz PPC603e.
- *
- * This driver also works with DP83934CVUL-20/25 MHz, tested on
- * Tharsys ERC32 VME board.
- *
- * Rehaul to fix lost interrupts and buffers, and to use to use
- * interrupt-free transmission by Jiri, 22/03/1999.
- */
-
-#define __INSIDE_RTEMS_BSD_TCPIP_STACK__
-
-#include <rtems.h>
-#include <rtems/rtems_bsdnet.h>
-#include <libchip/sonic.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <errno.h>
-#include <rtems/error.h>
-
-#include <sys/param.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/sockio.h>
-
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-extern rtems_isr_entry set_vector( rtems_isr_entry, rtems_vector_number, int );
-
-#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_MBUFS)
-#include <rtems/dumpbuf.h>
-#endif
-
-/*
- * Use the top line if you want more symbols.
- */
-
-#define SONIC_STATIC static
-
-/*
- * Number of devices supported by this driver
- */
-#ifndef NSONIC
-# define NSONIC 1
-#endif
-
-/*
- *
- * As suggested by National Application Note 746, make the
- * receive resource area bigger than the receive descriptor area.
- *
- * NOTE: Changing this may break this driver since it currently
- * assumes a 1<->1 mapping.
- */
-#define RRA_EXTRA_COUNT 0
-
-/*
- * RTEMS event used by interrupt handler to signal daemons.
- */
-#define INTERRUPT_EVENT RTEMS_EVENT_1
-
-/*
- * RTEMS event used to start transmit daemon.
- * This must not be the same as INTERRUPT_EVENT.
- */
-#define START_TRANSMIT_EVENT RTEMS_EVENT_2
-
-/*
- * Largest Ethernet frame.
- */
-#define MAXIMUM_FRAME_SIZE 1518
-
-/*
- * Receive buffer size.
- * Allow for a pointer, plus a full ethernet frame (including Frame
- * Check Sequence) rounded up to a 4-byte boundary.
- */
-#define RBUF_SIZE ((sizeof (void *) + (MAXIMUM_FRAME_SIZE) + 3) & ~3)
-/* #define RBUF_WC ((((MAXIMUM_FRAME_SIZE) + 3) & ~3) / 2) */
-#define RBUF_WC (RBUF_SIZE / 2)
-
-/*
- * Macros for manipulating 32-bit pointers as 16-bit fragments
- */
-#define LSW(p) ((uint16_t)((uintptr_t)(p)))
-#define MSW(p) ((uint16_t)((uintptr_t)(p) >> 16))
-#define PTR(m,l) ((void*)(((uint16_t)(m)<<16)|(uint16_t)(l)))
-
-/*
- * Hardware-specific storage
- */
-struct sonic_softc {
- /*
- * Connection to networking code
- * This entry *must* be the first in the sonic_softc structure.
- */
- struct arpcom arpcom;
-
- /*
- * Default location of device registers
- * ===CACHE===
- * This area must be non-cacheable, guarded.
- */
- void *sonic;
-
- /*
- * Register access routines
- */
- sonic_write_register_t write_register;
- sonic_read_register_t read_register;
-
- /*
- * Interrupt vector
- */
- rtems_vector_number vector;
-
- /*
- * Data Configuration Register values
- */
- uint32_t dcr_value;
- uint32_t dc2_value;
-
- /*
- * Indicates configuration
- */
- int acceptBroadcast;
-
- /*
- * Task waiting for interrupts
- */
- rtems_id rxDaemonTid;
- rtems_id txDaemonTid;
-
- /*
- * Receive resource area
- */
- int rdaCount;
- ReceiveResourcePointer_t rsa;
- ReceiveResourcePointer_t rea;
- CamDescriptorPointer_t cdp;
- ReceiveDescriptorPointer_t rda;
- ReceiveDescriptorPointer_t rdp_last;
-
- /*
- * Transmit descriptors
- */
- int tdaCount;
- TransmitDescriptorPointer_t tdaHead; /* Last filled */
- TransmitDescriptorPointer_t tdaTail; /* Next to retire */
-
- /*
- * Statistics
- */
- unsigned long Interrupts;
- unsigned long rxInterrupts;
- unsigned long rxMissed;
- unsigned long rxGiant;
- unsigned long rxNonOctet;
- unsigned long rxBadCRC;
- unsigned long rxCollision;
-
- unsigned long txInterrupts;
- unsigned long txSingleCollision;
- unsigned long txMultipleCollision;
- unsigned long txCollision;
- unsigned long txDeferred;
- unsigned long txUnderrun;
- unsigned long txLateCollision;
- unsigned long txExcessiveCollision;
- unsigned long txExcessiveDeferral;
- unsigned long txLostCarrier;
- unsigned long txRawWait;
-};
-SONIC_STATIC struct sonic_softc sonic_softc[NSONIC];
-
-
-/*
- ******************************************************************
- * *
- * Debug Routines *
- * *
- ******************************************************************
- */
-
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
-void sonic_print_tx_descriptor(
- TransmitDescriptorPointer_t tdp
-)
-{
- printf( "TXD ==> %p", tdp );
- printf( " pkt_config = 0x%04x", tdp->pkt_config & 0xffff);
- printf( " pkt_size = 0x%04x\n", tdp->pkt_size & 0xffff );
- printf( " frag_count = %d", tdp->frag_count & 0xffff );
- /* could print all the fragments */
- printf( " next = %p", tdp->next );
- printf( " linkp = %p\n", tdp->linkp );
- printf( " mbufp = %p", tdp->mbufp );
- if ( tdp->mbufp )
- printf( " mbufp->data = %p", mtod ( tdp->mbufp, void *) );
- puts("");
-}
-
-void sonic_print_rx_descriptor(
- ReceiveDescriptorPointer_t rdp
-)
-{
- printf( "RXD ==> %p\n", rdp );
- printf( " status = 0x%04x", rdp->status & 0xffff );
- printf( " byte_count = 0x%04x\n", rdp->byte_count & 0xffff );
- printf( " pkt = 0x%04x%04x", rdp->pkt_msw, rdp->pkt_lsw );
- printf( " seq_no = %d", rdp->seq_no );
- printf( " link = %d\n", rdp->link );
- printf( " in_use = %d", rdp->in_use );
- printf( " next = %p", rdp->next );
- printf( " mbufp = %p", rdp->mbufp );
- if ( rdp->mbufp )
- printf( " mbufp->data = %p", mtod ( rdp->mbufp, void *) );
- puts("");
-}
-#endif
-
-/*
- ******************************************************************
- * *
- * Support Routines *
- * *
- ******************************************************************
- */
-
-static void sonic_enable_interrupts(
- struct sonic_softc *sc,
- uint32_t mask
-)
-{
- void *rp = sc->sonic;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable( level );
- (*sc->write_register)(
- rp,
- SONIC_REG_IMR,
- (*sc->read_register)(rp, SONIC_REG_IMR) | mask
- );
- rtems_interrupt_enable( level );
-}
-
-static void sonic_disable_interrupts(
- struct sonic_softc *sc,
- uint32_t mask
-)
-{
- void *rp = sc->sonic;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable( level );
- (*sc->write_register)(
- rp,
- SONIC_REG_IMR,
- (*sc->read_register)(rp, SONIC_REG_IMR) & ~mask
- );
- rtems_interrupt_enable( level );
-}
-
-static void sonic_clear_interrupts(
- struct sonic_softc *sc,
- uint32_t mask
-)
-{
- void *rp = sc->sonic;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable( level );
- (*sc->write_register)( rp, SONIC_REG_ISR, mask);
- rtems_interrupt_enable( level );
-}
-
-static void sonic_command(
- struct sonic_softc *sc,
- uint32_t mask
-)
-{
- void *rp = sc->sonic;
- rtems_interrupt_level level;
-
- rtems_interrupt_disable( level );
- (*sc->write_register)( rp, SONIC_REG_CR, mask);
- rtems_interrupt_enable( level );
-}
-
-/*
- * Allocate non-cacheable memory on a single 64k page.
- * Very simple minded -- just keeps trying till the memory is on a single page.
- */
-SONIC_STATIC void * sonic_allocate(unsigned int nbytes)
-{
- void *p;
- unsigned long a1, a2;
-
- for (;;) {
- /*
- * ===CACHE===
- * Change malloc to malloc_noncacheable_guarded.
- */
- p = malloc( nbytes, M_MBUF, M_NOWAIT );
- if (p == NULL)
- rtems_panic ("No memory!");
- memset (p, '\0', nbytes);
- a1 = (unsigned long)p;
- a2 = a1 + nbytes - 1;
- if ((a1 >> 16) == (a2 >> 16))
- break;
- }
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_ALLOCATE)
- printf( "sonic_allocate %d bytes at %p\n", nbytes, p );
-#endif
- return p;
-}
-
-/*
- * Shut down the interface.
- */
-
-SONIC_STATIC void sonic_stop (struct sonic_softc *sc)
-{
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
- ifp->if_flags &= ~IFF_RUNNING;
-
- /*
- * Stop the transmitter and receiver.
- */
- sonic_command(sc, CR_HTX | CR_RXDIS );
-}
-
-/*
- * Show interface statistics
- */
-SONIC_STATIC void sonic_stats (struct sonic_softc *sc)
-{
- printf (" Total Interrupts:%-8lu", sc->Interrupts);
- printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
- printf (" Giant:%-8lu", sc->rxGiant);
- printf (" Non-octet:%-8lu\n", sc->rxNonOctet);
- printf (" Bad CRC:%-8lu", sc->rxBadCRC);
- printf (" Collision:%-8lu", sc->rxCollision);
- printf (" Missed:%-8lu\n", sc->rxMissed);
-
- printf ( " Tx Interrupts:%-8lu", sc->txInterrupts);
- printf ( " Deferred:%-8lu", sc->txDeferred);
- printf (" Lost Carrier:%-8lu\n", sc->txLostCarrier);
- printf ( "Single Collisions:%-8lu", sc->txSingleCollision);
- printf ( "Multiple Collisions:%-8lu", sc->txMultipleCollision);
- printf ("Excessive Collisions:%-8lu\n", sc->txExcessiveCollision);
- printf ( " Total Collisions:%-8lu", sc->txCollision);
- printf ( " Late Collision:%-8lu", sc->txLateCollision);
- printf (" Underrun:%-8lu\n", sc->txUnderrun);
- printf ( " Raw output wait:%-8lu\n", sc->txRawWait);
-}
-
-/*
- ******************************************************************
- * *
- * Interrupt Handler *
- * *
- ******************************************************************
- */
-
-SONIC_STATIC rtems_isr sonic_interrupt_handler (rtems_vector_number v)
-{
- struct sonic_softc *sc = sonic_softc;
- uint32_t isr, imr;
- void *rp;
-
-#if (NSONIC > 1)
- /*
- * Find the device which requires service
- */
- for (;;) {
- if (sc->vector == v)
- break;
- if (++sc == &sonic[NSONIC])
- return; /* Spurious interrupt? */
- }
-#endif /* NSONIC > 1 */
-
- /*
- * Get pointer to SONIC registers
- */
- rp = sc->sonic;
-
- sc->Interrupts++;
-
- isr = (*sc->read_register)( rp, SONIC_REG_ISR );
- imr = (*sc->read_register)( rp, SONIC_REG_IMR );
-
- /*
- * Packet received or receive buffer area exceeded?
- */
- if (imr & isr & (IMR_PRXEN | IMR_RBAEEN)) {
- imr &= ~(IMR_PRXEN | IMR_RBAEEN);
- sc->rxInterrupts++;
- rtems_bsdnet_event_send (sc->rxDaemonTid, INTERRUPT_EVENT);
- (*sc->write_register)( rp, SONIC_REG_IMR, imr );
- (*sc->write_register)( rp, SONIC_REG_ISR, isr & ISR_PKTRX );
- }
-
- /*
- * Packet started, transmitter done or transmitter error?
- * TX interrupts only occur after an error or when all TDA's are
- * exhausted and we are waiting for buffer to come free.
- */
- if (imr & isr & (IMR_PINTEN | IMR_TXEREN)) {
- sc->txInterrupts++;
- rtems_bsdnet_event_send (sc->txDaemonTid, INTERRUPT_EVENT);
- (*sc->write_register)( rp, SONIC_REG_ISR, ISR_PINT | ISR_TXDN | ISR_TXER );
- }
-
-}
-
-/*
- ******************************************************************
- * *
- * Transmitter Routines *
- * *
- ******************************************************************
- */
-
-/*
- * Soak up transmit descriptors that have been sent.
- */
-
-SONIC_STATIC void sonic_retire_tda (struct sonic_softc *sc)
-{
- uint16_t status;
- unsigned int collisions;
- struct mbuf *m, *n;
-
- /*
- * Repeat for all completed transmit descriptors.
- */
- while ((status = sc->tdaTail->status) != 0) {
-
-#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
- printf( "retire TDA %p (0x%04x)\n", sc->tdaTail, status );
-#endif
-
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- /*
- * If there is an error that was not a collision,
- * then someone may want to see it.
- */
-
- if ( (status & ~(TDA_STATUS_COLLISION_MASK|TDA_STATUS_DEF)) != 0x0001 )
- printf( "ERROR: retire TDA %p (0x%08x)\n",
- sc->tdaTail, sc->tdaTail->status );
-#endif
-
- /*
- * Check for errors which stop the transmitter.
- */
- if (status & (TDA_STATUS_EXD |
- TDA_STATUS_EXC |
- TDA_STATUS_FU |
- TDA_STATUS_BCM)) {
- /*
- * Restart the transmitter if there are
- * packets waiting to go.
- */
- uint16_t link;
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- printf("restarting sonic after error\n");
-#endif
-
- link = *(sc->tdaTail->linkp);
-
- if ((link & TDA_LINK_EOL) == 0) {
- void *rp = sc->sonic;
-
- (*sc->write_register)( rp, SONIC_REG_CTDA, link );
- sonic_command(sc, CR_TXP );
- }
- }
-
- /*
- * Update network statistics
- */
- collisions = (status & TDA_STATUS_COLLISION_MASK) >> TDA_STATUS_COLLISION_SHIFT;
- if (collisions) {
- if (collisions == 1)
- sc->txSingleCollision++;
- else
- sc->txMultipleCollision++;
- sc->txCollision += collisions;
- }
- if (status & TDA_STATUS_EXC)
- sc->txExcessiveCollision++;
- if (status & TDA_STATUS_OWC)
- sc->txLateCollision++;
- if (status & TDA_STATUS_EXD)
- sc->txExcessiveDeferral++;
- if (status & TDA_STATUS_DEF)
- sc->txDeferred++;
- if (status & TDA_STATUS_FU)
- sc->txUnderrun++;
- if (status & TDA_STATUS_CRSL)
- sc->txLostCarrier++;
-
- /*
- * Free the packet and reset a couple of fields
- */
- m = sc->tdaTail->mbufp;
- while ( m ) {
- MFREE(m, n);
- m = n;
- }
-
- /*
- sc->tdaTail->frag[0].frag_link = LSW(sc->tdaTail->link_pad);
- sc->tdaTail->frag_count = 0;
- */
- sc->tdaTail->status = 0;
-
- /*
- * Move to the next transmit descriptor
- */
- sc->tdaTail = sc->tdaTail->next;
-#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
- printf( "next TDA %p\n", sc->tdaTail );
-#endif
- }
-}
-
-/*
- * Send packet
- */
-SONIC_STATIC void sonic_sendpacket (struct ifnet *ifp, struct mbuf *m)
-{
- struct sonic_softc *sc = ifp->if_softc;
- struct mbuf *l = NULL;
- TransmitDescriptorPointer_t tdp;
- volatile struct TransmitDescriptorFragLink *fp;
- unsigned int packetSize;
- int i;
- rtems_event_set events;
- static char padBuf[64];
-
- /* printf( "sonic_sendpacket %p\n", m ); */
-
-
- /*
- * Wait for transmit descriptor to become available. Only retire TDA's
- * if there are no more free buffers to minimize TX latency. Retire TDA'a
- * on the way out.
- */
-
- while (sc->tdaHead->next->status != 0) {
-
- /*
- * Free up transmit descriptors
- */
- sonic_retire_tda (sc);
-
- if (sc->tdaHead->next->status == 0)
- break;
-
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- printf("blocking until TDAs are available\n");
-#endif
- /*
- * Enable PINT interrupts.
- sonic_clear_interrupts( sc, ISR_PINT );
- sonic_enable_interrupts( sc, IMR_PINTEN );
- */
-
- /*
- * Wait for PINT TX interrupt. Every fourth TX buffer will raise PINT.
- */
- rtems_bsdnet_event_receive (INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events);
- sonic_disable_interrupts( sc, IMR_PINTEN );
- sonic_retire_tda (sc);
- }
-
- /*
- * Fill in the transmit descriptor fragment descriptors.
- * ===CACHE===
- * If data cache is operating in write-back mode, flush cached
- * data to memory.
- */
- tdp = sc->tdaHead->next;
- tdp->mbufp = m;
- packetSize = 0;
- fp = tdp->frag;
- for (i = 0 ; i < MAXIMUM_FRAGS_PER_DESCRIPTOR ; i++, fp++) {
- /*
- * Throw away empty mbufs
- */
- if (m->m_len) {
- void *p = mtod (m, void *);
- fp->frag_lsw = LSW(p);
- fp->frag_msw = MSW(p);
- fp->frag_size = m->m_len;
- packetSize += m->m_len;
-#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
- printf( "fp %p 0x%04x%04x %d=%d .. %d\n",
- fp, fp->frag_msw, fp->frag_lsw, fp->frag_size, m->m_len, packetSize );
-#endif
-#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_TX_MBUFS)
- rtems_print_buffer(
- p,
- (fp->frag_size > MAXIMUM_FRAME_SIZE) ? MAXIMUM_FRAME_SIZE : fp->frag_size
- );
-#endif
- l = m;
- m = m->m_next;
- }
- else {
- struct mbuf *n;
- MFREE (m, n);
- m = n;
- if (l != NULL)
- l->m_next = m;
- }
- /*
- * Break out of the loop if this mbuf is the last in the frame.
- */
- if (m == NULL)
- break;
- }
-
- /*
- * Pad short packets.
- */
- if ((packetSize < 64) && (i < MAXIMUM_FRAGS_PER_DESCRIPTOR)) {
- int padSize = 64 - packetSize;
- fp++;
- fp->frag_lsw = LSW(padBuf);
- fp->frag_msw = MSW(padBuf);
- fp->frag_size = padSize;
-#if (SONIC_DEBUG & SONIC_DEBUG_FRAGMENTS)
- printf( "PAD fp %p 0x%04x%04x %d\n",
- fp, fp->frag_msw, fp->frag_lsw, fp->frag_size );
-#endif
- packetSize += padSize;
- i++;
- }
-
- /*
- * Fill Transmit Descriptor
- */
- tdp->pkt_size = packetSize;
- tdp->frag_count = i + 1;
- tdp->status = 0;
-
- /*
- * Chain onto list and start transmission.
- */
-
- tdp->linkp = &(fp+1)->frag_link;
- *tdp->linkp = LSW(tdp->next) | TDA_LINK_EOL;
- if ( sc->tdaHead->frag_count )
- *sc->tdaHead->linkp &= ~TDA_LINK_EOL;
- sc->tdaHead = tdp;
-
- /* Start transmission */
-
- sonic_command(sc, CR_TXP );
-
- /*
- * Free up transmit descriptors on the way out.
- */
- sonic_retire_tda (sc);
-}
-
-/*
- * Driver transmit daemon
- */
-SONIC_STATIC void sonic_txDaemon (void *arg)
-{
- struct sonic_softc *sc = (struct sonic_softc *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- struct mbuf *m;
- rtems_event_set events;
-
- for (;;) {
- /*
- * Wait for packet
- */
- rtems_bsdnet_event_receive (
- START_TRANSMIT_EVENT,
- RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
- &events
- );
-
- /*
- * Send packets till queue is empty
- */
- for (;;) {
- /*
- * Get the next mbuf chain to transmit.
- */
- IF_DEQUEUE(&ifp->if_snd, m);
- if (!m)
- break;
- sonic_sendpacket (ifp, m);
- }
- ifp->if_flags &= ~IFF_OACTIVE;
- }
-}
-
-/*
- ******************************************************************
- * *
- * Receiver Routines *
- * *
- ******************************************************************
- */
-
-/*
- * Wait for SONIC to hand over a Receive Descriptor.
- */
-
-SONIC_STATIC void sonic_rda_wait(
- struct sonic_softc *sc,
- ReceiveDescriptorPointer_t rdp
-)
-{
- int i;
- void *rp = sc->sonic;
- rtems_event_set events;
-
- /*
- * Wait for Receive Descriptor.
- * The order of the tests is very important.
- * The RDA is checked after RBAE is detected. This ensures that
- * the driver processes all RDA entries before reusing the RRA
- * entry holding the giant packet.
- * The event wait is done after the RDA and RBAE checks. This
- * catches the possibility that a Receive Descriptor became ready
- * between the call to this function and the clearing of the
- * interrupt status register bit.
- */
- for (;;) {
- /*
- * Has a giant packet arrived?
- * The National DP83932C data sheet is very vague on what
- * happens under this condition. The description of the
- * Interrupt Status Register (Section 4.3.6) states,
- * ``Reception is aborted and the SONIC fetches the next
- * available resource descriptors in the RRA. The buffer
- * space is not re-used and an RDA is not setup for the
- * truncated packet.''
- * I take ``Reception is aborted'' to mean that the RXEN
- * bit in the Command Register is cleared and must be set
- * by the driver to begin reception again.
- * Unfortunately, an alternative interpretation could be
- * that only reception of the current packet is aborted.
- * This would be more difficult to recover from....
- */
- if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBAE) {
-
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- printf( "ERROR: looks like a giant packet -- RBAE\n" );
-#endif
-
- /*
- * One more check to soak up any Receive Descriptors
- * that may already have been handed back to the driver.
- */
- if (rdp->in_use == RDA_IN_USE) {
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- printf( "ERROR: nope just an RBAE\n" );
-#endif
- break;
- }
-
- /*
- * Check my interpretation of the SONIC manual.
- */
- if ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_RXEN)
- rtems_panic ("SONIC RBAE/RXEN");
-
- /*
- * Update statistics
- */
- sc->rxGiant++;
-
- /*
- * Reuse receive buffer.
- * Again, the manual is subject to interpretation. The
- * RRP register is described as, `the lower address of
- * the next descriptor the SONIC will read.''
- * Since, acording to the ISR/RBAE notes, the SONIC has
- * ``fetched the next available resource descriptor in
- * the RRA'', I interpret this to mean that that the
- * driver has to move the RRP back *two* entries to
- * reuse the receive buffer holding the giant packet.
- */
- for (i = 0; i < 2; ++i) {
- uint32_t rrp = (*sc->read_register)( rp, SONIC_REG_RRP );
- const uint32_t rsa = (*sc->read_register)( rp, SONIC_REG_RSA );
-
- if (rrp == rsa) {
- const uint32_t rea = (*sc->read_register)( rp, SONIC_REG_REA );
- (*sc->write_register)( rp, SONIC_REG_RRP, rea );
- }
-
- rrp = (*sc->read_register)( rp, SONIC_REG_RRP );
- (*sc->write_register)( rp, SONIC_REG_RRP, rrp - sizeof(ReceiveResource_t) );
- }
-
- /*
- * Restart reception
- */
- sonic_clear_interrupts( sc, ISR_RBAE );
- sonic_command( sc, CR_RXEN );
- }
-
- /*
- * Has Receive Descriptor become available?
- */
- if (rdp->in_use == RDA_IN_USE)
- break;
-
- /*
- * Enable interrupts.
- */
- sonic_enable_interrupts( sc, (IMR_PRXEN | IMR_RBAEEN) );
-
- /*
- * Wait for interrupt.
- */
- rtems_bsdnet_event_receive(
- INTERRUPT_EVENT,
- RTEMS_WAIT|RTEMS_EVENT_ANY,
- RTEMS_NO_TIMEOUT,
- &events
- );
- }
-#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
- printf( "RDA %p\n", rdp );
-#endif
-
-#if (SONIC_DEBUG & SONIC_DEBUG_ERRORS)
- if (rdp->status & 0x000E)
- printf( "ERROR: RDA %p (0x%04x)\n", rdp, rdp->status );
-#endif
-
-}
-
-#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.
- */
-
-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
-
-/*
- * SONIC reader task
- */
-SONIC_STATIC void sonic_rxDaemon (void *arg)
-{
- struct sonic_softc *sc = (struct sonic_softc *)arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- void *rp = sc->sonic;
- struct mbuf *m;
- uint16_t status;
- ReceiveDescriptorPointer_t rdp;
- ReceiveResourcePointer_t rwp, rea;
- uint16_t newMissedTally, oldMissedTally;
-
- rwp = sc->rsa;
- rea = sc->rea;
- rdp = sc->rda;
-
- /*
- * Start the receiver
- */
- oldMissedTally = (*sc->read_register)( rp, SONIC_REG_MPT );
-
- /*
- * Input packet handling loop
- */
- for (;;) {
- /*
- * Wait till SONIC supplies a Receive Descriptor.
- */
- if (rdp->in_use == RDA_FREE) {
- sonic_rda_wait (sc, rdp);
- }
-
-#if (SONIC_DEBUG & SONIC_DEBUG_DESCRIPTORS)
- printf( "Incoming packet %p status=0x%04x\n", rdp, rdp->status );
-#endif
-
- /*
- * Check that packet is valid
- */
- status = rdp->status;
- if (status & RDA_STATUS_PRX) {
- struct ether_header *eh;
- void *p;
-
- /*
- * Pass the packet up the chain.
- * The mbuf count is reduced to remove
- * the frame check sequence at the end
- * of the packet.
- * ===CACHE===
- * Invalidate cache entries for this memory.
- */
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
- sonic_print_rx_descriptor( rdp );
- if ((LSW(rdp->mbufp->m_data) != rdp->pkt_lsw)
- || (MSW(rdp->mbufp->m_data) != rdp->pkt_msw))
- printf ("SONIC RDA/RRA %p, %08x\n",rdp->mbufp->m_data,(rdp->pkt_msw << 16) |
- (rdp->pkt_lsw & 0x0ffff));
-#endif
- rdp->byte_count &= 0x0ffff; /* ERC32 pollutes msb of byte_count */
- m = rdp->mbufp;
- m->m_len = m->m_pkthdr.len = rdp->byte_count -
- 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
-
-#if (SONIC_DEBUG & SONIC_DEBUG_DUMP_RX_MBUFS)
- rtems_print_buffer( (void *) eh, sizeof(struct ether_header) );
- rtems_print_buffer( (void *) m, 96 /* m->m_len*/ );
-#endif
-
- /* printf( "ether_input %p\n", m ); */
- /*
- printf( "pkt %p, seq %04x, mbuf %p, m_data %p\n", rdp, rdp->seq_no, m, m->m_data );
- printf( "%u, %u\n", ((int*)m->m_data)[6], ((int*)m->m_data)[7]);
- */
- ether_input (ifp, eh, m);
- /*
- */
-
- /*
- * Sanity check that Receive Resource Area is
- * still in sync with Receive Descriptor Area
- * The buffer reported in the Receive Descriptor
- * should be the same as the buffer in the Receive
- * Resource we are about to reuse.
- */
-/* XXX figure out whether this is valid or not */
-#if 0
- if ((LSW(p) != rwp->buff_ptr_lsw)
- || (MSW(p) != rwp->buff_ptr_msw))
- rtems_panic ("SONIC RDA/RRA");
-#endif
-
- /*
- * Allocate a new mbuf.
- */
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = ifp;
- rdp->mbufp = m;
- p = mtod (m, void *);
-
- /*
- * Reuse Receive Resource.
- */
-
- rwp->buff_ptr_lsw = LSW(p);
- rwp->buff_ptr_msw = MSW(p);
- rwp->buff_wc_lsw = RBUF_WC;
- rwp->buff_wc_msw = 0;
- rwp++;
-
- if (rwp == rea) {
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
- printf( "Wrapping RWP from %p to %p\n", rwp, sc->rsa );
-#endif
- rwp = sc->rsa;
- }
- (*sc->write_register)( rp, SONIC_REG_RWP , LSW(rwp) );
-
- /*
- * Tell the SONIC to reread the RRA.
- */
- if ((*sc->read_register)( rp, SONIC_REG_ISR ) & ISR_RBE)
- sonic_clear_interrupts( sc, ISR_RBE );
- }
- else {
- if (status & RDA_STATUS_COL)
- sc->rxCollision++;
- if (status & RDA_STATUS_FAER)
- sc->rxNonOctet++;
- else if (status & RDA_STATUS_CRCR)
- sc->rxBadCRC++;
- }
-
- /*
- * Count missed packets
- */
- newMissedTally = (*sc->read_register)( rp, SONIC_REG_MPT );
- if (newMissedTally != oldMissedTally) {
- sc->rxMissed += (newMissedTally - oldMissedTally) & 0xFFFF;
- newMissedTally = oldMissedTally;
- }
-
- /*
- * Move to next receive descriptor and update EOL
- */
-
- rdp->link |= RDA_LINK_EOL;
- rdp->in_use = RDA_FREE;
- sc->rdp_last->link &= ~RDA_LINK_EOL;
- sc->rdp_last = rdp;
- rdp = rdp->next;
-
- }
-}
-
-/*
- ******************************************************************
- * *
- * Initialization Routines *
- * *
- ******************************************************************
- */
-
-/*
- * Initialize the SONIC hardware
- */
-SONIC_STATIC void sonic_initialize_hardware(struct sonic_softc *sc)
-{
- void *rp = sc->sonic;
- int i;
- unsigned char *hwaddr;
- TransmitDescriptorPointer_t tdp;
- ReceiveDescriptorPointer_t ordp, rdp;
- ReceiveResourcePointer_t rwp;
- struct mbuf *m;
- void *p;
- CamDescriptorPointer_t cdp;
-
- /*
- * The Revision B SONIC has a horrible bug known as the "Zero
- * Length Packet bug". The initial board used to develop this
- * driver had a newer revision of the SONIC so there was no reason
- * to check for this. If you have the Revision B SONIC chip, then
- * you need to add some code to the RX path to handle this weirdness.
- */
-
- if ( (*sc->read_register)( rp, SONIC_REG_SR ) <= SONIC_REVISION_B ) {
- rtems_fatal_error_occurred( 0x0BADF00D ); /* don't eat this part :) */
- }
-
- /*
- * Set up circular linked list in Transmit Descriptor Area.
- * Use the PINT bit in the transmit configuration field to
- * request an interrupt on every other transmitted packet.
- *
- * NOTE: sonic_allocate() zeroes all of the memory allocated.
- */
-
- sc->tdaTail = sonic_allocate(sc->tdaCount * sizeof *tdp);
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
- printf( "tdaTail = %p\n", sc->tdaTail );
-#endif
- tdp = sc->tdaTail;
- for (i = 0 ; i < sc->tdaCount ; i++) {
- /*
- * Start off with the table of outstanding mbuf's
- */
-
- /*
- * status, pkt_config, pkt_size, and all fragment fields
- * are set to zero by sonic_allocate.
- */
-
-/* XXX not used by the BSD drivers
- tdp->frag[0].frag_link = LSW(tdp + 1);
-*/
- if (i & 3)
- tdp->pkt_config = TDA_CONFIG_PINT;
-
- tdp->status = 0;
- tdp->frag_count = 0;
- tdp->link_pad = LSW(tdp + 1) | TDA_LINK_EOL;
- tdp->linkp = &((tdp + 1)->frag[0].frag_link);
- tdp->next = (TransmitDescriptor_t *)(tdp + 1);
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
- sonic_print_tx_descriptor( tdp );
-#endif
- tdp++;
- }
- tdp--;
- sc->tdaHead = tdp;
- tdp->link_pad = LSW(sc->tdaTail) | TDA_LINK_EOL;
- tdp->next = (TransmitDescriptor_t *)sc->tdaTail;
- tdp->linkp = &sc->tdaTail->frag[0].frag_link;
-
- /*
- * Set up circular linked list in Receive Descriptor Area.
- * Leaves sc->rda pointing at the `beginning' of the list.
- *
- * NOTE: The RDA and CDP must have the same MSW for their addresses.
- */
-
- sc->rda = sonic_allocate(
- (sc->rdaCount * sizeof(ReceiveDescriptor_t)) +
- sizeof(CamDescriptor_t) );
- sc->cdp = (CamDescriptorPointer_t) ((unsigned char *)sc->rda +
- (sc->rdaCount * sizeof(ReceiveDescriptor_t)));
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
- printf( "rda area = %p\n", sc->rda );
- printf( "cdp area = %p\n", sc->cdp );
-#endif
-
- ordp = rdp = sc->rda;
- for (i = 0 ; i < sc->rdaCount ; i++) {
- /*
- * status, byte_count, pkt_ptr0, pkt_ptr1, and seq_no are set
- * to zero by sonic_allocate.
- */
- rdp->link = LSW(rdp + 1);
- rdp->in_use = RDA_FREE;
- rdp->next = (ReceiveDescriptor_t *)(rdp + 1);
- ordp = rdp;
- rdp++;
- }
- /*
- * Link the last desriptor to the 1st one and mark it as the end
- * of the list.
- */
- ordp->next = sc->rda;
- ordp->link = LSW(sc->rda) | RDA_LINK_EOL;
- sc->rdp_last = ordp;
-
- /*
- * Allocate the receive resource area.
- * In accordance with National Application Note 746, make the
- * receive resource area bigger than the receive descriptor area.
- * This has the useful side effect of making the receive resource
- * area big enough to hold the CAM descriptor area.
- */
-
- sc->rsa = sonic_allocate((sc->rdaCount + RRA_EXTRA_COUNT) * sizeof *sc->rsa);
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
- printf( "rsa area = %p\n", sc->rsa );
-#endif
-
- /*
- * Set up list in Receive Resource Area.
- * Allocate space for incoming packets.
- */
-
- rwp = sc->rsa;
- for (i = 0 ; i < (sc->rdaCount + RRA_EXTRA_COUNT) ; i++, rwp++) {
-
- /*
- * Allocate memory for buffer.
- * Place a pointer to the mbuf at the beginning of the buffer
- * so we can find the mbuf when the SONIC returns the buffer
- * to the driver.
- */
-
- MGETHDR (m, M_WAIT, MT_DATA);
- MCLGET (m, M_WAIT);
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- sc->rda[i].mbufp = m;
-
- p = mtod (m, void *);
-
- /*
- * Set up RRA entry
- */
- rwp->buff_ptr_lsw = LSW(p);
- rwp->buff_ptr_msw = MSW(p);
- rwp->buff_wc_lsw = RBUF_WC;
- rwp->buff_wc_msw = 0;
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY_DESCRIPTORS)
- sonic_print_rx_descriptor( &sc->rda[i] );
-#endif
- }
- sc->rea = rwp;
-#if (SONIC_DEBUG & SONIC_DEBUG_MEMORY)
- printf( "rea area = %p\n", sc->rea );
-#endif
-
-
- /*
- * Issue a software reset.
- */
- (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
-
- /*
- * Set up data configuration registers.
- */
- (*sc->write_register)( rp, SONIC_REG_DCR, sc->dcr_value );
- (*sc->write_register)( rp, SONIC_REG_DCR2, sc->dc2_value );
-
- (*sc->write_register)( rp, SONIC_REG_CR, CR_STP | CR_RXDIS | CR_HTX );
-
- /*
- * Mask all interrupts
- */
- (*sc->write_register)( rp, SONIC_REG_IMR, 0x0 ); /* XXX was backwards */
-
- /*
- * Clear outstanding interrupts.
- */
- (*sc->write_register)( rp, SONIC_REG_ISR, 0x7FFF );
-
- /*
- * Clear the tally counters
- */
-
- (*sc->write_register)( rp, SONIC_REG_CRCT, 0xFFFF );
- (*sc->write_register)( rp, SONIC_REG_FAET, 0xFFFF );
- (*sc->write_register)( rp, SONIC_REG_MPT, 0xFFFF );
- (*sc->write_register)( rp, SONIC_REG_RSC, 0 );
-
- /*
- * Set the Receiver mode
- *
- * Enable/disable reception of broadcast packets
- */
-
- if (sc->acceptBroadcast)
- (*sc->write_register)( rp, SONIC_REG_RCR, RCR_BRD );
- else
- (*sc->write_register)( rp, SONIC_REG_RCR, 0 );
-
- /*
- * Set up Resource Area pointers
- */
-
- (*sc->write_register)( rp, SONIC_REG_URRA, MSW(sc->rsa) );
- (*sc->write_register)( rp, SONIC_REG_RSA, LSW(sc->rsa) );
-
- (*sc->write_register)( rp, SONIC_REG_REA, LSW(sc->rea) );
-
- (*sc->write_register)( rp, SONIC_REG_RRP, LSW(sc->rsa) );
- (*sc->write_register)( rp, SONIC_REG_RWP, LSW(sc->rsa) ); /* XXX was rea */
-
- (*sc->write_register)( rp, SONIC_REG_URDA, MSW(sc->rda) );
- (*sc->write_register)( rp, SONIC_REG_CRDA, LSW(sc->rda) );
-
- (*sc->write_register)( rp, SONIC_REG_UTDA, MSW(sc->tdaTail) );
- (*sc->write_register)( rp, SONIC_REG_CTDA, LSW(sc->tdaTail) );
-
- /*
- * Set End Of Buffer Count register to the value recommended
- * in Note 1 of Section 3.4.4.4 of the SONIC data sheet.
- */
-
- (*sc->write_register)( rp, SONIC_REG_EOBC, RBUF_WC - 2 );
-
- /*
- * Issue the load RRA command
- */
-
- (*sc->write_register)( rp, SONIC_REG_CR, CR_RRRA );
- while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_RRRA)
- continue;
-
- /*
- * Remove device reset
- */
-
- (*sc->write_register)( rp, SONIC_REG_CR, 0 );
-
- /*
- * Set up the SONIC CAM with our hardware address.
- */
-
- hwaddr = sc->arpcom.ac_enaddr;
- cdp = sc->cdp;
-
-#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
- printf( "hwaddr: %2x:%2x:%2x:%2x:%2x:%2x\n",
- hwaddr[0], hwaddr[1], hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5] );
-#endif
-
- cdp->cep = 0; /* Fill first and only entry in CAM */
- cdp->cap0 = hwaddr[1] << 8 | hwaddr[0];
- cdp->cap1 = hwaddr[3] << 8 | hwaddr[2];
- cdp->cap2 = hwaddr[5] << 8 | hwaddr[4];
- cdp->ce = 0x0001; /* Enable first entry in CAM */
-
- (*sc->write_register)( rp, SONIC_REG_CDC, 1 ); /* 1 entry in CDA */
- (*sc->write_register)( rp, SONIC_REG_CDP, LSW(cdp) );
- (*sc->write_register)( rp, SONIC_REG_CR, CR_LCAM ); /* Load the CAM */
-
- while ((*sc->read_register)( rp, SONIC_REG_CR ) & CR_LCAM)
- continue;
-
- /*
- * Verify that CAM was properly loaded.
- */
-
- (*sc->write_register)( rp, SONIC_REG_CR, CR_RST | CR_STP | CR_RXDIS | CR_HTX );
-
-#if (SONIC_DEBUG & SONIC_DEBUG_CAM)
- (*sc->write_register)( rp, SONIC_REG_CEP, 0 ); /* Select first entry in CAM */
- printf ("Loaded Ethernet address into SONIC CAM.\n"
- " Wrote %04x%04x%04x - %#x\n"
- " Read %04x%04x%04x - %#x\n",
- cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
- (*sc->read_register)( rp, SONIC_REG_CAP2 ),
- (*sc->read_register)( rp, SONIC_REG_CAP1 ),
- (*sc->read_register)( rp, SONIC_REG_CAP0 ),
- (*sc->read_register)( rp, SONIC_REG_CE ));
-
- (*sc->write_register)( rp, SONIC_REG_CEP, 0 ); /* Select first entry in CAM */
- if (((*sc->read_register)( rp, SONIC_REG_CAP2 ) != cdp->cap2)
- || ((*sc->read_register)( rp, SONIC_REG_CAP1 ) != cdp->cap1)
- || ((*sc->read_register)( rp, SONIC_REG_CAP0 ) != cdp->cap0)
- || ((*sc->read_register)( rp, SONIC_REG_CE ) != cdp->ce)) {
- printf ("Failed to load Ethernet address into SONIC CAM.\n"
- " Wrote %04x%04x%04x - %#x\n"
- " Read %04x%04x%04x - %#x\n",
- cdp->cap2, cdp->cap1, cdp->cap0, cdp->ce,
- (*sc->read_register)( rp, SONIC_REG_CAP2 ),
- (*sc->read_register)( rp, SONIC_REG_CAP1 ),
- (*sc->read_register)( rp, SONIC_REG_CAP0 ),
- (*sc->read_register)( rp, SONIC_REG_CE ));
- rtems_panic ("SONIC LCAM");
- }
-#endif
-
- (*sc->write_register)(rp, SONIC_REG_CR, /* CR_TXP | */CR_RXEN | CR_STP);
-
- /*
- * Attach SONIC interrupt handler
- */
-/* XXX
- (*sc->write_register)( rp, SONIC_REG_IMR, 0 );
-*/
-
- /* Ignore returned old handler */
- (void) set_vector(sonic_interrupt_handler, sc->vector, 1);
-
- /*
- * Remainder of hardware initialization is
- * done by the receive and transmit daemons.
- */
-}
-
-/*
- * Send packet (caller provides header).
- */
-
-SONIC_STATIC void sonic_start(struct ifnet *ifp)
-{
- struct sonic_softc *sc = ifp->if_softc;
-
- rtems_bsdnet_event_send(sc->txDaemonTid, START_TRANSMIT_EVENT);
- ifp->if_flags |= IFF_OACTIVE;
-}
-
-/*
- * Initialize and start the device
- */
-
-SONIC_STATIC void sonic_init (void *arg)
-{
- struct sonic_softc *sc = arg;
- struct ifnet *ifp = &sc->arpcom.ac_if;
- void *rp = sc->sonic;
- int rcr;
-
- if (sc->txDaemonTid == 0) {
-
- /*
- * Set up SONIC hardware
- */
- sonic_initialize_hardware (sc);
-
- /*
- * Start driver tasks
- */
- sc->rxDaemonTid = rtems_bsdnet_newproc ("SNrx", 4096, sonic_rxDaemon, sc);
- sc->txDaemonTid = rtems_bsdnet_newproc ("SNtx", 4096, sonic_txDaemon, sc);
- }
-
- /*
- * Set flags appropriately
- */
- rcr = (*sc->read_register)( rp, SONIC_REG_RCR );
- if (ifp->if_flags & IFF_PROMISC)
- rcr |= RCR_PRO;
- else
- rcr &= ~RCR_PRO;
- (*sc->write_register)( rp, SONIC_REG_RCR, rcr);
-
- /*
- * Tell the world that we're running.
- */
- ifp->if_flags |= IFF_RUNNING;
-
- /*
- * Enable receiver and transmitter
- */
- sonic_enable_interrupts( sc, IMR_TXEREN | (IMR_PRXEN | IMR_RBAEEN) );
- sonic_command( sc, CR_RXEN );
-}
-
-/*
- * Driver ioctl handler
- */
-static int
-sonic_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
-{
- struct sonic_softc *sc = 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:
- sonic_stop (sc);
- break;
-
- case IFF_UP:
- sonic_init (sc);
- break;
-
- case IFF_UP | IFF_RUNNING:
- sonic_stop (sc);
- sonic_init (sc);
- break;
-
- default:
- break;
- }
- break;
-
- case SIO_RTEMS_SHOW_STATS:
- sonic_stats (sc);
- break;
-
- /*
- * FIXME: All sorts of multicast commands need to be added here!
- */
- default:
- error = EINVAL;
- break;
- }
- return error;
-}
-
-/*
- * Attach an SONIC driver to the system
- * This is the only `extern' function in the driver.
- */
-
-int
-rtems_sonic_driver_attach (
- struct rtems_bsdnet_ifconfig *config,
- sonic_configuration_t *chip
-)
-{
- struct sonic_softc *sc;
- struct ifnet *ifp;
- int mtu;
- int unitNumber;
- char *unitName;
-
- /*
- * Parse driver name
- */
- if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
- return 0;
-
- /*
- * Is driver free?
- */
- if ((unitNumber <= 0) || (unitNumber > NSONIC)) {
- printf ("Bad SONIC unit number.\n");
- return 0;
- }
- sc = &sonic_softc[unitNumber - 1];
- ifp = &sc->arpcom.ac_if;
- if (ifp->if_softc != NULL) {
- printf ("Driver already in use.\n");
- return 0;
- }
-
- /*
- * zero out the control structure
- */
-
- memset( sc, 0, sizeof(*sc) );
-
-
- /*
- * Process options
- */
- if (config->hardware_address) {
- memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
- }
- else {
- memset (sc->arpcom.ac_enaddr, 0x08, ETHER_ADDR_LEN);
- }
- if (config->mtu)
- mtu = config->mtu;
- else
- mtu = ETHERMTU;
- if (config->rbuf_count)
- sc->rdaCount = config->rbuf_count;
- else
- sc->rdaCount = chip->rda_count;
- if (config->xbuf_count)
- sc->tdaCount = config->xbuf_count;
- else
- sc->tdaCount = chip->tda_count;
- sc->acceptBroadcast = !config->ignore_broadcast;
-
- sc->sonic = chip->base_address;
- sc->vector = chip->vector;
- sc->dcr_value = chip->dcr_value;
- sc->dc2_value = chip->dc2_value;
- sc->write_register = chip->write_register;
- sc->read_register = chip->read_register;
-
- /*
- * Set up network interface values
- */
- ifp->if_softc = sc;
- ifp->if_unit = unitNumber;
- ifp->if_name = unitName;
- ifp->if_mtu = mtu;
- ifp->if_init = sonic_init;
- ifp->if_ioctl = sonic_ioctl;
- ifp->if_start = sonic_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;
-
- /*
- * Attach the interface
- */
- if_attach (ifp);
- ether_ifattach (ifp);
- return 1;
-}
-
-#if (SONIC_DEBUG & SONIC_DEBUG_PRINT_REGISTERS)
-#include <stdio.h>
-
-char SONIC_Reg_name[64][6]= {
- "CR", /* 0x00 */
- "DCR", /* 0x01 */
- "RCR", /* 0x02 */
- "TCR", /* 0x03 */
- "IMR", /* 0x04 */
- "ISR", /* 0x05 */
- "UTDA", /* 0x06 */
- "CTDA", /* 0x07 */
- "0x08", /* 0x08 */
- "0x09", /* 0x09 */
- "0x0A", /* 0x0A */
- "0x0B", /* 0x0B */
- "0x0C", /* 0x0C */
- "URDA", /* 0x0D */
- "CRDA", /* 0x0E */
- "0x0F", /* 0x0F */
- "0x10", /* 0x10 */
- "0x11", /* 0x11 */
- "0x12", /* 0x12 */
- "EOBC", /* 0x13 */
- "URRA", /* 0x14 */
- "RSA", /* 0x15 */
- "REA", /* 0x16 */
- "RRP", /* 0x17 */
- "RWP", /* 0x18 */
- "0x19", /* 0x19 */
- "0x1A", /* 0x1A */
- "0x1B", /* 0x1B */
- "0x1C", /* 0x1C */
- "0x0D", /* 0x1D */
- "0x1E", /* 0x1E */
- "0x1F", /* 0x1F */
- "0x20", /* 0x20 */
- "CEP", /* 0x21 */
- "CAP2", /* 0x22 */
- "CAP1", /* 0x23 */
- "CAP0", /* 0x24 */
- "CE", /* 0x25 */
- "CDP", /* 0x26 */
- "CDC", /* 0x27 */
- "SR", /* 0x28 */
- "WT0", /* 0x29 */
- "WT1", /* 0x2A */
- "RSC", /* 0x2B */
- "CRCT", /* 0x2C */
- "FAET", /* 0x2D */
- "MPT", /* 0x2E */
- "MDT", /* 0x2F */
- "0x30", /* 0x30 */
- "0x31", /* 0x31 */
- "0x32", /* 0x32 */
- "0x33", /* 0x33 */
- "0x34", /* 0x34 */
- "0x35", /* 0x35 */
- "0x36", /* 0x36 */
- "0x37", /* 0x37 */
- "0x38", /* 0x38 */
- "0x39", /* 0x39 */
- "0x3A", /* 0x3A */
- "0x3B", /* 0x3B */
- "0x3C", /* 0x3C */
- "0x3D", /* 0x3D */
- "0x3E", /* 0x3E */
- "DCR2" /* 0x3F */
-};
-#endif
diff --git a/c/src/libchip/rtc/README.ds1643 b/c/src/libchip/rtc/README.ds1643
deleted file mode 100644
index a3a38605c8..0000000000
--- a/c/src/libchip/rtc/README.ds1643
+++ /dev/null
@@ -1,3 +0,0 @@
-The Mostek M48T08 is compatible with the Dallas Semiconductor DS1643. Please
-use that driver.
-
diff --git a/c/src/libchip/rtc/README.icm7170 b/c/src/libchip/rtc/README.icm7170
deleted file mode 100644
index d4ecff570f..0000000000
--- a/c/src/libchip/rtc/README.icm7170
+++ /dev/null
@@ -1,48 +0,0 @@
-
-Configuration Table Use
-=======================
-
-sDeviceName
-
- The name of this device.
-
-deviceType
-
- This field must be RTC_ICM7170.
-
-pDeviceFns
-
- The device interface control table. This must be icm7170_fns.
-
-deviceProbe
-
- This is the address of the routine which probes to see if the device
- is present.
-
-pDeviceParams
-
- This field specifies the clock frequency. It may be one of the
- following:
- ICM7170_AT_32_KHZ
- ICM7170_AT_1_MHZ
- ICM7170_AT_2_MHZ
- ICM7170_AT_4_MHZ
-
-ulCtrlPort1
-
- This field is the base address of the RTC area of the chip.
-
-ulCtrlPort2
-
- This field is ignored.
-
-ulDataPort
-
- This field is ignored.
-
-
-getRegister
-setRegister
-
- These follow standard conventions.
-
diff --git a/c/src/libchip/rtc/README.m48t08 b/c/src/libchip/rtc/README.m48t08
deleted file mode 100644
index 25c032e85e..0000000000
--- a/c/src/libchip/rtc/README.m48t08
+++ /dev/null
@@ -1,44 +0,0 @@
-
-Configuration Table Use
-=======================
-
-sDeviceName
-
- The name of this device.
-
-deviceType
-
- This field must be RTC_M48T08.
-
-pDeviceFns
-
- The device interface control table. This must be m48t08_fns.
-
-deviceProbe
-
- This is the address of the routine which probes to see if the device
- is present.
-
-pDeviceParams
-
- This is ignored and should be NULL.
-
-ulCtrlPort1
-
- This field is the base address of the RTC area of the chip. The
- NVRAM portion of the chip is ignored.
-
-ulCtrlPort2
-
- This field is ignored.
-
-ulDataPort
-
- This field is ignored.
-
-
-getRegister
-setRegister
-
- These follow standard conventions.
-
diff --git a/c/src/libchip/rtc/README.m48t18 b/c/src/libchip/rtc/README.m48t18
deleted file mode 100644
index 0925c62115..0000000000
--- a/c/src/libchip/rtc/README.m48t18
+++ /dev/null
@@ -1 +0,0 @@
-This is supported by the m48t08 driver.
diff --git a/c/src/libchip/rtc/README.mc146818a b/c/src/libchip/rtc/README.mc146818a
deleted file mode 100644
index e9a9c86447..0000000000
--- a/c/src/libchip/rtc/README.mc146818a
+++ /dev/null
@@ -1 +0,0 @@
-This is supported by the mc146818a driver.
diff --git a/c/src/libchip/rtc/STATUS b/c/src/libchip/rtc/STATUS
deleted file mode 100644
index a6d5c41cd5..0000000000
--- a/c/src/libchip/rtc/STATUS
+++ /dev/null
@@ -1,33 +0,0 @@
-General
-=======
-
-+ It would be nice to utilize the interrupt capabilities of some
- RTC parts. This could be used to trigger checking the software
- clock against the hardware clock.
-
-+ The periodic capability of most RTCs is not suitable for use
- as a general purpose flexible clock tick source. For example,
- many RTCs generate only a handful of periods with 100 Hz being the
- most frequent.
-
-+ The tick field is not set on get. Anything smaller than a second
- is ignored on set and get operations.
-
-+ Day of week is ignored since RTEMS does not set it internally.
-
-+ There is no attempt in RTEMS to know about time zones.
-
-Harris ICM7170
-==============
-
-+ Tested on a DMV177.
-
-+ Interrupt capabilities are ignored.
-
-Mostek 48T08
-============
-
-+ Untested.
-
-+ NVRAM is ignored.
-
diff --git a/c/src/libchip/rtc/ds1375.c b/c/src/libchip/rtc/ds1375.c
deleted file mode 100644
index 4a23a0044b..0000000000
--- a/c/src/libchip/rtc/ds1375.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/* Driver for the Maxim 1375 i2c RTC (TOD only; very simple...) */
-
-/*
- * Authorship
- * ----------
- * This software was created by
- *
- * Till Straumann <strauman@slac.stanford.edu>, 2005-2007,
- * Stanford Linear Accelerator Center, Stanford University.
- *
- * Acknowledgement of sponsorship
- * ------------------------------
- * The software was produced by
- * the Stanford Linear Accelerator Center, Stanford University,
- * under Contract DE-AC03-76SFO0515 with the Department of Energy.
- *
- * Government disclaimer of liability
- * ----------------------------------
- * Neither the United States nor the United States Department of Energy,
- * nor any of their employees, makes any warranty, express or implied, or
- * assumes any legal liability or responsibility for the accuracy,
- * completeness, or usefulness of any data, apparatus, product, or process
- * disclosed, or represents that its use would not infringe privately owned
- * rights.
- *
- * Stanford disclaimer of liability
- * --------------------------------
- * Stanford University makes no representations or warranties, express or
- * implied, nor assumes any liability for the use of this software.
- *
- * Stanford disclaimer of copyright
- * --------------------------------
- * Stanford University, owner of the copyright, hereby disclaims its
- * copyright and all other rights in this software. Hence, anyone may
- * freely use it for any purpose without restriction.
- *
- * Maintenance of notices
- * ----------------------
- * In the interest of clarity regarding the origin and status of this
- * SLAC software, this and all the preceding Stanford University notices
- * are to remain affixed to any copy or derivative of this software made
- * or distributed by the recipient and are to be affixed to any copy of
- * software made or distributed by the recipient that contains a copy or
- * derivative of this software.
- *
- * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
- */
-
-/* This driver uses the file-system interface to the i2c bus */
-
-#include <unistd.h> /* write, read, close */
-
-#include <rtems.h>
-#include <rtems/bspIo.h>
-#include <rtems/rtc.h>
-#include <rtems/score/sysstate.h>
-#include <libchip/rtc.h>
-#include <libchip/ds1375-rtc.h>
-
-#include <sys/fcntl.h>
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-
-
-#define STATIC static
-#undef DEBUG
-
-/* The RTC driver routines are possibly called during
- * system initialization -- that would be prior to opening
- * the console. At this point it is not safe to use stdio
- * (printf, perror etc.).
- * Our file descriptors may even be 0..2
- */
-#define STDIOSAFE(fmt,args...) \
- do { \
- if ( _System_state_Is_up( _System_state_Get() ) ) { \
- fprintf(stderr,fmt,args); \
- } else { \
- printk(fmt,args); \
- } \
- } while (0)
-
-
-STATIC uint8_t ds1375_bcd2bin(uint8_t x)
-{
- uint8_t h = x & 0xf0;
-
- /* 8*hi + 2*hi + lo */
- return ( h >> 1 ) + ( h >> 3 ) + ( x & 0xf );
-}
-
-STATIC uint8_t ds1375_bin2bcd(uint8_t x)
-{
- uint8_t h = x/10;
-
- return ( h << 4 ) + ( x - ( ( h << 3 ) + ( h << 1 ) ) );
-}
-
-/*
- * Register Definitions and Access Macros
- *
- * The xxx_REG macros are offsets into the register files
- * The xxx_OFF macros are offsets into a in-memory buffer
- * starting at the seconds (for the 1375 both,
- * _REG and _OFF happen to be identical).
- */
-#define DS1375_SEC_REG 0x0
-#define DS1375_SEC_OFF (DS1375_SEC_REG-DS1375_SEC_REG)
-/* Extract seconds and convert to binary */
-#define DS1375_SEC(x) ds1375_bcd2bin( ((x)[DS1375_SEC_OFF]) & 0x7f )
-
-#define DS1375_MIN_REG 0x1
-#define DS1375_MIN_OFF (DS1375_MIN_REG-DS1375_SEC_REG)
-/* Extract minutes and convert to binary */
-#define DS1375_MIN(x) ds1375_bcd2bin( ((x)[DS1375_MIN_OFF]) & 0x7f )
-
-#define DS1375_HR_REG 0x2
-#define DS1375_HR_OFF (DS1375_HR_REG-DS1375_SEC_REG)
-#define DS1375_HR_1224 (1<<6)
-#define DS1375_HR_AMPM (1<<5)
-/* Are hours in AM/PM representation ? */
-#define DS1375_IS_AMPM(x) (DS1375_HR_1224 & ((x)[DS1375_HR_OFF]))
-/* Are we PM ? */
-#define DS1375_IS_PM(x) (DS1375_HR_AMPM & ((x)[DS1375_HR_OFF]))
-/* Extract hours (12h mode) and convert to binary */
-#define DS1375_HR_12(x) ds1375_bcd2bin( ((x)[DS1375_HR_OFF]) & 0x1f )
-/* Extract hours (24h mode) and convert to binary */
-#define DS1375_HR_24(x) ds1375_bcd2bin( ((x)[DS1375_HR_OFF]) & 0x3f )
-
-#define DS1375_DAY_REG 0x3
-#define DS1375_DAY_OFF (DS1375_DAY_REG-DS1375_SEC_REG)
-#define DS1375_DAT_REG 0x4
-#define DS1375_DAT_OFF (DS1375_DAT_REG-DS1375_SEC_REG)
-/* Extract date and convert to binary */
-#define DS1375_DAT(x) ds1375_bcd2bin( ((x)[DS1375_DAT_OFF]) & 0x3f )
-#define DS1375_MON_REG 0x5
-#define DS1375_MON_OFF (DS1375_MON_REG-DS1375_SEC_REG)
-#define DS1375_MON_CTRY (1<<7)
-/* Is century bit set ? */
-#define DS1375_IS_CTRY(x) (((x)[DS1375_MON_OFF]) & DS1375_MON_CTRY)
-/* Extract month and convert to binary */
-#define DS1375_MON(x) ds1375_bcd2bin( ((x)[DS1375_MON_OFF]) & 0x1f )
-
-#define DS1375_YR_REG 0x6
-#define DS1375_YR_OFF (DS1375_YR_REG-DS1375_SEC_REG)
-/* Extract year and convert to binary */
-#define DS1375_YR(x) ds1375_bcd2bin( ((x)[DS1375_YR_OFF]) & 0xff )
-
-/* CR Register and bit definitions */
-#define DS1375_CR_REG 0xe
-#define DS1375_CR_ECLK (1<<7)
-#define DS1375_CR_CLKSEL1 (1<<6)
-#define DS1375_CR_CLKSEL0 (1<<5)
-#define DS1375_CR_RS2 (1<<4)
-#define DS1375_CR_RS1 (1<<3)
-#define DS1375_CR_INTCN (1<<2)
-#define DS1375_CR_A2IE (1<<1)
-#define DS1375_CR_A1IE (1<<0)
-
-#define DS1375_CSR_REG 0xf
-
-/* User SRAM (8 bytes) */
-#define DS1375_RAM 0x10 /* start of 8 bytes user ram */
-
-/* Access Primitives */
-
-STATIC int rd_bytes(
- int fd,
- uint32_t off,
- uint8_t *buf,
- int len
-)
-{
- uint8_t ptr = off;
-
- return 1 == write( fd, &ptr, 1 ) && len == read( fd, buf, len ) ? 0 : -1;
-}
-
-STATIC int wr_bytes(
- int fd,
- uint32_t off,
- uint8_t *buf,
- int len
-)
-{
- uint8_t d[ len + 1 ];
-
- /* Must not break up writing of the register pointer and
- * the data to-be-written into multiple write() calls
- * because every 'write()' operation sends START and
- * the chip interprets the first byte after START as
- * the register pointer.
- */
-
- d[0] = off;
- memcpy( d + 1, buf, len );
-
- return len + 1 == write( fd, d, len + 1 ) ? 0 : -1;
-}
-
-/* Helpers */
-
-static int getfd(
- int minor
-)
-{
- return open( (const char *)RTC_Table[minor].ulCtrlPort1, O_RDWR );
-}
-
-/* Driver Access Functions */
-
-STATIC void ds1375_initialize(
- int minor
-)
-{
- int fd;
- uint8_t cr;
-
- if ( ( fd = getfd( minor ) ) >= 0 ) {
- if ( 0 == rd_bytes( fd, DS1375_CR_REG, &cr, 1 ) ) {
- /* make sure clock is enabled */
- if ( ! ( DS1375_CR_ECLK & cr ) ) {
- cr |= DS1375_CR_ECLK;
- wr_bytes( fd, DS1375_CR_REG, &cr, 1 );
- }
- }
- close( fd );
- }
-
-}
-
-STATIC int ds1375_get_time(
- int minor,
- rtems_time_of_day *time
-)
-{
- int rval = -1;
- int fd;
- uint8_t buf[DS1375_YR_REG + 1 - DS1375_SEC_REG];
-
- if ( time && ( ( fd = getfd( minor ) ) >= 0 ) ) {
- if ( 0 == rd_bytes( fd, DS1375_SEC_REG, buf, sizeof(buf) ) ) {
- time->year = DS1375_IS_CTRY( buf ) ? 2000 : 1900;
- time->year += DS1375_YR ( buf );
- time->month = DS1375_MON( buf );
- time->day = DS1375_DAT( buf ); /* DAY is weekday */
-
- if ( DS1375_IS_AMPM( buf ) ) {
- time->hour = DS1375_HR_12 ( buf );
- if ( DS1375_IS_PM( buf ) )
- time->hour += 12;
- } else {
- time->hour = DS1375_HR_24 ( buf );
- }
-
- time->minute = DS1375_MIN( buf );
- time->second = DS1375_SEC( buf );
- time->ticks = 0;
- rval = 0;
- }
- close( fd );
- }
- return rval;
-}
-
-STATIC int ds1375_set_time(
- int minor,
- const rtems_time_of_day *time
-)
-{
- int rval = -1;
- int fd = -1;
- time_t secs;
- struct tm tm;
- uint8_t buf[DS1375_YR_REG + 1 - DS1375_SEC_REG];
- uint8_t cr = 0xff;
-
- /*
- * The clock hardware maintains the day-of-week as a separate counter
- * so we must compute it ourselves (rtems_time_of_day doesn't come
- * with a day of week).
- */
- secs = _TOD_To_seconds( time );
- /* we're only interested in tm_wday... */
- gmtime_r( &secs, &tm );
-
- buf[DS1375_SEC_OFF] = ds1375_bin2bcd( time->second );
- buf[DS1375_MIN_OFF] = ds1375_bin2bcd( time->minute );
- /* bin2bcd(hour) implicitly selects 24h mode since ms-bit is clear */
- buf[DS1375_HR_OFF] = ds1375_bin2bcd( time->hour );
- buf[DS1375_DAY_OFF] = tm.tm_wday + 1;
- buf[DS1375_DAT_OFF] = ds1375_bin2bcd( time->day );
- buf[DS1375_MON_OFF] = ds1375_bin2bcd( time->month );
-
- if ( time->year >= 2000 ) {
- buf[DS1375_YR_OFF] = ds1375_bin2bcd( time->year - 2000 );
- buf[DS1375_MON_OFF] |= DS1375_MON_CTRY;
- } else {
- buf[DS1375_YR_OFF] = ds1375_bin2bcd( time->year - 1900 );
- }
-
- /*
- * Stop clock; update registers and restart. This is slightly
- * slower than just writing everyting but if we did that we
- * could get inconsistent registers if this routine would not
- * complete in less than 1s (says the datasheet) and we don't
- * know if we are going to be pre-empted for some time...
- */
- if ( ( fd = getfd( minor ) ) < 0 ) {
- goto cleanup;
- }
-
- if ( rd_bytes( fd, DS1375_CR_REG, &cr, 1 ) )
- goto cleanup;
-
- cr &= ~DS1375_CR_ECLK;
-
- /* This stops the clock */
- if ( wr_bytes( fd, DS1375_CR_REG, &cr, 1 ) )
- goto cleanup;
-
- /* write new contents */
- if ( wr_bytes( fd, DS1375_SEC_REG, buf, sizeof(buf) ) )
- goto cleanup;
-
- rval = 0;
-
-cleanup:
- if ( fd >= 0 ) {
- if ( ! ( DS1375_CR_ECLK & cr ) ) {
- /* start clock; this handles some cases of failure
- * after stopping the clock by restarting it again
- */
- cr |= DS1375_CR_ECLK;
- if ( wr_bytes( fd, DS1375_CR_REG, &cr, 1 ) )
- rval = -1;
- }
- close( fd );
- }
- return rval;
-}
-
-/* Debugging / Testing */
-
-#ifdef DEBUG
-
-/* Don't forget to set "TZ" when using these test routines */
-
-/* What is rtems_time_of_day good for ? Why not use std types ? */
-
-uint32_t
-ds1375_get_time_tst()
-{
-rtems_time_of_day rtod;
-time_t secs;
-
- ds1375_get_time( 0, &rtod );
- secs = _TOD_To_seconds( &rtod );
- printf( "%s\n", ctime( &secs ) );
- return secs;
-}
-
-int
-ds1375_set_time_tst( const char *datstr, rtems_time_of_day *prt )
-{
-struct tm tm;
-time_t secs;
-rtems_time_of_day rt;
-
- if ( !datstr )
- return -1;
-
- if ( ! strptime( datstr, "%Y-%m-%d/%T", &tm ) )
- return -2;
-
- if ( ! prt )
- prt = &rt;
-
- secs = mktime( &tm );
-
- /* convert to UTC */
- gmtime_r( &secs, &tm );
-
- printf("Y: %"PRIu32" ", (prt->year = tm.tm_year + 1900) );
- printf("M: %"PRIu32" ", (prt->month = tm.tm_mon + 1) );
- printf("D: %"PRIu32" ", (prt->day = tm.tm_mday ) );
- printf("h: %"PRIu32" ", (prt->hour = tm.tm_hour ) );
- printf("m: %"PRIu32" ", (prt->minute = tm.tm_min ) );
- printf("s: %"PRIu32"\n", (prt->second = tm.tm_sec ) );
- prt->ticks = 0;
-
- return ( prt == &rt ) ? ds1375_set_time( 0, &rt ) : 0;
-}
-
-#endif
-
-
-uint32_t
-rtc_ds1375_get_register( uintptr_t port, uint8_t reg )
-{
-int fd;
-uint8_t v;
-uint32_t rval = -1;
-
- if ( ( fd = open( (const char*)port, O_RDWR ) ) >= 0 ) {
-
- if ( 0 == rd_bytes( fd, reg, &v, 1 ) ) {
- rval = v;
- }
- close( fd );
- }
-
- return rval;
-}
-
-void
-rtc_ds1375_set_register( uintptr_t port, uint8_t reg, uint32_t value )
-{
-int fd;
-uint8_t v = value;
-
- if ( ( fd = open( (const char*)port, O_RDWR ) ) >= 0 ) {
- wr_bytes( fd, reg, &v, 1 );
- close( fd );
- }
-
-}
-
-bool rtc_ds1375_device_probe(
- int minor
-)
-{
- int fd;
-
- if ( ( fd = getfd( minor ) ) < 0 ) {
- STDIOSAFE( "ds1375_probe (open): %s\n", strerror( errno ) );
- return false;
- }
-
- /* Try to set file pointer */
- if ( 0 != wr_bytes( fd, DS1375_SEC_REG, 0, 0 ) ) {
- STDIOSAFE( "ds1375_probe (wr_bytes): %s\n", strerror( errno ) );
- close( fd );
- return false;
- }
-
- if ( close( fd ) ) {
- STDIOSAFE( "ds1375_probe (close): %s\n", strerror( errno ) );
- return false;
- }
-
- return true;
-}
-
-rtc_fns rtc_ds1375_fns = {
- .deviceInitialize = ds1375_initialize,
- .deviceGetTime = ds1375_get_time,
- .deviceSetTime = ds1375_set_time,
-};
diff --git a/c/src/libchip/rtc/icm7170.c b/c/src/libchip/rtc/icm7170.c
deleted file mode 100644
index 1cc9e980f7..0000000000
--- a/c/src/libchip/rtc/icm7170.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * This file interfaces with the real-time clock found in
- * a Harris ICM7170
- *
- * Year 2K Notes:
- *
- * This chip only uses a two digit field to store the year. This
- * code uses the RTEMS Epoch as a pivot year. This lets us map the
- * two digit year field as follows:
- *
- * + two digit years 0-87 are mapped to 2000-2087.
- * + two digit years 88-99 are mapped to 1988-1999.
- *
- * This is less than the time span supported by RTEMS.
- *
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <libchip/rtc.h>
-#include <libchip/icm7170.h>
-
-/*
- * Control register bits
- */
-
-/* XXX */
-
-/*
- * icm7170_initialize
- */
-
-static void icm7170_initialize(
- int minor
-)
-{
- uintptr_t icm7170;
- setRegister_f setReg;
- uintptr_t clock;
-
- icm7170 = RTC_Table[ minor ].ulCtrlPort1;
- setReg = RTC_Table[ minor ].setRegister;
-
- /*
- * Initialize the RTC with the proper clock frequency
- */
-
- clock = (uintptr_t) RTC_Table[ minor ].pDeviceParams;
- (*setReg)( icm7170, ICM7170_CONTROL, 0x0c | clock );
-}
-
-/*
- * icm7170_get_time
- */
-
-static int icm7170_get_time(
- int minor,
- rtems_time_of_day *time
-)
-{
- uint32_t icm7170;
- getRegister_f getReg;
- uint32_t year;
-
- icm7170 = RTC_Table[ minor ].ulCtrlPort1;
- getReg = RTC_Table[ minor ].getRegister;
-
- /*
- * Put the RTC into read mode
- */
-
- (void) (*getReg)( icm7170, ICM7170_COUNTER_HUNDREDTHS );
-
- /*
- * Now get the time
- */
-
-
- year = (*getReg)( icm7170, ICM7170_YEAR );
- if ( year < 88 )
- year += 2000;
- else
- year += 1900;
-
- time->year = year;
- time->month = (*getReg)( icm7170, ICM7170_MONTH );
- time->day = (*getReg)( icm7170, ICM7170_DATE );
- time->hour = (*getReg)( icm7170, ICM7170_HOUR );
- time->minute = (*getReg)( icm7170, ICM7170_MINUTE );
- time->second = (*getReg)( icm7170, ICM7170_SECOND );
-
- time->ticks = 0;
-
- /*
- * Put the RTC back into normal mode.
- */
-
- (void) (*getReg)( icm7170, ICM7170_COUNTER_HUNDREDTHS );
-
- return 0;
-}
-
-/*
- * icm7170_set_time
- */
-
-static int icm7170_set_time(
- int minor,
- const rtems_time_of_day *time
-)
-{
- uintptr_t icm7170;
- setRegister_f setReg;
- uint32_t year;
- uintptr_t clock;
-
- icm7170 = RTC_Table[ minor ].ulCtrlPort1;
- setReg = RTC_Table[ minor ].setRegister;
- clock = (uintptr_t) RTC_Table[ minor ].pDeviceParams;
-
- year = time->year;
-
- if ( year >= 2088 )
- rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
-
- if ( year >= 2000 )
- year -= 2000;
- else
- year -= 1900;
-
- (*setReg)( icm7170, ICM7170_CONTROL, 0x04 | clock );
-
- (*setReg)( icm7170, ICM7170_YEAR, year );
- (*setReg)( icm7170, ICM7170_MONTH, time->month );
- (*setReg)( icm7170, ICM7170_DATE, time->day );
- (*setReg)( icm7170, ICM7170_HOUR, time->hour );
- (*setReg)( icm7170, ICM7170_MINUTE, time->minute );
- (*setReg)( icm7170, ICM7170_SECOND, time->second );
-
- /*
- * This is not really right.
- */
-
- (*setReg)( icm7170, ICM7170_DAY_OF_WEEK, 1 );
-
- /*
- * Put the RTC back into normal mode.
- */
-
- (*setReg)( icm7170, ICM7170_CONTROL, 0x0c | clock );
-
- return 0;
-}
-
-/*
- * Driver function table
- */
-
-rtc_fns icm7170_fns = {
- icm7170_initialize,
- icm7170_get_time,
- icm7170_set_time
-};
diff --git a/c/src/libchip/rtc/icm7170_reg.c b/c/src/libchip/rtc/icm7170_reg.c
deleted file mode 100644
index 747f1f218d..0000000000
--- a/c/src/libchip/rtc/icm7170_reg.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the icm7170 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are only byte-aligned (no address gaps)
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <libchip/rtc.h>
-#include <libchip/icm7170.h>
-
-#ifndef _ICM7170_MULTIPLIER
-#define _ICM7170_MULTIPLIER 1
-#define _ICM7170_NAME(_X) _X
-#define _ICM7170_TYPE uint8_t
-#endif
-
-#define CALCULATE_REGISTER_ADDRESS( _base, _reg ) \
- (_ICM7170_TYPE *)((_base) + ((_reg) * _ICM7170_MULTIPLIER ))
-
-/*
- * ICM7170 Get Register Routine
- */
-
-uint32_t _ICM7170_NAME(icm7170_get_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum
-)
-{
- _ICM7170_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- return *port;
-}
-
-/*
- * ICM7170 Set Register Routine
- */
-
-void _ICM7170_NAME(icm7170_set_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum,
- uint32_t ucData
-)
-{
- _ICM7170_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- *port = ucData;
-}
diff --git a/c/src/libchip/rtc/icm7170_reg2.c b/c/src/libchip/rtc/icm7170_reg2.c
deleted file mode 100644
index 179d76c6f5..0000000000
--- a/c/src/libchip/rtc/icm7170_reg2.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the icm7170 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 16-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _ICM7170_MULTIPLIER 2
-#define _ICM7170_NAME(_X) _X##_2
-#define _ICM7170_TYPE uint8_t
-
-#include "icm7170_reg.c"
diff --git a/c/src/libchip/rtc/icm7170_reg4.c b/c/src/libchip/rtc/icm7170_reg4.c
deleted file mode 100644
index dada40961c..0000000000
--- a/c/src/libchip/rtc/icm7170_reg4.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the icm7170 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 32-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _ICM7170_MULTIPLIER 4
-#define _ICM7170_NAME(_X) _X##_4
-#define _ICM7170_TYPE uint8_t
-
-#include "icm7170_reg.c"
diff --git a/c/src/libchip/rtc/icm7170_reg8.c b/c/src/libchip/rtc/icm7170_reg8.c
deleted file mode 100644
index a1fb1a5ea2..0000000000
--- a/c/src/libchip/rtc/icm7170_reg8.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the icm7170 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 64-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _ICM7170_MULTIPLIER 8
-#define _ICM7170_NAME(_X) _X##_8
-#define _ICM7170_TYPE uint8_t
-
-#include "icm7170_reg.c"
diff --git a/c/src/libchip/rtc/m48t08.c b/c/src/libchip/rtc/m48t08.c
deleted file mode 100644
index 3b600bd995..0000000000
--- a/c/src/libchip/rtc/m48t08.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * This file interfaces with the real-time clock found in
- * a Mostek M48T08 or M48T18 or compatibles.
- *
- * Year 2K Notes:
- *
- * This chip only uses a two digit field to store the year. This
- * code uses the RTEMS Epoch as a pivot year. This lets us map the
- * two digit year field as follows:
- *
- * + two digit years 0-87 are mapped to 2000-2087.
- * + two digit years 88-99 are mapped to 1988-1999.
- *
- * This is less than the time span supported by RTEMS.
- *
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <libchip/rtc.h>
-#include <libchip/m48t08.h>
-
-/*
- * Control register bits
- */
-
-#define M48T08_CONTROL_WRITE 0x80
-#define M48T08_CONTROL_READ 0x40
-#define M48T08_CONTROL_SIGN 0x20
-
-/*
- * m48t08_initialize
- */
-
-static void m48t08_initialize(
- int minor
-)
-{
-}
-
-/*
- * m48t08_get_time
- */
-
-#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
-#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
-
-static int m48t08_get_time(
- int minor,
- rtems_time_of_day *time
-)
-{
- uint32_t m48t08;
- getRegister_f getReg;
- setRegister_f setReg;
- uint8_t controlReg;
- uint32_t value1;
- uint32_t value2;
-
- m48t08 = RTC_Table[ minor ].ulCtrlPort1;
- getReg = RTC_Table[ minor ].getRegister;
- setReg = RTC_Table[ minor ].setRegister;
-
- /*
- * Put the RTC into read mode
- */
-
- controlReg = (*getReg)( m48t08, M48T08_CONTROL );
- (*setReg)( m48t08, M48T08_CONTROL, controlReg | M48T08_CONTROL_READ );
-
- value1 = (*getReg)( m48t08, M48T08_YEAR );
- value2 = From_BCD( value1 );
- if ( value2 < 88 )
- time->year = 2000 + value2;
- else
- time->year = 1900 + value2;
-
- value1 = (*getReg)( m48t08, M48T08_MONTH );
- time->month = From_BCD( value1 );
-
- value1 = (*getReg)( m48t08, M48T08_DATE );
- time->day = From_BCD( value1 );
-
- value1 = (*getReg)( m48t08, M48T08_HOUR );
- time->hour = From_BCD( value1 );
-
- value1 = (*getReg)( m48t08, M48T08_MINUTE );
- time->minute = From_BCD( value1 );
-
- value1 = (*getReg)( m48t08, M48T08_SECOND );
- time->second = From_BCD( value1 );
-
- time->ticks = 0;
-
- /*
- * Put the RTC back into normal mode.
- */
-
- (*setReg)( m48t08, M48T08_CONTROL, controlReg );
-
- return 0;
-}
-
-/*
- * m48t08_set_time
- */
-
-static int m48t08_set_time(
- int minor,
- const rtems_time_of_day *time
-)
-{
- uint32_t m48t08;
- getRegister_f getReg;
- setRegister_f setReg;
- uint8_t controlReg;
-
- m48t08 = RTC_Table[ minor ].ulCtrlPort1;
- getReg = RTC_Table[ minor ].getRegister;
- setReg = RTC_Table[ minor ].setRegister;
-
- /*
- * Put the RTC into read mode
- */
-
- controlReg = (*getReg)( m48t08, M48T08_CONTROL );
- (*setReg)( m48t08, M48T08_CONTROL, controlReg | M48T08_CONTROL_WRITE );
-
- if ( time->year >= 2088 )
- rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
-
- (*setReg)( m48t08, M48T08_YEAR, To_BCD(time->year % 100) );
- (*setReg)( m48t08, M48T08_MONTH, To_BCD(time->month) );
- (*setReg)( m48t08, M48T08_DATE, To_BCD(time->day) );
- (*setReg)( m48t08, M48T08_HOUR, To_BCD(time->hour) );
- (*setReg)( m48t08, M48T08_MINUTE, To_BCD(time->minute) );
- (*setReg)( m48t08, M48T08_SECOND, To_BCD(time->second) );
-
- /*
- * Put the RTC back into normal mode.
- */
-
- (*setReg)( m48t08, M48T08_CONTROL, controlReg );
-
- return 0;
-}
-
-/*
- * Driver function table
- */
-
-rtc_fns m48t08_fns = {
- m48t08_initialize,
- m48t08_get_time,
- m48t08_set_time
-};
diff --git a/c/src/libchip/rtc/m48t08_reg.c b/c/src/libchip/rtc/m48t08_reg.c
deleted file mode 100644
index 2174496fda..0000000000
--- a/c/src/libchip/rtc/m48t08_reg.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the m48t08 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are only byte-aligned (no address gaps)
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <libchip/rtc.h>
-#include <libchip/m48t08.h>
-
-#ifndef _M48T08_MULTIPLIER
-#define _M48T08_MULTIPLIER 1
-#define _M48T08_NAME(_X) _X
-#define _M48T08_TYPE uint8_t
-#endif
-
-#define CALCULATE_REGISTER_ADDRESS( _base, _reg ) \
- (_M48T08_TYPE *)((_base) + ((_reg) * _M48T08_MULTIPLIER ))
-
-/*
- * M48T08 Get Register Routine
- */
-
-uint32_t _M48T08_NAME(m48t08_get_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum
-)
-{
- _M48T08_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- return *port;
-}
-
-/*
- * M48T08 Set Register Routine
- */
-
-void _M48T08_NAME(m48t08_set_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum,
- uint32_t ucData
-)
-{
- _M48T08_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- *port = ucData;
-}
diff --git a/c/src/libchip/rtc/m48t08_reg2.c b/c/src/libchip/rtc/m48t08_reg2.c
deleted file mode 100644
index 87d2041946..0000000000
--- a/c/src/libchip/rtc/m48t08_reg2.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the m48t08 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 16-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _M48T08_MULTIPLIER 2
-#define _M48T08_NAME(_X) _X##_2
-#define _M48T08_TYPE uint8_t
-
-#include "m48t08_reg.c"
diff --git a/c/src/libchip/rtc/m48t08_reg4.c b/c/src/libchip/rtc/m48t08_reg4.c
deleted file mode 100644
index 2203249503..0000000000
--- a/c/src/libchip/rtc/m48t08_reg4.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the m48t08 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 32-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _M48T08_MULTIPLIER 4
-#define _M48T08_NAME(_X) _X##_4
-#define _M48T08_TYPE uint8_t
-
-#include "m48t08_reg.c"
diff --git a/c/src/libchip/rtc/m48t08_reg8.c b/c/src/libchip/rtc/m48t08_reg8.c
deleted file mode 100644
index 83044d752b..0000000000
--- a/c/src/libchip/rtc/m48t08_reg8.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the m48t08 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 64-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _M48T08_MULTIPLIER 8
-#define _M48T08_NAME(_X) _X##_8
-#define _M48T08_TYPE uint8_t
-
-#include "m48t08_reg.c"
diff --git a/c/src/libchip/rtc/mc146818a.c b/c/src/libchip/rtc/mc146818a.c
deleted file mode 100644
index 2720ce5e8a..0000000000
--- a/c/src/libchip/rtc/mc146818a.c
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * This file interfaces with the real-time clock found in
- * a Motorola MC146818A (common on PC hardware)
- *
- * Year 2K Notes:
- *
- * This chip only uses a two digit field to store the year. This
- * code uses the RTEMS Epoch as a pivot year. This lets us map the
- * two digit year field as follows:
- *
- * + two digit years 0-87 are mapped to 2000-2087.
- * + two digit years 88-99 are mapped to 1988-1999.
- *
- * This is less than the time span supported by RTEMS.
- *
- * 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.org/license/LICENSE.
- */
-#include <rtems.h>
-#include <libchip/rtc.h>
-#include <libchip/mc146818a.h>
-
-#define From_BCD( _x ) ((((_x) >> 4) * 10) + ((_x) & 0x0F))
-#define To_BCD( _x ) ((((_x) / 10) << 4) + ((_x) % 10))
-
-/*
- * See if chip is present
- */
-bool mc146818a_probe(
- int minor
-)
-{
- uint32_t mc146818a;
- getRegister_f getReg;
- uint32_t value;
-
- /*
- * Verify that chip is present and that time is valid
- */
- mc146818a = RTC_Table[ minor ].ulCtrlPort1;
- getReg = RTC_Table[ minor ].getRegister;
- value = (*getReg)( mc146818a, MC146818A_STATUSD );
- if ((value == 0) || (value == 0xFF))
- return false;
- return true;
-}
-
-/*
- * Initialize chip
- */
-static void mc146818a_initialize(
- int minor
-)
-{
- uintptr_t mc146818a;
- setRegister_f setReg;
-
- mc146818a = RTC_Table[ minor ].ulCtrlPort1;
- setReg = RTC_Table[ minor ].setRegister;
-
- (*setReg)(
- mc146818a,
- MC146818A_STATUSA,
- MC146818ASA_DIVIDER|MC146818ASA_1024
- );
- (*setReg)(
- mc146818a,
- MC146818A_STATUSB,
- MC146818ASB_24HR
- );
-}
-
-/*
- * Read time from chip
- */
-static int mc146818a_get_time(
- int minor,
- rtems_time_of_day *time
-)
-{
- uintptr_t mc146818a;
- getRegister_f getReg;
- uint32_t value;
- rtems_interrupt_level level;
-
- mc146818a = RTC_Table[ minor ].ulCtrlPort1;
- getReg = RTC_Table[ minor ].getRegister;
-
- /*
- * No time if power failed
- */
- if (((*getReg)( mc146818a, MC146818A_STATUSD ) & MC146818ASD_PWR) == 0)
- return -1;
-
- /*
- * Wait for time update to complete
- */
- rtems_interrupt_disable( level );
- while (((*getReg)( mc146818a, MC146818A_STATUSA ) & MC146818ASA_TUP) != 0) {
- rtems_interrupt_flash( level );
- }
-
- /*
- * Read the time (we have at least 244 usec to do this)
- */
- value = (*getReg)( mc146818a, MC146818A_YEAR );
- value = From_BCD( value );
- if ( value < 88 )
- time->year = 2000 + value;
- else
- time->year = 1900 + value;
-
- value = (*getReg)( mc146818a, MC146818A_MONTH );
- time->month = From_BCD( value );
-
- value = (*getReg)( mc146818a, MC146818A_DAY );
- time->day = From_BCD( value );
-
- value = (*getReg)( mc146818a, MC146818A_HRS );
- time->hour = From_BCD( value );
-
- value = (*getReg)( mc146818a, MC146818A_MIN );
- time->minute = From_BCD( value );
-
- value = (*getReg)( mc146818a, MC146818A_SEC );
- rtems_interrupt_enable( level );
- time->second = From_BCD( value );
- time->ticks = 0;
-
- return 0;
-}
-
-/*
- * Set time into chip
- */
-static int mc146818a_set_time(
- int minor,
- const rtems_time_of_day *time
-)
-{
- uint32_t mc146818a;
- setRegister_f setReg;
-
- mc146818a = RTC_Table[ minor ].ulCtrlPort1;
- setReg = RTC_Table[ minor ].setRegister;
-
- /*
- * Stop the RTC
- */
- (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_HALT|MC146818ASB_24HR );
-
- if ( time->year >= 2088 )
- rtems_fatal_error_occurred( RTEMS_INVALID_NUMBER );
-
- (*setReg)( mc146818a, MC146818A_YEAR, To_BCD(time->year % 100) );
- (*setReg)( mc146818a, MC146818A_MONTH, To_BCD(time->month) );
- (*setReg)( mc146818a, MC146818A_DAY, To_BCD(time->day) );
- (*setReg)( mc146818a, MC146818A_HRS, To_BCD(time->hour) );
- (*setReg)( mc146818a, MC146818A_MIN, To_BCD(time->minute) );
- (*setReg)( mc146818a, MC146818A_SEC, To_BCD(time->second) );
-
- /*
- * Restart the RTC
- */
- (*setReg)( mc146818a, MC146818A_STATUSB, MC146818ASB_24HR );
- return 0;
-}
-
-/*
- * Driver function table
- */
-rtc_fns mc146818a_fns = {
- mc146818a_initialize,
- mc146818a_get_time,
- mc146818a_set_time
-};
diff --git a/c/src/libchip/rtc/mc146818a_ioreg.c b/c/src/libchip/rtc/mc146818a_ioreg.c
deleted file mode 100644
index 4c438a516a..0000000000
--- a/c/src/libchip/rtc/mc146818a_ioreg.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the MC146818A chip if accesses to the chip are as follows:
- *
- * + registers are in I/O space
- * + registers are accessed as bytes
- * + registers are only byte-aligned (no address gaps)
- */
-
-/*
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <bsp.h>
-#include <libchip/rtc.h>
-#include <libchip/mc146818a.h>
-
-/*
- * At this point, not all CPUs or BSPs have defined in/out port routines.
- */
-#if defined(__i386__) || defined(__PPC__)
-#if defined(inport_byte)
-uint32_t mc146818a_get_register(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum
-)
-{
- uint8_t val;
- uint8_t tmp;
-
- (void) tmp; /* eliminate warning for set but not used */
-
- outport_byte( ulCtrlPort, ucRegNum );
- inport_byte( 0x84, tmp ); /* Hack a delay to give chip time to settle */
- inport_byte( ulCtrlPort+1, val );
- inport_byte( 0x84, tmp ); /* Hack a delay to give chip time to settle */
- return val;
-}
-
-void mc146818a_set_register(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum,
- uint32_t ucData
-)
-{
- outport_byte( ulCtrlPort, ucRegNum );
- outport_byte( ulCtrlPort+1, (uint8_t)ucData );
-}
-#endif
-#endif
diff --git a/c/src/libchip/rtc/rtcprobe.c b/c/src/libchip/rtc/rtcprobe.c
deleted file mode 100644
index 71472ffd7c..0000000000
--- a/c/src/libchip/rtc/rtcprobe.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * This file contains the default Real-Time Clock probe routine.
- *
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <libchip/rtc.h>
-
-
-bool rtc_probe(
- int minor
-)
-{
- return true;
-}
diff --git a/c/src/libchip/serial/README b/c/src/libchip/serial/README
deleted file mode 100644
index 59bb9e90fa..0000000000
--- a/c/src/libchip/serial/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This is the serial controller portion of the libchip library. This
-directory contains the source code for reusable console driver
-support code. Each individual driver is configured using the
-console_tbl data structure. This structure is defined and explained
-in the console.h file.
-
-The reusable chip drivers do not directly access the serial controller.
-They access the registers on the controller via a set of up to four
-functions which are provided by the BSP. These functins set and get
-general registers and data buffers. Some chips can access the data
-buffers as general registers and thus the driver may not require
-those interface routines.
-
diff --git a/c/src/libchip/serial/README.mc68681 b/c/src/libchip/serial/README.mc68681
deleted file mode 100644
index e0966d0e10..0000000000
--- a/c/src/libchip/serial/README.mc68681
+++ /dev/null
@@ -1,83 +0,0 @@
-Configuration Table Use
-=======================
-
-sDeviceName
-
- The name of this device.
-
-deviceType
-
- This field must be SERIAL_MC68681.
-
-pDeviceFns
-
- The device interface control table. This may be:
- + mc68681_fns for interrupt driven IO
- + mc68681_fns_polled for polled IO
-
-deviceProbe
-
- This is the address of the routine which probes to see if the device
- is present.
-
-pDeviceFlow
-
- This field is ignored as hardware flow control is not currently supported.
-
-ulMargin
-
- This is currently unused.
-
-ulHysteresis
-
- This is currently unused.
-
-pDeviceParams
-
- This is set to the default settings.
-
-ulCtrlPort1
-
- This field is the base address of the entire DUART.
-
-ulCtrlPort2
-
- This field is the base address of the port specific registers.
-
-ulDataPort
-
- This field is bit mapped as follows:
- bit 0: baud rate set a or b
- bit 1-2: BRG selection ("Select Extend bit")
-
- Note: If both ports on single DUART are not configured for the same
- baud rate set, then unexpected results will occur.
-
- Note: On the Exar 88c681, if a standard clock of 3.6864 Mhz is used
- and the "Select Extend bit" is 0 (disabled), then the default
- MC68681 baud rate table is selected.
-
-getRegister
-setRegister
-
- These follow standard conventions.
-
-getData
-setData
-
- These are unused since the TX and RX data registers can be accessed
- as regular registers.
-
-ulClock
-
- This is a pointer to a baud rate mapping table. If set to
- mc68681_baud_rate_table, then the CSR/ACR/X bit mappings shown
- in the 68681 and 88681 manuals are used. Otherwise, the board
- specific baud rate mapping is used.
-
- NULL is not a valid value.
-
-ulIntVector
-
- This is the interrupt vector number associated with this chip.
-
diff --git a/c/src/libchip/serial/README.ns16550 b/c/src/libchip/serial/README.ns16550
deleted file mode 100644
index a0c31b5506..0000000000
--- a/c/src/libchip/serial/README.ns16550
+++ /dev/null
@@ -1,82 +0,0 @@
-Status
-======
-
-There are no known problems with this driver.
-
-Configuration Table Use
-=======================
-
-sDeviceName
-
- The name of this device.
-
-deviceType
-
- This field must be SERIAL_NS16550.
-
-pDeviceFns
-
- The device interface control table. This may be:
- + ns16550_fns for interrupt driven IO
- + ns16550_fns_polled for polled IO
-
-deviceProbe
-
- This is the address of the routine which probes to see if the device
- is present.
-
-pDeviceFlow
-
- This field is ignored as hardware flow control is not currently supported.
-
-ulMargin
-
- This is currently unused.
-
-ulHysteresis
-
- This is currently unused.
-
-pDeviceParams
-
- This is set to the default settings. At this point, it is the default
- baud rate cast as a (void *).
-
-ulCtrlPort1
-
- This field is the base address of this port on the UART.
-
-ulCtrlPort2
-
- This field is unused for the NS16550.
-
-ulDataPort
-
- This field is the base address of this port on the UART.
-
-getRegister
-setRegister
-
- These follow standard conventions.
-
-getData
-setData
-
- These are unused since the TX and RX data registers can be accessed
- as regular registers.
-
-ulClock
-
- This is the clock constant which is divided by the desired baud
- to get the value programmed into the part. The formula for this
- for 9600 baud is:
-
- chip_divisor_value = ulClock / 9600.
-
- NOTE: When ulClock is 0, the correct value for a PC (115,200) is
- used.
-
-ulIntVector
-
- This is the interrupt vector number associated with this chip.
-
diff --git a/c/src/libchip/serial/README.xr88681 b/c/src/libchip/serial/README.xr88681
deleted file mode 100644
index 89b661143f..0000000000
--- a/c/src/libchip/serial/README.xr88681
+++ /dev/null
@@ -1,2 +0,0 @@
-The Exar XR88681 is an enhanced version of the Motorola MC68681 and is
-supported by the mc68681 driver.
diff --git a/c/src/libchip/serial/README.z85c30 b/c/src/libchip/serial/README.z85c30
deleted file mode 100644
index f6e0b8cb11..0000000000
--- a/c/src/libchip/serial/README.z85c30
+++ /dev/null
@@ -1,74 +0,0 @@
-Configuration Table Use
-=======================
-
-sDeviceName
-
- The name of this device.
-
-deviceType
-
- This field must be SERIAL_Z85C30.
-
-pDeviceFns
-
- The device interface control table. This may be:
- + z85c30_fns for interrupt driven IO
- + z85c30_fns_polled for polled IO
-
-deviceProbe
-
- This is the address of the routine which probes to see if the device
- is present.
-
-pDeviceFlow
-
- This field is set to one of the following values:
- + NULL for no hardware flow control
- + z85c30_flow_RTSCTS for RTS/CTS based flow control
- + z85c30_flow_DTRCTS for DTR/CTS based flow control
-
-ulMargin
-
- This is currently unused.
-
-ulHysteresis
-
- This is currently unused.
-
-pDeviceParams
-
- This is set to the default settings.
-
-ulCtrlPort1
-
- This field is the address of the control register for this port.
-
-ulCtrlPort2
-
- This field is the address of the control register for chip.
-
-ulDataPort
-
- This field is the address of the data register for this port.
-
-getRegister
-setRegister
-
- These follow standard conventions.
-
-getData
-setData
-
- These follow standard conventions.
-
-ulClock
-
- This is the clock speed of the baud rate clock.
- NULL, then the CSR/ACR/X bit mappings shown in the 68681 and 88681
- manuals are used. Otherwise, the board specific baud rate mapping
- is used.
-
-ulIntVector
-
- This is the interrupt vector number associated with this chip.
-
diff --git a/c/src/libchip/serial/STATUS b/c/src/libchip/serial/STATUS
deleted file mode 100644
index 243b1a9de5..0000000000
--- a/c/src/libchip/serial/STATUS
+++ /dev/null
@@ -1,48 +0,0 @@
-General
-=======
-
-+ Hardware flow control is not currently supported. Some of the chip
- drivers (in particular the z8530) have support for hardware flow control
- but this has not been tested in the libchip context. There will need
- to be a way to totally disabled hardware flow control which is not
- currently in this.
-
-+ "ulClockSpeed" configuration item field to become a pointer to a table
- of chip specific information. For example, the z8530 should specify
- clock speed and clock divisor setting.
-
-+ A termios structure should be included to specify the initial settings.
- Right now all drivers default to 9600, 8N1.
-
-+ Need to switch to passing pointers rather than a minor number to
- functions which are strictly internal to each chip driver. This
- should be a performance win.
-
-+ Need a test which prompts you for termios settings and tests them. Until
- this happens, testing for the variety of settings possible will be limited.
- This test should be able to test any serial port while prompts come to the
- console.
-
-MC68681
-=======
-
-+ Works interrupt and polled.
-
-+ Hardware flow control not included.
-
-NS16650
-=======
-
-+ ns16550_set-attributes function is untested.
-
-+ Hardware flow control included but is currently disabled in ISR.
-
-Z85C30
-======
-
-+ Works polled and interrupt.
-
-+ Hardware flow control included but is currently disabled in ISR.
-
-+ Needs to support mode where more specific vectors are generated.
-
diff --git a/c/src/libchip/serial/mc68681.c b/c/src/libchip/serial/mc68681.c
deleted file mode 100644
index f4ddbd6a50..0000000000
--- a/c/src/libchip/serial/mc68681.c
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
- * This file contains the termios TTY driver for the Motorola MC68681.
- *
- * This part is available from a number of secondary sources.
- * In particular, we know about the following:
- *
- * + Exar 88c681 and 68c681
- *
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/score/sysstate.h>
-#include <stdlib.h>
-
-#include <libchip/serial.h>
-#include <libchip/mc68681.h>
-#include <libchip/sersupp.h>
-#include "mc68681_p.h"
-
-/*
- * Flow control is only supported when using interrupts
- */
-
-const console_fns mc68681_fns =
-{
- libchip_serial_default_probe, /* deviceProbe */
- mc68681_open, /* deviceFirstOpen */
- NULL, /* deviceLastClose */
- NULL, /* deviceRead */
- mc68681_write_support_int, /* deviceWrite */
- mc68681_initialize_interrupts, /* deviceInitialize */
- mc68681_write_polled, /* deviceWritePolled */
- mc68681_set_attributes, /* deviceSetAttributes */
- true /* deviceOutputUsesInterrupts */
-};
-
-const console_fns mc68681_fns_polled =
-{
- libchip_serial_default_probe, /* deviceProbe */
- mc68681_open, /* deviceFirstOpen */
- mc68681_close, /* deviceLastClose */
- mc68681_inbyte_nonblocking_polled, /* deviceRead */
- mc68681_write_support_polled, /* deviceWrite */
- mc68681_init, /* deviceInitialize */
- mc68681_write_polled, /* deviceWritePolled */
- mc68681_set_attributes, /* deviceSetAttributes */
- false, /* deviceOutputUsesInterrupts */
-};
-
-
-#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
- extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
-#endif
-
-/*
- * Console Device Driver Entry Points
- */
-
-/*
- * mc68681_baud_rate
- *
- * This routine returns the proper ACR bit and baud rate field values
- * based on the requested baud rate. The baud rate set to be used
- * must be configured by the user.
- */
-
-MC68681_STATIC int mc68681_baud_rate(
- int minor,
- int baud,
- unsigned int *baud_mask_p,
- unsigned int *acr_bit_p,
- unsigned int *command
-);
-
-/*
- * mc68681_set_attributes
- *
- * This function sets the DUART channel to reflect the requested termios
- * port settings.
- */
-
-MC68681_STATIC int mc68681_set_attributes(
- int minor,
- const struct termios *t
-)
-{
- uint32_t pMC68681_port;
- uint32_t pMC68681;
- unsigned int mode1;
- unsigned int mode2;
- unsigned int baud_mask;
- unsigned int acr_bit;
- unsigned int cmd = 0;
- setRegister_f setReg;
- rtems_interrupt_level Irql;
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Set the baud rate
- */
-
- if (mc68681_baud_rate( minor, t->c_cflag, &baud_mask, &acr_bit, &cmd ) == -1)
- return -1;
-
- baud_mask |= baud_mask << 4;
- acr_bit <<= 7;
-
- /*
- * Parity
- */
-
- mode1 = 0;
- mode2 = 0;
-
- if (t->c_cflag & PARENB) {
- if (t->c_cflag & PARODD)
- mode1 |= 0x04;
- /* else
- mode1 |= 0x04; */
- } else {
- mode1 |= 0x10;
- }
-
- /*
- * Character Size
- */
-
- if (t->c_cflag & CSIZE) {
- switch (t->c_cflag & CSIZE) {
- case CS5: break;
- case CS6: mode1 |= 0x01; break;
- case CS7: mode1 |= 0x02; break;
- case CS8: mode1 |= 0x03; break;
- }
- } else {
- mode1 |= 0x03; /* default to 9600,8,N,1 */
- }
-
- /*
- * Stop Bits
- */
-
- if (t->c_cflag & CSTOPB) {
- mode2 |= 0x0F; /* 2 stop bits */
- } else {
- if ((t->c_cflag & CSIZE) == CS5) /* CS5 and 1 stop bits not supported */
- return -1;
- mode2 |= 0x07; /* 1 stop bit */
- }
-
- /*
- * Hardware Flow Control
- */
-
- if(t->c_cflag & CRTSCTS) {
- mode1 |= 0x80; /* Enable Rx RTS Control */
- mode2 |= 0x10; /* Enable CTS Enable Tx */
- }
-
-
- rtems_interrupt_disable(Irql);
- (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit );
- (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud_mask );
- if ( cmd ) {
- (*setReg)( pMC68681_port, MC68681_COMMAND, cmd ); /* RX */
- (*setReg)( pMC68681_port, MC68681_COMMAND, cmd | 0x20 ); /* TX */
- }
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
- (*setReg)( pMC68681_port, MC68681_MODE, mode1 );
- (*setReg)( pMC68681_port, MC68681_MODE, mode2 );
- rtems_interrupt_enable(Irql);
- return 0;
-}
-
-/*
- * mc68681_initialize_context
- *
- * This function sets the default values of the per port context structure.
- */
-
-MC68681_STATIC void mc68681_initialize_context(
- int minor,
- mc68681_context *pmc68681Context
-)
-{
- int port;
- unsigned int pMC68681;
- unsigned int pMC68681_port;
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
-
- pmc68681Context->mate = -1;
-
- for (port=0 ; port<Console_Port_Count ; port++ ) {
- if ( Console_Port_Tbl[port]->ulCtrlPort1 == pMC68681 &&
- Console_Port_Tbl[port]->ulCtrlPort2 != pMC68681_port ) {
- pmc68681Context->mate = port;
- pmc68681Context->imr = 0;
- break;
- }
- }
-
-}
-
-/*
- * mc68681_init
- *
- * This function initializes the DUART to a quiecsent state.
- */
-
-MC68681_STATIC void mc68681_init(int minor)
-{
- uint32_t pMC68681_port;
- mc68681_context *pmc68681Context;
- setRegister_f setReg;
-
- pmc68681Context = (mc68681_context *) malloc(sizeof(mc68681_context));
-
- Console_Port_Data[minor].pDeviceContext = (void *)pmc68681Context;
-
- mc68681_initialize_context( minor, pmc68681Context );
-
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Reset everything and leave this port disabled.
- */
-
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_RX );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_TX );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_BREAK );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_STOP_BREAK );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
-
-
- (*setReg)( pMC68681_port, MC68681_MODE_REG_1A, 0x00 );
- (*setReg)( pMC68681_port, MC68681_MODE_REG_2A, 0x02 );
-
- /*
- * Disable interrupts on RX and TX for this port
- */
-
- mc68681_enable_interrupts( minor, MC68681_IMR_DISABLE_ALL );
-}
-
-/*
- * mc68681_open
- *
- * This function opens a port for communication.
- *
- * Default state is 9600 baud, 8 bits, No parity, and 1 stop bit.
- */
-
-MC68681_STATIC int mc68681_open(
- int major,
- int minor,
- void *arg
-)
-{
- uint32_t pMC68681;
- uint32_t pMC68681_port;
- unsigned int baud;
- unsigned int acr_bit;
- unsigned int vector;
- unsigned int command = 0;
- rtems_interrupt_level Irql;
- setRegister_f setReg;
- int status;
-
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- setReg = Console_Port_Tbl[minor]->setRegister;
- vector = Console_Port_Tbl[minor]->ulIntVector;
-
- /* XXX default baud rate should be from configuration table */
-
- status = mc68681_baud_rate( minor, B9600, &baud, &acr_bit, &command );
- if (status < 0) rtems_fatal_error_occurred (RTEMS_NOT_DEFINED);
-
- /*
- * Set the DUART channel to a default useable state
- */
-
- rtems_interrupt_disable(Irql);
- (*setReg)( pMC68681, MC68681_AUX_CTRL_REG, acr_bit << 7 );
- (*setReg)( pMC68681_port, MC68681_CLOCK_SELECT, baud );
- if ( command ) {
- (*setReg)( pMC68681_port, MC68681_COMMAND, command ); /* RX */
- (*setReg)( pMC68681_port, MC68681_COMMAND, command | 0x20 ); /* TX */
- }
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_MR_PTR );
- (*setReg)( pMC68681_port, MC68681_MODE, 0x13 );
- (*setReg)( pMC68681_port, MC68681_MODE, 0x07 );
- rtems_interrupt_enable(Irql);
-
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_TX );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_ENABLE_RX );
-
- (*setReg)( pMC68681, MC68681_INTERRUPT_VECTOR_REG, vector );
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * mc68681_close
- *
- * This function shuts down the requested port.
- */
-
-MC68681_STATIC int mc68681_close(
- int major,
- int minor,
- void *arg
-)
-{
- uint32_t pMC68681_port;
- setRegister_f setReg;
-
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Disable interrupts from this channel and then disable it totally.
- */
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_TX );
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_DISABLE_RX );
-
- return(RTEMS_SUCCESSFUL);
-}
-
-/*
- * mc68681_write_polled
- *
- * This routine polls out the requested character.
- */
-
-MC68681_STATIC void mc68681_write_polled(
- int minor,
- char cChar
-)
-{
- uint32_t pMC68681_port;
- unsigned char ucLineStatus;
- int iTimeout;
- getRegister_f getReg;
- setRegister_f setReg;
-
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- getReg = Console_Port_Tbl[minor]->getRegister;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * wait for transmitter holding register to be empty
- */
- iTimeout = 1000;
- ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
- while ((ucLineStatus & (MC68681_TX_READY|MC68681_TX_EMPTY)) == 0) {
-
- if ((ucLineStatus & 0xF0))
- (*setReg)( pMC68681_port, MC68681_COMMAND, MC68681_MODE_REG_RESET_ERROR );
-
- /*
- * Yield while we wait
- */
-
-#if 0
- if(_System_state_Is_up(_System_state_Get())) {
- rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
- }
-#endif
- ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
- if(!--iTimeout) {
- break;
- }
- }
-
- /*
- * transmit character
- */
-
- (*setReg)(pMC68681_port, MC68681_TX_BUFFER, cChar);
-}
-
-/*
- * mc68681_isr
- *
- * This is the single interrupt entry point which parcels interrupts
- * out to the various ports.
- */
-
-MC68681_STATIC rtems_isr mc68681_isr(
- rtems_vector_number vector
-)
-{
- int minor;
-
- for(minor=0 ; minor<Console_Port_Count ; minor++) {
- if(Console_Port_Tbl[minor]->ulIntVector == vector &&
- Console_Port_Tbl[minor]->deviceType == SERIAL_MC68681 ) {
- mc68681_process(minor);
- }
- }
-}
-
-/*
- * mc68681_initialize_interrupts
- *
- * This routine initializes the console's receive and transmit
- * ring buffers and loads the appropriate vectors to handle the interrupts.
- */
-
-MC68681_STATIC void mc68681_initialize_interrupts(int minor)
-{
- mc68681_init(minor);
-
- Console_Port_Data[minor].bActive = FALSE;
-
-#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
- set_vector(mc68681_isr, Console_Port_Tbl[minor]->ulIntVector, 1);
-#endif
-
- mc68681_enable_interrupts(minor,MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
-}
-
-/*
- * mc68681_write_support_int
- *
- * Console Termios output entry point when using interrupt driven output.
- */
-
-MC68681_STATIC ssize_t mc68681_write_support_int(
- int minor,
- const char *buf,
- size_t len
-)
-{
- uint32_t Irql;
- uint32_t pMC68681_port;
- setRegister_f setReg;
-
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * We are using interrupt driven output and termios only sends us
- * one character at a time.
- */
-
- if ( !len )
- return 0;
-
- /*
- * Put the character out and enable interrupts if necessary.
- */
-
- rtems_interrupt_disable(Irql);
- if ( Console_Port_Data[minor].bActive == FALSE ) {
- Console_Port_Data[minor].bActive = TRUE;
- mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL);
- }
- (*setReg)(pMC68681_port, MC68681_TX_BUFFER, *buf);
- rtems_interrupt_enable(Irql);
-
- return 0;
-}
-
-/*
- * mc68681_write_support_polled
- *
- * Console Termios output entry point when using polled output.
- *
- */
-
-MC68681_STATIC ssize_t mc68681_write_support_polled(
- int minor,
- const char *buf,
- size_t len
-)
-{
- int nwrite = 0;
-
- /*
- * poll each byte in the string out of the port.
- */
- while (nwrite < len) {
- /*
- * transmit character
- */
- mc68681_write_polled(minor, *buf++);
- nwrite++;
- }
-
- /*
- * return the number of bytes written.
- */
- return nwrite;
-}
-
-/*
- * mc68681_inbyte_nonblocking_polled
- *
- * Console Termios polling input entry point.
- */
-
-MC68681_STATIC int mc68681_inbyte_nonblocking_polled(
- int minor
-)
-{
- uint32_t pMC68681_port;
- unsigned char ucLineStatus;
- unsigned char cChar;
- getRegister_f getReg;
-
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- getReg = Console_Port_Tbl[minor]->getRegister;
-
- ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
- if(ucLineStatus & MC68681_RX_READY) {
- cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
- return (int)cChar;
- } else {
- return -1;
- }
-}
-
-/*
- * mc68681_baud_rate
- */
-
-MC68681_STATIC int mc68681_baud_rate(
- int minor,
- int baud,
- unsigned int *baud_mask_p,
- unsigned int *acr_bit_p,
- unsigned int *command
-)
-{
- unsigned int baud_mask;
- unsigned int acr_bit;
- int status;
- int is_extended;
- int baud_requested;
- mc68681_baud_table_t *baud_tbl;
-
- baud_mask = 0;
- acr_bit = 0;
- status = 0;
-
- if (Console_Port_Tbl[minor]->ulDataPort & MC68681_DATA_BAUD_RATE_SET_2)
- {
- acr_bit = 1;
- }
-
- is_extended = 0;
-
- switch (Console_Port_Tbl[minor]->ulDataPort & MC68681_XBRG_MASK) {
- case MC68681_XBRG_IGNORED:
- *command = 0x00;
- break;
- case MC68681_XBRG_ENABLED:
- *command = 0x80;
- is_extended = 1;
- break;
- case MC68681_XBRG_DISABLED:
- *command = 0x90;
- break;
- }
-
- baud_requested = baud;
- if (!baud_requested)
- baud_requested = B9600; /* default to 9600 baud */
-
- baud_requested = rtems_termios_baud_to_index( baud_requested );
- if (baud_requested == -1)
- return -1;
-
- baud_tbl = (mc68681_baud_table_t *)
- ((uintptr_t)Console_Port_Tbl[minor]->ulClock);
- if (!baud_tbl)
- rtems_fatal_error_occurred(RTEMS_INVALID_ADDRESS);
-
- if ( is_extended )
- baud_mask = (unsigned int)baud_tbl[ acr_bit + 2 ][ baud_requested ];
- else
- baud_mask = baud_tbl[ acr_bit ][ baud_requested ];
-
- if ( baud_mask == MC68681_BAUD_NOT_VALID )
- status = -1;
-
- /*
- * upper nibble is receiver and lower nibble is transmitter
- */
-
- *baud_mask_p = (baud_mask << 4) | baud_mask;
- *acr_bit_p = acr_bit;
- return status;
-}
-
-/*
- * mc68681_process
- *
- * This routine is the per port console interrupt handler.
- */
-
-MC68681_STATIC void mc68681_process(
- int minor
-)
-{
- uint32_t pMC68681;
- uint32_t pMC68681_port;
- volatile uint8_t ucLineStatus;
- volatile uint8_t ucISRStatus;
- char cChar;
- getRegister_f getReg;
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- getReg = Console_Port_Tbl[minor]->getRegister;
-
- /* Get ISR at the beginning of the IT routine */
- ucISRStatus = (*getReg)(pMC68681, MC68681_INTERRUPT_STATUS_REG);
-
- /* Get good ISR a or b channel */
- if (pMC68681 != pMC68681_port){
- ucISRStatus >>= 4;
- }
-
- /* See if is usefull to call rtems_termios_dequeue */
- if(Console_Port_Data[minor].bActive == FALSE) {
- ucISRStatus = ucISRStatus & ~MC68681_IR_TX_READY;
- }
-
- /*
- * Deal with any received characters
- */
- while(true) {
- ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
- if(!(ucLineStatus & MC68681_RX_READY)) {
- break;
- }
- /*
- * If there is a RX error, then dump all the data.
- */
- if ( ucLineStatus & MC68681_RX_ERRORS ) {
- do {
- cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
- ucLineStatus = (*getReg)(pMC68681_port, MC68681_STATUS);
- } while ( ucLineStatus & MC68681_RX_READY );
- continue;
- }
- cChar = (*getReg)(pMC68681_port, MC68681_RX_BUFFER);
- rtems_termios_enqueue_raw_characters(
- Console_Port_Data[minor].termios_data,
- &cChar,
- 1
- );
- }
-
- /*
- * Deal with the transmitter
- */
-
- if (ucISRStatus & MC68681_IR_TX_READY) {
- if (!rtems_termios_dequeue_characters(
- Console_Port_Data[minor].termios_data, 1)) {
- /* If no more char to send, disable TX interrupt */
- Console_Port_Data[minor].bActive = FALSE;
- mc68681_enable_interrupts(minor, MC68681_IMR_ENABLE_ALL_EXCEPT_TX);
- }
- }
-}
-
-/*
- * mc68681_build_imr
- *
- * This function returns the value for the interrupt mask register for this
- * DUART. Since this is a shared register, we must look at the other port
- * on this chip to determine whether or not it is using interrupts.
- */
-
-MC68681_STATIC unsigned int mc68681_build_imr(
- int minor,
- int enable_flag
-)
-{
- int mate;
- int is_a;
- unsigned int mask;
- unsigned int mate_mask;
- unsigned int pMC68681;
- unsigned int pMC68681_port;
- mc68681_context *pmc68681Context;
- mc68681_context *mateContext;
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- pMC68681_port = Console_Port_Tbl[minor]->ulCtrlPort2;
- pmc68681Context = (mc68681_context *) Console_Port_Data[minor].pDeviceContext;
- mate = pmc68681Context->mate;
-
- mask = 0;
- mate_mask = 0;
-
- is_a = (pMC68681 == pMC68681_port);
-
- /*
- * If there is a mate for this port, get its IMR mask.
- */
-
- if ( mate != -1 ) {
- mateContext = Console_Port_Data[mate].pDeviceContext;
-
- if (mateContext)
- mate_mask = mateContext->imr;
- }
-
- /*
- * Calculate this port's IMR mask and save it in the context area.
- */
-
- if ( Console_Port_Tbl[minor]->pDeviceFns->deviceOutputUsesInterrupts )
- mask = enable_flag;
-
- pmc68681Context->imr = mask;
-
- /*
- * Now return the full IMR value
- */
-
- if (is_a)
- return (mate_mask << 4) | mask;
-
- return (mask << 4) | mate_mask;
-}
-
-/*
- * mc68681_enable_interrupts
- *
- * This function enables specific interrupt sources on the DUART.
- */
-
-MC68681_STATIC void mc68681_enable_interrupts(
- int minor,
- int imr_mask
-)
-{
- uint32_t pMC68681;
- setRegister_f setReg;
-
- pMC68681 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Enable interrupts on RX and TX -- not break
- */
-
- (*setReg)(
- pMC68681,
- MC68681_INTERRUPT_MASK_REG,
- mc68681_build_imr(minor, imr_mask)
- );
-}
diff --git a/c/src/libchip/serial/mc68681_baud.c b/c/src/libchip/serial/mc68681_baud.c
deleted file mode 100644
index 0f8e87c2c2..0000000000
--- a/c/src/libchip/serial/mc68681_baud.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * MC68681 Default Baud Rate Table
- */
-
-#include <rtems.h>
-#include <libchip/serial.h>
-#include <libchip/mc68681.h>
-
-/* major index of 0 : ACR[7] = 0, X = 0 -- 68c681 only has these */
-/* major index of 1 : ACR[7] = 1, X = 0 -- 68c681 only has these */
-/* major index of 2 : ACR[7] = 0, X = 1 */
-/* major index of 3 : ACR[7] = 1, X = 1 */
-
-/* mc68681_baud_table_t mc68681_baud_rate_table[4] = { */
-mc68681_baud_t mc68681_baud_rate_table[4][RTEMS_TERMIOS_NUMBER_BAUD_RATES] = {
- { /* ACR[7] = 0, X = 0 */
- MC68681_BAUD_NOT_VALID, /* B0 */
- 0x00, /* B50 */
- MC68681_BAUD_NOT_VALID, /* B75 */
- 0x01, /* B110 */
- 0x02, /* B134 */
- MC68681_BAUD_NOT_VALID, /* B150 */
- 0x03, /* B200 */
- 0x04, /* B300 */
- 0x05, /* B600 */
- 0x06, /* B1200 */
- MC68681_BAUD_NOT_VALID, /* B1800 */
- 0x08, /* B2400 */
- 0x09, /* B4800 */
- 0x0B, /* B9600 */
- MC68681_BAUD_NOT_VALID, /* B19200 */
- 0x0C, /* B38400 */
- MC68681_BAUD_NOT_VALID, /* B7200 */
- MC68681_BAUD_NOT_VALID, /* B14400 */
- MC68681_BAUD_NOT_VALID, /* B28800 */
- MC68681_BAUD_NOT_VALID, /* B57600 */
- MC68681_BAUD_NOT_VALID, /* B76800 */
- MC68681_BAUD_NOT_VALID, /* B115200 */
- MC68681_BAUD_NOT_VALID, /* B230400 */
- MC68681_BAUD_NOT_VALID, /* B460800 */
- MC68681_BAUD_NOT_VALID /* B921600 */
- },
- { /* ACR[7] = 1, X = 0 */
- MC68681_BAUD_NOT_VALID, /* B0 */
- MC68681_BAUD_NOT_VALID, /* B50 */
- 0x00, /* B75 */
- 0x01, /* B110 */
- 0x02, /* B134 */
- 0x03, /* B150 */
- MC68681_BAUD_NOT_VALID, /* B200 */
- 0x04, /* B300 */
- 0x05, /* B600 */
- 0x06, /* B1200 */
- 0x0A, /* B1800 */
- 0x08, /* B2400 */
- 0x09, /* B4800 */
- 0x0B, /* B9600 */
- 0x0C, /* B19200 */
- MC68681_BAUD_NOT_VALID, /* B38400 */
- MC68681_BAUD_NOT_VALID, /* B7200 */
- MC68681_BAUD_NOT_VALID, /* B14400 */
- MC68681_BAUD_NOT_VALID, /* B28800 */
- MC68681_BAUD_NOT_VALID, /* B57600 */
- MC68681_BAUD_NOT_VALID, /* B76800 */
- MC68681_BAUD_NOT_VALID, /* B115200 */
- MC68681_BAUD_NOT_VALID, /* B230400 */
- MC68681_BAUD_NOT_VALID, /* B460800 */
- MC68681_BAUD_NOT_VALID /* B921600 */
- },
- { /* ACR[7] = 0, X = 1 */
- MC68681_BAUD_NOT_VALID, /* B0 */
- MC68681_BAUD_NOT_VALID, /* B50 */
- 0x00, /* B75 */
- 0x01, /* B110 */
- 0x02, /* B134 */
- 0x03, /* B150 */
- MC68681_BAUD_NOT_VALID, /* B200 */
- MC68681_BAUD_NOT_VALID, /* B300 */
- MC68681_BAUD_NOT_VALID, /* B600 */
- MC68681_BAUD_NOT_VALID, /* B1200 */
- 0x0A, /* B1800 */
- MC68681_BAUD_NOT_VALID, /* B2400 */
- 0x08, /* B4800 */
- 0x0B, /* B9600 */
- 0x0C, /* B19200 */
- MC68681_BAUD_NOT_VALID, /* B38400 */
- MC68681_BAUD_NOT_VALID, /* B7200 */
- MC68681_BAUD_NOT_VALID, /* B14400 */
- MC68681_BAUD_NOT_VALID, /* B28800 */
- 0x07, /* B57600 */
- MC68681_BAUD_NOT_VALID, /* B76800 */
- 0x08, /* B115200 */
- MC68681_BAUD_NOT_VALID, /* B230400 */
- MC68681_BAUD_NOT_VALID, /* B460800 */
- MC68681_BAUD_NOT_VALID /* B921600 */
- },
- { /* ACR[7] = 1, X = 1 */
- MC68681_BAUD_NOT_VALID, /* B0 */
- 0x00, /* B50 */
- MC68681_BAUD_NOT_VALID, /* B75 */
- 0x01, /* B110 */
- 0x02, /* B134 */
- MC68681_BAUD_NOT_VALID, /* B150 */
- 0x03, /* B200 */
- MC68681_BAUD_NOT_VALID, /* B300 */
- MC68681_BAUD_NOT_VALID, /* B600 */
- MC68681_BAUD_NOT_VALID, /* B1200 */
- MC68681_BAUD_NOT_VALID, /* B1800 */
- MC68681_BAUD_NOT_VALID, /* B2400 */
- 0x09, /* B4800 */
- 0x0B, /* B9600 */
- MC68681_BAUD_NOT_VALID, /* B19200 */
- 0x0C, /* B38400 */
- MC68681_BAUD_NOT_VALID, /* B7200 */
- MC68681_BAUD_NOT_VALID, /* B14400 */
- MC68681_BAUD_NOT_VALID, /* B28800 */
- 0x07, /* B57600 */
- MC68681_BAUD_NOT_VALID, /* B76800 */
- 0x08, /* B115200 */
- MC68681_BAUD_NOT_VALID, /* B230400 */
- MC68681_BAUD_NOT_VALID, /* B460800 */
- MC68681_BAUD_NOT_VALID /* B921600 */
- },
-};
diff --git a/c/src/libchip/serial/mc68681_p.h b/c/src/libchip/serial/mc68681_p.h
deleted file mode 100644
index 4623276303..0000000000
--- a/c/src/libchip/serial/mc68681_p.h
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- *
- * 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.org/license/LICENSE.
- */
-
-#ifndef _MC68681_P_H_
-#define _MC68681_P_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Define MC68681_STATIC to nothing while debugging so the entry points
- * will show up in the symbol table.
- */
-
-#define MC68681_STATIC
-
-/* #define MC68681_STATIC static */
-
-/*
- * mc68681 register offsets Read/Write Addresses
- */
-
-#define MC68681_MODE_REG_1A 0 /* MR1A-MR Prior to Read */
-#define MC68681_MODE_REG_2A 0 /* MR2A-MR After Read */
-
-#define MC68681_COUNT_MODE_CURRENT_MSB 6 /* CTU */
-#define MC68681_COUNTER_TIMER_UPPER_REG 6 /* CTU */
-#define MC68681_COUNT_MODE_CURRENT_LSB 7 /* CTL */
-#define MC68681_COUNTER_TIMER_LOWER_REG 7 /* CTL */
-#define MC68681_INTERRUPT_VECTOR_REG 12 /* IVR */
-
-#define MC68681_MODE_REG_1B 8 /* MR1B-MR Prior to Read */
-#define MC68681_MODE_REG_2B 8 /* MR2BA-MR After Read */
-
-/*
- * mc68681 register offsets Read Only Addresses
- */
-
-#define MC68681_STATUS_REG_A 1 /* SRA */
-#define MC68681_MASK_ISR_REG 2 /* MISR */
-#define MC68681_RECEIVE_BUFFER_A 3 /* RHRA */
-#define MC68681_INPUT_PORT_CHANGE_REG 4 /* IPCR */
-#define MC68681_INTERRUPT_STATUS_REG 5 /* ISR */
-#define MC68681_STATUS_REG_B 9 /* SRB */
-#define MC68681_RECEIVE_BUFFER_B 11 /* RHRB */
-#define MC68681_INPUT_PORT 13 /* IP */
-#define MC68681_START_COUNT_CMD 14 /* SCC */
-#define MC68681_STOP_COUNT_CMD 15 /* STC */
-
-/*
- * mc68681 register offsets Write Only Addresses
- */
-
-#define MC68681_CLOCK_SELECT_REG_A 1 /* CSRA */
-#define MC68681_COMMAND_REG_A 2 /* CRA */
-#define MC68681_TRANSMIT_BUFFER_A 3 /* THRA */
-#define MC68681_AUX_CTRL_REG 4 /* ACR */
-#define MC68681_INTERRUPT_MASK_REG 5 /* IMR */
-#define MC68681_CLOCK_SELECT_REG_B 9 /* CSRB */
-#define MC68681_COMMAND_REG_B 10 /* CRB */
-#define MC68681_TRANSMIT_BUFFER_B 11 /* THRB */
-#define MC68681_OUTPUT_PORT_CONFIG_REG 13 /* OPCR */
-#define MC68681_OUTPUT_PORT_SET_REG 14 /* SOPBC */
-#define MC68681_OUTPUT_PORT_RESET_BITS 15 /* COPBC */
-
-/*
- * DUART Command Register Definitions:
- *
- * MC68681_COMMAND_REG_A,MC68681_COMMAND_REG_B
- */
-
-#define MC68681_MODE_REG_ENABLE_RX 0x01
-#define MC68681_MODE_REG_DISABLE_RX 0x02
-#define MC68681_MODE_REG_ENABLE_TX 0x04
-#define MC68681_MODE_REG_DISABLE_TX 0x08
-#define MC68681_MODE_REG_RESET_MR_PTR 0x10
-#define MC68681_MODE_REG_RESET_RX 0x20
-#define MC68681_MODE_REG_RESET_TX 0x30
-#define MC68681_MODE_REG_RESET_ERROR 0x40
-#define MC68681_MODE_REG_RESET_BREAK 0x50
-#define MC68681_MODE_REG_START_BREAK 0x60
-#define MC68681_MODE_REG_STOP_BREAK 0x70
-#define MC68681_MODE_REG_SET_RX_BRG 0x80
-#define MC68681_MODE_REG_CLEAR_RX_BRG 0x90
-#define MC68681_MODE_REG_SET_TX_BRG 0xa0
-#define MC68681_MODE_REG_CLEAR_TX_BRG 0xb0
-#define MC68681_MODE_REG_SET_STANDBY 0xc0
-#define MC68681_MODE_REG_SET_ACTIVE 0xd0
-
-/*
- * Mode Register Definitions
- *
- * MC68681_MODE_REG_1A
- * MC68681_MODE_REG_1B
- */
-
-#define MC68681_5BIT_CHARS 0x00
-#define MC68681_6BIT_CHARS 0x01
-#define MC68681_7BIT_CHARS 0x02
-#define MC68681_8BIT_CHARS 0x03
-
-#define MC68681_ODD_PARITY 0x00
-#define MC68681_EVEN_PARITY 0x04
-
-#define MC68681_WITH_PARITY 0x00
-#define MC68681_FORCE_PARITY 0x08
-#define MC68681_NO_PARITY 0x10
-#define MC68681_MULTI_DROP 0x18
-
-#define MC68681_ERR_MODE_CHAR 0x00
-#define MC68681_ERR_MODE_BLOCK 0x20
-
-#define MC68681_RX_INTR_RX_READY 0x00
-#define MC68681_RX_INTR_FFULL 0x40
-
-#define MC68681_NO_RX_RTS_CTL 0x00
-#define MC68681_RX_RTS_CTRL 0x80
-
-/*
- * Mode Register Definitions
- *
- * MC68681_MODE_REG_2A
- * MC68681_MODE_REG_2B
- */
-
-#define MC68681_STOP_BIT_LENGTH__563 0x00
-#define MC68681_STOP_BIT_LENGTH__625 0x01
-#define MC68681_STOP_BIT_LENGTH__688 0x02
-#define MC68681_STOP_BIT_LENGTH__75 0x03
-#define MC68681_STOP_BIT_LENGTH__813 0x04
-#define MC68681_STOP_BIT_LENGTH__875 0x05
-#define MC68681_STOP_BIT_LENGTH__938 0x06
-#define MC68681_STOP_BIT_LENGTH_1 0x07
-#define MC68681_STOP_BIT_LENGTH_1_563 0x08
-#define MC68681_STOP_BIT_LENGTH_1_625 0x09
-#define MC68681_STOP_BIT_LENGTH_1_688 0x0a
-#define MC68681_STOP_BIT_LENGTH_1_75 0x0b
-#define MC68681_STOP_BIT_LENGTH_1_813 0x0c
-#define MC68681_STOP_BIT_LENGTH_1_875 0x0d
-#define MC68681_STOP_BIT_LENGTH_1_938 0x0e
-#define MC68681_STOP_BIT_LENGTH_2 0x0f
-
-#define MC68681_CTS_ENABLE_TX 0x10
-#define MC68681_TX_RTS_CTRL 0x20
-
-#define MC68681_CHANNEL_MODE_NORMAL 0x00
-#define MC68681_CHANNEL_MODE_ECHO 0x40
-#define MC68681_CHANNEL_MODE_LOCAL_LOOP 0x80
-#define MC68681_CHANNEL_MODE_REMOTE_LOOP 0xc0
-
-/*
- * Status Register Definitions
- *
- * MC68681_STATUS_REG_A, MC68681_STATUS_REG_B
- */
-
-#define MC68681_RX_READY 0x01
-#define MC68681_FFULL 0x02
-#define MC68681_TX_READY 0x04
-#define MC68681_TX_EMPTY 0x08
-#define MC68681_OVERRUN_ERROR 0x10
-#define MC68681_PARITY_ERROR 0x20
-#define MC68681_FRAMING_ERROR 0x40
-#define MC68681_RECEIVED_BREAK 0x80
-
-#define MC68681_RX_ERRORS \
- (MC68681_OVERRUN_ERROR|MC68681_PARITY_ERROR| \
- MC68681_FRAMING_ERROR|MC68681_RECEIVED_BREAK)
-
-/*
- * Interupt Status Register Definitions.
- *
- * MC68681_INTERRUPT_STATUS_REG
- */
-
-/*
- * Interupt Mask Register Definitions
- *
- * MC68681_INTERRUPT_MASK_REG
- */
-
-/* These are passed to mc68681_build_imr */
-#define MC68681_IR_TX_READY 0x01
-#define MC68681_IR_RX_READY 0x02
-#define MC68681_IR_BREAK 0x04
-#define MC68681_IMR_ENABLE_ALL 0x07
-#define MC68681_IMR_DISABLE_ALL 0x00
-#define MC68681_IMR_ENABLE_ALL_EXCEPT_TX 0x06
-
-#define MC68681_IR_TX_READY_A 0x01
-#define MC68681_IR_RX_READY_A 0x02
-#define MC68681_IR_BREAK_A 0x04
-#define MC68681_IR_COUNTER_READY 0x08
-#define MC68681_IR_TX_READY_B 0x10
-#define MC68681_IR_RX_READY_B 0x20
-#define MC68681_IR_BREAK_B 0x40
-#define MC68681_IR_INPUT_PORT_CHANGE 0x80
-
-/*
- * Status Register Definitions.
- *
- * MC68681_STATUS_REG_A,MC68681_STATUS_REG_B
- */
-
-#define MC68681_STATUS_RXRDY 0x01
-#define MC68681_STATUS_FFULL 0x02
-#define MC68681_STATUS_TXRDY 0x04
-#define MC68681_STATUS_TXEMT 0x08
-#define MC68681_STATUS_OVERRUN_ERROR 0x10
-#define MC68681_STATUS_PARITY_ERROR 0x20
-#define MC68681_STATUS_FRAMING_ERROR 0x40
-#define MC68681_STATUS_RECEIVED_BREAK 0x80
-
-/*
- * Definitions for the Interrupt Vector Register:
- *
- * MC68681_INTERRUPT_VECTOR_REG
- */
-
-#define MC68681_INTERRUPT_VECTOR_INIT 0x0f
-
-/*
- * Definitions for the Auxiliary Control Register
- *
- * MC68681_AUX_CTRL_REG
- */
-
-#define MC68681_AUX_BRG_SET1 0x00
-#define MC68681_AUX_BRG_SET2 0x80
-
-/*
- * Per chip context control
- */
-
-typedef struct _mc68681_context
-{
- int mate;
- unsigned char imr;
-} mc68681_context;
-
-/*
- * Driver functions
- */
-MC68681_STATIC void mc68681_initialize_context(
- int minor,
- mc68681_context *pmc68681Context
-);
-
-MC68681_STATIC bool mc68681_probe(int minor);
-
-MC68681_STATIC int mc68681_set_attributes(
- int minor,
- const struct termios *t
-);
-
-MC68681_STATIC void mc68681_init(int minor);
-
-MC68681_STATIC int mc68681_open(
- int major,
- int minor,
- void * arg
-);
-
-MC68681_STATIC int mc68681_close(
- int major,
- int minor,
- void * arg
-);
-
-MC68681_STATIC void mc68681_write_polled(
- int minor,
- char cChar
-);
-
-MC68681_STATIC void mc68681_initialize_interrupts(int minor);
-
-MC68681_STATIC ssize_t mc68681_write_support_int(
- int minor,
- const char *buf,
- size_t len
-);
-
-MC68681_STATIC ssize_t mc68681_write_support_polled(
- int minor,
- const char *buf,
- size_t len
- );
-
-MC68681_STATIC int mc68681_inbyte_nonblocking_polled(
- int minor
-);
-
-MC68681_STATIC unsigned int mc68681_build_imr(
- int minor,
- int enable_flag
-);
-
-MC68681_STATIC void mc68681_process(
- int minor
-);
-
-MC68681_STATIC void mc68681_enable_interrupts(
- int minor,
- int imr_mask
-);
-
-MC68681_STATIC rtems_isr mc68681_isr(
- rtems_vector_number vector
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MC68681_P_H_ */
diff --git a/c/src/libchip/serial/mc68681_reg.c b/c/src/libchip/serial/mc68681_reg.c
deleted file mode 100644
index fb92b8fcd3..0000000000
--- a/c/src/libchip/serial/mc68681_reg.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the mc68681 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are only byte-aligned (no address gaps)
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-
-#include <libchip/serial.h>
-#include <libchip/mc68681.h>
-
-#ifndef _MC68681_MULTIPLIER
-#define _MC68681_MULTIPLIER 1
-#define _MC68681_NAME(_X) _X
-#define _MC68681_TYPE uint8_t
-#endif
-
-#define CALCULATE_REGISTER_ADDRESS( _base, _reg ) \
- (_MC68681_TYPE *)((_base) + ((_reg) * _MC68681_MULTIPLIER ))
-
-/*
- * MC68681 Get Register Routine
- */
-
-uint8_t _MC68681_NAME(mc68681_get_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum
-)
-{
- _MC68681_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- return *port;
-}
-
-/*
- * MC68681 Set Register Routine
- */
-
-void _MC68681_NAME(mc68681_set_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum,
- uint8_t ucData
-)
-{
- _MC68681_TYPE *port;
-
- port = CALCULATE_REGISTER_ADDRESS( ulCtrlPort, ucRegNum );
-
- *port = ucData;
-}
diff --git a/c/src/libchip/serial/mc68681_reg2.c b/c/src/libchip/serial/mc68681_reg2.c
deleted file mode 100644
index 0e0121eb40..0000000000
--- a/c/src/libchip/serial/mc68681_reg2.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the mc68681 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 16-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _MC68681_MULTIPLIER 2
-#define _MC68681_NAME(_X) _X##_2
-#define _MC68681_TYPE uint8_t
-
-#include "mc68681_reg.c"
diff --git a/c/src/libchip/serial/mc68681_reg4.c b/c/src/libchip/serial/mc68681_reg4.c
deleted file mode 100644
index e9dd94ce4b..0000000000
--- a/c/src/libchip/serial/mc68681_reg4.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the mc68681 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 32-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _MC68681_MULTIPLIER 4
-#define _MC68681_NAME(_X) _X##_4
-#define _MC68681_TYPE uint8_t
-
-#include "mc68681_reg.c"
diff --git a/c/src/libchip/serial/mc68681_reg8.c b/c/src/libchip/serial/mc68681_reg8.c
deleted file mode 100644
index 402c2ffe1b..0000000000
--- a/c/src/libchip/serial/mc68681_reg8.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the mc68681 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- * + registers are on 64-bit boundaries
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#define _MC68681_MULTIPLIER 8
-#define _MC68681_NAME(_X) _X##_8
-#define _MC68681_TYPE uint8_t
-
-#include "mc68681_reg.c"
diff --git a/c/src/libchip/serial/ns16550-context.c b/c/src/libchip/serial/ns16550-context.c
deleted file mode 100644
index b42be96a26..0000000000
--- a/c/src/libchip/serial/ns16550-context.c
+++ /dev/null
@@ -1,814 +0,0 @@
-/**
- * @file
- *
- * This file contains the TTY driver for the National Semiconductor NS16550.
- *
- * This part is widely cloned and second sourced. It is found in a number
- * of "Super IO" controllers.
- *
- * This driver uses the termios pseudo driver.
- */
-
-/*
- * COPYRIGHT (c) 1998 by Radstone Technology
- *
- * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
- * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
- *
- * You are hereby granted permission to use, copy, modify, and distribute
- * this file, provided that this notice, plus the above copyright notice
- * and disclaimer, appears in all copies. Radstone Technology will provide
- * no support for this code.
- *
- * COPYRIGHT (c) 1989-2012.
- * 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.org/license/LICENSE.
- */
-
-#include <stdlib.h>
-
-#include <rtems/bspIo.h>
-
-#include <bsp.h>
-
-#include <libchip/ns16550.h>
-#include <libchip/ns16550_p.h>
-
-#if defined(BSP_FEATURE_IRQ_EXTENSION)
- #include <bsp/irq.h>
-#elif defined(BSP_FEATURE_IRQ_LEGACY)
- #include <bsp/irq.h>
-#elif defined(__PPC__) || defined(__i386__)
- #include <bsp/irq.h>
- #define BSP_FEATURE_IRQ_LEGACY
- #ifdef BSP_SHARED_HANDLER_SUPPORT
- #define BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
- #endif
-#endif
-
-static uint32_t NS16550_GetBaudDivisor(ns16550_context *ctx, uint32_t baud)
-{
- uint32_t clock = ctx->clock;
- uint32_t baudDivisor = (clock != 0 ? clock : 115200) / (baud * 16);
-
- if (ctx->has_fractional_divider_register) {
- uint32_t fractionalDivider = 0x10;
- uint32_t err = baud;
- uint32_t mulVal;
- uint32_t divAddVal;
-
- clock /= 16 * baudDivisor;
- for (mulVal = 1; mulVal < 16; ++mulVal) {
- for (divAddVal = 0; divAddVal < mulVal; ++divAddVal) {
- uint32_t actual = (mulVal * clock) / (mulVal + divAddVal);
- uint32_t newErr = actual > baud ? actual - baud : baud - actual;
-
- if (newErr < err) {
- err = newErr;
- fractionalDivider = (mulVal << 4) | divAddVal;
- }
- }
- }
-
- (*ctx->set_reg)(
- ctx->port,
- NS16550_FRACTIONAL_DIVIDER,
- fractionalDivider
- );
- }
-
- return baudDivisor;
-}
-
-/*
- * ns16550_enable_interrupts
- *
- * This routine initializes the port to have the specified interrupts masked.
- */
-static void ns16550_enable_interrupts(
- ns16550_context *ctx,
- int mask
-)
-{
- (*ctx->set_reg)(ctx->port, NS16550_INTERRUPT_ENABLE, mask);
-}
-
-static void ns16550_clear_and_set_interrupts(
- ns16550_context *ctx,
- uint8_t clear,
- uint8_t set
-)
-{
- rtems_interrupt_lock_context lock_context;
- ns16550_get_reg get_reg = ctx->get_reg;
- ns16550_set_reg set_reg = ctx->set_reg;
- uintptr_t port = ctx->port;
- uint8_t val;
-
- rtems_termios_device_lock_acquire(&ctx->base, &lock_context);
- val = (*get_reg)(port, NS16550_INTERRUPT_ENABLE);
- val &= ~clear;
- val |= set;
- (*set_reg)(port, NS16550_INTERRUPT_ENABLE, val);
- rtems_termios_device_lock_release(&ctx->base, &lock_context);
-}
-
-/*
- * ns16550_probe
- */
-
-bool ns16550_probe(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- uintptr_t pNS16550;
- uint8_t ucDataByte;
- uint32_t ulBaudDivisor;
- ns16550_set_reg setReg;
- ns16550_get_reg getReg;
-
- ctx->modem_control = SP_MODEM_IRQ;
-
- pNS16550 = ctx->port;
- setReg = ctx->set_reg;
- getReg = ctx->get_reg;
-
- /* Clear the divisor latch, clear all interrupt enables,
- * and reset and
- * disable the FIFO's.
- */
-
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
- ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR );
-
- /* Set the divisor latch and set the baud rate. */
-
- ulBaudDivisor = NS16550_GetBaudDivisor(ctx, ctx->initial_baud);
- ctx->baud_divisor = ulBaudDivisor;
- ucDataByte = SP_LINE_DLAB;
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
-
- /* XXX */
- (*setReg)(pNS16550,NS16550_TRANSMIT_BUFFER,(uint8_t)(ulBaudDivisor & 0xffU));
- (*setReg)(
- pNS16550,NS16550_INTERRUPT_ENABLE,
- (uint8_t)(( ulBaudDivisor >> 8 ) & 0xffU )
- );
-
- /* Clear the divisor latch and set the character size to eight bits */
- /* with one stop bit and no parity checking. */
- ucDataByte = EIGHT_BITS;
- ctx->line_control = ucDataByte;
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
-
- /* Enable and reset transmit and receive FIFOs. TJA */
- ucDataByte = SP_FIFO_ENABLE;
- (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
-
- ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
- (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
-
- ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
-
- /* Set data terminal ready. */
- /* And open interrupt tristate line */
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL,ctx->modem_control);
-
- (*getReg)(pNS16550, NS16550_LINE_STATUS );
- (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER );
-
- return true;
-}
-
-static size_t ns16550_write_to_fifo(
- const ns16550_context *ctx,
- const char *buf,
- size_t len
-)
-{
- uintptr_t port = ctx->port;
- ns16550_set_reg set = ctx->set_reg;
- size_t out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
- size_t i;
-
- for (i = 0; i < out; ++i) {
- (*set)(port, NS16550_TRANSMIT_BUFFER, buf[i]);
- }
-
- return out;
-}
-
-/**
- * @brief Process interrupt.
- */
-static void ns16550_isr(void *arg)
-{
- rtems_termios_tty *tty = arg;
- ns16550_context *ctx = rtems_termios_get_device_context(tty);
- uintptr_t port = ctx->port;
- ns16550_get_reg get = ctx->get_reg;
- int i = 0;
- char buf [SP_FIFO_SIZE];
-
- /* Iterate until no more interrupts are pending */
- do {
- /* Fetch received characters */
- for (i = 0; i < SP_FIFO_SIZE; ++i) {
- if ((get( port, NS16550_LINE_STATUS) & SP_LSR_RDY) != 0) {
- buf [i] = (char) get(port, NS16550_RECEIVE_BUFFER);
- } else {
- break;
- }
- }
-
- /* Enqueue fetched characters */
- rtems_termios_enqueue_raw_characters(tty, buf, i);
-
- /* Do transmit */
- if (ctx->out_total > 0
- && (get(port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
- size_t current = ctx->out_current;
-
- ctx->out_buf += current;
- ctx->out_remaining -= current;
-
- if (ctx->out_remaining > 0) {
- ctx->out_current =
- ns16550_write_to_fifo(ctx, ctx->out_buf, ctx->out_remaining);
- } else {
- rtems_termios_dequeue_characters(tty, ctx->out_total);
- }
- }
- } while ((get( port, NS16550_INTERRUPT_ID) & SP_IID_0) == 0);
-}
-
-static void ns16550_isr_task(void *arg)
-{
- rtems_termios_tty *tty = arg;
- ns16550_context *ctx = rtems_termios_get_device_context(tty);
- uint8_t status = (*ctx->get_reg)(ctx->port, NS16550_LINE_STATUS);
-
- if ((status & SP_LSR_RDY) != 0) {
- ns16550_clear_and_set_interrupts(ctx, SP_INT_RX_ENABLE, 0);
- rtems_termios_rxirq_occured(tty);
- }
-
- if (ctx->out_total > 0 && (status & SP_LSR_THOLD) != 0) {
- size_t current = ctx->out_current;
-
- ctx->out_buf += current;
- ctx->out_remaining -= current;
-
- if (ctx->out_remaining > 0) {
- ctx->out_current =
- ns16550_write_to_fifo(ctx, ctx->out_buf, ctx->out_remaining);
- } else {
- size_t done = ctx->out_total;
-
- ctx->out_total = 0;
- ns16550_clear_and_set_interrupts(ctx, SP_INT_TX_ENABLE, 0);
- rtems_termios_dequeue_characters(tty, done);
- }
- }
-}
-
-static int ns16550_read_task(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- uintptr_t port = ctx->port;
- ns16550_get_reg get = ctx->get_reg;
- char buf[SP_FIFO_SIZE];
- int i;
-
- for (i = 0; i < SP_FIFO_SIZE; ++i) {
- if ((get(port, NS16550_LINE_STATUS) & SP_LSR_RDY) != 0) {
- buf[i] = (char) get(port, NS16550_RECEIVE_BUFFER);
- } else {
- break;
- }
- }
-
- rtems_termios_enqueue_raw_characters(ctx->tty, buf, i);
- ns16550_clear_and_set_interrupts(ctx, 0, SP_INT_RX_ENABLE);
-
- return -1;
-}
-
-/*
- * ns16550_initialize_interrupts
- *
- * This routine initializes the port to operate in interrupt driver mode.
- */
-static void ns16550_initialize_interrupts(
- struct rtems_termios_tty *tty,
- ns16550_context *ctx,
- void (*isr)(void *)
-)
-{
- #ifdef BSP_FEATURE_IRQ_EXTENSION
- {
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- sc = rtems_interrupt_handler_install(
- ctx->irq,
- "NS16550",
- RTEMS_INTERRUPT_SHARED,
- isr,
- tty
- );
- if (sc != RTEMS_SUCCESSFUL) {
- /* FIXME */
- printk( "%s: Error: Install interrupt handler\n", __func__);
- rtems_fatal_error_occurred( 0xdeadbeef);
- }
- }
- #elif defined(BSP_FEATURE_IRQ_LEGACY)
- {
- int rv = 0;
- #ifdef BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
- rtems_irq_connect_data cd = {
- ctx->irq,
- isr,
- tty,
- NULL,
- NULL,
- NULL,
- NULL
- };
- rv = BSP_install_rtems_shared_irq_handler( &cd);
- #else
- rtems_irq_connect_data cd = {
- ctx->irq,
- isr,
- tty,
- NULL,
- NULL,
- NULL
- };
- rv = BSP_install_rtems_irq_handler( &cd);
- #endif
- if (rv == 0) {
- /* FIXME */
- printk( "%s: Error: Install interrupt handler\n", __func__);
- rtems_fatal_error_occurred( 0xdeadbeef);
- }
- }
- #endif
-}
-
-/*
- * ns16550_open
- */
-
-static bool ns16550_open(
- struct rtems_termios_tty *tty,
- rtems_termios_device_context *base,
- struct termios *term,
- rtems_libio_open_close_args_t *args
-)
-{
- ns16550_context *ctx = (ns16550_context *) base;
-
- ctx->tty = tty;
-
- /* Set initial baud */
- rtems_termios_set_initial_baud(tty, ctx->initial_baud);
-
- if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
- ns16550_initialize_interrupts(tty, ctx, ns16550_isr);
- ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
- } else if (tty->handler.mode == TERMIOS_TASK_DRIVEN) {
- ns16550_initialize_interrupts(tty, ctx, ns16550_isr_task);
- ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
- }
-
- return true;
-}
-
-static void ns16550_cleanup_interrupts(
- struct rtems_termios_tty *tty,
- ns16550_context *ctx,
- void (*isr)(void *)
-)
-{
- #if defined(BSP_FEATURE_IRQ_EXTENSION)
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- sc = rtems_interrupt_handler_remove(
- ctx->irq,
- isr,
- tty
- );
- if (sc != RTEMS_SUCCESSFUL) {
- /* FIXME */
- printk("%s: Error: Remove interrupt handler\n", __func__);
- rtems_fatal_error_occurred(0xdeadbeef);
- }
- #elif defined(BSP_FEATURE_IRQ_LEGACY)
- int rv = 0;
- rtems_irq_connect_data cd = {
- .name = ctx->irq,
- .hdl = isr,
- .handle = tty
- };
- rv = BSP_remove_rtems_irq_handler(&cd);
- if (rv == 0) {
- /* FIXME */
- printk("%s: Error: Remove interrupt handler\n", __func__);
- rtems_fatal_error_occurred(0xdeadbeef);
- }
- #endif
-}
-
-/*
- * ns16550_close
- */
-
-static void ns16550_close(
- struct rtems_termios_tty *tty,
- rtems_termios_device_context *base,
- rtems_libio_open_close_args_t *args
-)
-{
- ns16550_context *ctx = (ns16550_context *) base;
-
- ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
-
- if (tty->handler.mode == TERMIOS_IRQ_DRIVEN) {
- ns16550_cleanup_interrupts(tty, ctx, ns16550_isr);
- } else if (tty->handler.mode == TERMIOS_TASK_DRIVEN) {
- ns16550_cleanup_interrupts(tty, ctx, ns16550_isr_task);
- }
-}
-
-/**
- * @brief Polled write for NS16550.
- */
-void ns16550_polled_putchar(rtems_termios_device_context *base, char out)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- uintptr_t port = ctx->port;
- ns16550_get_reg get = ctx->get_reg;
- ns16550_set_reg set = ctx->set_reg;
- uint32_t status = 0;
- rtems_interrupt_lock_context lock_context;
-
- /* Save port interrupt mask */
- uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE);
-
- /* Disable port interrupts */
- ns16550_enable_interrupts(ctx, NS16550_DISABLE_ALL_INTR);
-
- while (true) {
- /* Try to transmit the character in a critical section */
- rtems_termios_device_lock_acquire(&ctx->base, &lock_context);
-
- /* Read the transmitter holding register and check it */
- status = get( port, NS16550_LINE_STATUS);
- if ((status & SP_LSR_THOLD) != 0) {
- /* Transmit character */
- set( port, NS16550_TRANSMIT_BUFFER, out);
-
- /* Finished */
- rtems_termios_device_lock_release(&ctx->base, &lock_context);
- break;
- } else {
- rtems_termios_device_lock_release(&ctx->base, &lock_context);
- }
-
- /* Wait for transmitter holding register to be empty */
- do {
- status = get( port, NS16550_LINE_STATUS);
- } while ((status & SP_LSR_THOLD) == 0);
- }
-
- /* Restore port interrupt mask */
- set( port, NS16550_INTERRUPT_ENABLE, interrupt_mask);
-}
-
-/*
- * These routines provide control of the RTS and DTR lines
- */
-
-/*
- * ns16550_assert_RTS
- */
-
-static void ns16550_assert_RTS(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- rtems_interrupt_lock_context lock_context;
-
- /*
- * Assert RTS
- */
- rtems_termios_device_lock_acquire(base, &lock_context);
- ctx->modem_control |= SP_MODEM_RTS;
- (*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
- rtems_termios_device_lock_release(base, &lock_context);
-}
-
-/*
- * ns16550_negate_RTS
- */
-
-static void ns16550_negate_RTS(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- rtems_interrupt_lock_context lock_context;
-
- /*
- * Negate RTS
- */
- rtems_termios_device_lock_acquire(base, &lock_context);
- ctx->modem_control &= ~SP_MODEM_RTS;
- (*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
- rtems_termios_device_lock_release(base, &lock_context);
-}
-
-/*
- * These flow control routines utilise a connection from the local DTR
- * line to the remote CTS line
- */
-
-/*
- * ns16550_assert_DTR
- */
-
-static void ns16550_assert_DTR(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- rtems_interrupt_lock_context lock_context;
-
- /*
- * Assert DTR
- */
- rtems_termios_device_lock_acquire(base, &lock_context);
- ctx->modem_control |= SP_MODEM_DTR;
- (*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL, ctx->modem_control);
- rtems_termios_device_lock_release(base, &lock_context);
-}
-
-/*
- * ns16550_negate_DTR
- */
-
-static void ns16550_negate_DTR(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- rtems_interrupt_lock_context lock_context;
-
- /*
- * Negate DTR
- */
- rtems_termios_device_lock_acquire(base, &lock_context);
- ctx->modem_control &=~SP_MODEM_DTR;
- (*ctx->set_reg)(ctx->port, NS16550_MODEM_CONTROL,ctx->modem_control);
- rtems_termios_device_lock_release(base, &lock_context);
-}
-
-/*
- * ns16550_set_attributes
- *
- * This function sets the channel to reflect the requested termios
- * port settings.
- */
-
-static bool ns16550_set_attributes(
- rtems_termios_device_context *base,
- const struct termios *t
-)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- uint32_t pNS16550;
- uint32_t ulBaudDivisor;
- uint8_t ucLineControl;
- uint32_t baud_requested;
- ns16550_set_reg setReg;
-
- pNS16550 = ctx->port;
- setReg = ctx->set_reg;
-
- /*
- * Calculate the baud rate divisor
- *
- * Assert ensures there is no division by 0.
- */
-
- baud_requested = rtems_termios_baud_to_number(t->c_ospeed);
- _Assert( baud_requested != 0 );
-
- ulBaudDivisor = NS16550_GetBaudDivisor(ctx, baud_requested);
-
- ucLineControl = 0;
-
- /*
- * Parity
- */
-
- if (t->c_cflag & PARENB) {
- ucLineControl |= SP_LINE_PAR;
- if (!(t->c_cflag & PARODD))
- ucLineControl |= SP_LINE_ODD;
- }
-
- /*
- * Character Size
- */
-
- if (t->c_cflag & CSIZE) {
- switch (t->c_cflag & CSIZE) {
- case CS5: ucLineControl |= FIVE_BITS; break;
- case CS6: ucLineControl |= SIX_BITS; break;
- case CS7: ucLineControl |= SEVEN_BITS; break;
- case CS8: ucLineControl |= EIGHT_BITS; break;
- }
- } else {
- ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */
- }
-
- /*
- * Stop Bits
- */
-
- if (t->c_cflag & CSTOPB) {
- ucLineControl |= SP_LINE_STOP; /* 2 stop bits */
- } else {
- ; /* 1 stop bit */
- }
-
- /*
- * Now actually set the chip
- */
-
- if (ulBaudDivisor != ctx->baud_divisor || ucLineControl != ctx->line_control) {
- rtems_interrupt_lock_context lock_context;
-
- ctx->baud_divisor = ulBaudDivisor;
- ctx->line_control = ucLineControl;
-
- rtems_termios_device_lock_acquire(base, &lock_context);
-
- /*
- * Set the baud rate
- *
- * NOTE: When the Divisor Latch Access Bit (DLAB) is set to 1,
- * the transmit buffer and interrupt enable registers
- * turn into the LSB and MSB divisor latch registers.
- */
-
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
- (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
- (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);
-
- /*
- * Now write the line control
- */
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );
-
- rtems_termios_device_lock_release(base, &lock_context);
- }
-
- return true;
-}
-
-/**
- * @brief Transmits up to @a len characters from @a buf.
- *
- * This routine is invoked either from task context with disabled interrupts to
- * start a new transmission process with exactly one character in case of an
- * idle output state or from the interrupt handler to refill the transmitter.
- *
- * Returns always zero.
- */
-static void ns16550_write_support_int(
- rtems_termios_device_context *base,
- const char *buf,
- size_t len
-)
-{
- ns16550_context *ctx = (ns16550_context *) base;
-
- ctx->out_total = len;
-
- if (len > 0) {
- ctx->out_remaining = len;
- ctx->out_buf = buf;
- ctx->out_current = ns16550_write_to_fifo(ctx, buf, len);
-
- ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR);
- } else {
- ns16550_enable_interrupts(ctx, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
- }
-}
-
-static void ns16550_write_support_task(
- rtems_termios_device_context *base,
- const char *buf,
- size_t len
-)
-{
- ns16550_context *ctx = (ns16550_context *) base;
-
- ctx->out_total = len;
-
- if (len > 0) {
- ctx->out_remaining = len;
- ctx->out_buf = buf;
- ctx->out_current = ns16550_write_to_fifo(ctx, buf, len);
-
- ns16550_clear_and_set_interrupts(ctx, 0, SP_INT_TX_ENABLE);
- }
-}
-
-/*
- * ns16550_write_support_polled
- *
- * Console Termios output entry point.
- *
- */
-
-static void ns16550_write_support_polled(
- rtems_termios_device_context *base,
- const char *buf,
- size_t len
-)
-{
- size_t nwrite = 0;
-
- /*
- * poll each byte in the string out of the port.
- */
- while (nwrite < len) {
- /*
- * transmit character
- */
- ns16550_polled_putchar(base, *buf++);
- nwrite++;
- }
-}
-
-/*
- * Debug gets() support
- */
-int ns16550_polled_getchar(rtems_termios_device_context *base)
-{
- ns16550_context *ctx = (ns16550_context *) base;
- uint32_t pNS16550;
- unsigned char ucLineStatus;
- uint8_t cChar;
- ns16550_get_reg getReg;
-
- pNS16550 = ctx->port;
- getReg = ctx->get_reg;
-
- ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
- if (ucLineStatus & SP_LSR_RDY) {
- cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
- return (int)cChar;
- }
- return -1;
-}
-
-/*
- * Flow control is only supported when using interrupts
- */
-
-const rtems_termios_device_flow ns16550_flow_rtscts = {
- .stop_remote_tx = ns16550_negate_RTS,
- .start_remote_tx = ns16550_assert_RTS
-};
-
-const rtems_termios_device_flow ns16550_flow_dtrcts = {
- .stop_remote_tx = ns16550_negate_DTR,
- .start_remote_tx = ns16550_assert_DTR
-};
-
-const rtems_termios_device_handler ns16550_handler_interrupt = {
- .first_open = ns16550_open,
- .last_close = ns16550_close,
- .poll_read = NULL,
- .write = ns16550_write_support_int,
- .set_attributes = ns16550_set_attributes,
- .mode = TERMIOS_IRQ_DRIVEN
-};
-
-const rtems_termios_device_handler ns16550_handler_polled = {
- .first_open = ns16550_open,
- .last_close = ns16550_close,
- .poll_read = ns16550_polled_getchar,
- .write = ns16550_write_support_polled,
- .set_attributes = ns16550_set_attributes,
- .mode = TERMIOS_POLLED
-};
-
-const rtems_termios_device_handler ns16550_handler_task = {
- .first_open = ns16550_open,
- .last_close = ns16550_close,
- .poll_read = ns16550_read_task,
- .write = ns16550_write_support_task,
- .set_attributes = ns16550_set_attributes,
- .mode = TERMIOS_TASK_DRIVEN
-};
diff --git a/c/src/libchip/serial/ns16550.c b/c/src/libchip/serial/ns16550.c
deleted file mode 100644
index b1e5892c15..0000000000
--- a/c/src/libchip/serial/ns16550.c
+++ /dev/null
@@ -1,875 +0,0 @@
-/**
- * @file
- *
- * This file contains the TTY driver for the National Semiconductor NS16550.
- *
- * This part is widely cloned and second sourced. It is found in a number
- * of "Super IO" controllers.
- *
- * This driver uses the termios pseudo driver.
- */
-
-/*
- * COPYRIGHT (c) 1998 by Radstone Technology
- *
- * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
- * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
- *
- * You are hereby granted permission to use, copy, modify, and distribute
- * this file, provided that this notice, plus the above copyright notice
- * and disclaimer, appears in all copies. Radstone Technology will provide
- * no support for this code.
- *
- * COPYRIGHT (c) 1989-2012.
- * 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.org/license/LICENSE.
- */
-
-#include <stdlib.h>
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/ringbuf.h>
-#include <rtems/bspIo.h>
-#include <rtems/termiostypes.h>
-
-#include <libchip/serial.h>
-#include <libchip/sersupp.h>
-
-#include <bsp.h>
-
-#include <libchip/ns16550_p.h>
-#include <libchip/ns16550.h>
-
-#if defined(BSP_FEATURE_IRQ_EXTENSION)
- #include <bsp/irq.h>
-#elif defined(BSP_FEATURE_IRQ_LEGACY)
- #include <bsp/irq.h>
-#elif defined(__PPC__) || defined(__i386__)
- #include <bsp/irq.h>
- #define BSP_FEATURE_IRQ_LEGACY
- #ifdef BSP_SHARED_HANDLER_SUPPORT
- #define BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
- #endif
-#endif
-
-typedef struct {
- uint8_t ucModemCtrl;
- int transmitFifoChars;
-} NS16550Context;
-
-/*
- * Driver functions
- */
-
-NS16550_STATIC void ns16550_init(int minor);
-
-NS16550_STATIC int ns16550_open(
- int major,
- int minor,
- void * arg
-);
-
-NS16550_STATIC int ns16550_close(
- int major,
- int minor,
- void * arg
-);
-
-NS16550_STATIC void ns16550_write_polled(
- int minor,
- char cChar
-);
-
-NS16550_STATIC int ns16550_assert_RTS(
- int minor
-);
-
-NS16550_STATIC int ns16550_negate_RTS(
- int minor
-);
-
-NS16550_STATIC int ns16550_assert_DTR(
- int minor
-);
-
-NS16550_STATIC int ns16550_negate_DTR(
- int minor
-);
-
-NS16550_STATIC void ns16550_initialize_interrupts(int minor);
-
-NS16550_STATIC void ns16550_cleanup_interrupts(int minor);
-
-NS16550_STATIC ssize_t ns16550_write_support_int(
- int minor,
- const char *buf,
- size_t len
-);
-
-NS16550_STATIC ssize_t ns16550_write_support_polled(
- int minor,
- const char *buf,
- size_t len
- );
-
-int ns16550_inbyte_nonblocking_polled(
- int minor
-);
-
-NS16550_STATIC void ns16550_enable_interrupts(
- console_tbl *c,
- int mask
-);
-
-NS16550_STATIC int ns16550_set_attributes(
- int minor,
- const struct termios *t
-);
-
-#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
- NS16550_STATIC void ns16550_isr(void *arg);
-#endif
-
-RTEMS_INTERRUPT_LOCK_DEFINE(static, ns16550_lock, "NS16550")
-
-/*
- * Flow control is only supported when using interrupts
- */
-
-const console_flow ns16550_flow_RTSCTS = {
- ns16550_negate_RTS, /* deviceStopRemoteTx */
- ns16550_assert_RTS /* deviceStartRemoteTx */
-};
-
-const console_flow ns16550_flow_DTRCTS = {
- ns16550_negate_DTR, /* deviceStopRemoteTx */
- ns16550_assert_DTR /* deviceStartRemoteTx */
-};
-
-const console_fns ns16550_fns = {
- libchip_serial_default_probe, /* deviceProbe */
- ns16550_open, /* deviceFirstOpen */
- ns16550_close, /* deviceLastClose */
- NULL, /* deviceRead */
- ns16550_write_support_int, /* deviceWrite */
- ns16550_init, /* deviceInitialize */
- ns16550_write_polled, /* deviceWritePolled */
- ns16550_set_attributes, /* deviceSetAttributes */
- true /* deviceOutputUsesInterrupts */
-};
-
-const console_fns ns16550_fns_polled = {
- libchip_serial_default_probe, /* deviceProbe */
- ns16550_open, /* deviceFirstOpen */
- ns16550_close, /* deviceLastClose */
- ns16550_inbyte_nonblocking_polled, /* deviceRead */
- ns16550_write_support_polled, /* deviceWrite */
- ns16550_init, /* deviceInitialize */
- ns16550_write_polled, /* deviceWritePolled */
- ns16550_set_attributes, /* deviceSetAttributes */
- false /* deviceOutputUsesInterrupts */
-};
-
-static uint32_t NS16550_GetBaudDivisor(const console_tbl *c, uint32_t baud)
-{
- uint32_t clock = c->ulClock;
- uint32_t baudDivisor = (clock != 0 ? clock : 115200) / (baud * 16);
-
- if (c->deviceType == SERIAL_NS16550_WITH_FDR) {
- uint32_t fractionalDivider = 0x10;
- uint32_t err = baud;
- uint32_t mulVal;
- uint32_t divAddVal;
-
- clock /= 16 * baudDivisor;
- for (mulVal = 1; mulVal < 16; ++mulVal) {
- for (divAddVal = 0; divAddVal < mulVal; ++divAddVal) {
- uint32_t actual = (mulVal * clock) / (mulVal + divAddVal);
- uint32_t newErr = actual > baud ? actual - baud : baud - actual;
-
- if (newErr < err) {
- err = newErr;
- fractionalDivider = (mulVal << 4) | divAddVal;
- }
- }
- }
-
- (*c->setRegister)(
- c->ulCtrlPort1,
- NS16550_FRACTIONAL_DIVIDER,
- fractionalDivider
- );
- }
-
- return baudDivisor;
-}
-
-/*
- * ns16550_init
- */
-
-void ns16550_init(int minor)
-{
- uintptr_t pNS16550;
- uint8_t ucDataByte;
- uint32_t ulBaudDivisor;
- NS16550Context *pns16550Context;
- setRegister_f setReg;
- getRegister_f getReg;
- console_tbl *c = Console_Port_Tbl [minor];
-
- pns16550Context=(NS16550Context *)malloc(sizeof(NS16550Context));
-
- if (pns16550Context == NULL) {
- printk( "%s: Error: Not enough memory\n", __func__);
- rtems_fatal_error_occurred( 0xdeadbeef);
- }
-
- Console_Port_Data[minor].pDeviceContext=(void *)pns16550Context;
- pns16550Context->ucModemCtrl=SP_MODEM_IRQ;
-
- pNS16550 = c->ulCtrlPort1;
- setReg = c->setRegister;
- getReg = c->getRegister;
-
- /* Clear the divisor latch, clear all interrupt enables,
- * and reset and
- * disable the FIFO's.
- */
-
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, 0x0);
- ns16550_enable_interrupts( c, NS16550_DISABLE_ALL_INTR );
-
- /* Set the divisor latch and set the baud rate. */
-
- ulBaudDivisor = NS16550_GetBaudDivisor(c, (uintptr_t) c->pDeviceParams);
- ucDataByte = SP_LINE_DLAB;
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
-
- /* XXX */
- (*setReg)(pNS16550,NS16550_TRANSMIT_BUFFER,(uint8_t)(ulBaudDivisor & 0xffU));
- (*setReg)(
- pNS16550,NS16550_INTERRUPT_ENABLE,
- (uint8_t)(( ulBaudDivisor >> 8 ) & 0xffU )
- );
-
- /* Clear the divisor latch and set the character size to eight bits */
- /* with one stop bit and no parity checking. */
- ucDataByte = EIGHT_BITS;
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucDataByte);
-
- /* Enable and reset transmit and receive FIFOs. TJA */
- ucDataByte = SP_FIFO_ENABLE;
- (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
-
- ucDataByte = SP_FIFO_ENABLE | SP_FIFO_RXRST | SP_FIFO_TXRST;
- (*setReg)(pNS16550, NS16550_FIFO_CONTROL, ucDataByte);
-
- ns16550_enable_interrupts(c, NS16550_DISABLE_ALL_INTR);
-
- /* Set data terminal ready. */
- /* And open interrupt tristate line */
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);
-
- (*getReg)(pNS16550, NS16550_LINE_STATUS );
- (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER );
-}
-
-/*
- * ns16550_open
- */
-
-int ns16550_open(
- int major,
- int minor,
- void *arg
-)
-{
- rtems_libio_open_close_args_t *oc = (rtems_libio_open_close_args_t *) arg;
- struct rtems_termios_tty *tty = (struct rtems_termios_tty *) oc->iop->data1;
- console_tbl *c = Console_Port_Tbl [minor];
- console_data *d = &Console_Port_Data [minor];
-
- d->termios_data = tty;
-
- /* Assert DTR */
- if (c->pDeviceFlow != &ns16550_flow_DTRCTS) {
- ns16550_assert_DTR( minor);
- }
-
- /* Set initial baud */
- rtems_termios_set_initial_baud( tty, (intptr_t) c->pDeviceParams);
-
- if (c->pDeviceFns->deviceOutputUsesInterrupts) {
- ns16550_initialize_interrupts( minor);
- ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
- }
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * ns16550_close
- */
-
-int ns16550_close(
- int major,
- int minor,
- void * arg
-)
-{
- console_tbl *c = Console_Port_Tbl [minor];
-
- /*
- * Negate DTR
- */
- if (c->pDeviceFlow != &ns16550_flow_DTRCTS) {
- ns16550_negate_DTR(minor);
- }
-
- ns16550_enable_interrupts(c, NS16550_DISABLE_ALL_INTR);
-
- if (c->pDeviceFns->deviceOutputUsesInterrupts) {
- ns16550_cleanup_interrupts(minor);
- }
-
- return(RTEMS_SUCCESSFUL);
-}
-
-/**
- * @brief Polled write for NS16550.
- */
-void ns16550_outch_polled(console_tbl *c, char out)
-{
- uintptr_t port = c->ulCtrlPort1;
- getRegister_f get = c->getRegister;
- setRegister_f set = c->setRegister;
- uint32_t status = 0;
- rtems_interrupt_lock_context lock_context;
-
- /* Save port interrupt mask */
- uint32_t interrupt_mask = get( port, NS16550_INTERRUPT_ENABLE);
-
- /* Disable port interrupts */
- ns16550_enable_interrupts( c, NS16550_DISABLE_ALL_INTR);
-
- while (true) {
- /* Try to transmit the character in a critical section */
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
-
- /* Read the transmitter holding register and check it */
- status = get( port, NS16550_LINE_STATUS);
- if ((status & SP_LSR_THOLD) != 0) {
- /* Transmit character */
- set( port, NS16550_TRANSMIT_BUFFER, out);
-
- /* Finished */
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- break;
- } else {
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- }
-
- /* Wait for transmitter holding register to be empty */
- do {
- status = get( port, NS16550_LINE_STATUS);
- } while ((status & SP_LSR_THOLD) == 0);
- }
-
- /* Restore port interrupt mask */
- set( port, NS16550_INTERRUPT_ENABLE, interrupt_mask);
-}
-
-void ns16550_write_polled(int minor, char out)
-{
- console_tbl *c = Console_Port_Tbl [minor];
-
- ns16550_outch_polled( c, out );
-}
-
-/*
- * These routines provide control of the RTS and DTR lines
- */
-
-/*
- * ns16550_assert_RTS
- */
-
-NS16550_STATIC int ns16550_assert_RTS(int minor)
-{
- uint32_t pNS16550;
- rtems_interrupt_lock_context lock_context;
- NS16550Context *pns16550Context;
- setRegister_f setReg;
-
- pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
-
- pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Assert RTS
- */
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
- pns16550Context->ucModemCtrl|=SP_MODEM_RTS;
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- return 0;
-}
-
-/*
- * ns16550_negate_RTS
- */
-
-NS16550_STATIC int ns16550_negate_RTS(int minor)
-{
- uint32_t pNS16550;
- rtems_interrupt_lock_context lock_context;
- NS16550Context *pns16550Context;
- setRegister_f setReg;
-
- pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
-
- pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Negate RTS
- */
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
- pns16550Context->ucModemCtrl&=~SP_MODEM_RTS;
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- return 0;
-}
-
-/*
- * These flow control routines utilise a connection from the local DTR
- * line to the remote CTS line
- */
-
-/*
- * ns16550_assert_DTR
- */
-
-NS16550_STATIC int ns16550_assert_DTR(int minor)
-{
- uint32_t pNS16550;
- rtems_interrupt_lock_context lock_context;
- NS16550Context *pns16550Context;
- setRegister_f setReg;
-
- pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
-
- pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Assert DTR
- */
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
- pns16550Context->ucModemCtrl|=SP_MODEM_DTR;
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL, pns16550Context->ucModemCtrl);
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- return 0;
-}
-
-/*
- * ns16550_negate_DTR
- */
-
-NS16550_STATIC int ns16550_negate_DTR(int minor)
-{
- uint32_t pNS16550;
- rtems_interrupt_lock_context lock_context;
- NS16550Context *pns16550Context;
- setRegister_f setReg;
-
- pns16550Context=(NS16550Context *) Console_Port_Data[minor].pDeviceContext;
-
- pNS16550 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Negate DTR
- */
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
- pns16550Context->ucModemCtrl&=~SP_MODEM_DTR;
- (*setReg)(pNS16550, NS16550_MODEM_CONTROL,pns16550Context->ucModemCtrl);
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
- return 0;
-}
-
-/*
- * ns16550_set_attributes
- *
- * This function sets the channel to reflect the requested termios
- * port settings.
- */
-
-int ns16550_set_attributes(
- int minor,
- const struct termios *t
-)
-{
- uint32_t pNS16550;
- uint32_t ulBaudDivisor;
- uint8_t ucLineControl;
- uint32_t baud_requested;
- setRegister_f setReg;
- rtems_interrupt_lock_context lock_context;
- const console_tbl *c = Console_Port_Tbl [minor];
-
- pNS16550 = c->ulCtrlPort1;
- setReg = c->setRegister;
-
- /*
- * Calculate the baud rate divisor
- *
- * Assert ensures there is no division by 0.
- */
-
- baud_requested = rtems_termios_baud_to_number(t->c_ospeed);
- _Assert( baud_requested != 0 );
- ulBaudDivisor = NS16550_GetBaudDivisor(c, baud_requested);
-
- ucLineControl = 0;
-
- /*
- * Parity
- */
-
- if (t->c_cflag & PARENB) {
- ucLineControl |= SP_LINE_PAR;
- if (!(t->c_cflag & PARODD))
- ucLineControl |= SP_LINE_ODD;
- }
-
- /*
- * Character Size
- */
-
- if (t->c_cflag & CSIZE) {
- switch (t->c_cflag & CSIZE) {
- case CS5: ucLineControl |= FIVE_BITS; break;
- case CS6: ucLineControl |= SIX_BITS; break;
- case CS7: ucLineControl |= SEVEN_BITS; break;
- case CS8: ucLineControl |= EIGHT_BITS; break;
- }
- } else {
- ucLineControl |= EIGHT_BITS; /* default to 9600,8,N,1 */
- }
-
- /*
- * Stop Bits
- */
-
- if (t->c_cflag & CSTOPB) {
- ucLineControl |= SP_LINE_STOP; /* 2 stop bits */
- } else {
- ; /* 1 stop bit */
- }
-
- /*
- * Now actually set the chip
- */
-
- rtems_interrupt_lock_acquire(&ns16550_lock, &lock_context);
-
- /*
- * Set the baud rate
- *
- * NOTE: When the Divisor Latch Access Bit (DLAB) is set to 1,
- * the transmit buffer and interrupt enable registers
- * turn into the LSB and MSB divisor latch registers.
- */
-
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, SP_LINE_DLAB);
- (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, ulBaudDivisor&0xff);
- (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, (ulBaudDivisor>>8)&0xff);
-
- /*
- * Now write the line control
- */
- (*setReg)(pNS16550, NS16550_LINE_CONTROL, ucLineControl );
-
- rtems_interrupt_lock_release(&ns16550_lock, &lock_context);
-
- return 0;
-}
-
-#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
-
-/**
- * @brief Process interrupt.
- */
-NS16550_STATIC void ns16550_process( int minor)
-{
- console_tbl *c = Console_Port_Tbl [minor];
- console_data *d = &Console_Port_Data [minor];
- NS16550Context *ctx = d->pDeviceContext;
- uint32_t port = c->ulCtrlPort1;
- getRegister_f get = c->getRegister;
- int i;
- char buf [SP_FIFO_SIZE];
-
- /* Iterate until no more interrupts are pending */
- do {
- /* Fetch received characters */
- i = 0;
- while ((get(port, NS16550_LINE_STATUS) & SP_LSR_RDY) != 0) {
- buf[i++] = (char) get(port, NS16550_RECEIVE_BUFFER);
- if (i == SP_FIFO_SIZE) {
- /* Enqueue fetched characters */
- rtems_termios_enqueue_raw_characters( d->termios_data, buf, i);
- i = 0;
- }
- }
-
- if (i > 0)
- rtems_termios_enqueue_raw_characters( d->termios_data, buf, i);
-
- /* Check if we can dequeue transmitted characters */
- if (ctx->transmitFifoChars > 0
- && (get( port, NS16550_LINE_STATUS) & SP_LSR_THOLD) != 0) {
- /* Dequeue transmitted characters */
- rtems_termios_dequeue_characters(
- d->termios_data,
- ctx->transmitFifoChars
- );
- }
- } while ((get( port, NS16550_INTERRUPT_ID) & SP_IID_0) == 0);
-}
-#endif
-
-/**
- * @brief Transmits up to @a len characters from @a buf.
- *
- * This routine is invoked either from task context with disabled interrupts to
- * start a new transmission process with exactly one character in case of an
- * idle output state or from the interrupt handler to refill the transmitter.
- *
- * Returns always zero.
- */
-ssize_t ns16550_write_support_int(
- int minor,
- const char *buf,
- size_t len
-)
-{
- console_tbl *c = Console_Port_Tbl [minor];
- console_data *d = &Console_Port_Data [minor];
- NS16550Context *ctx = d->pDeviceContext;
- uint32_t port = c->ulCtrlPort1;
- setRegister_f set = c->setRegister;
- int i = 0;
- int out = len > SP_FIFO_SIZE ? SP_FIFO_SIZE : len;
-
- for (i = 0; i < out; ++i) {
- set( port, NS16550_TRANSMIT_BUFFER, buf [i]);
- }
-
- ctx->transmitFifoChars = out;
-
- if (out > 0) {
- ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR);
- } else {
- ns16550_enable_interrupts( c, NS16550_ENABLE_ALL_INTR_EXCEPT_TX);
- }
-
- return 0;
-}
-
-/*
- * ns16550_enable_interrupts
- *
- * This routine initializes the port to have the specified interrupts masked.
- */
-NS16550_STATIC void ns16550_enable_interrupts(
- console_tbl *c,
- int mask
-)
-{
- uint32_t pNS16550;
- setRegister_f setReg;
-
- pNS16550 = c->ulCtrlPort1;
- setReg = c->setRegister;
-
- (*setReg)(pNS16550, NS16550_INTERRUPT_ENABLE, mask);
-}
-
-#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
- void ns16550_isr(void *arg)
- {
- int minor = (intptr_t) arg;
-
- ns16550_process( minor);
- }
-#endif
-
-/*
- * ns16550_initialize_interrupts
- *
- * This routine initializes the port to operate in interrupt driver mode.
- */
-NS16550_STATIC void ns16550_initialize_interrupts( int minor)
-{
-#if defined(BSP_FEATURE_IRQ_EXTENSION) || defined(BSP_FEATURE_IRQ_LEGACY)
- console_tbl *c = Console_Port_Tbl [minor];
-#endif
-
- #ifdef BSP_FEATURE_IRQ_EXTENSION
- {
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- sc = rtems_interrupt_handler_install(
- c->ulIntVector,
- "NS16550",
- RTEMS_INTERRUPT_SHARED,
- ns16550_isr,
- (void *) (intptr_t) minor
- );
- if (sc != RTEMS_SUCCESSFUL) {
- /* FIXME */
- printk( "%s: Error: Install interrupt handler\n", __func__);
- rtems_fatal_error_occurred( 0xdeadbeef);
- }
- }
- #elif defined(BSP_FEATURE_IRQ_LEGACY)
- {
- int rv = 0;
- #ifdef BSP_FEATURE_IRQ_LEGACY_SHARED_HANDLER_SUPPORT
- rtems_irq_connect_data cd = {
- c->ulIntVector,
- ns16550_isr,
- (void *) minor,
- NULL,
- NULL,
- NULL,
- NULL
- };
- rv = BSP_install_rtems_shared_irq_handler( &cd);
- #else
- rtems_irq_connect_data cd = {
- c->ulIntVector,
- ns16550_isr,
- (void *) minor,
- NULL,
- NULL,
- NULL
- };
- rv = BSP_install_rtems_irq_handler( &cd);
- #endif
- if (rv == 0) {
- /* FIXME */
- printk( "%s: Error: Install interrupt handler\n", __func__);
- rtems_fatal_error_occurred( 0xdeadbeef);
- }
- }
- #endif
-}
-
-NS16550_STATIC void ns16550_cleanup_interrupts(int minor)
-{
- #if defined(BSP_FEATURE_IRQ_EXTENSION)
- rtems_status_code sc = RTEMS_SUCCESSFUL;
- console_tbl *c = Console_Port_Tbl [minor];
- sc = rtems_interrupt_handler_remove(
- c->ulIntVector,
- ns16550_isr,
- (void *) (intptr_t) minor
- );
- if (sc != RTEMS_SUCCESSFUL) {
- /* FIXME */
- printk("%s: Error: Remove interrupt handler\n", __func__);
- rtems_fatal_error_occurred(0xdeadbeef);
- }
- #elif defined(BSP_FEATURE_IRQ_LEGACY)
- int rv = 0;
- console_tbl *c = Console_Port_Tbl [minor];
- rtems_irq_connect_data cd = {
- .name = c->ulIntVector,
- .hdl = ns16550_isr,
- .handle = (void *) minor
- };
- rv = BSP_remove_rtems_irq_handler(&cd);
- if (rv == 0) {
- /* FIXME */
- printk("%s: Error: Remove interrupt handler\n", __func__);
- rtems_fatal_error_occurred(0xdeadbeef);
- }
- #endif
-}
-
-/*
- * ns16550_write_support_polled
- *
- * Console Termios output entry point.
- *
- */
-
-ssize_t ns16550_write_support_polled(
- int minor,
- const char *buf,
- size_t len
-)
-{
- int nwrite = 0;
-
- /*
- * poll each byte in the string out of the port.
- */
- while (nwrite < len) {
- /*
- * transmit character
- */
- ns16550_write_polled(minor, *buf++);
- nwrite++;
- }
-
- /*
- * return the number of bytes written.
- */
- return nwrite;
-}
-
-/*
- * Debug gets() support
- */
-int ns16550_inch_polled(
- console_tbl *c
-)
-{
- uint32_t pNS16550;
- unsigned char ucLineStatus;
- uint8_t cChar;
- getRegister_f getReg;
-
- pNS16550 = c->ulCtrlPort1;
- getReg = c->getRegister;
-
- ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS);
- if (ucLineStatus & SP_LSR_RDY) {
- cChar = (*getReg)(pNS16550, NS16550_RECEIVE_BUFFER);
- return (int)cChar;
- }
- return -1;
-}
-
-/*
- * ns16550_inbyte_nonblocking_polled
- *
- * Console Termios polling input entry point.
- */
-int ns16550_inbyte_nonblocking_polled(int minor)
-{
- console_tbl *c = Console_Port_Tbl [minor];
-
- return ns16550_inch_polled( c );
-}
diff --git a/c/src/libchip/serial/serprobe.c b/c/src/libchip/serial/serprobe.c
deleted file mode 100644
index 7f8d392452..0000000000
--- a/c/src/libchip/serial/serprobe.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <rtems.h>
-#include <libchip/serial.h>
-#include <libchip/sersupp.h>
-
-bool libchip_serial_default_probe(int minor)
-{
- /*
- * If the configuration dependent probe has located the device then
- * assume it is there
- */
-
- return true;
-}
diff --git a/c/src/libchip/serial/z85c30.c b/c/src/libchip/serial/z85c30.c
deleted file mode 100644
index 55df9d3451..0000000000
--- a/c/src/libchip/serial/z85c30.c
+++ /dev/null
@@ -1,893 +0,0 @@
-/*
- * This file contains the console driver chip level routines for the
- * Zilog z85c30 chip.
- *
- * The Zilog Z8530 is also available as:
- *
- * + Intel 82530
- * + AMD ???
- *
- * COPYRIGHT (c) 1998 by Radstone Technology
- *
- *
- * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
- * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
- *
- * You are hereby granted permission to use, copy, modify, and distribute
- * this file, provided that this notice, plus the above copyright notice
- * and disclaimer, appears in all copies. Radstone Technology will provide
- * no support for this code.
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <rtems/score/sysstate.h>
-#include <stdlib.h>
-
-#include <libchip/serial.h>
-#include <libchip/sersupp.h>
-#include "z85c30_p.h"
-
-/*
- * Flow control is only supported when using interrupts
- */
-
-const console_flow z85c30_flow_RTSCTS = {
- z85c30_negate_RTS, /* deviceStopRemoteTx */
- z85c30_assert_RTS /* deviceStartRemoteTx */
-};
-
-const console_flow z85c30_flow_DTRCTS = {
- z85c30_negate_DTR, /* deviceStopRemoteTx */
- z85c30_assert_DTR /* deviceStartRemoteTx */
-};
-
-/*
- * Exported driver function table
- */
-
-const console_fns z85c30_fns = {
- libchip_serial_default_probe, /* deviceProbe */
- z85c30_open, /* deviceFirstOpen */
- NULL, /* deviceLastClose */
- NULL, /* deviceRead */
- z85c30_write_support_int, /* deviceWrite */
- z85c30_initialize_interrupts, /* deviceInitialize */
- z85c30_write_polled, /* deviceWritePolled */
- NULL, /* deviceSetAttributes */
- true /* deviceOutputUsesInterrupts */
-};
-
-const console_fns z85c30_fns_polled = {
- libchip_serial_default_probe, /* deviceProbe */
- z85c30_open, /* deviceFirstOpen */
- z85c30_close, /* deviceLastClose */
- z85c30_inbyte_nonblocking_polled, /* deviceRead */
- z85c30_write_support_polled, /* deviceWrite */
- z85c30_init, /* deviceInitialize */
- z85c30_write_polled, /* deviceWritePolled */
- NULL, /* deviceSetAttributes */
- false /* deviceOutputUsesInterrupts */
-};
-
-#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
- extern void set_vector( rtems_isr_entry, rtems_vector_number, int );
-#endif
-
-/*
- * z85c30_initialize_port
- *
- * initialize a z85c30 Port
- */
-
-Z85C30_STATIC void z85c30_initialize_port(
- int minor
-)
-{
- uintptr_t ulCtrlPort;
- uintptr_t ulBaudDivisor;
- setRegister_f setReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Using register 4
- * Set up the clock rate is 16 times the data
- * rate, 8 bit sync char, 1 stop bit, no parity
- */
-
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, SCC_WR4_1_STOP | SCC_WR4_16_CLOCK );
-
- /*
- * Set up for 8 bits/character on receive with
- * receiver disable via register 3
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS );
-
- /*
- * Set up for 8 bits/character on transmit
- * with transmitter disable via register 5
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS );
-
- /*
- * Clear misc control bits
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR10, 0x00 );
-
- /*
- * Setup the source of the receive and xmit
- * clock as BRG output and the transmit clock
- * as the output source for TRxC pin via register 11
- */
- (*setReg)(
- ulCtrlPort,
- SCC_WR0_SEL_WR11,
- SCC_WR11_OUT_BR_GEN | SCC_WR11_TRXC_OI |
- SCC_WR11_TX_BR_GEN | SCC_WR11_RX_BR_GEN
- );
-
- ulBaudDivisor = Z85C30_Baud(
- (uint32_t) Console_Port_Tbl[minor]->ulClock,
- (uint32_t) ((uintptr_t)Console_Port_Tbl[minor]->pDeviceParams)
- );
-
- /*
- * Setup the lower 8 bits time constants=1E.
- * If the time constans=1E, then the desire
- * baud rate will be equilvalent to 9600, via register 12.
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff );
-
- /*
- * using register 13
- * Setup the upper 8 bits time constant
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff );
-
- /*
- * Enable the baud rate generator enable with clock from the
- * SCC's PCLK input via register 14.
- */
- (*setReg)(
- ulCtrlPort,
- SCC_WR0_SEL_WR14,
- SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_NULL
- );
-
- /*
- * We are only interested in CTS state changes
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR15, SCC_WR15_CTS_IE );
-
- /*
- * Reset errors
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
-
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_ERR_RST );
-
- /*
- * Enable the receiver via register 3
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, SCC_WR3_RX_8_BITS | SCC_WR3_RX_EN );
-
- /*
- * Enable the transmitter pins set via register 5.
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN );
-
- /*
- * Disable interrupts
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR1, 0 );
-
- /*
- * Reset TX CRC
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_CRC );
-
- /*
- * Reset interrupts
- */
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT );
-}
-
-/*
- * z85c30_open
- */
-
-Z85C30_STATIC int z85c30_open(
- int major,
- int minor,
- void *arg
-)
-{
-
- z85c30_initialize_port(minor);
-
- /*
- * Assert DTR
- */
-
- if (Console_Port_Tbl[minor]->pDeviceFlow !=&z85c30_flow_DTRCTS) {
- z85c30_assert_DTR(minor);
- }
-
- return(RTEMS_SUCCESSFUL);
-}
-
-/*
- * z85c30_close
- */
-
-Z85C30_STATIC int z85c30_close(
- int major,
- int minor,
- void *arg
-)
-{
- /*
- * Negate DTR
- */
-
- if (Console_Port_Tbl[minor]->pDeviceFlow !=&z85c30_flow_DTRCTS) {
- z85c30_negate_DTR(minor);
- }
-
- return(RTEMS_SUCCESSFUL);
-}
-
-/*
- * z85c30_init
- */
-
-Z85C30_STATIC void z85c30_init(int minor)
-{
- uintptr_t ulCtrlPort;
- z85c30_context *pz85c30Context;
- setRegister_f setReg;
- getRegister_f getReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
- getReg = Console_Port_Tbl[minor]->getRegister;
-
- pz85c30Context = (z85c30_context *)malloc(sizeof(z85c30_context));
-
- Console_Port_Data[minor].pDeviceContext = (void *)pz85c30Context;
-
- pz85c30Context->ucModemCtrl = SCC_WR5_TX_8_BITS | SCC_WR5_TX_EN;
-
- if ( ulCtrlPort == Console_Port_Tbl[minor]->ulCtrlPort2 ) {
- /*
- * This is channel A
- */
- /*
- * Ensure port state machine is reset
- */
- (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
-
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_A_RST);
-
- } else {
- /*
- * This is channel B
- */
- /*
- * Ensure port state machine is reset
- */
- (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
-
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR9, SCC_WR9_CH_B_RST);
- }
-}
-
-/*
- * These routines provide control of the RTS and DTR lines
- */
-
-/*
- * z85c30_assert_RTS
- */
-
-Z85C30_STATIC int z85c30_assert_RTS(int minor)
-{
- rtems_interrupt_level Irql;
- z85c30_context *pz85c30Context;
- setRegister_f setReg;
-
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
-
- /*
- * Assert RTS
- */
-
- rtems_interrupt_disable(Irql);
- pz85c30Context->ucModemCtrl|=SCC_WR5_RTS;
- (*setReg)(
- Console_Port_Tbl[minor]->ulCtrlPort1,
- SCC_WR0_SEL_WR5,
- pz85c30Context->ucModemCtrl
- );
- rtems_interrupt_enable(Irql);
- return 0;
-}
-
-/*
- * z85c30_negate_RTS
- */
-
-Z85C30_STATIC int z85c30_negate_RTS(int minor)
-{
- rtems_interrupt_level Irql;
- z85c30_context *pz85c30Context;
- setRegister_f setReg;
-
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
-
- /*
- * Negate RTS
- */
-
- rtems_interrupt_disable(Irql);
- pz85c30Context->ucModemCtrl&=~SCC_WR5_RTS;
- (*setReg)(
- Console_Port_Tbl[minor]->ulCtrlPort1,
- SCC_WR0_SEL_WR5,
- pz85c30Context->ucModemCtrl
- );
- rtems_interrupt_enable(Irql);
- return 0;
-}
-
-/*
- * These flow control routines utilise a connection from the local DTR
- * line to the remote CTS line
- */
-
-/*
- * z85c30_assert_DTR
- */
-
-Z85C30_STATIC int z85c30_assert_DTR(int minor)
-{
- rtems_interrupt_level Irql;
- z85c30_context *pz85c30Context;
- setRegister_f setReg;
-
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
-
- /*
- * Assert DTR
- */
-
- rtems_interrupt_disable(Irql);
- pz85c30Context->ucModemCtrl|=SCC_WR5_DTR;
- (*setReg)(
- Console_Port_Tbl[minor]->ulCtrlPort1,
- SCC_WR0_SEL_WR5,
- pz85c30Context->ucModemCtrl
- );
- rtems_interrupt_enable(Irql);
- return 0;
-}
-
-/*
- * z85c30_negate_DTR
- */
-
-Z85C30_STATIC int z85c30_negate_DTR(int minor)
-{
- rtems_interrupt_level Irql;
- z85c30_context *pz85c30Context;
- setRegister_f setReg;
-
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- pz85c30Context = (z85c30_context *) Console_Port_Data[minor].pDeviceContext;
-
- /*
- * Negate DTR
- */
-
- rtems_interrupt_disable(Irql);
- pz85c30Context->ucModemCtrl&=~SCC_WR5_DTR;
- (*setReg)(
- Console_Port_Tbl[minor]->ulCtrlPort1,
- SCC_WR0_SEL_WR5,
- pz85c30Context->ucModemCtrl
- );
- rtems_interrupt_enable(Irql);
- return 0;
-}
-
-/*
- * z85c30_set_attributes
- *
- * This function sets the SCC channel to reflect the requested termios
- * port settings.
- */
-
-Z85C30_STATIC int z85c30_set_attributes(
- int minor,
- const struct termios *t
-)
-{
- uintptr_t ulCtrlPort;
- uint32_t ulBaudDivisor;
- uint32_t wr3;
- uint32_t wr4;
- uint32_t wr5;
- int baud_requested;
- uint32_t baud_number;
- setRegister_f setReg;
- rtems_interrupt_level Irql;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Calculate the baud rate divisor
- *
- * Assert ensures there is no division by 0.
- */
-
- baud_requested = t->c_ospeed;
- if (!baud_requested)
- baud_requested = B9600; /* default to 9600 baud */
-
- baud_number = (uint32_t) rtems_termios_baud_to_number( baud_requested );
- _Assert( baud_number != 0 );
-
- ulBaudDivisor = Z85C30_Baud(
- (uint32_t) Console_Port_Tbl[minor]->ulClock,
- baud_number
- );
-
- wr3 = SCC_WR3_RX_EN;
- wr4 = SCC_WR4_16_CLOCK;
- wr5 = SCC_WR5_TX_EN;
-
- /*
- * Parity
- */
-
- if (t->c_cflag & PARENB) {
- wr4 |= SCC_WR4_PAR_EN;
- if (!(t->c_cflag & PARODD))
- wr4 |= SCC_WR4_PAR_EVEN;
- }
-
- /*
- * Character Size
- */
-
- if (t->c_cflag & CSIZE) {
- switch (t->c_cflag & CSIZE) {
- case CS5: break;
- case CS6: wr3 |= SCC_WR3_RX_6_BITS; wr5 |= SCC_WR5_TX_6_BITS; break;
- case CS7: wr3 |= SCC_WR3_RX_7_BITS; wr5 |= SCC_WR5_TX_7_BITS; break;
- case CS8: wr3 |= SCC_WR3_RX_8_BITS; wr5 |= SCC_WR5_TX_8_BITS; break;
- }
- } else {
- wr3 |= SCC_WR3_RX_8_BITS; /* default to 9600,8,N,1 */
- wr5 |= SCC_WR5_TX_8_BITS; /* default to 9600,8,N,1 */
- }
-
- /*
- * Stop Bits
- */
-
- if (t->c_cflag & CSTOPB) {
- wr4 |= SCC_WR4_2_STOP; /* 2 stop bits */
- } else {
- wr4 |= SCC_WR4_1_STOP; /* 1 stop bits */
- }
-
- /*
- * Now actually set the chip
- */
-
- rtems_interrupt_disable(Irql);
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR4, wr4 );
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR3, wr3 );
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR5, wr5 );
-
- /*
- * Setup the lower 8 bits time constants=1E.
- * If the time constans=1E, then the desire
- * baud rate will be equilvalent to 9600, via register 12.
- */
-
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR12, ulBaudDivisor & 0xff );
-
- /*
- * using register 13
- * Setup the upper 8 bits time constant
- */
-
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR13, (ulBaudDivisor>>8) & 0xff );
-
- rtems_interrupt_enable(Irql);
-
- return 0;
-}
-
-/*
- * z85c30_process
- *
- * This is the per port ISR handler.
- */
-
-Z85C30_STATIC void z85c30_process(
- int minor,
- uint8_t ucIntPend
-)
-{
- uint32_t ulCtrlPort;
- volatile uint8_t z85c30_status;
- char cChar;
- setRegister_f setReg;
- getRegister_f getReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
- getReg = Console_Port_Tbl[minor]->getRegister;
-
- /*
- * Deal with any received characters
- */
-
- while (ucIntPend&SCC_RR3_B_RX_IP)
- {
- z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
- if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
- break;
- }
-
- /*
- * Return the character read.
- */
-
- cChar = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD8);
-
- rtems_termios_enqueue_raw_characters(
- Console_Port_Data[minor].termios_data,
- &cChar,
- 1
- );
- }
-
- /*
- * There could be a race condition here if there is not yet a TX
- * interrupt pending but the buffer is empty. This condition has
- * been seen before on other z8530 drivers but has not been seen
- * with this one. The typical solution is to use "vector includes
- * status" or to only look at the interrupts actually pending
- * in RR3.
- */
-
- while (true) {
- z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
- if (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
- /*
- * We'll get another interrupt when
- * the transmitter holding reg. becomes
- * free again and we are clear to send
- */
- break;
- }
-
-#if 0
- if (!Z85C30_Status_Is_CTS_asserted(z85c30_status)) {
- /*
- * We can't transmit yet
- */
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
- /*
- * The next state change of CTS will wake us up
- */
- break;
- }
-#endif
-
- rtems_termios_dequeue_characters(Console_Port_Data[minor].termios_data, 1);
- if (rtems_termios_dequeue_characters(
- Console_Port_Data[minor].termios_data, 1)) {
- if (Console_Port_Tbl[minor]->pDeviceFlow != &z85c30_flow_RTSCTS) {
- z85c30_negate_RTS(minor);
- }
- Console_Port_Data[minor].bActive = FALSE;
- z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR_EXCEPT_TX);
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_TX_INT);
- break;
- }
-
- }
-
- if (ucIntPend & SCC_RR3_B_EXT_IP) {
- /*
- * Clear the external status interrupt
- */
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
- z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
- }
-
- /*
- * Reset interrupts
- */
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR0, SCC_WR0_RST_HI_IUS);
-}
-
-/*
- * z85c30_isr
- *
- * This is the ISR handler for each Z8530.
- */
-
-Z85C30_STATIC rtems_isr z85c30_isr(
- rtems_vector_number vector
-)
-{
- int minor;
- uint32_t ulCtrlPort;
- volatile uint8_t ucIntPend;
- volatile uint8_t ucIntPendPort;
- getRegister_f getReg;
-
- for (minor=0;minor<Console_Port_Count;minor++) {
- if(Console_Port_Tbl[minor]->ulIntVector == vector &&
- Console_Port_Tbl[minor]->deviceType == SERIAL_Z85C30 ) {
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort2;
- getReg = Console_Port_Tbl[minor]->getRegister;
- do {
- ucIntPend = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD3);
-
- /*
- * If this is channel A select channel A status
- */
-
- if (ulCtrlPort == Console_Port_Tbl[minor]->ulCtrlPort1) {
- ucIntPendPort = ucIntPend >> 3;
- ucIntPendPort &= 7;
- } else {
- ucIntPendPort = ucIntPend &= 7;
- }
-
- if (ucIntPendPort) {
- z85c30_process(minor, ucIntPendPort);
- }
- } while (ucIntPendPort);
- }
- }
-}
-
-/*
- * z85c30_enable_interrupts
- *
- * This routine enables the specified interrupts for this minor.
- */
-
-Z85C30_STATIC void z85c30_enable_interrupts(
- int minor,
- int interrupt_mask
-)
-{
- uint32_t ulCtrlPort;
- setRegister_f setReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR1, interrupt_mask);
-}
-
-/*
- * z85c30_initialize_interrupts
- *
- * This routine initializes the port to use interrupts.
- */
-
-Z85C30_STATIC void z85c30_initialize_interrupts(
- int minor
-)
-{
- uint32_t ulCtrlPort1;
- setRegister_f setReg;
-
- ulCtrlPort1 = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
-
- z85c30_init(minor);
-
- Console_Port_Data[minor].bActive=FALSE;
-
- z85c30_initialize_port( minor );
-
- if (Console_Port_Tbl[minor]->pDeviceFlow != &z85c30_flow_RTSCTS) {
- z85c30_negate_RTS(minor);
- }
-
-#if (CPU_SIMPLE_VECTORED_INTERRUPTS == TRUE)
- set_vector(z85c30_isr, Console_Port_Tbl[minor]->ulIntVector, 1);
-#endif
-
- z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR_EXCEPT_TX);
-
- (*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR2, 0); /* XXX vector */
- (*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR9, SCC_WR9_MIE);
-
- /*
- * Reset interrupts
- */
-
- (*setReg)(ulCtrlPort1, SCC_WR0_SEL_WR0, SCC_WR0_RST_INT);
-}
-
-/*
- * z85c30_write_support_int
- *
- * Console Termios output entry point.
- *
- */
-
-Z85C30_STATIC ssize_t z85c30_write_support_int(
- int minor,
- const char *buf,
- size_t len)
-{
- uint32_t Irql;
- uint32_t ulCtrlPort;
- setRegister_f setReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * We are using interrupt driven output and termios only sends us
- * one character at a time.
- */
-
- if ( !len )
- return 0;
-
- /*
- * Put the character out and enable interrupts if necessary.
- */
-
- if (Console_Port_Tbl[minor]->pDeviceFlow != &z85c30_flow_RTSCTS) {
- z85c30_assert_RTS(minor);
- }
- rtems_interrupt_disable(Irql);
- if ( Console_Port_Data[minor].bActive == FALSE) {
- Console_Port_Data[minor].bActive = TRUE;
- z85c30_enable_interrupts(minor, SCC_ENABLE_ALL_INTR);
- }
- (*setReg)(ulCtrlPort, SCC_WR0_SEL_WR8, *buf);
- rtems_interrupt_enable(Irql);
-
- return 0;
-}
-
-/*
- * z85c30_inbyte_nonblocking_polled
- *
- * This routine polls for a character.
- */
-
-Z85C30_STATIC int z85c30_inbyte_nonblocking_polled(
- int minor
-)
-{
- volatile uint8_t z85c30_status;
- uint32_t ulCtrlPort;
- getRegister_f getReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- getReg = Console_Port_Tbl[minor]->getRegister;
-
- /*
- * return -1 if a character is not available.
- */
- z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
- if (!Z85C30_Status_Is_RX_character_available(z85c30_status)) {
- return -1;
- }
-
- /*
- * Return the character read.
- */
-
- return (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD8);
-}
-
-/*
- * z85c30_write_support_polled
- *
- * Console Termios output entry point.
- *
- */
-
-Z85C30_STATIC ssize_t z85c30_write_support_polled(
- int minor,
- const char *buf,
- size_t len)
-{
- int nwrite=0;
-
- /*
- * poll each byte in the string out of the port.
- */
- while (nwrite < len) {
- z85c30_write_polled(minor, *buf++);
- nwrite++;
- }
-
- /*
- * return the number of bytes written.
- */
- return nwrite;
-}
-
-/*
- * z85c30_write_polled
- *
- * This routine transmits a character using polling.
- */
-
-Z85C30_STATIC void z85c30_write_polled(
- int minor,
- char cChar
-)
-{
- volatile uint8_t z85c30_status;
- uint32_t ulCtrlPort;
- getRegister_f getReg;
- setRegister_f setReg;
-
- ulCtrlPort = Console_Port_Tbl[minor]->ulCtrlPort1;
- getReg = Console_Port_Tbl[minor]->getRegister;
- setReg = Console_Port_Tbl[minor]->setRegister;
-
- /*
- * Wait for the Transmit buffer to indicate that it is empty.
- */
-
- z85c30_status = (*getReg)( ulCtrlPort, SCC_WR0_SEL_RD0 );
-
- while (!Z85C30_Status_Is_TX_buffer_empty(z85c30_status)) {
- /*
- * Yield while we wait
- */
-#if 0
- if (_System_state_Is_up(_System_state_Get())) {
- rtems_task_wake_after(RTEMS_YIELD_PROCESSOR);
- }
-#endif
- z85c30_status = (*getReg)(ulCtrlPort, SCC_WR0_SEL_RD0);
- }
-
- /*
- * Write the character.
- */
-
- (*setReg)( ulCtrlPort, SCC_WR0_SEL_WR8, cChar );
-}
diff --git a/c/src/libchip/serial/z85c30_p.h b/c/src/libchip/serial/z85c30_p.h
deleted file mode 100644
index af2ed6507c..0000000000
--- a/c/src/libchip/serial/z85c30_p.h
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * This include file contains all private driver definitions for the
- * Zilog z85c30.
- *
- * COPYRIGHT (c) 1998 by Radstone Technology
- *
- *
- * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
- * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
- * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
- *
- * You are hereby granted permission to use, copy, modify, and distribute
- * this file, provided that this notice, plus the above copyright notice
- * and disclaimer, appears in all copies. Radstone Technology will provide
- * no support for this code.
- *
- * COPYRIGHT (c) 1989-1997.
- * On-Line Applications Research Corporation (OAR).
- *
- * The license and distribution terms for this file may in
- * the file LICENSE in this distribution or at
- * http://www.rtems.org/license/LICENSE.
- */
-
-#ifndef __Z85C30_P_H
-#define __Z85C30_P_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Define Z85C30_STATIC to nothing while debugging so the entry points
- * will show up in the symbol table.
- */
-
-#define Z85C30_STATIC
-
-/* #define Z85C30_STATIC static */
-
-/* bit values for write register 0 */
-/* command register */
-
-#define SCC_WR0_SEL_WR0 0x00
-#define SCC_WR0_SEL_WR1 0x01
-#define SCC_WR0_SEL_WR2 0x02
-#define SCC_WR0_SEL_WR3 0x03
-#define SCC_WR0_SEL_WR4 0x04
-#define SCC_WR0_SEL_WR5 0x05
-#define SCC_WR0_SEL_WR6 0x06
-#define SCC_WR0_SEL_WR7 0x07
-#define SCC_WR0_SEL_WR8 0x08
-#define SCC_WR0_SEL_WR9 0x09
-#define SCC_WR0_SEL_WR10 0x0a
-#define SCC_WR0_SEL_WR11 0x0b
-#define SCC_WR0_SEL_WR12 0x0c
-#define SCC_WR0_SEL_WR13 0x0d
-#define SCC_WR0_SEL_WR14 0x0e
-#define SCC_WR0_SEL_WR15 0x0f
-#define SCC_WR0_SEL_RD0 0x00
-#define SCC_WR0_SEL_RD1 0x01
-#define SCC_WR0_SEL_RD2 0x02
-#define SCC_WR0_SEL_RD3 0x03
-#define SCC_WR0_SEL_RD4 0x04
-#define SCC_WR0_SEL_RD5 0x05
-#define SCC_WR0_SEL_RD6 0x06
-#define SCC_WR0_SEL_RD7 0x07
-#define SCC_WR0_SEL_RD8 0x08
-#define SCC_WR0_SEL_RD9 0x09
-#define SCC_WR0_SEL_RD10 0x0a
-#define SCC_WR0_SEL_RD11 0x0b
-#define SCC_WR0_SEL_RD12 0x0c
-#define SCC_WR0_SEL_RD13 0x0d
-#define SCC_WR0_SEL_RD14 0x0e
-#define SCC_WR0_SEL_RD15 0x0f
-#define SCC_WR0_NULL_CODE 0x00
-#define SCC_WR0_RST_INT 0x10
-#define SCC_WR0_SEND_ABORT 0x18
-#define SCC_WR0_EN_INT_RX 0x20
-#define SCC_WR0_RST_TX_INT 0x28
-#define SCC_WR0_ERR_RST 0x30
-#define SCC_WR0_RST_HI_IUS 0x38
-#define SCC_WR0_RST_RX_CRC 0x40
-#define SCC_WR0_RST_TX_CRC 0x80
-#define SCC_WR0_RST_TX_UND 0xc0
-
-/* write register 2 */
-/* interrupt vector */
-
-/* bit values for write register 1 */
-/* tx/rx interrupt and data transfer mode definition */
-
-#define SCC_WR1_EXT_INT_EN 0x01
-#define SCC_WR1_TX_INT_EN 0x02
-#define SCC_WR1_PARITY 0x04
-#define SCC_WR1_RX_INT_DIS 0x00
-#define SCC_WR1_RX_INT_FIR 0x08
-#define SCC_WR1_INT_ALL_RX 0x10
-#define SCC_WR1_RX_INT_SPE 0x18
-#define SCC_WR1_RDMA_RECTR 0x20
-#define SCC_WR1_RDMA_FUNC 0x40
-#define SCC_WR1_RDMA_EN 0x80
-
-#define SCC_ENABLE_ALL_INTR \
- (SCC_WR1_EXT_INT_EN | SCC_WR1_TX_INT_EN | SCC_WR1_INT_ALL_RX)
-
-#define SCC_DISABLE_ALL_INTR 0x00
-
-#define SCC_ENABLE_ALL_INTR_EXCEPT_TX \
- (SCC_WR1_EXT_INT_EN | SCC_WR1_INT_ALL_RX)
-
-/* bit values for write register 3 */
-/* receive parameters and control */
-
-#define SCC_WR3_RX_EN 0x01
-#define SCC_WR3_SYNC_CHAR 0x02
-#define SCC_WR3_ADR_SEARCH 0x04
-#define SCC_WR3_RX_CRC_EN 0x08
-#define SCC_WR3_ENTER_HUNT 0x10
-#define SCC_WR3_AUTO_EN 0x20
-#define SCC_WR3_RX_5_BITS 0x00
-#define SCC_WR3_RX_7_BITS 0x40
-#define SCC_WR3_RX_6_BITS 0x80
-#define SCC_WR3_RX_8_BITS 0xc0
-
-/* bit values for write register 4 */
-/* tx/rx misc parameters and modes */
-
-#define SCC_WR4_PAR_EN 0x01
-#define SCC_WR4_PAR_EVEN 0x02
-#define SCC_WR4_SYNC_EN 0x00
-#define SCC_WR4_1_STOP 0x04
-#define SCC_WR4_2_STOP 0x0c
-#define SCC_WR4_8_SYNC 0x00
-#define SCC_WR4_16_SYNC 0x10
-#define SCC_WR4_SDLC 0x20
-#define SCC_WR4_EXT_SYNC 0x30
-#define SCC_WR4_1_CLOCK 0x00
-#define SCC_WR4_16_CLOCK 0x40
-#define SCC_WR4_32_CLOCK 0x80
-#define SCC_WR4_64_CLOCK 0xc0
-
-/* bit values for write register 5 */
-/* transmit parameter and controls */
-
-#define SCC_WR5_TX_CRC_EN 0x01
-#define SCC_WR5_RTS 0x02
-#define SCC_WR5_SDLC 0x04
-#define SCC_WR5_TX_EN 0x08
-#define SCC_WR5_SEND_BRK 0x10
-
-#define SCC_WR5_TX_5_BITS 0x00
-#define SCC_WR5_TX_7_BITS 0x20
-#define SCC_WR5_TX_6_BITS 0x40
-#define SCC_WR5_TX_8_BITS 0x60
-#define SCC_WR5_DTR 0x80
-
-/* write register 6 */
-/* sync chars or sdlc address field */
-
-/* write register 7 */
-/* sync char or sdlc flag */
-
-/* write register 8 */
-/* transmit buffer */
-
-/* bit values for write register 9 */
-/* master interrupt control */
-
-#define SCC_WR9_VIS 0x01
-#define SCC_WR9_NV 0x02
-#define SCC_WR9_DLC 0x04
-#define SCC_WR9_MIE 0x08
-#define SCC_WR9_STATUS_HI 0x10
-#define SCC_WR9_NO_RST 0x00
-#define SCC_WR9_CH_B_RST 0x40
-#define SCC_WR9_CH_A_RST 0x80
-#define SCC_WR9_HDWR_RST 0xc0
-
-/* bit values for write register 10 */
-/* misc tx/rx control bits */
-
-#define SCC_WR10_6_BIT_SYNC 0x01
-#define SCC_WR10_LOOP_MODE 0x02
-#define SCC_WR10_ABORT_UND 0x04
-#define SCC_WR10_MARK_IDLE 0x08
-#define SCC_WR10_ACT_POLL 0x10
-#define SCC_WR10_NRZ 0x00
-#define SCC_WR10_NRZI 0x20
-#define SCC_WR10_FM1 0x40
-#define SCC_WR10_FM0 0x60
-#define SCC_WR10_CRC_PRESET 0x80
-
-/* bit values for write register 11 */
-/* clock mode control */
-
-#define SCC_WR11_OUT_XTAL 0x00
-#define SCC_WR11_OUT_TX_CLK 0x01
-#define SCC_WR11_OUT_BR_GEN 0x02
-#define SCC_WR11_OUT_DPLL 0x03
-#define SCC_WR11_TRXC_OI 0x04
-#define SCC_WR11_TX_RTXC 0x00
-#define SCC_WR11_TX_TRXC 0x08
-#define SCC_WR11_TX_BR_GEN 0x10
-#define SCC_WR11_TX_DPLL 0x18
-#define SCC_WR11_RX_RTXC 0x00
-#define SCC_WR11_RX_TRXC 0x20
-#define SCC_WR11_RX_BR_GEN 0x40
-#define SCC_WR11_RX_DPLL 0x60
-#define SCC_WR11_RTXC_XTAL 0x80
-
-/* write register 12 */
-/* lower byte of baud rate generator time constant */
-
-/* write register 13 */
-/* upper byte of baud rate generator time constant */
-
-/* bit values for write register 14 */
-/* misc control bits */
-
-#define SCC_WR14_BR_EN 0x01
-#define SCC_WR14_BR_SRC 0x02
-#define SCC_WR14_DTR_FUNC 0x04
-#define SCC_WR14_AUTO_ECHO 0x08
-#define SCC_WR14_LCL_LOOP 0x10
-#define SCC_WR14_NULL 0x00
-#define SCC_WR14_SEARCH 0x20
-#define SCC_WR14_RST_CLK 0x40
-#define SCC_WR14_DIS_DPLL 0x60
-#define SCC_WR14_SRC_BR 0x80
-#define SCC_WR14_SRC_RTXC 0xa0
-#define SCC_WR14_FM_MODE 0xc0
-#define SCC_WR14_NRZI 0xe0
-
-/* bit values for write register 15 */
-/* external/status interrupt control */
-
-#define SCC_WR15_ZERO_CNT 0x02
-#define SCC_WR15_CD_IE 0x08
-#define SCC_WR15_SYNC_IE 0x10
-#define SCC_WR15_CTS_IE 0x20
-#define SCC_WR15_TX_UND_IE 0x40
-#define SCC_WR15_BREAK_IE 0x80
-
-/* bit values for read register 0 */
-/* tx/rx buffer status and external status */
-
-#define SCC_RR0_RX_AVAIL 0x01
-#define SCC_RR0_ZERO_CNT 0x02
-#define SCC_RR0_TX_EMPTY 0x04
-#define SCC_RR0_CD 0x08
-#define SCC_RR0_SYNC 0x10
-#define SCC_RR0_CTS 0x20
-#define SCC_RR0_TX_UND 0x40
-#define SCC_RR0_BREAK 0x80
-
-/* bit values for read register 1 */
-
-#define SCC_RR1_ALL_SENT 0x01
-#define SCC_RR1_RES_CD_2 0x02
-#define SCC_RR1_RES_CD_1 0x01
-#define SCC_RR1_RES_CD_0 0x08
-#define SCC_RR1_PAR_ERR 0x10
-#define SCC_RR1_RX_OV_ERR 0x20
-#define SCC_RR1_CRC_ERR 0x40
-#define SCC_RR1_END_FRAME 0x80
-
-/* read register 2 */
-/* interrupt vector */
-
-/* bit values for read register 3 */
-/* interrupt pending register */
-
-#define SCC_RR3_B_EXT_IP 0x01
-#define SCC_RR3_B_TX_IP 0x02
-#define SCC_RR3_B_RX_IP 0x04
-#define SCC_RR3_A_EXT_IP 0x08
-#define SCC_RR3_A_TX_IP 0x10
-#define SCC_RR3_A_RX_IP 0x20
-
-/* read register 8 */
-/* receive data register */
-
-/* bit values for read register 10 */
-/* misc status bits */
-
-#define SCC_RR10_ON_LOOP 0x02
-#define SCC_RR10_LOOP_SEND 0x10
-#define SCC_RR10_2_CLK_MIS 0x40
-#define SCC_RR10_1_CLK_MIS 0x80
-
-/* read register 12 */
-/* lower byte of time constant */
-
-/* read register 13 */
-/* upper byte of time constant */
-
-/* bit values for read register 15 */
-/* external/status ie bits */
-
-#define SCC_RR15_ZERO_CNT 0x02
-#define SCC_RR15_CD_IE 0x08
-#define SCC_RR15_SYNC_IE 0x10
-#define SCC_RR15_CTS_IE 0x20
-#define SCC_RR15_TX_UND_IE 0x40
-#define SCC_RR15_BREAK_IE 0x80
-
-typedef struct _z85c30_context
-{
- uint8_t ucModemCtrl;
-} z85c30_context;
-
-/*
- * The following macro calculates the Baud constant. For the Z85C30 chip.
- *
- * Note: baud constant = ((clock frequency / Clock_X) / (2 * Baud Rate)) - 2
- * eg ((10,000,000 / 16) / (2 * Baud Rate)) - 2
- */
-
-#define Z85C30_Baud( _clock, _baud_rate ) \
- ( ((_clock) /( 16 * 2 * _baud_rate)) - 2)
-
-#define Z85C30_Status_Is_RX_character_available(_status) \
- ((_status) & SCC_RR0_RX_AVAIL)
-
-#define Z85C30_Status_Is_TX_buffer_empty(_status) \
- ((_status) & SCC_RR0_TX_EMPTY)
-
-#define Z85C30_Status_Is_CTS_asserted(_status) \
- ((_status) & SCC_RR0_CTS)
-
-#define Z85C30_Status_Is_break_abort(_status) \
- ((_status) & SCC_RR0_BREAK)
-
-/*
- * Private routines
- */
-
-Z85C30_STATIC void z85c30_initialize_port(
- int minor
-);
-
-Z85C30_STATIC void z85c30_init(int minor);
-
-Z85C30_STATIC int z85c30_set_attributes(
- int minor,
- const struct termios *t
-);
-
-Z85C30_STATIC int z85c30_open(
- int major,
- int minor,
- void * arg
-);
-
-Z85C30_STATIC int z85c30_close(
- int major,
- int minor,
- void * arg
-);
-
-Z85C30_STATIC void z85c30_write_polled(
- int minor,
- char cChar
-);
-
-Z85C30_STATIC int z85c30_assert_RTS(
- int minor
-);
-
-Z85C30_STATIC int z85c30_negate_RTS(
- int minor
-);
-
-Z85C30_STATIC int z85c30_assert_DTR(
- int minor
-);
-
-Z85C30_STATIC int z85c30_negate_DTR(
- int minor
-);
-
-Z85C30_STATIC void z85c30_initialize_interrupts(int minor);
-
-Z85C30_STATIC ssize_t z85c30_write_support_int(
- int minor,
- const char *buf,
- size_t len
-);
-
-Z85C30_STATIC ssize_t z85c30_write_support_polled(
- int minor,
- const char *buf,
- size_t len
-);
-
-Z85C30_STATIC int z85c30_inbyte_nonblocking_polled(
- int minor
-);
-
-Z85C30_STATIC void z85c30_enable_interrupts(
- int minor,
- int interrupt_mask
-);
-
-Z85C30_STATIC void z85c30_process(
- int minor,
- uint8_t ucIntPend
-);
-
-Z85C30_STATIC rtems_isr z85c30_isr(
- rtems_vector_number vector
-);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/c/src/libchip/serial/z85c30_reg.c b/c/src/libchip/serial/z85c30_reg.c
deleted file mode 100644
index 6e7b5d3494..0000000000
--- a/c/src/libchip/serial/z85c30_reg.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This file contains a typical set of register access routines which may be
- * used with the z85c30 chip if accesses to the chip are as follows:
- *
- * + registers are accessed as bytes
- *
- * COPYRIGHT (c) 1989-1997.
- * 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.org/license/LICENSE.
- */
-
-#include <rtems.h>
-
-#include <libchip/z85c30.h>
-
-#ifndef _Z85C30_MULTIPLIER
-#define _Z85C30_MULTIPLIER 1
-#define _Z85C30_NAME(_X) _X
-#define _Z85C30_TYPE uint8_t
-#endif
-
-/*
- * Z85C30 Get Register Routine
- */
-
-uint8_t _Z85C30_NAME(z85c30_get_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum
-)
-{
- _Z85C30_TYPE *port;
- uint8_t data;
- rtems_interrupt_level level;
-
- port = (_Z85C30_TYPE *)ulCtrlPort;
-
- rtems_interrupt_disable(level);
-
- if(ucRegNum) {
- *port = ucRegNum;
- }
- data = *port;
- rtems_interrupt_enable(level);
-
- return data;
-}
-
-/*
- * Z85C30 Set Register Routine
- */
-
-void _Z85C30_NAME(z85c30_set_register)(
- uintptr_t ulCtrlPort,
- uint8_t ucRegNum,
- uint8_t ucData
-)
-{
- _Z85C30_TYPE *port;
- rtems_interrupt_level level;
-
- port = (_Z85C30_TYPE *)ulCtrlPort;
-
- rtems_interrupt_disable(level);
- if(ucRegNum) {
- *port = ucRegNum;
- }
- *port = ucData;
- rtems_interrupt_enable(level);
-}