📄 motcpmend.c
字号:
/* motCpmEnd.c - END style Motorola MC68EN360/MPC800 network interface driver */
/* Copyright 1997-1999 Wind River Systems, Inc. */
#include "copyright_wrs.h"
/*
modification history
--------------------
01x,29mar99,dat SPR 26119, documentation, usage of .bS/.bE
01w,26nov98,dbt removed splimp() and splx() calls in motCmpEndIoctl
(SPR #23528). Added a missing netMblkClChainFree() call.
01v,22sep98,dat added Didier's fix for system-mode transitions. (SPR 22325)
removed warnings.
01u,09sep98,n_s removed promiscous mode filter from motCpmEndPollReceive ().
spr 21143.
01t,28aug98,dat chg'd all names from motCmp to motCpm.
01s,21aug98,n_s removed promiscous mode filter from motCmpRecv (). spr 21143.
01r,30jun98,cn changed include file motCmpEnd.h to motCpmEnd.h
01q,22jun98,cn added support for PPC800-series Ethernet Controller.
01p,11dec97,kbw making man page edits
01o,08dec97,gnn END code review fixes.
01n,19oct97,vin moved swapping of loaned buffer before END_RCV_RTN_CALL
01m,17oct97,vin removed extra free.
01l,07oct97,vin MTU size to ETHER_MTU.
01k,03oct97,gnn fixed SPR 8988, memory leak
01j,25sep97,gnn SENS beta feedback fixes
01i,24sep97,vin added clBlk related calls
01h,03sep97,gnn fixed a crashing bug under heavy load
01g,25aug97,gnn changes due to new netPool routines.
01f,22aug97,gnn changes due to new buffering scheme.
01e,12aug97,gnn changes necessitated by MUX/END update.
01d,15may97,map fixed intr event ack (scce) handling (SPR# 8580).
01c,18apr97,gnn fixed a bug in the receive code.
01b,09apr97,gnn updated buffer handling code to follow new MUX level
requirements.
01a,15feb97,dbt modified if_qu.c to END style.
*/
/*
This module implements the Motorola MC68EN360 QUICC as well as the MPC821 and
MPC860 Power-QUICC Ethernet Enhanced network interface driver.
All the above mentioned microprocessors feature a number of Serial
Communication Controllers (SCC) that support different serial protocols
including IEEE 802.3 and Ethernet CSMA-CD. As a result, when the Ethernet
mode of a SCC is selected, by properly programming its general Mode Register
(GSMR), they can implement the full set of media access control and channel
interface functions those protocol require. However, while the MC68EN360
QUICC and the MPC860 Power-QUICC support up to four SCCs per unit, the
MPC821 only includes two on-chip SCCs.
This driver is designed to support the Ethernet mode of a SCC residing on the
CPM processor core, no matter which among the MC68EN360 QUICC or any of the
PPC800 Series. In fact, the major differences among these processors, as far
as the driver is concerned, are to be found in the mapping of the internal
Dual-Port RAM. The driver is generic in the sense that it does not care
which SCC is being used. In addition, it poses no constraint on the number
of individual units that may be used per board. However, this number should
be specified in the bsp through the macro MAX_SCC_CHANNELS. The default value
for this macro in the driver is 4.
To achieve these goals, the driver requires several target-specific values
provided as an input string to the load routine. It also requires some
external support routines. These target-specific values and the external
support routines are described below.
This network interface driver does not include support for trailer protocols
or data chaining. However, buffer loaning has been implemented in an effort
to boost performance.
This driver maintains cache coherency by allocating buffer space using
the cacheDmaMalloc() routine. This is provided for boards whose host
processor use data cache space, e.g. the MPC800 Series. Altough the
MC68EN360 does not have cache memory, it may be used in a particular
configuration: 'MC68EN360 in 040 companion mode' where that is attached
to processors that may cache memory. However, due to a lack of suitable
hardware, the multiple unit support and '040 companion mode support have
not been tested.
BOARD LAYOUT
This device is on-chip. No jumpering diagram is necessary.
EXTERNAL INTERFACE
This driver provides the standard END external interface. The only external
interface is the motCpmEndLoad() routine. The parameters are passed
into the motCpmEndLoad() function as a single colon-delimited string.
The motCpmEndLoad() function uses strtok() to parse the string, which it
expects to be of the following format:
<unit>:<motCpmAddr>:<ivec>:<sccNum>:<txBdNum>:<rxBdNum>:
<txBdBase>: <rxBdBase>:<bufBase>
TARGET-SPECIFIC PARAMETERS
.IP <unit>
A convenient holdover from the former model. This parameter is used only
in the string name for the driver.
.IP <motCpmAddr>
Indicates the address at which the host processor presents its internal
memory (also known as the dual ported RAM base address). With this address,
and the SCC number (see below), the driver is able to compute the location
of the SCC parameter RAM and the SCC register map, and, ultimately, to
program the SCC for proper operations. This parameter should point to the
internal memory of the processor where the SCC physically resides. This
location might not necessarily be the Dual-Port RAM of the microprocessor
configured as master on the target board.
.IP <ivec>
This driver configures the host processor to generate hardware interrupts
for various events within the device. The interrupt-vector offset
parameter is used to connect the driver's ISR to the interrupt through
a call to the VxWorks system function intConnect().
.IP <sccNum>
This driver is written to support multiple individual device units.
Thus, the multiple units supported by this driver can reside on different
chips or on different SCCs within a single host processor. This parameter
is used to explicitly state which SCC is being used (SCC1 is most commonly
used, thus this parameter most often equals "1").
.IP "<txBdNum> and <rxBdNum>"
Specify the number of transmit and receive buffer descriptors (BDs).
Each buffer descriptor resides in 8 bytes of the processor's dual-ported
RAM space, and each one points to a 1520 byte buffer in regular RAM.
There must be a minimum of two transmit and two receive BDs. There is
no maximum, although more than a certain amount does not speed up the
driver and wastes valuable dual-ported RAM space. If any of these parameters
is "NULL", a default value of "32" BDs is used.
.IP "<txBdBase> and <rxBdBase>"
Indicate the base location of the transmit and receive buffer descriptors
(BDs). They are offsets, in bytes, from the base address of the host
processor's internal memory (see above). Each BD takes up 8 bytes of
dual-ported RAM, and it is the user's responsibility to ensure that all
specified BDs fit within dual-ported RAM. This includes any other
BDs the target board might be using, including other SCCs, SMCs, and the
SPI device. There is no default for these parameters. They must be
provided by the user.
.IP <bufBase>
Tells the driver that space for the transmit and receive buffers need not
be allocated but should be taken from a cache-coherent private memory space
provided by the user at the given address. The user should be aware that
memory used for buffers must be 4-byte aligned and non-cacheable. All the
buffers must fit in the given memory space. No checking is performed.
This includes all transmit and receive buffers (see above). Each buffer
is 1520 bytes. If this parameter is "NONE", space for buffers is obtained
by calling cacheDmaMalloc() in motCpmEndLoad().
.LP
EXTERNAL SUPPORT REQUIREMENTS
This driver requires three external support functions:
.IP sysXxxEnetEnable()
.LP
This is either sys360EnetEnable() or sysCpmEnetEnable(), based on the
actual host processor being used. See below for the actual prototypes.
This routine is expected to handle any target-specific functions needed
to enable the Ethernet controller. These functions typically include
enabling the Transmit Enable signal (TENA) and connecting the transmit
and receive clocks to the SCC. This routine is expected to return OK on
success, or ERROR. The driver calls this routine, once per unit, from the
motCpmEndLoad() routine.
.IP sysXxxEnetDisable()
.LP
This is either sys360EnetDisable() or sysCpmEnetDisable(), based on the
actual host processor being used. See below for the actual prototypes.
This routine is expected to handle any target-specific functions required
to disable the Ethernet controller. This usually involves disabling the
Transmit Enable (TENA) signal. This routine is expected to return OK on
success, or ERROR. The driver calls this routine from the motCpmEndStop()
routine each time a unit is disabled.
.IP sysXxxEnetAddrGet()
.LP
This is either sys360EnetAddrGet() or sysCpmEnetAddrGet(), based on the
actual host processor being used. See below for the actual prototypes.
The driver expects this routine to provide the six-byte Ethernet hardware
address that is used by this unit. This routine must copy the six-byte
address to the space provided by <addr>. This routine is expected to
return OK on success, or ERROR. The driver calls this routine, once per
unit, from the motCpmEndLoad() routine.
.LP
In the case of the CPU32, the prototypes of the above mentioned support
routines are as follows:
.CS
STATUS sys360EnetEnable (int unit, UINT32 regBase)
void sys360EnetDisable (int unit, UINT32 regBase)
STATUS sys360EnetAddrGet (int unit, u_char * addr)
.CE
.LP
In the case of the PPC860, the prototypes of the above mentioned support
routines are as follows:
.CS
STATUS sysCpmEnetEnable (int unit)
void sysCpmEnetDisable (int unit)
STATUS sysCpmEnetAddrGet (int unit, UINT8 * addr)
.CE
.LP
SYSTEM RESOURCE USAGE
When implemented, this driver requires the following system resources:
- one mutual exclusion semaphore
- one interrupt vector
- 0 bytes in the initialized data section (data)
- 1272 bytes in the uninitialized data section (BSS)
The data and BSS sections are quoted for the CPU32 architecture and could
vary for other architectures. The code size (text) varies greatly between
architectures, and is therefore not quoted here.
If the driver allocates the memory to share with the Ethernet device unit,
it does so by calling the cacheDmaMalloc() routine. For the default case
of 32 transmit buffers, 32 receive buffers, and 16 loaner buffers (this is not
configurable), the total size requested is 121,600 bytes. If a non-cacheable
memory region is provided by the user, the size of this region should be this
amount, unless the user has specified a different number of transmit or
receive BDs.
This driver can operate only if this memory region is non-cacheable
or if the hardware implements bus snooping. The driver cannot maintain
cache coherency for the device because the buffers are asynchronously
modified by both the driver and the device, and these fields might share
the same cache line. Additionally, the chip's dual-ported RAM must be
declared as non-cacheable memory where applicable (for example, when attached
to a 68040 processor). For more information, see the
.I "Motorola MC68EN360 User's Manual",
.I "Motorola MPC860 User's Manual",
.I "Motorola MPC821 User's Manual"
INTERNAL
This driver contains conditional compilation switch DEBUG.
If defined, adds debug output routines. Output is further
selectable at run-time via the motCpmDebug global variable.
*/
/* includes */
#include "vxWorks.h"
#include "iv.h"
#include "taskLib.h"
#include "memLib.h"
#include "ioctl.h"
#include "net/mbuf.h"
#include "net/protosw.h"
#include "socket.h"
#include "errno.h"
#include "errnoLib.h"
#include "net/unixLib.h"
#include "net/route.h"
#include "net/if_subr.h"
#include "cacheLib.h"
#include "stdio.h"
#include "intLib.h"
#include "logLib.h"
#include "netLib.h"
#include "iosLib.h"
#include "drv/netif/netifDev.h"
#include "drv/end/motCpmEnd.h"
#include "net/if.h"
#include "netinet/in.h"
#include "netinet/in_systm.h"
#include "netinet/in_var.h"
#include "netinet/ip.h"
#include "netinet/if_ether.h"
#include "etherLib.h"
#include "etherMultiLib.h"
#include "end.h"
#include "semLib.h"
#undef END_MACROS
#include "endLib.h"
#include "lstLib.h"
#include "netBufLib.h"
/* defines */
#define ENET_ADDR_SIZE 0x6 /* size of Ethernet src/dest addresses */
#define TX_BD_MIN 2 /* minimum number of Tx buffer descriptors */
#define TX_BD_MAX 128 /* maximum number of Tx buffer descriptors */
#define RX_BD_MIN 2 /* minimum number of Rx buffer descriptors */
#define TX_BD_DEFAULT 0x20 /* default number of Tx buffer descriptors */
#define RX_BD_DEFAULT 0x20 /* default number of Rx buffer descriptors */
#define FRAME_MAX 0x05ee /* maximum frame size */
#define FRAME_MAX_AL 0x0650/*0x05f0*/ /* maximum frame size, 4 byte alligned */
#define FRAME_MIN 0x0040 /* minimum frame size */
#define LENGTH_MIN_FBUF 9 /* min. size of the first buffer in a frame */
#define SPEED 10000000/* ethernet speed */
#define L_POOL 0x10 /* number of Rx loaner buffers in pool */
BOOL send1=0,send2=0,send3=0,send4=0,send5=0,send6=0,send7=0,send8=0,send9=0,send10=0,send11=0;
BOOL rev1=0,rev2=0,rev3=0,rev4=0,rev5=0;
void printfonoff_rev(BOOL a,BOOL b,BOOL c,BOOL d,BOOL e);
void printfonoff_send(BOOL a,BOOL b,BOOL c,BOOL d,BOOL e,BOOL f,BOOL g,BOOL k,BOOL m,BOOL n,BOOL l);
/* A shortcut for getting the hardware address from the MIB II stuff. */
#define END_HADDR(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)
#define END_HADDR_LEN(pEnd) \
((pEnd)->mib2Tbl.ifPhysAddress.addrLength)
#ifndef SYS_INT_CONNECT
#define SYS_INT_CONNECT(pFunc, arg, pRet) \
{ \
*pRet = (intConnect) (INUM_TO_IVEC (pDrvCtrl->ivec), \
(pFunc), (int) (arg)); \
}
#endif /* SYS_INT_CONNECT */
#define MOT_CPM_DEBUG /* debug support */
int motCpmDebug = 0;
#ifdef MOT_CPM_DEBUG
#define MOTCPMLOGMSG(x) \
if (motCpmDebug) \
{ \
logMsg x; \
}
#else
#define MOTCPMLOGMSG(x)
#endif /* MOT_CPM_DEBUG */
/* typedefs */
/* Ethernet header */
typedef struct free_args
{
void* arg1;
void* arg2;
} FREE_ARGS;
typedef struct end_ctrl /* END_CTRL */
{
END_OBJ endObject; /* base class */
UINT32 regBase; /* register/DPR base address */
SCC_ETHER_DEV ether; /* ETHERNET SCC device */
int txBdIndexC; /* current tx buffer descriptor index */
UINT32 bufBase; /* address of memory pool; */
/* NONE = malloc it */
int unit; /* unit number */
int ivec; /* interrupt vector */
BOOL polling; /* polling mode */
BOOL txCleaning; /* cleaning queue */
u_char * txBuf; /* transmit buffer */
u_char * rxBuf; /* receive buffer */
BOOL txStop; /* emergency stop output */
FUNCPTR freeRtn[TX_BD_MAX]; /* Array of free routines. */
FREE_ARGS freeData[TX_BD_MAX]; /* Array of free arguments */
CL_POOL_ID pClPoolId; /* for the free routines. */
BOOL txBlocked; /* flag for implementing flow control */
} END_CTRL;
typedef struct {
int unit; /* unit number */
UINT32 motCpmAddr; /* base address of processor internal mem */
int ivec; /* interrupt vector */
int sccNum; /* Serial Communication Controler number */
int txBdNum; /* number of transmit buffer descriptors */
int rxBdNum; /* number of receive buffer descriptors */
UINT32 txBdBase; /* transmit buffer descriptor offset */
UINT32 rxBdBase; /* receive buffer descriptor offset */
UINT32 bufBase; /* address of memory pool; NONE = malloc it */
} END_PARM;
/* globals */
/* locals */
M_CL_CONFIG motMclBlkConfig = /* network mbuf configuration table */
{
/*
no. mBlks no. clBlks memArea memSize
----------- ---------- ------- -------
*/
0, 0, NULL, 0
};
CL_DESC motClDescTbl [] = /* network cluster pool configuration table */
{
/*
clusterSize num memArea memSize
----------- ---- ------- -------
*/
{FRAME_MAX_AL, 0, NULL, 0}
};
int motClDescTblNumEnt = (NELEMENTS(motClDescTbl));
NET_POOL motCpmNetPool;
LOCAL END_CTRL drvCtrl[MAX_SCC_CHANNELS]; /* array of driver control */
/* forward declarations */
#ifdef __STDC__
LOCAL STATUS motCpmInitParse (END_PARM *pEndParm, char *initString);
LOCAL STATUS motCpmInitMem (END_CTRL *pDrvCtrl);
LOCAL void motCpmRecv (END_CTRL *pDrvCtrl, SCC_BUF * pRxBd);
LOCAL void motCpmIntr (END_CTRL *pDrvCtrl);
LOCAL void motCpmReset (END_CTRL * pDrvCtrl);
LOCAL void motCpmMCastFilterSet (END_CTRL * pDrvCtrl, char * pAddress);
LOCAL void motCpmMCastConfig (END_CTRL * pDrvCtrl);
LOCAL void motCpmTxRestart (END_CTRL * pDrvCtrl);
LOCAL void motCpmHandleInt (END_CTRL * pDrvCtrl);
LOCAL void motCpmCleanTxBdQueue (END_CTRL * pDrvCtrl);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -