?? lan8xx.c
字號:
/* @(#) pSOSystem PowerPC/V2.2.2: bsps/e360/src/lan360.c (mpc8xx) 2.30 97/10/15 09:35:51 */
/***********************************************************************/
/* */
/* MODULE: bsps/devices/lan/lan8xx.c */
/* DATE: 97/10/15 */
/* PURPOSE: Ethernet driver for the MPC8xx SCC1 */
/* */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 1991 - 1997, Integrated Systems, Inc. */
/* ALL RIGHTS RESERVED */
/* */
/* Permission is hereby granted to licensees of Integrated Systems, */
/* Inc. products to use or abstract this computer program for the */
/* sole purpose of implementing a product based on Integrated */
/* Systems, Inc. products. No other rights to reproduce, use, */
/* or disseminate this computer program, whether in part or in */
/* whole, are granted. */
/* */
/* Integrated Systems, Inc. makes no representation or warranties */
/* with respect to the performance of this computer program, and */
/* specifically disclaims any responsibility for any damages, */
/* special or consequential, connected with the use of this program. */
/* */
/***********************************************************************/
#include "bsp.h"
#include "board.h"
#include <bspfuncs.h>
#include <pna.h>
#include <pna_mib.h>
#include <psos.h>
#include <string.h>
#include <lan/lan8xx.h>
#include <lan_mib.h>
#include <icontrol/mpc8xx.h>
#ifndef CPM_CMD
#define SPLX(A) { unsigned long ilev=splx(1); A; splx(ilev); }
#define CPM_CMD(t) {\
unsigned long old=splx(1); \
while ((S_CP_CommandReg& SEMAPHORE_FLAG) == SEMAPHORE_FLAG); \
S_CP_CommandReg =t|SEMAPHORE_FLAG; \
splx(old); \
while ((S_CP_CommandReg& SEMAPHORE_FLAG) == SEMAPHORE_FLAG); }
#endif
/*---------------------------------------------------------------------*/
/* The Ethernet hardware address can be changed in the startup dialog */
/*---------------------------------------------------------------------*/
extern unsigned char EthernetAddress[6]; /* defined in bpdialog.c */
#if ((BSP_LAN1_FLAGS) & (IFF_MULTICAST))
extern struct MCTable_struct lan_mcast; /* Multicast address table */
#endif
extern ULONG NrTxBds; /* Number of transmit BDs */
extern ULONG NrTxHdrs; /* Number of transmit headers */
extern TX_HDR TxHeaders[]; /* The actual headers */
/*---------------------------------------------------------------------*/
/* Global Variables */
/*---------------------------------------------------------------------*/
unsigned char RxBuffs[RXSIZE * NR_RXBUFFS];
#ifdef USE_UNCACHE_SECTION
#pragma use_section UNCACHE RxBuffs
#else
ULONG DummyVar;
#endif
TX_HDR *TxhFreeHead; /* Free list of transmit headers */
TX_HDR *TxhOutHead, *TxhOutTail; /* Head, tail of hdrs awaiting BDs */
RX_BUFF *RxbFreeHead; /* Head of free list */
/*---------------------------------------------------------------------*/
/* Miscellaneous variables */
/*---------------------------------------------------------------------*/
ULONG TxFreeBDs; /* # of free transmit BDs */
static long If_Num; /* interface number (assigned by pNA) */
static HWA OurAddress; /* our Ethernet address */
static UINT pSOS_Is_Up; /* TRUE if pSOS has been initialized */
static struct ni_funcs Ni_funcs; /* pNA functions (esballoc, freemsg) */
static long (*Announce)(ULONG, char *, ULONG, ULONG, char *, char *);
static BuffDescType *RxNewPtr; /* ptr to next Rx BD to become full */
static BuffDescType *RxUsedPtr; /* ptr to next Rx BD needing buffer */
BuffDescType *TxNewPtr; /* ptr to next Tx BD to transmit with */
BuffDescType *TxUsedPtr; /* ptr to next Tx BD to reclaim */
BuffDescType *TxLastBdPtr; /* ptr to last allocated Tx BD */
BuffDescType *RxLastBdPtr; /* ptr to last allocated Rx BD */
BuffDescType *TxFirstBdPtr; /* ptr to first allocated Tx BD */
BuffDescType *RxFirstBdPtr; /* ptr to first allocated Rx BD */
/*---------------------------------------------------------------------*/
/* MIB-Related Variables */
/* inerrors - # of frames received with errors. */
/* outerrors - # of frames not transmitted due to errors. */
/* outdiscards - # of frames not transmitted due to lack of resources */
/* Postponed - # of frames placed on the transmit queue (i.e. not */
/* enough BDs to transmit). */
/* CopyFallBack - # of frames which reverted from zero copy to copying */
/* the tail end due to low BDs (or frames with more */
/* buffers than Tx BDs configured in the system). */
/* CopiedBytes - # of bytes actually copied for CopyFallBack frames. */
/* CopiedBuffers- # of buffers copied for the CopyFallBack frames. */
/*---------------------------------------------------------------------*/
mib_stat MG_stat;
long inerrors, outerrors, outdiscards;
unsigned long Postponed, CopyFallBack, CopiedBytes, CopiedBuffers;
/***********************************************************************/
/* NI Function Prototypes */
/***********************************************************************/
static void InitSCC1(void);
static void InitBuffers(void);
static long ni_init(long (*ap_addr)(ULONG, char *, ULONG, ULONG,
char *, char *), long if_num, struct ni_funcs *funcs);
static void ReturnBuffer(RX_BUFF *env_ptr);
void ni_send(char *hwa_p, char *pkb_p, USHORT size, USHORT type);
static UINT ni_isr(void);
static void ReceivePackets(void);
static void AssignRxBuffers(void);
static void FillTxBDs(void);
static void AddTxBuffer(void *addr, USHORT status, USHORT len);
static void ReclaimTxFrames(void);
static void CleanUpTx(void);
void ni_pna_init(void);
#if ((BSP_LAN1_FLAGS) & (IFF_MULTICAST))
long lan_lookup_mcast(UCHAR *addr);
ULONG lan_add_mcast(UCHAR *addr);
ULONG lan_del_mcast(UCHAR *addr);
#endif
static void clear(volatile void *ptr, ULONG size);
extern ULONG ni_ioctl(ULONG if_num, long net_type, ULONG cmd, long *arg);
extern UCHAR *dpram_alloc(UINT, UINT);
extern void dpram_dealloc(UINT, UCHAR *, UINT);
/***********************************************************************/
/* NI Local Function Definitions */
/***********************************************************************/
/***********************************************************************/
/* InitSCC1: Initialize the SCC1 in Ethernet mode. */
/* */
/* NOTE: Initializes everything related to SCC1 except the */
/* receive and transmit buffer descriptors. */
/* */
/* This must be called after TxFirstBdPtr and */
/* RxFirstBdPtr are initialized. */
/***********************************************************************/
static void InitSCC1(void)
{
ULONG tmp_long, i;
/*---------------------------------------------------------------------*/
/* Disable the transmitter and receiver. */
/*---------------------------------------------------------------------*/
E_SCC1GenModeReg_h = E_SCC1GenModeReg_l = 0;
#if ADS8xx
/*---------------------------------------------------------------------*/
/* Configure port A to enable the TXD1, RXD1, CLK1, and CLK2 pins. */
/*---------------------------------------------------------------------*/
E_PortAPinAssgmntReg |= (BIT9 | BIT8 | BIT1 | BIT0);
E_PortADataDirReg &= ~(BIT9 | BIT8 | BIT1 | BIT0);
E_PortAOpenDrainReg &= ~BIT1;
#elif SBC8xx
S_PortAPinAssgmntReg |= (PA15 | PA14 | PA7 | PA6);
S_PortADataDirReg &= ~(PA15 | PA14 | PA7 | PA6);
S_PortAOpenDrainReg &= ~PA14;
#endif /* ADS8xx */
#if (ADS8xx || SBC8xx)
/*---------------------------------------------------------------------*/
/* Configure port C to enable !CTS1(CLSN) and !CD1(RENA). */
/*---------------------------------------------------------------------*/
E_PortCPinAssgmntReg &= ~(BIT5 | BIT4);
E_PortCDataDirReg &= ~(BIT5 | BIT4);
E_PortCSpecialOptsReg |= (BIT5 | BIT4);
#elif MBX8xx
/*---------------------------------------------------------------------*/
/* Configure port A to enable the TXD1, RXD1 */
/*---------------------------------------------------------------------*/
E_PortAPinAssgmntReg |= (PA14 | PA15);
E_PortADataDirReg &= ~(PA14 | PA15);
E_PortAOpenDrainReg &= ~PA14;
/*---------------------------------------------------------------------*/
/* Configure port C to enable !CTS1(CLSN), CD1(RXEN) */
/*---------------------------------------------------------------------*/
E_PortCPinAssgmntReg &= ~(PC10 | PC11);
E_PortCDataDirReg &= ~(PC10 | PC11);
E_PortCSpecialOptsReg |= (PC10 | PC11);
/*---------------------------------------------------------------------*/
/* Configure port A to enable the CLK2, and CLK4 pins. */
/*---------------------------------------------------------------------*/
E_PortAPinAssgmntReg |= (PA4 | PA6);
E_PortADataDirReg &= ~(PA4 | PA6);
#endif /* (ADS8xx || SBC8xx) */
#ifdef ADS8xx
/*---------------------------------------------------------------------*/
/* The MC68160 has a few more things that have to be done. Here is a */
/* list of other pins that need to be set up. */
/* */
/* Port C Bit 2 -> MC68160 CS2 pin - Set to 0 per documentation. */
/* Port C Bit 7 -> MC68160 Aport pin - Set to 1 to auto select the */
/* Twisted Pair/AUI Port */
/* Port C Bit 11 -> MC68160 Loop pin - Set to 0 for !diag mode */
/*---------------------------------------------------------------------*/
E_PortCPinAssgmntReg &= ~(BIT9 | BIT10 | BIT11);
E_PortCDataDirReg |= (BIT9 | BIT10 | BIT11);
E_PortCSpecialOptsReg &= ~(BIT9 | BIT10 | BIT11);
E_PortCDataReg |= BIT9;
E_PortCDataReg |= BIT10;
E_PortCDataReg &= ~(BIT11);
#endif /* ADS8xx */
#ifdef MBX8xx
/*---------------------------------------------------------------------*/
/* Connect the CLK2 and CLK4 pins to SCC1 as the transmit and receive */
/* clocks, respectively. */
/*---------------------------------------------------------------------*/
tmp_long = E_SI_ClockRouteReg;
tmp_long &= ~0xFF;
E_SI_ClockRouteReg = tmp_long | 0x3d;
E_SDMAConfigReg = 0x1;
#endif
#if (ADS8xx || SBC8xx)
/*---------------------------------------------------------------------*/
/* Connect the CLK1 and CLK2 pins to SCC1 as the transmit and receive */
/* clocks, respectively. */
/*---------------------------------------------------------------------*/
tmp_long = E_SI_ClockRouteReg;
tmp_long &= ~0xFF;
E_SI_ClockRouteReg = tmp_long | 0x2C;
#endif
/*---------------------------------------------------------------------*/
/* Setup SCC1 parameter RAM common to all protocols. */
/*---------------------------------------------------------------------*/
RxBDBaseAddr(E_SCC1_BASE) = E_BuffDescOffset(RxFirstBdPtr);
TxBDBaseAddr(E_SCC1_BASE) = E_BuffDescOffset(TxFirstBdPtr);
RxFunctionCode(E_SCC1_BASE) = MOT + DMA_SPACE;
TxFunctionCode(E_SCC1_BASE) = MOT + DMA_SPACE;
MaxRxBufferLgth(E_SCC1_BASE) = 1520;
/*---------------------------------------------------------------------*/
/* Setup SCC1 parameter RAM Ethernet-specific parameters. */
/*---------------------------------------------------------------------*/
ETHER(E_SCC1_BASE).c_pres = 0xFFFFFFFF;
ETHER(E_SCC1_BASE).c_mask = 0xDEBB20E3;
ETHER(E_SCC1_BASE).crc_err_cntr = 0;
ETHER(E_SCC1_BASE).align_err_cntr = 0;
ETHER(E_SCC1_BASE).dis_frame_cntr = 0;
ETHER(E_SCC1_BASE).pads = 0x8888;
ETHER(E_SCC1_BASE).retry_limit = 15;
ETHER(E_SCC1_BASE).max_frame_lgth = 1518;
ETHER(E_SCC1_BASE).min_frame_lgth = 64;
ETHER(E_SCC1_BASE).max_dma1_lgth = 1518;
ETHER(E_SCC1_BASE).max_dma2_lgth = 1518;
/*---------------------------------------------------------------------*/
/* Enable recption of all multicast addresses, if the lan driver is */
/* configured to do multicasting. The hash table in the 68360 seemed */
/* to correctly handle some addresses, but not others. */
/*---------------------------------------------------------------------*/
#if (BSP_LAN1_FLAGS & IFF_MULTICAST)
ETHER(E_SCC1_BASE).gaddr1 = 0xFFFF;
ETHER(E_SCC1_BASE).gaddr2 = 0xFFFF;
ETHER(E_SCC1_BASE).gaddr3 = 0xFFFF;
ETHER(E_SCC1_BASE).gaddr4 = 0xFFFF;
#else
ETHER(E_SCC1_BASE).gaddr1 = 0;
ETHER(E_SCC1_BASE).gaddr2 = 0;
ETHER(E_SCC1_BASE).gaddr3 = 0;
ETHER(E_SCC1_BASE).gaddr4 = 0;
#endif
/*---------------------------------------------------------------------*/
/* Write our Ethernet address to the parameter RAM in reverse byte */
/* order. */
/*---------------------------------------------------------------------*/
for (i = 0; i < 6; ++i)
((char *)ÐER(E_SCC1_BASE).paddr1_h)[5 - i] = OurAddress.byte[i];
ETHER(E_SCC1_BASE).p_per = 0;
ETHER(E_SCC1_BASE).iaddr1 = 0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -