2000-12-11 Joel Sherrill <joel@OARcorp.com>

* Makefile.am, configure.in, include/Makefile.am,
	wrapup/Makefile.am: Updated to reflect addition of network driver
	by  Franck Julien <FranckJ@cxr.fr>.
	* include/m302_int.h, network/.cvsignore, network/Makefile.am,
	network/network.c: New file.
This commit is contained in:
Joel Sherrill
2000-12-14 17:53:53 +00:00
parent cec6bb08c4
commit 8b868a11d9
9 changed files with 1594 additions and 5 deletions

View File

@@ -1,3 +1,11 @@
2000-12-11 Joel Sherrill <joel@OARcorp.com>
* Makefile.am, configure.in, include/Makefile.am,
wrapup/Makefile.am: Updated to reflect addition of network driver
by Franck Julien <FranckJ@cxr.fr>.
* include/m302_int.h, network/.cvsignore, network/Makefile.am,
network/network.c: New file.
2000-11-09 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Use ... instead of RTEMS_TOPdir in ACLOCAL_AMFLAGS.

View File

@@ -7,7 +7,7 @@ ACLOCAL_AMFLAGS = -I ../../../../../../aclocal
# wrapup is the one that actually builds and installs the library
# from the individual .rel files built in other directories
SUBDIRS = . include start startup clock console timer wrapup
SUBDIRS = . include start startup clock console timer network wrapup
include $(top_srcdir)/../../bsp.am

View File

@@ -17,8 +17,11 @@ RTEMS_CANONICALIZE_TOOLS
RTEMS_ENV_RTEMSBSP
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
RTEMS_CHECK_BSP_CACHE(RTEMS_BSP)
RTEMS_CHECK_NETWORKING
RTEMS_CANONICAL_HOST
AM_CONDITIONAL(HAS_NETWORKING,test "$HAS_NETWORKING" = "yes")
RTEMS_PROJECT_ROOT
# Explicitly list all Makefiles here
@@ -27,6 +30,7 @@ Makefile
clock/Makefile
console/Makefile
include/Makefile
network/Makefile
start/Makefile
startup/Makefile
timer/Makefile

View File

@@ -4,7 +4,7 @@
AUTOMAKE_OPTIONS = foreign 1.4
H_FILES = bsp.h coverhd.h
H_FILES = bsp.h coverhd.h m302_int.h
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
@@ -12,14 +12,17 @@ $(PROJECT_INCLUDE):
$(PROJECT_INCLUDE)/bsp.h: bsp.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/m302_int.h: m302_int.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/coverhd.h: coverhd.h
$(INSTALL_DATA) $< $@
TMPINSTALL_FILES += $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/bsp.h \
$(PROJECT_INCLUDE)/coverhd.h
$(PROJECT_INCLUDE)/coverhd.h $(PROJECT_INCLUDE)/m302_int.h
all-local: $(TMPINSTALL_FILES)
EXTRA_DIST = bsp.h coverhd.h
EXTRA_DIST = bsp.h coverhd.h m302_int.h
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,545 @@
/*
* Implements the Motorola 68302 multi-protocol chip parameter
* definition header.
*
* $Id$
*/
#ifndef __M302_INT_h
#define __M302_INT_h
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef ushort
#define ushort unsigned short
#endif
#ifndef ulong
#define ulong unsigned long
#endif
/* Ethernet Control Register ECNTRL */
#define ECNTRL_BIT_RESET 0x0001
#define ECNTRL_BIT_ETHER_EN 0x0002
#define ECNTRL_BIT_GTS 0x0004
/* Ethernet DMA Configuration Status Register EDMA */
#define EDMA_BDERR_MASK 0xFE00
#define EDMA_BDSIZE_MASK 0x00C0
#define EDMA_BDSIZE_8T_120R 0x0000
#define EDMA_BDSIZE_16T_112R 0x0040
#define EDMA_BDSIZE_32T_96R 0x0080
#define EDMA_BDSIZE_64T_64R 0x00C0
#define EDMA_BIT_TSRLY 0x0020
#define EDMA_WMRK_MASK 0x0018
#define EDMA_WMRK_8FIFO 0x0000
#define EDMA_WMRK_16FIFO 0x0008
#define EDMA_WMRK_24FIFO 0x0010
#define EDMA_WMRK_32FIFO 0x0018
#define EDMA_BLIM_MASK 0x0007
#define EDMA_BLIM_8ACCESS 0x0003
/* Ethernet Maximum Receive Buffer Length EMRBLR */
#define EMRBLR_MASK 0x07FFE
/* Interrupt Vector Register IVEC */
#define IVEC_BIT_VG 0x0100
#define IVEC_INV_MASK 0x00FF
/* Interrupt Event Register INTR_EVENT */
#define INTR_EVENT_BIT_RXB 0x0001
#define INTR_EVENT_BIT_TXB 0x0002
#define INTR_EVENT_BIT_BSY 0x0004
#define INTR_EVENT_BIT_RFINT 0x0008
#define INTR_EVENT_BIT_TFINT 0x0010
#define INTR_EVENT_BIT_EBERR 0x0020
#define INTR_EVENT_BIT_BOD 0x0040
#define INTR_EVENT_BIT_GRA 0x0080
#define INTR_EVENT_BIT_BABT 0x0100
#define INTR_EVENT_BIT_BABR 0x0200
#define INTR_EVENT_BIT_HBERR 0x0400
/* Interrupt Mask Register INTR_MASK */
#define INTR_MASK_BIT_RXIEN 0x0001
#define INTR_MASK_BIT_TXIEN 0x0002
#define INTR_MASK_BIT_BSYEN 0x0004
#define INTR_MASK_BIT_RFIEN 0x0008
#define INTR_MASK_BIT_TFIEN 0x0010
#define INTR_MASK_BIT_EBERREN 0x0020
#define INTR_MASK_BIT_BODEN 0x0040
#define INTR_MASK_BIT_GRAEN 0x0080
#define INTR_MASK_BIT_BTEN 0x0100
#define INTR_MASK_BIT_BREN 0x0200
#define INTR_MASK_BIT_HBEEN 0x0400
/* Ethernet Configuration ECNFIG */
#define ECNFIG_BIT_LOOP 0x0001
#define ECNFIG_BIT_FDEN 0x0002
#define ECNFIG_BIT_HBC 0x0004
#define ECNFIG_BIT_RDT 0x0008
/* Ethernet Test ETHER_TEST */
#define ETHER_TEST_BIT_TWS 0x0001
#define ETHER_TEST_BIT_RWS 0x0002
#define ETHER_TEST_BIT_DRTY 0x0004
#define ETHER_TEST_BIT_COLL 0x0008
#define ETHER_TEST_BIT_SLOT 0x0010
#define ETHER_TEST_BIT_TRND 0x0020
#define ETHER_TEST_BIT_TBO 0x0040
#define ETHER_TEST_BIT_RNGT 0x0080
#define ETHER_TEST_REV_MASK 0xF000
/* Ethernet AR Control Registere AR_CNTRL */
#define AR_CNTRL_BIT_PROM 0x0400
#define AR_CNTRL_BIT_PA_REJ 0x0800
#define AR_CNTRL_BIT_NO_BROADCAST 0x1000
#define AR_CNTRL_BIT_MULTI1 0x2000
#define AR_CNTRL_BIT_INDEX_EN 0x4000
#define AR_CNTRL_BIT_HASH_EN 0x8000
#define AR_CNTRL_MULTI_MASK (AR_CNTRL_BIT_MULTI0 | AR_CNTRL_BIT_MULTI1)
/* Ethernet buffer Status TX */
#define BUF_STAT_CARRIER_LOST 0x0001
#define BUF_STAT_UNDERRUN 0x0002
#define BUF_STAT_RETRANS_COUNT 0x003C
#define BUF_STAT_RETRY_LIMIT 0x0040
#define BUF_STAT_LATE_COLLISION 0x0080
#define BUF_STAT_HEARTBIT 0x0100
#define BUF_STAT_DEFER 0x0200
#define BUF_STAT_TX_CRC 0x0400
#define BUF_STAT_LAST 0x0800
#define BUF_STAT_INTERRUPT 0x1000
#define BUF_STAT_WRAP 0x2000
#define BUF_STAT_TO 0x4000
#define BUF_STAT_READY 0x8000
/* Ethernet buffer Status RX */
#define BUF_STAT_COLLISION 0x0001
#define BUF_STAT_OVERRUN 0x0002
#define BUF_STAT_CRC_ERROR 0x0004
#define BUF_STAT_SHORT 0x0008
#define BUF_STAT_NONALIGNED 0x0010
#define BUF_STAT_LONG 0x0020
#define BUF_STAT_FIRST_IN_FRAME 0x0400
#define BUF_STAT_EMPTY 0x8000
/* SCC Buffer Descriptor structure
----------------------------------*/
struct m68302_scc_bd {
ushort stat_ctrl;
ushort data_lgth;
uchar *p_buffer;
};
#define M68302_scc_bd_stat_ctrl(p) \
(((struct m68302_scc_bd *)(p)) -> stat_ctrl)
#define M68302_scc_bd_data_lgth(p) \
(((struct m68302_scc_bd *)(p)) -> data_lgth)
#define M68302_scc_bd_p_buffer(p) \
(((struct m68302_scc_bd *)(p)) -> p_buffer)
struct m68302_imp {
/* BASE : user data memory */
uchar user_data[0x240]; /* 0x240 bytes user data */
uchar user_reserved[0x1c0]; /* empty till 0x400 */
/* BASE + 400H: PARAMETER RAM */
struct {
struct m68302_scc_bd scc_bd_rx[8]; /* Rx buffer descriptors */
struct m68302_scc_bd scc_bd_tx[8]; /* Tx buffer descriptors */
uchar rfcr; /* Rx function code */
uchar tfcr; /* Tx function code */
ushort mrblr; /* maximum Rx buffer length */
ushort rist; /* internal state */
uchar res1;
uchar rbdn; /* Rx internal buffer number */
ulong ridp;
ushort ribc;
ushort rtmp;
ushort tist;
uchar res2;
uchar tbdn; /* Tx internal buffer number */
ulong tidp;
ushort tibc;
ushort ttmp;
unsigned char scc_spp [0x64]; /* SCC specific parameters */
} parm_ram [3];
uchar reserved_1 [0x100];
/* BASE + 800H: INTERNAL REGISTERS */
/* DMA */
ushort dma_res1; /* reserved */
ushort dma_mode; /* dma mode reg */
ulong dma_src; /* dma source */
ulong dma_dest; /* dma destination */
ushort dma_count; /* dma byte count */
uchar dma_status; /* dma status */
uchar dma_res2; /* reserved */
uchar dma_fct_code; /* dma function code */
uchar dma_res3; /* reserved */
/* Interrupt Controller */
ushort it_mode; /* interrupt mode register */
ushort it_pending; /* interrupt pending register */
ushort it_mask; /* interrupt mask register */
ushort it_inservice; /* interrupt in service register */
ulong it_reserved; /* reserved */
/* Parallel I/O */
struct {
ushort control; /* port control register */
ushort direction; /* port data direction register */
ushort data; /* port data value register */
} port[2];
ushort p_reserved; /* reserved */
/* Chip Select */
ulong cs_reserved;
struct {
ushort base; /* chip select base register */
ushort option; /* chip select option register */
} cs[4];
/* Timer */
ushort t1_mode; /* timer 1 mode register */
ushort t1_reference; /* timer 1 reference register */
ushort t1_capture; /* timer 1 capture register */
ushort t1_counter; /* timer 1 counter */
uchar tim_res1; /* reserved */
uchar t1_event; /* timer 1 event */
ushort t3_reference; /* timer 3 reference register */
ushort t3_counter; /* timer 3 counter */
ushort tim_res2; /* reserved */
ushort t2_mode; /* timer 2 mode register */
ushort t2_reference; /* timer 2 reference register */
ushort t2_capture; /* timer 2 capture register */
ushort t2_counter; /* timer 2 counter */
uchar tim_res3; /* reserved */
uchar t2_event; /* timer 2 event */
ushort tim_res4[3]; /* reserved */
/* command register */
uchar cp_cmd; /* communication processor command register */
uchar cp_cmd_res; /* reserved */
/* reserved */
uchar reserved_2[0x1e];
/* SCC registers */
struct scc_regs {
ushort resvd; /* reserved */
ushort scon; /* SCC configuration register */
ushort scm; /* SCC mode register */
ushort dsr; /* SCC sync register */
uchar scce; /* SCC event register */
uchar res1; /* reserved */
uchar sccm; /* SCC mask register */
uchar res2; /* reserved */
uchar sccs; /* SCC status register */
uchar res3; /* reserved */
ushort res4; /* reserved */
} scc_regs[3];
/* SP (SCP + SMI) */
ushort scc_mode_reg; /* scp, smi mode + clock control */
/* Serial Interface */
ushort serial_int_mask; /* mask register */
ushort serial_int_mode; /* mode register */
/* reserved */
uchar reserved_3[0x74A];
/****************** 68 EN 302 specific registers **********************/
/** only available here if
M68302_INTERNAL_RAM_BASE_ADD+0x1000=M68EN302_INTERNAL_RAM_BASE_ADD*/
/* Module Bus Control Registers */
ushort mbc; /* module bus control register MBC */
ushort ier; /* interrupt extension register IER */
ushort cser[4]; /* Chip Select extension registers CSERx */
ushort pcsr; /* parity control & status register PCSR */
ushort mbc_reserved;
/* DRAM Controller Registers */
ushort dcr; /* DRAM Configuration register DCR */
ushort drfrsh; /* DRAM Refresh register DRFRSH */
ushort dba[2]; /* DRAM Bank Base Address Register */
uchar dram_reserved[0x7E8];
/* Ethernet Controller Registers */
ushort ecntrl; /* Ethernet Control Register */
ushort edma; /* Ethernet DMA Configuration Register */
ushort emrblr; /* Ethernet Max receive buffer length */
ushort intr_vect; /* Interruppt vector register */
ushort intr_event; /* Interruppt event register */
ushort intr_mask; /* Interruppt mask register */
ushort ecnfig; /* Ethernet Configuration */
ushort ether_test; /* Ethernet Test register */
ushort ar_cntrl; /* Address Recognition Control register */
uchar eth_reserved[0x1EE];
uchar cet[0x200]; /* CAM Entry Table */
struct m68302_scc_bd eth_bd[128]; /* Ethernet Buffer Descriptors Table */
};
#define M68302imp_ a_m68302_imp ->
#define M68302imp_a_scc_bd_rx(scc,bd) \
(struct m68302_scc_bd FAR *)(&(M68302imp_ parm_ram[scc].scc_bd_rx[bd]))
#define M68302imp_a_scc_bd_tx(scc,bd) \
(struct m68302_scc_bd FAR *)(&(M68302imp_ parm_ram[scc].scc_bd_tx[bd]))
#define M68302imp_scc_rfcr(scc) (M68302imp_ parm_ram[scc].rfcr)
#define M68302imp_scc_tfcr(scc) (M68302imp_ parm_ram[scc].tfcr)
#define M68302imp_scc_mrblr(scc) (M68302imp_ parm_ram[scc].mrblr)
#define M68302imp_scc_rbdn(scc) (M68302imp_ parm_ram[scc].rbdn)
#define M68302imp_scc_tbdn(scc) (M68302imp_ parm_ram[scc].tbdn)
#define M68302imp_a_scc_spp(scc) ((struct m68302_scc_spp FAR *)(M68302imp_ parm_ram[scc].scc_spp))
#define M68302imp_dma_res1 (M68302imp_ dma_res1)
#define M68302imp_dma_mode (M68302imp_ dma_mode)
#define M68302imp_dma_src (M68302imp_ dma_src)
#define M68302imp_dma_dest (M68302imp_ dma_dest)
#define M68302imp_dma_count (M68302imp_ dma_count)
#define M68302imp_dma_status (M68302imp_ dma_status)
#define M68302imp_dma_fct_code (M68302imp_ dma_fct_code)
#define M68302imp_it_mode (M68302imp_ it_mode)
#define M68302imp_it_pending (M68302imp_ it_pending)
#define M68302imp_it_mask (M68302imp_ it_mask)
#define M68302imp_it_inservice (M68302imp_ it_inservice)
#define M68302imp_cs_base(i) (M68302imp_ cs[i].base)
#define M68302imp_cs_option(i) (M68302imp_ cs[i].option)
#define M68302imp_port_control(i) (M68302imp_ port[i].control)
#define M68302imp_port_direction(i) (M68302imp_ port[i].direction)
#define M68302imp_port_data(i) (M68302imp_ port[i].data)
#define M68302imp_timer1_mode (M68302imp_ t1_mode)
#define M68302imp_timer1_reference (M68302imp_ t1_reference)
#define M68302imp_timer1_capture (M68302imp_ t1_capture)
#define M68302imp_timer1_counter (M68302imp_ t1_counter)
#define M68302imp_timer1_event (M68302imp_ t1_event)
#define M68302imp_timer3_reference (M68302imp_ t3_reference)
#define M68302imp_timer3_counter (M68302imp_ t3_counter)
#define M68302imp_timer2_mode (M68302imp_ t2_mode)
#define M68302imp_timer2_reference (M68302imp_ t2_reference)
#define M68302imp_timer2_capture (M68302imp_ t2_capture)
#define M68302imp_timer2_counter (M68302imp_ t2_counter)
#define M68302imp_timer2_event (M68302imp_ t2_event)
#define M68302imp_cp_cmd (M68302imp_ cp_cmd)
#define M68302imp_scc_mode_reg (M68302imp_ scc_mode_reg)
#define M68302imp_serial_int_mask (M68302imp_ serial_int_mask)
#define M68302imp_serial_int_mode (M68302imp_ serial_int_mode)
#define M68302imp_simask (M68302imp_serial_int_mask)
#define M68302imp_simode (M68302imp_serial_int_mode)
#define M68302imp_scon(i) (M68302imp_ scc_regs[i].scon)
#define M68302imp_scm(i) (M68302imp_ scc_regs[i].scm)
#define M68302imp_dsr(i) (M68302imp_ scc_regs[i].dsr)
#define M68302imp_scce(i) (M68302imp_ scc_regs[i].scce)
#define M68302imp_sccm(i) (M68302imp_ scc_regs[i].sccm)
#define M68302imp_sccs(i) (M68302imp_ scc_regs[i].sccs)
/*----------------------------------------------------------------------------*/
#define M68en302imp_mbc (M68302imp_ mbc)
#define M68en302imp_ier (M68302imp_ ier)
#define M68en302imp_cser(i) (M68302imp_ cser[i])
#define M68en302imp_pcsr (M68302imp_ pcsr)
#define M68en302imp_dcr (M68302imp_ dcr)
#define M68en302imp_drfrsh (M68302imp_ drfrsh)
#define M68en302imp_dba(i) (M68302imp_ dba[i])
#define M68en302imp_ecntrl (M68302imp_ ecntrl)
#define M68en302imp_edma (M68302imp_ edma)
#define M68en302imp_emrblr (M68302imp_ emrblr)
#define M68en302imp_intr_vect (M68302imp_ intr_vect)
#define M68en302imp_intr_event (M68302imp_ intr_event)
#define M68en302imp_intr_mask (M68302imp_ intr_mask)
#define M68en302imp_ecnfig (M68302imp_ ecnfig)
#define M68en302imp_ether_test (M68302imp_ ether_test)
#define M68en302imp_ar_cntrl (M68302imp_ ar_cntrl)
#define M68en302imp_cet (M68302imp_ cet)
#define M68302imp_a_eth_bd(bd) \
(struct m68302_scc_bd *)(&(M68302imp_ eth_bd[bd]))
/* PORTS */
#define PA0 0x0001 /* PORT A bit 0 */
#define PA1 0x0002 /* PORT A bit 1 */
#define PA2 0x0004 /* PORT A bit 2 */
#define PA3 0x0008 /* PORT A bit 3 */
#define PA4 0x0010 /* PORT A bit 4 */
#define PA5 0x0020 /* PORT A bit 5 */
#define PA6 0x0040 /* PORT A bit 6 */
#define PA7 0x0080 /* PORT A bit 7 */
#define PA8 0x0100 /* PORT A bit 8 */
#define PA9 0x0200 /* PORT A bit 9 */
#define PA10 0x0400 /* PORT A bit 10 */
#define PA11 0x0800 /* PORT A bit 11 */
#define PA12 0x1000 /* PORT A bit 12 */
#define PA13 0x2000 /* PORT A bit 13 */
#define PA14 0x4000 /* PORT A bit 14 */
#define PA15 0x8000 /* PORT A bit 15 */
#define PB0 0x0001 /* PORT B bit 0 */
#define PB1 0x0002 /* PORT B bit 1 */
#define PB2 0x0004 /* PORT B bit 2 */
#define PB3 0x0008 /* PORT B bit 3 */
#define PB4 0x0010 /* PORT B bit 4 */
#define PB5 0x0020 /* PORT B bit 5 */
#define PB6 0x0040 /* PORT B bit 6 */
#define PB7 0x0080 /* PORT B bit 7 */
#define PB8 0x0100 /* PORT B bit 8 */
#define PB9 0x0200 /* PORT B bit 9 */
#define PB10 0x0400 /* PORT B bit 10 */
#define PB11 0x0800 /* PORT B bit 11 */
/* MODULE BUS CONTROL (MBCTL) */
#define MBC_BCE 0x8000
#define MBC_MFC2 0x4000
#define MBC_MFC1 0x2000
#define MBC_MFC0 0x1000
#define MBC_BB 0x0800
#define MBC_PPE 0x0400
#define MBC_PM9 0x0200
#define MBC_PM8 0x0100
#define MBC_PM7 0x0080
#define MBC_PM6 0x0040
#define MBC_PM5 0x0020
#define MBC_PM4 0x0010
#define MBC_PM3 0x0008
#define MBC_PM2 0x0004
#define MBC_PM1 0x0002
#define MBC_PM0 0x0001
/* DRAM CONFIGURATION REG (DCR) */
#define DCR_SU0 0x0001
#define DCR_SU1 0x0002
#define DCR_WP0 0x0004
#define DCR_WP1 0x0008
#define DCR_W0 0x0010
#define DCR_W1 0x0020
#define DCR_P0 0x0040
#define DCR_P1 0x0080
#define DCR_PE0 0x0100
#define DCR_PE1 0x0200
#define DCR_E0 0x0400
#define DCR_E1 0x0800
/* M68302 INTERNAL RAM BASE ADDRESS INSTALLATION */
#define M68302_ram_base_add_install(base_reg_add,ram_base_add) \
do { \
*((ushort *)base_reg_add) = (ushort)(ram_base_add >> 12); \
a_m68302_imp = (struct m68302_imp *)ram_base_add; \
} while (0)
#define M68302_system_ctrl_reg_install(val) (*((ulong *)M68302_SCR_ADD) = val)
/* INTERRUPTION */
/* Interrupt mode selection */
#define M68302_it_mode_install(mode,vector_bank, \
extvect1,extvect6,extvect7,edgetrig1,edgetrig6,edgetrig7) \
M68302imp_it_mode = 0 | (mode << 15) | (vector_bank << 5) | \
(extvect7 << 14) | (extvect6 << 13) | (extvect1 <<12) | \
(edgetrig7 << 10) | (edgetrig6 << 9)|(edgetrig1 << 8)
/* CHIP SELECTION */
/* 'read_write' support values :
*
* M68302_CS_READ_ONLY for read only memory access chip select
* M68302_CS_READ_WRITE_ONLY for write only memory access chip select
* M68302_CS_READ_AND_WRITE for read & write memory access chip select
*
* 'nb_wait_state' : number of wait-state(s) from 0 to 6, 7 for external
*
*/
#define M68302_CS_READ_ONLY 0x02 /* read only memory access */
#define M68302_CS_WRITE_ONLY 0x22 /* write only memory access */
#define M68302_CS_READ_AND_WRITE 0x00 /* read and write memory access */
#define M68302_cs_install(cs_nb,base_add,range,nb_wait_state,read_write) \
do { \
M68302imp_cs_option(cs_nb) = (((~(range - 1)) >> 11) & 0x1FFC) | \
(nb_wait_state << 13) | (read_write & 0x2); \
M68302imp_cs_base(cs_nb) = (((base_add >> 11) & 0x1FFC) | \
((read_write >> 4) & 0x2) | 1); \
} while (0)
#define M68302_set_cs_br(base_add, read_write) \
((((base_add) >> 11) & 0x1FFC) | (((read_write) >> 4) & 0x2) | 1)
#define M68302_set_cs_or(range, nb_wait_state, read_write) \
((((~(range - 1)) >> 11) & 0x1FFC) | \
((nb_wait_state) << 13) | ((read_write) & 0x2))
#define M68302_get_cs_br(cs) \
(((ulong)((M68302imp_cs_base(cs)) & 0x1FFC)) << 11 )
/* DRAM */
#define M68en302_dram_install(bank,base_add,range) \
M68en302imp_dba (bank) = \
(((base_add >> 8) & 0xFE00) | (((~(range-1))>>16) & 0x007E) | 1)
#endif

View File

@@ -0,0 +1,2 @@
Makefile
Makefile.in

View File

@@ -0,0 +1,37 @@
##
## $Id$
##
AUTOMAKE_OPTIONS = foreign 1.4
PGM = $(ARCH)/network.rel
C_FILES = network.c
C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
OBJS = $(C_O_FILES)
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
include $(top_srcdir)/../../../../../../automake/compile.am
include $(top_srcdir)/../../../../../../automake/lib.am
#
# (OPTIONAL) Add local stuff here using +=
#
AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__
$(PGM): $(OBJS)
$(make-rel)
# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
if HAS_NETWORKING
all-local: $(ARCH) $(OBJS) $(PGM)
endif
.PRECIOUS: $(PGM)
EXTRA_DIST = network.c
include $(top_srcdir)/../../../../../../automake/local.am

View File

@@ -0,0 +1,985 @@
/*
* RTEMS driver for M68360 SCC1 Ethernet
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* Saskatoon, Saskatchewan, CANADA
* eric@skatter.usask.ca
*
* $Id$
*
* Modify for Motorola 68en320 Ethernet Controller
* CXR S.A. France - 2000/09/14 - franckj@cxr.fr
*/
#include <bsp.h>
#include <stdio.h>
#include <rtems/error.h>
#include <m302_int.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 <m68302.h>
/*
* Number of SCCs supported by this driver
*/
#define NSCCDRIVER 1
/*
* Default number of buffer descriptors set aside for this driver.
* The number of transmit buffer descriptors has to be quite large
* since a single frame often uses four or more buffer descriptors.
*/
#define RX_BUF_COUNT 64
#define TX_BUF_COUNT 64
/*
* 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
/*
* Receive buffer size -- Allow for a full ethernet packet including CRC
*/
#define RBUF_SIZE 1520
#if (MCLBYTES < RBUF_SIZE)
# error "Driver must have MCLBYTES > RBUF_SIZE"
#endif
static struct m68302_imp * a_m68302_imp;
#define M302_ETHER_IVECTOR 0x40
/*
* Per-device data
*/
struct scc_softc {
struct arpcom arpcom;
struct mbuf **rxMbuf;
struct mbuf **txMbuf;
int acceptBroadcast;
int rxBdCount;
int txBdCount;
int txBdHead;
int txBdTail;
int txBdActiveCount;
struct m68302_scc_bd *rxBdBase;
struct m68302_scc_bd *txBdBase;
rtems_id rxDaemonTid;
rtems_id txDaemonTid;
/*
* 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;
unsigned long txCoalesced;
unsigned long txCoalesceFailed;
unsigned long txRetry;
};
static struct scc_softc scc_softc[NSCCDRIVER];
/*
* interrupt handler
*/
static rtems_isr
m302Enet_interrupt_handler (rtems_vector_number v)
{
/*
* Frame received?
*/
if (M68en302imp_intr_event & INTR_EVENT_BIT_RFINT) {
M68en302imp_intr_event = INTR_EVENT_BIT_RFINT;
M68en302imp_intr_mask &= ~INTR_MASK_BIT_RFIEN;
scc_softc[0].rxInterrupts++;
rtems_event_send (scc_softc[0].rxDaemonTid, INTERRUPT_EVENT);
}
/*
* Buffer transmitted or transmitter error?
*/
if ((M68en302imp_intr_event & INTR_EVENT_BIT_TFINT) ||
((M68en302imp_intr_event & INTR_EVENT_BIT_TXB))){
M68en302imp_intr_event = INTR_EVENT_BIT_TFINT | INTR_EVENT_BIT_TXB;
M68en302imp_intr_mask &= ~(INTR_MASK_BIT_TFIEN | INTR_MASK_BIT_TXIEN);
scc_softc[0].txInterrupts++;
rtems_event_send (scc_softc[0].txDaemonTid, INTERRUPT_EVENT);
}
}
/*
* Initialize the ethernet hardware
*/
static void
m302Enet_initialize_hardware (struct scc_softc *sc)
{
int i;
unsigned char *hwaddr;
rtems_status_code status;
rtems_isr_entry old_handler;
struct m68302_scc_bd *a_bd; /* Buffer Descriptor pointer */
ushort *cam;
void **p;
ushort tmp;
#define LBK 0x0008
#define DSQE 0x0010
#define FDE 0x0020
/*
* standard loopback
*/
M68302imp_port_data (1) &= ~(LBK);
M68302imp_port_data (1) |= (FDE);
M68en302imp_ecntrl=0x0001;
/*
* Set dma configuration status register EDMA
*/
i = (sc->txBdCount == 16) ? EDMA_BDSIZE_16T_112R :
(sc->txBdCount == 32) ? EDMA_BDSIZE_32T_96R :
(sc->txBdCount == 64) ? EDMA_BDSIZE_64T_64R :
EDMA_BDSIZE_8T_120R;
M68en302imp_edma = EDMA_BLIM_8ACCESS | EDMA_WMRK_16FIFO | EDMA_BIT_TSRLY | (ushort)i;
/*
* Set maximum receive buffer length
*/
M68en302imp_emrblr = RBUF_SIZE; /* 1520 */
/*
* Set interrupt vector
*/
M68en302imp_intr_vect = M302_ETHER_IVECTOR;
M68en302imp_intr_mask=0x0;
/*
* Set ethernet Configuration
*/
M68en302imp_ecnfig=0x0000;
/*
* Set ETHER_TEST
*/
M68en302imp_ether_test=0x0000;
/*
* Set AR control Register
* Ignore/accept broadcast packets as specified
*/
M68en302imp_ar_cntrl = ((sc->acceptBroadcast) ? 0 : AR_CNTRL_BIT_NO_BROADCAST) ;
/*
* Allocate mbuf pointers
*/
sc->rxMbuf = malloc (sc->rxBdCount * sizeof *sc->rxMbuf, M_MBUF, M_NOWAIT);
sc->txMbuf = malloc (sc->txBdCount * sizeof *sc->txMbuf, M_MBUF, M_NOWAIT);
if (!sc->rxMbuf || !sc->txMbuf)
rtems_panic ("No memory for mbuf pointers");
/*
* Set our physical address
*/
hwaddr = sc->arpcom.ac_enaddr;
cam=(ushort *)(M68en302imp_cet);
for (i=0;i<64;i++){
cam[(4*i)]=0x00ff;
cam[(4*i)+1]=0x00ff;
cam[(4*i)+2]=0x00ff;
}
cam[4] = (hwaddr[0] << 8) | hwaddr[1];
cam[5] = (hwaddr[2] << 8) | hwaddr[3];
cam[6] = (hwaddr[4] << 8) | hwaddr[5];
/*
* Set receiver and transmitter buffer descriptor bases
*/
a_bd = M68302imp_a_eth_bd (0); /* point to first BD */
for (i=0;i<128;i++){
M68302_scc_bd_stat_ctrl (a_bd + i) = 0;
M68302_scc_bd_data_lgth (a_bd + i) = 0;
M68302_scc_bd_p_buffer (a_bd + i) = NULL;
}
sc->txBdBase = M68302imp_a_eth_bd ( 0 ); /* point to first BD */
sc->rxBdBase = M68302imp_a_eth_bd ( sc->txBdCount); /* point to first RX BD atfer all TX*/
/*
* Set up transmit buffer descriptors
*/
for (i = 0 ; i < sc->txBdCount ; i++) {
sc->txMbuf[i] = NULL;
}
sc->txBdHead = sc->txBdTail = 0;
sc->txBdActiveCount = 0;
/*
* Clear any outstanding events
*/
M68en302imp_intr_event = 0x07FF;
/*
* Set up interrupts
*/
status = rtems_interrupt_catch (m302Enet_interrupt_handler,
M302_ETHER_IVECTOR,
&old_handler);
if (status != RTEMS_SUCCESSFUL)
rtems_panic ("Can't attach M302 ether interrupt handler: %s\r\n",
rtems_status_text (status));
}
/*
* Soak up buffer descriptors that have been sent
* Note that a buffer descriptor can't be retired as soon as it becomes
* ready. The MC68360 Errata (May 96) says that, "If an Ethernet frame is
* made up of multiple buffers, the user should not reuse the first buffer
* descriptor until the last buffer descriptor of the frame has had its
* ready bit cleared by the CPM".
*/
static void
m302Enet_retire_tx_bd (struct scc_softc *sc)
{
rtems_unsigned16 status;
int i;
int nRetired;
struct mbuf *m, *n;
int retries = 0;
int saveStatus = 0;
i = sc->txBdTail;
nRetired = 0;
while ((sc->txBdActiveCount != 0)
&& (((status = (sc->txBdBase + i)->stat_ctrl) & BUF_STAT_READY) == 0)) {
/*
* Check for errors which stop the transmitter.
*/
if (status & (BUF_STAT_LATE_COLLISION |
BUF_STAT_RETRY_LIMIT |
BUF_STAT_UNDERRUN)) {
int j;
if (status & BUF_STAT_LATE_COLLISION)
sc->txLateCollision++;
if (status & BUF_STAT_RETRY_LIMIT)
sc->txRetryLimit++;
if (status & BUF_STAT_UNDERRUN)
sc->txUnderrun++;
/*
* Reenable buffer descriptors
*/
j = sc->txBdTail;
for (;;) {
status = (sc->txBdBase + j)->stat_ctrl;
if (status & BUF_STAT_READY)
break;
(sc->txBdBase + j)->stat_ctrl = BUF_STAT_READY |
(status & ( BUF_STAT_WRAP |
BUF_STAT_INTERRUPT |
BUF_STAT_LAST |
BUF_STAT_TX_CRC));
if (status & BUF_STAT_LAST)
break;
if (++j == sc->txBdCount)
j = 0;
}
/*
* Move transmitter back to the first
* buffer descriptor in the frame.
*/
/* m360.scc1p._tbptr = m360.scc1p.tbase +
sc->txBdTail * sizeof (m360BufferDescriptor_t);
*/
/*
* Restart the transmitter
*/
/* M360ExecuteRISC (M360_CR_OP_RESTART_TX | M360_CR_CHAN_SCC1);*/
continue;
}
saveStatus |= status;
retries += (status >> 2) & 0xF;
nRetired++;
if (status & BUF_STAT_LAST) {
/*
* A full frame has been transmitted.
* Free all the associated buffer descriptors.
*/
if (saveStatus & BUF_STAT_DEFER)
sc->txDeferred++;
if (saveStatus & BUF_STAT_HEARTBIT)
sc->txHeartbeat++;
if (saveStatus & BUF_STAT_CARRIER_LOST)
sc->txLostCarrier++;
saveStatus = 0;
sc->txRetry += retries;
retries = 0;
sc->txBdActiveCount -= nRetired;
while (nRetired) {
nRetired--;
m = sc->txMbuf[sc->txBdTail];
MFREE (m, n);
if (++sc->txBdTail == sc->txBdCount)
sc->txBdTail = 0;
}
}
if (++i == sc->txBdCount)
i = 0;
}
}
/*
* SCC reader task
*/
static void
scc_rxDaemon (void *arg)
{
struct scc_softc *sc = (struct scc_softc *)arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
struct mbuf *m;
rtems_unsigned16 status;
volatile struct m68302_scc_bd *rxBd;
int rxBdIndex;
/*
* Allocate space for incoming packets and start reception
*/
for (rxBdIndex = 0 ; ;) {
rxBd = sc->rxBdBase + rxBdIndex;
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->p_buffer = mtod (m, void *);
if (++rxBdIndex == sc->rxBdCount) {
rxBd->stat_ctrl = BUF_STAT_EMPTY | BUF_STAT_INTERRUPT | BUF_STAT_WRAP;
break;
}
rxBd->stat_ctrl = BUF_STAT_EMPTY | BUF_STAT_INTERRUPT;
}
/*
* Input packet handling loop
*/
rxBdIndex = 0;
for (;;) {
rxBd = sc->rxBdBase + rxBdIndex;
/*
* Wait for packet if there's not one ready
*/
if ((status = rxBd->stat_ctrl) & BUF_STAT_EMPTY) {
/*
* Clear old events
*/
M68en302imp_intr_event = INTR_EVENT_BIT_RFINT;
/*
* Wait for packet
* Note that the buffer descriptor is checked
* *before* the event wait -- this catches the
* possibility that a packet arrived between the
* `if' above, and the clearing of the event register.
*/
while ((status = rxBd->stat_ctrl) & BUF_STAT_EMPTY) {
rtems_interrupt_level level;
rtems_event_set events;
/*
* Unmask RXF (Full frame received) event
*/
rtems_interrupt_disable (level);
M68en302imp_intr_mask |= INTR_MASK_BIT_RFIEN;
rtems_interrupt_enable (level);
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
}
}
/*
* Check that packet is valid
*/
if ((status & (BUF_STAT_LAST |
BUF_STAT_FIRST_IN_FRAME |
BUF_STAT_LONG |
BUF_STAT_NONALIGNED |
BUF_STAT_SHORT |
BUF_STAT_CRC_ERROR |
BUF_STAT_OVERRUN |
BUF_STAT_COLLISION)) ==
(BUF_STAT_LAST |
BUF_STAT_FIRST_IN_FRAME)) {
/*
* Pass the packet up the chain.
* FIXME: Packet filtering hook could be done here.
*/
struct ether_header *eh;
m = sc->rxMbuf[rxBdIndex];
m->m_len = m->m_pkthdr.len = rxBd->data_lgth -
sizeof(rtems_unsigned32) -
sizeof(struct ether_header);
eh = mtod (m, struct ether_header *);
m->m_data += sizeof(struct ether_header);
ether_input (ifp, eh, m);
/*
* Allocate a new mbuf
*/
MGETHDR (m, M_WAIT, MT_DATA);
MCLGET (m, M_WAIT);
m->m_pkthdr.rcvif = ifp;
sc->rxMbuf[rxBdIndex] = m;
rxBd->p_buffer = mtod (m, void *);
}
else {
/*
* Something went wrong with the reception
*/
if (!(status & BUF_STAT_LAST))
sc->rxNotLast++;
if (!(status & BUF_STAT_FIRST_IN_FRAME))
sc->rxNotFirst++;
if (status & BUF_STAT_LONG)
sc->rxGiant++;
if (status & BUF_STAT_NONALIGNED)
sc->rxNonOctet++;
if (status & BUF_STAT_SHORT)
sc->rxRunt++;
if (status & BUF_STAT_CRC_ERROR)
sc->rxBadCRC++;
if (status & BUF_STAT_OVERRUN)
sc->rxOverrun++;
if (status & BUF_STAT_COLLISION)
sc->rxCollision++;
}
/*
* Reenable the buffer descriptor
*/
rxBd->stat_ctrl = (status & (BUF_STAT_WRAP | BUF_STAT_INTERRUPT)) | BUF_STAT_EMPTY;
/*
* Move to next buffer descriptor
*/
if (++rxBdIndex == sc->rxBdCount)
rxBdIndex = 0;
}
}
static void
sendpacket (struct ifnet *ifp, struct mbuf *m)
{
struct scc_softc *sc = ifp->if_softc;
volatile struct m68302_scc_bd *firstTxBd, *txBd;
struct mbuf *l = NULL;
rtems_unsigned16 status;
int nAdded;
char buf[20];
/*
* Free up buffer descriptors
*/
m302Enet_retire_tx_bd (sc);
/*
* Set up the transmit buffer descriptors.
* No need to pad out short packets since the
* hardware takes care of that automatically.
* No need to copy the packet to a contiguous buffer
* since the hardware is capable of scatter/gather DMA.
*/
status = 0;
nAdded = 0;
txBd = firstTxBd = sc->txBdBase + sc->txBdHead;
while (m) {
/*
* There are more mbufs in the packet than there
* are transmit buffer descriptors.
* Coalesce into a single buffer.
*/
if (nAdded == sc->txBdCount) {
struct mbuf *nm;
int j;
char *dest;
/*
* Get the pointer to the first mbuf of the packet
*/
if (sc->txBdTail != sc->txBdHead)
rtems_panic ("sendpacket coalesce");
m = sc->txMbuf[sc->txBdTail];
/*
* Rescind the buffer descriptor READY bits
*/
for (j = 0 ; j < sc->txBdCount ; j++)
(sc->txBdBase + j)->stat_ctrl = 0;
/*
* Allocate an mbuf cluster
* Toss the packet if allocation fails
*/
MGETHDR (nm, M_DONTWAIT, MT_DATA);
if (nm == NULL) {
sc->txCoalesceFailed++;
m_freem (m);
return;
}
MCLGET (nm, M_DONTWAIT);
if (nm->m_ext.ext_buf == NULL) {
sc->txCoalesceFailed++;
m_freem (m);
m_free (nm);
return;
}
nm->m_pkthdr = m->m_pkthdr;
nm->m_len = nm->m_pkthdr.len;
/*
* Copy data from packet chain to mbuf cluster
*/
sc->txCoalesced++;
dest = nm->m_ext.ext_buf;
while (m) {
struct mbuf *n;
if (m->m_len) {
memcpy (dest, mtod(m, caddr_t), m->m_len);
dest += m->m_len;
}
MFREE (m, n);
m = n;
}
/*
* Redo the send with the new mbuf cluster
*/
m = nm;
nAdded = 0;
status = 0;
continue;
}
/*
* Wait for buffer descriptor to become available.
*/
if ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
/*
* Clear old events
*/
M68en302imp_intr_event = INTR_EVENT_BIT_TFINT | INTR_EVENT_BIT_TXB;
/*
* Wait for buffer descriptor to become available.
* Note that the buffer descriptors are checked
* *before* entering the wait loop -- this catches
* the possibility that a buffer descriptor became
* available between the `if' above, and the clearing
* of the event register.
* This is to catch the case where the transmitter
* stops in the middle of a frame -- and only the
* last buffer descriptor in a frame can generate
* an interrupt.
*/
m302Enet_retire_tx_bd (sc);
while ((sc->txBdActiveCount + nAdded) == sc->txBdCount) {
rtems_interrupt_level level;
rtems_event_set events;
/*
* Unmask TXB (buffer transmitted) and
* TXE (transmitter error) events.
*/
rtems_interrupt_disable (level);
M68en302imp_intr_mask |= INTR_MASK_BIT_TFIEN | INTR_MASK_BIT_TXIEN;
rtems_interrupt_enable (level);
rtems_bsdnet_event_receive (INTERRUPT_EVENT,
RTEMS_WAIT|RTEMS_EVENT_ANY,
RTEMS_NO_TIMEOUT,
&events);
m302Enet_retire_tx_bd (sc);
}
}
/*
* The IP fragmentation routine in ip_output
* can produce packet fragments with zero length.
*/
if (m->m_len) {
/*
* Fill in the buffer descriptor.
* Don't set the READY flag in the first buffer
* descriptor till the whole packet has been readied.
*/
txBd = sc->txBdBase + sc->txBdHead;
txBd->p_buffer = mtod (m, void *);
txBd->data_lgth = m->m_len;
sc->txMbuf[sc->txBdHead] = m;
status = nAdded ? BUF_STAT_READY : 0;
if (++sc->txBdHead == sc->txBdCount) {
status |= BUF_STAT_WRAP;
sc->txBdHead = 0;
}
txBd->stat_ctrl = status;
l = m;
m = m->m_next;
nAdded++;
}
else {
/*
* Just toss empty mbufs
*/
struct mbuf *n;
MFREE (m, n);
m = n;
if (l != NULL)
l->m_next = m;
}
}
if (nAdded) {
/*
* Send the packet
*/
txBd->stat_ctrl = status | BUF_STAT_LAST | BUF_STAT_TX_CRC | BUF_STAT_INTERRUPT;
firstTxBd->stat_ctrl |= BUF_STAT_READY;
sc->txBdActiveCount += nAdded;
}
}
/*
* Driver transmit daemon
*/
void
scc_txDaemon (void *arg)
{
struct scc_softc *sc = (struct scc_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;
sendpacket (ifp, m);
}
ifp->if_flags &= ~IFF_OACTIVE;
}
}
/*
* Send packet (caller provides header).
*/
static void
scc_start (struct ifnet *ifp)
{
struct scc_softc *sc = ifp->if_softc;
rtems_event_send (sc->txDaemonTid, START_TRANSMIT_EVENT);
ifp->if_flags |= IFF_OACTIVE;
}
/*
* Initialize and start the device
*/
static void
scc_init (void *arg)
{
struct scc_softc *sc = arg;
struct ifnet *ifp = &sc->arpcom.ac_if;
if (sc->txDaemonTid == 0) {
/*
* Set up SCC hardware
*/
m302Enet_initialize_hardware (sc);
sc->txDaemonTid = rtems_bsdnet_newproc ("SCtx", 4096, scc_txDaemon, sc);
sc->rxDaemonTid = rtems_bsdnet_newproc ("SCrx", 4096, scc_rxDaemon, sc);
}
/*
* Set flags appropriately
*/
/* if (ifp->if_flags & IFF_PROMISC)
m360.scc1.psmr |= 0x200;
else
m360.scc1.psmr &= ~0x200;
*/
/*
* Tell the world that we're running.
*/
ifp->if_flags |= IFF_RUNNING;
/*
* Enable receiver and transmitter
*/
M68en302imp_ecntrl = ECNTRL_BIT_RESET | ECNTRL_BIT_ETHER_EN;
}
/*
* Stop the device
*/
static void
scc_stop (struct scc_softc *sc)
{
struct ifnet *ifp = &sc->arpcom.ac_if;
ifp->if_flags &= ~IFF_RUNNING;
/*
* Shut down receiver and transmitter
*/
M68en302imp_ecntrl &= ~(ECNTRL_BIT_RESET | ECNTRL_BIT_ETHER_EN);
}
/*
* Show interface statistics
*/
static void
scc_stats (struct scc_softc *sc)
{
printf (" Rx Interrupts:%-8lu", sc->rxInterrupts);
printf (" Not First:%-8lu", sc->rxNotFirst);
printf (" Not Last:%-8lu\r\n", sc->rxNotLast);
printf (" Giant:%-8lu", sc->rxGiant);
printf (" Runt:%-8lu", sc->rxRunt);
printf (" Non-octet:%-8lu\r\n", sc->rxNonOctet);
printf (" Bad CRC:%-8lu", sc->rxBadCRC);
printf (" Overrun:%-8lu", sc->rxOverrun);
printf (" Collision:%-8lu\r\n", sc->rxCollision);
/* printf (" Discarded:%-8lu\r\n", (unsigned long)m360.scc1p.un.ethernet.disfc);
*/
printf (" Tx Interrupts:%-8lu", sc->txInterrupts);
printf (" Deferred:%-8lu", sc->txDeferred);
printf (" Missed Hearbeat:%-8lu\r\n", sc->txHeartbeat);
printf (" No Carrier:%-8lu", sc->txLostCarrier);
printf ("Retransmit Limit:%-8lu", sc->txRetryLimit);
printf (" Late Collision:%-8lu\r\n", sc->txLateCollision);
printf (" Underrun:%-8lu", sc->txUnderrun);
printf (" Raw output wait:%-8lu", sc->txRawWait);
printf (" Coalesced:%-8lu\r\n", sc->txCoalesced);
printf (" Coalesce failed:%-8lu", sc->txCoalesceFailed);
printf (" Retries:%-8lu\r\n", sc->txRetry);
}
/*
* Driver ioctl handler
*/
static int
scc_ioctl (struct ifnet *ifp, int command, caddr_t data)
{
struct scc_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:
scc_stop (sc);
break;
case IFF_UP:
scc_init (sc);
break;
case IFF_UP | IFF_RUNNING:
scc_stop (sc);
scc_init (sc);
break;
default:
break;
}
break;
case SIO_RTEMS_SHOW_STATS:
scc_stats (sc);
break;
/*
* FIXME: All sorts of multicast commands need to be added here!
*/
default:
error = EINVAL;
break;
}
return error;
}
/*
* Attach an SCC driver to the system
*/
int
rtems_ether1_driver_attach (struct rtems_bsdnet_ifconfig *config)
{
struct scc_softc *sc;
struct ifnet *ifp;
int mtu;
int unitNumber;
char *unitName;
a_m68302_imp = (struct m68302_imp *)0x700000L;
/*
* Parse driver name
*/
if ((unitNumber = rtems_bsdnet_parse_driver_name (config, &unitName)) < 0)
return 0;
/*
* Is driver free?
*/
if ((unitNumber <= 0) || (unitNumber > NSCCDRIVER)) {
printf ("Bad SCC unit number.\r\n");
return 0;
}
sc = &scc_softc[unitNumber - 1];
ifp = &sc->arpcom.ac_if;
if (ifp->if_softc != NULL) {
printf ("Driver already in use.\r\n");
return 0;
}
/*
* Process options
*/
if (config->hardware_address) {
memcpy (sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
}
if (config->mtu)
mtu = config->mtu;
else
mtu = ETHERMTU;
if (config->rbuf_count)
sc->rxBdCount = config->rbuf_count;
else
sc->rxBdCount = RX_BUF_COUNT;
if (config->xbuf_count)
sc->txBdCount = config->xbuf_count;
else
sc->txBdCount = TX_BUF_COUNT;
sc->acceptBroadcast = !config->ignore_broadcast;
/*
* Set up network interface values
*/
ifp->if_softc = sc;
ifp->if_unit = unitNumber;
ifp->if_name = unitName;
ifp->if_mtu = mtu;
ifp->if_init = scc_init;
ifp->if_ioctl = scc_ioctl;
ifp->if_start = scc_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;
};

View File

@@ -4,7 +4,12 @@
AUTOMAKE_OPTIONS = foreign 1.4
BSP_PIECES = startup clock console timer
# We only build the networking device driver if HAS_NETWORKING was defined
if HAS_NETWORKING
NETWORKING_DRIVER = network
endif
BSP_PIECES = startup clock console timer $(NETWORKING_DRIVER)
# bummer; have to use $foreach since % pattern subst rules only replace 1x
OBJS = $(foreach piece, $(BSP_PIECES), $(wildcard ../$(piece)/$(ARCH)/*.o))