📄 eth860.c
字号:
recbd - "[i_a] err, given this I guess this file shouldn't be here..."
/*
* ETH860.C - RTIP Device driver for Motorola mpc860 PowerPC
* Based originally on eth360.c RTIP distribution.
* this file uses 3 spaces instead of tabs
*
* Copyright Peter Van Oudenaren , 1993
* All rights reserved.
* This code may not be redistributed in source or linkable object form
* without the consent of its author.
*
* Notes:
* 1) #define ETHER_LOOPBACK_MODE to enable internal loopback.
*
* 2) The data cache is assumed to be disabled. If you enable the data cache
* set up the MMU to define the area to which the SCC does DMA as
* non-cacheable. The function os_alloc_packet() in os.c allocates the
* memory for the packets.
*
* 3) Ethernet will not work unless the board is running at 24 MHz rather
* than the default to 20 MHz. Write a 5 to the MF field in the PLPRCR reg
* to set multiplication factor to 6 (5+1). This is done for you in SDS
* SingleStep file 821ads.cfg
*
* 4) Modify the set_up_mpc860ads_board() function to work with your hardware.
*
*
*/
#include "rtip.h"
#if (INCLUDE_SLIP || INCLUDE_CSLIP || defined(INCLUDE_PPP))
#include "circbuff.h"
#include "uartport.h"
#include "uart.h"
#endif /* end of (INCLUDE_SLIP || INCLUDE_CSLIP || INCLUDE_PPP) */
#if (INCLUDE_ETH860)
/* comment out #define ETHER_LOOPBACK_MODE for normal operation */
/*#define ETHER_LOOPBACK_MODE */
#ifdef ETHER_LOOPBACK_MODE
#define GSMR_DIAG_MODE GSMR_L_DIAG_LOOPBACK
#define PSMR_DIAG_MODE PSMR_LPB
#else /* normal operation */
#define GSMR_DIAG_MODE GSMR_L_DIAG_NORM
#define PSMR_DIAG_MODE 0
#endif
/*#define RECEIVE_ALL_FRAMES promiscuous mode */
#ifdef RECEIVE_ALL_FRAMES
#define PSMR_PRO_MODE PSMR_PRO
#else /* normal operation */
#define PSMR_PRO_MODE 0
#endif
long n_interrupts = 0;
long n_bogus_interrupts = 0;
NODE_ADDRESS myEthAddr = { { 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 } };
/*NODE_ADDRESS myEthAddr = { { 0x00, 0x12, 0x34, 0x56, 0x78, 0x9a } }; */
PIFACE myIface;
DCU RxDCU[NumRxBDs]; /* we DMA directly into DCU, remember it's address */
int CurrentRx; /* index into RxDCU of next BD to process */
static word eth860_wait_ticks; /* xmit timeout wait ticks */
static int eth860_retry;
volatile BUFFER_DESCRIPTOR *sendbd;
volatile BUFFER_DESCRIPTOR *sentbd;
volatile BUFFER_DESCRIPTOR *recbd;
bd_union_type bd_union;
/*#define DEBUG_ETH 1 */
#if (DEBUG_ETH)
int aa_n_rcv_ints = 0;
int aa_n_bad_rcv_ints = 0;
int aa_n_bad_rcv_miss = 0;
int aa_n_bad_rcv_vi = 0;
int aa_n_bad_rcv_non = 0;
int aa_n_bad_rcv_little = 0;
int aa_n_bad_rcv_crc = 0;
int aa_n_bad_rcv_ov = 0;
int aa_n_bad_rcv_coll = 0;
#endif
struct eth860_statistics
{
dword packets_in;
dword packets_out;
dword bytes_in;
dword bytes_out;
dword errors_in;
dword errors_out;
dword packets_lost;
};
struct eth860_statistics mcstats;
/* serial debug port input buffer, etc. */
char *term_c_pointer;
char term_inbuf[80]; /* input buffer */
volatile BUFFER_DESCRIPTOR *term_sendbd;
volatile BUFFER_DESCRIPTOR *term_recbd;
#if (EBSSMCUART)
/* serial UART port data structures, etc. Designed for SMC1 port */
/* The SMC ports do not support handshaking */
PIFACE uartIface;
PUART_INFO uartInfo;
char uart_inbuf[SMC1RxBDs*4]; /* input buffer */
int CurrentRxBuf; /* index into uart_inbuf to process */
DCU uartTxDCU[SMC1TxBDs]; /* buffer length is defined by CFG_RS232_XMBUFSIZE */
volatile BUFFER_DESCRIPTOR *uart_sendbd;
volatile BUFFER_DESCRIPTOR *uart_sentbd;
volatile BUFFER_DESCRIPTOR *uart_recbd;
long n_SMC1_interrupts = 0;
long n_bogus_SMC1_interrupts = 0;
long n_SMC1_RX_interrupts = 0;
long n_SMC1_TX_interrupts = 0;
long n_SMC1_BSY_interrupts = 0;
long n_SMC1_CHARS_in = 0;
long n_SMC1_CHARS_out = 0;
long n_SMC1_ERR_in = 0;
long n_SMC1_LOST_in = 0;
#endif /* end of (EBSSMCUART) */
/* function prototypes */
void ether_enable_ads(word setting);
void rs232_1_enable_ads(word setting);
void rs232_2_enable_ads(word setting);
void smc_term_open();
int smc_term_send( void *buf, int length );
char smc_term_getc();
#if (RTKD860)
int RTKsmc_term_sendl( char *buf,int length );
char RTKsmc_term_getc();
int RTKsmc_term_kbhit(void);
#endif
#if (EBSSMCUART)
BOOLEAN smc_uart_open(PUART_INFO uinfo);
void smc_uart_close(PIFACE pi);
int smc_uart_send(char *pdata, int n_bytes);
void smc_receiver(PUART_INFO uinfo);
#endif /* end of (EBSSMCUART) */
/********************************************************************** */
/* eth860_setmcast() - */
/* Takes an interface structures a contiguous array */
/* of bytes containing N IP multicast addresses and n, the number */
/* of addresses (not number of bytes). */
/* Calls the packet packet driver's set_multicast_list */
BOOLEAN eth860_setmcast(PIFACE pi) /* __fn__ */
{
return(FALSE);
}
/********************************************************************** */
/* set_up_mpc860ads_board() - */
/* This function inits board specfic i/o */
/* MODIFY THIS FUNCTION FOR YOUR OWN HARDWARE */
/* */
static void set_up_mpc860ads_board(void)
{
/*------------------------------------------------------------------------ */
/* control line for the EEST: (16-468) */
/* THIS SETUP IS FOR MPC860ADS BOARD ONLY */
/* Your board may use different i/o lines to */
/* control the EEST */
/* */
/* Set up PC4, PC5 and PC6 for output */
/* PC4 = EEST loopback (0 for normal operation) */
/* EEST loopback does not work on 860, because 860 won't do full */
/* duplex with the external (EEST) loopback. see page 16-327 */
/* PC5 = TPFLDL (0 for normal operation) */
/* Forcing this pin low allows simultaneous transmit and receive */
/* operation on the twisted pair port without an indicated collision. */
/* This pin is not to be asserted with LOOP */
/* as a test mode is enabled that disrupts normal operation. */
/* (ie dont let PC4 = 1 and PC5 = 0 at the same time) */
/* PC6 = TPSQEL (1 for normal operation) */
/* See MPC860ADS manual page 50 */
/*------------------------------------------------------------------------ */
#if(ADS860)
IMMR->pio_pcpar &= ~(PCPAR_DD4 | PCPAR_DD5 | PCPAR_DD6);
IMMR->pio_pcdir |= PCDIR_DR4 | PCDIR_DR5 | PCDIR_DR6;
IMMR->pio_pcso &= ~(PCPAR_DD4 | PCPAR_DD5 | PCDIR_DR6);
IMMR->pio_pcdat &= ~(PCPAR_DD4);
IMMR->pio_pcdat |= PCPAR_DD6;
IMMR->pio_pcdat |= PCPAR_DD5; /* set TPFLDL high (setting lo caused xmit errors */
#endif
ether_enable_ads(1); /* enable ethernet on mpc860ads and mpc821ads board */
}
/**************************************************************************** */
/* open the packet driver interface. */
/* */
/* This routine opens a packet device driver and copies the board's */
/* ethernet address into the interface structure. If the open is successful */
/* and the ethernet address was ascertained it returns TRUE otherwise FALSE. */
/* */
void EthernetIntHandler(int vector);
BOOLEAN eth860_open(PIFACE pi) /*__fn_*/
{
int i;
/***************************************************************** */
/* Disable SCC1 while we program the buffer (16-153) */
/* descriptors and the parameter RAM. */
/* Clear the ENT/ENR bits in the GSMR -- disable Transmit/Receive */
/***************************************************************** */
IMMR->scc_regs[SCC1_REG].scc_gsmr_l &= 0xFFFFFFCF;
/* copy the ethernet address to my_hw_addr */
tc_movebytes(pi->addr.my_hw_addr, myEthAddr.bytes, 6);
myIface = pi; /* remember our interface ID */
#if (defined(CYGMA860)) /* Cygnus MBX and ADS boards */
/* Set up cpm in this open routine to interrrupt the external interrupt at */
/* irq level 4. Let the interrupt handler in initppc.c decode the cpm interrupt source. */
ks_hook_interrupt(CYGNUM_HAL_INTERRUPT_SIU_LVL4, ext_int_handler, 0);
#endif
#if (defined(RTKD860)||1) /* RTKernel MBX and ADS boards */
ks_hook_interrupt(1, (PFVOID) pi, (RTIPINTFN_POINTER)EthernetIntHandler,(RTIPINTFN_POINTER) 0, pi->minor_number);
#endif
/*---------------------------------------------------------------- */
/* Write CICR to Configure SCC1 Interrupt Priority Settings: */
/* (16-480) */
/* SCC Priorities */
/* SCC1 - Highest Priority */
/* IRL0-IRL2 (Interrupt Request Level) = Constant set by user */
/* HP0-HP4 (Highest Priority) = Original Priority */
/* IEN = Enable CPM Interrupts */
/*---------------------------------------------------------------- */
IMMR->cpmi_cicr = 0x000E11F80 | (CPM_INTERRUPT_LEVEL << 13);
/**************************** */
/* Configure Pins and Clocks */
/**************************** */
/*----------------------------------------------------- */
/* Configure Port A pins to enable RXD1, TXD1. (16-457) */
/*----------------------------------------------------- */
#if(ADS860)
IMMR->pio_papar |= PA_SCCRXD1 | PA_SCCTXD1 | PA_CLK2 | PA_CLK1;
#elif(MPC860)
IMMR->pio_papar |= PA_SCCRXD1 | PA_SCCTXD1 | PA_CLK2 | PA_CLK4;
#else
#error
#endif
/*-------------------------------------------------------------- */
/* These two bits must be zero when these two port A */
/* pins are configured as on-chip dedicated peripheral. (16-457) */
/*-------------------------------------------------------------- */
#if(ADS860)
IMMR->pio_padir &= ~(PA_SCCRXD1 | PA_SCCTXD1 | PA_CLK2 | PA_CLK1);
IMMR->pio_paodr &= ~PA_SCCTXD1;
#elif(MPC860)
IMMR->pio_padir &= ~(PA_SCCRXD1 | PA_SCCTXD1 | PA_CLK2 | PA_CLK4);
IMMR->pio_paodr &= ~PA_SCCTXD1;
#else
#error
#endif
/* IMMR->pio_paodr &= ~(PA_SCCRXD1 | PA_SCCTXD1 | PA_CLK2 | PA_CLK1); */
#if(ADS860)
/* Mustn't enable RTS yet as we haven't set ethernet mode, otherwise we might start transmitting! */
/* RTS1 is TENA Transmit enable */
/* CD1 is RENA/CD1*=PC10 Receive enable */
/* CTS1 is CLSN/CTS1*=PC11 Collision */
IMMR->pip_pbpar &= ~(PB_RTS1);
IMMR->pio_pcpar &= ~(PC_SCCCTS1 | PC_SCCCD1 );
IMMR->pio_pcdir &= ~(PC_SCCCTS1 | PC_SCCCD1 );
IMMR->pio_pcso |= PC_SCCCTS1 | PC_SCCCD1; /* (16-469) */
#elif(MPC860)
/* Mustn't enable RTS yet as we haven't set ethernet mode, otherwise we might start transmitting! */
/* RTS1 on pc15 is TENA Transmit enable */
/* CD1 on pc10 is RENA/CD1*=PC10 Receive enable */
/* CTS1 on pc11 is CLSN/CTS1*=PC11 Collision */
IMMR->pio_pcpar &= ~(PC_SCCRTS1);
IMMR->pio_pcpar &= ~(PC_SCCCTS1 | PC_SCCCD1 );
IMMR->pio_pcdir &= ~(PC_SCCCTS1 | PC_SCCCD1 );
IMMR->pio_pcso |= PC_SCCCTS1 | PC_SCCCD1; /* (16-469) */
#else
#error
#endif
/*------------------------------------------------------------------- */
/* Initialize baud rate generator. Our Motorola ADS target is */
/* configured to have a 24Mhz clock out of the system PLL. The 24Mhz */
/* internal clock will be divided down by 12 to give a baud clock of */
/* 2Mhz. CD bits will be programmed to 0xB. They are not programmed */
/* to 0xC because total divide ratio is CD value+1 {can never divide */
/* by 0}. (16-141) */
/*------------------------------------------------------------------- */
#ifdef ETHER_LOOPBACK_MODE
IMMR->brgc4 = (0x00010016); /* Enable BRG with division factor 12 */
#endif
/*--------------------------------------------------------- */
/* Initialize the SI Clock Route Register (SICR) for SCC1. */
/* (16-121) */
/* - Connect SCC1 to NMSI, */
/* - Transmit Clock = BRG4, Receive Clock = BRG4 */
/*--------------------------------------------------------- */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -