⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dm9000xend.c

📁 博创PXA270-S开发箱的VxWorks BSP驱动(含注释)
💻 C
📖 第 1 页 / 共 3 页
字号:
/*dm9000xend.c*/#include "vxWorks.h"#include "iv.h"#include "vme.h"#include "net/mbuf.h"#include "lstLib.h"#include "semLib.h"#include "sys/times.h"#include "net/unixLib.h"#include "net/protosw.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "errno.h"#include "memLib.h"#include "intLib.h"#include "net/route.h"#include "iosLib.h"#include "errnoLib.h"#include "logLib.h"#include "cacheLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#include "etherLib.h"#include "net/systm.h"#include "net/if_subr.h"#include "config.h"#undef	ETHER_MAP_IP_MULTICAST#include "etherMultiLib.h"#include "end.h"#include "endLib.h"#include "dm9000xEnd.h"#include "config.h"#ifdef INCLUDE_DM_END/*#define  CONFIG_DM9K_BASE (0x10000000+(1<<23)+0x300)*/#define  CONFIG_DM9K_BASE (0x10000000+0x300)#define DM9000_DEV_NAME	"dm"#define DM9000_DEV_NAME_LEN	3#define DM9000_EADR_LEN	6#define DM9000_SPEED		10000000	/* 10Mbps or 100Mbps *//* Board/System/Debug information/definition ---------------- */#define ADVERTISE_SLCT          0x001f  /* Selector bits               */#define ADVERTISE_CSMA          0x0001  /* Only selector supported     */#define ADVERTISE_10HALF        0x0020  /* Try for 10mbps half-duplex  */#define ADVERTISE_10FULL        0x0040  /* Try for 10mbps full-duplex  */#define ADVERTISE_100HALF       0x0080  /* Try for 100mbps half-duplex */#define ADVERTISE_100FULL       0x0100  /* Try for 100mbps full-duplex */#define ADVERTISE_100BASE4      0x0200  /* Try for 100mbps 4k packets  */#define ADVERTISE_RESV          0x1c00  /* Unused...                   */#define ADVERTISE_RFAULT        0x2000  /* Say we can detect faults    */#define ADVERTISE_LPACK         0x4000  /* Ack link partners response  */#define ADVERTISE_NPAGE         0x8000  /* Next page bit               */#define BMCR_RESV               0x003f  /* Unused...                   */#define BMCR_SPEED1000		0x0040  /* MSB of Speed (1000)         */#define BMCR_CTST               0x0080  /* Collision test              */#define BMCR_FULLDPLX           0x0100  /* Full duplex                 */#define BMCR_ANRESTART          0x0200  /* Auto negotiation restart    */#define BMCR_ISOLATE            0x0400  /* Disconnect DP83840 from MII */#define BMCR_PDOWN              0x0800  /* Powerdown the DP83840       */#define BMCR_ANENABLE           0x1000  /* Enable auto negotiation     */#define BMCR_SPEED100           0x2000  /* Select 100Mbps              */#define BMCR_LOOPBACK           0x4000  /* TXD loopback bits           */#define BMCR_RESET              0x8000  /* Reset the DP83840           */#define MII_BMCR            0x00        /* Basic mode control register */#define MII_BMSR            0x01        /* Basic mode status register  */#define MII_PHYSID1         0x02        /* PHYS ID 1                   */#define MII_PHYSID2         0x03        /* PHYS ID 2                   */#define MII_ADVERTISE       0x04        /* Advertisement control reg   */#define MII_LPA             0x05        /* Link partner ability reg    */#define MII_EXPANSION       0x06        /* Expansion register          */#define MII_DCOUNTER        0x12        /* Disconnect counter          */#define MII_FCSCOUNTER      0x13        /* False carrier counter       */#define MII_NWAYTEST        0x14        /* N-way auto-neg test reg     */#define MII_RERRCOUNTER     0x15        /* Receive error counter       */#define MII_SREVISION       0x16        /* Silicon revision            */#define MII_RESV1           0x17        /* Reserved...                 */#define MII_LBRERROR        0x18        /* Lpback, rx, bypass error    */#define MII_PHYADDR         0x19        /* PHY address                 */#define MII_RESV2           0x1a        /* Reserved...                 */#define MII_TPISTATUS       0x1b        /* TPI status for 10mbps       */#define MII_NCONFIG         0x1c        /* Network interface config    */#define DM9000_REG00		0x00#define DM9000_REG05		0x30	/* SKIP_CRC/SKIP_LONG */#define DM9000_REG08		0x27#define DM9000_REG09		0x38#define DM9000_REG0A		0xff#define DM9000_REGFF		0x83	/* IMR */#define DM9000_PHY		0x40	/* PHY address 0x01 */#define TRUE			1#define FALSE			0#define CARDNAME "dm9000"#define DMFE_TIMER_WUT  jiffies+(HZ*2)	/* timer wakeup time : 2 second */#define DMFE_TX_TIMEOUT (HZ*2)	/* tx packet time-out time 1.5 s" */#define DMFE_DEBUG 0#ifndef SYS_ENET_ADDR_GET#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) 				\    do { 								\    IMPORT STATUS sysEnetAddrGet (int, char*);				\    sysEnetAddrGet (pDrvCtrl->unit, pAddress); 				\    } while (0)#endif /* SYS_ENET_ADDR_GET */enum DM9000_PHY_mode {	DM9000_10MHD = 0,	DM9000_100MHD = 1,	DM9000_10MFD = 4,	DM9000_100MFD = 5,	DM9000_AUTO = 8,	DM9000_1M_HPNA = 0x10};typedef struct dm9000_end_device	/* driver control structure */    {    END_OBJ		endObj;		/* The class we inherit from. */       int			unit;		/* unit number */    UCHAR		enetAddr[DM9000_EADR_LEN];	/* ethernet address */    CL_POOL_ID        pClPoolId;         /* cluster pool Id */       M_CL_CONFIG       mClCfg;            /* mBlk & cluster config structure */        CL_DESC           clDesc;            /* cluster descriptor table */    u32 ioaddr;		/* Register I/O base address */    u32 io_data;		/* Data I/O address */    u16 irq;		/* IRQ */    u8 op_mode;		/* PHY operation mode */    u8 reg0, reg5, reg8, reg9, rega;	/* registers saved */	int flags;	u8 io_mode;		/* 0:word, 2:byte */       } DM9000_END_DEVICE;/* Global variable declaration ----------------------------- */static int dmfe_debug = 0;/* For module input parameter */static int media_mode = DM9000_AUTO;static u8 reg5 = DM9000_REG05;static u8 reg8 = DM9000_REG08;static u8 reg9 = DM9000_REG09;static u8 rega = DM9000_REG0A;/* function declaration ------------------------------------- */static int dmfe_probe(DM9000_END_DEVICE *pDrvCtrl);static int dmfe_open(DM9000_END_DEVICE *pDrvCtrl);static int dmfe_start_xmit(M_BLK* pMblk, DM9000_END_DEVICE *pDrvCtrl);static int dmfe_stop( DM9000_END_DEVICE *pDrvCtrl);static void dmfe_interrupt(DM9000_END_DEVICE *pDrvCtrl);static void dmfe_init_dm9000(DM9000_END_DEVICE *pDrvCtrl);static u8 ior(DM9000_END_DEVICE *pDrvCtrl, int);static void iow(DM9000_END_DEVICE *pDrvCtrl, int reg, int value);static int dmfe_phy_read(DM9000_END_DEVICE *pDrvCtrl, int phyaddr_unsused, int reg);static void dmfe_phy_write(DM9000_END_DEVICE *pDrvCtrl, int phyaddr_unused, int reg,			   int value);static u16 read_srom_word(DM9000_END_DEVICE *pDrvCtrl, int);static void dmfe_rx(DM9000_END_DEVICE *pDrvCtrl);static void dm9000_hash_table(DM9000_END_DEVICE *pDrvCtrl);LOCAL STATUS dm9000InitParse(DM9000_END_DEVICE * pDrvCtrl,char * initString);LOCAL STATUS dm9000InitMem(DM9000_END_DEVICE * pDrvCtrl);LOCAL void dm9000EnetAddrGet(DM9000_END_DEVICE*pDrvCtrl, char*addr);LOCAL STATUS dm9000PollStart(DM9000_END_DEVICE*	pDrvCtrl);LOCAL STATUS dm9000PollStop(DM9000_END_DEVICE*	pDrvCtrl);static void dmfe_shutdown(DM9000_END_DEVICE *pDrvCtrl);static void dmfe_mx1_ins(u_long ioaddr, u_char * buf, int len);#define DRV_FLAGS_SET(setBits)                                          \    (pDrvCtrl->flags |= (setBits))#define DRV_FLAGS_ISSET(setBits)                                        \    (pDrvCtrl->flags & (setBits))#define DRV_FLAGS_CLR(clrBits)                                          \    (pDrvCtrl->flags &= ~(clrBits))#define DRV_FLAGS_GET()                                                 \    (pDrvCtrl->flags)#define DM9000_IS_IN_POLL_MODE()					\    ((DRV_FLAGS_GET() & NS83902_FLAG_POLL) == DM9000_FLAG_POLL)#define DM9000_SEM_TAKE(pDrvCtrl, timeout)				\    semTake ((pDrvCtrl)->endObj.txSem, timeout)#define DM9000_SEM_GIVE(pDrvCtrl)					\    semGive((pDrvCtrl)->endObj.txSem)/* 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)#define END_FLAGS_ISSET(pEnd, setBits) 					\    ((pEnd)->flags & (setBits))/* network buffers configuration */M_CL_CONFIG dm9000MclBlkConfig = 	/* network mbuf configuration table */    {    /*     no. mBlks	no. clBlks	memArea		memSize    ---------	----------	-------		-------    */    100, 		100, 		NULL, 		0    };CL_DESC dm9000ClDescTbl [] =		/* cluster pool configuration table */    {    /*     clSize	num	memArea		memSize    ------	----	-------		-------    */    {2048,		100,	NULL,		0}    }; int dm9000ClDescTblNumEnt = (NELEMENTS(dm9000ClDescTbl));/* DM9000 network board routine ---------------------------- */LOCAL STATUS dm9000Start    (    DM9000_END_DEVICE *pDrvCtrl    );LOCAL STATUS dm9000Stop    (    DM9000_END_DEVICE* pDrvCtrl    );LOCAL STATUS dm9000Unload    (    DM9000_END_DEVICE* pDrvCtrl    );LOCAL int dm9000Ioctl		(		DM9000_END_DEVICE* pDrvCtrl,		int 		cmd,		caddr_t 	data			);LOCAL STATUS dm9000Send    (    DM9000_END_DEVICE* pDrvCtrl,    M_BLK* pMblk    );LOCAL STATUS dm9000MCastAddrAdd    (    DM9000_END_DEVICE*	pDrvCtrl,    char *		pAddr    );LOCAL STATUS dm9000MCastAddrDel    (    DM9000_END_DEVICE*	pDrvCtrl,    char *		pAddr    );LOCAL STATUS dm9000MCastAddrGet    (    DM9000_END_DEVICE*	pDrvCtrl,    MULTI_TABLE *	pTable    );LOCAL STATUS dm9000PollSend    (    DM9000_END_DEVICE*	pDrvCtrl,    M_BLK*		pMblk    );LOCAL STATUS dm9000PollReceive    (    DM9000_END_DEVICE*	pDrvCtrl,    M_BLK*		pMblk    );LOCAL void dm9000Int    (    DM9000_END_DEVICE*	pDrvCtrl    );/* * Declare our function table.  This is static across all driver * instances. */LOCAL NET_FUNCS dm9000FuncTable =    {    (FUNCPTR)dm9000Start,		/* Function to start the device. */    (FUNCPTR)dm9000Stop,		/* Function to stop the device. */    (FUNCPTR)dm9000Unload,		/* Unloading function */    (FUNCPTR)dm9000Ioctl,		/* Ioctl function */    (FUNCPTR)dm9000Send,		/* Send function */    (FUNCPTR)dm9000MCastAddrAdd,	/* Multicast address add */    (FUNCPTR)dm9000MCastAddrDel,	/* Multicast address delete */    (FUNCPTR)dm9000MCastAddrGet,	/* Multicast table retrieve */    (FUNCPTR)dm9000PollSend,		/* Polling send function  */    (FUNCPTR)dm9000PollReceive,	/* Polling receive function */    endEtherAddressForm,		/* Put address info into a packet.  */    endEtherPacketDataGet,		/* Get a pointer to packet data. */    endEtherPacketAddrGet,		/* Get packet addresses. */    NULL				/* Bind function */    };DM9000_END_DEVICE	*temp;/******************************************************************************** dm9000EndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device-specific parameters are passed in <initString>.* This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "ln") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ* dm9000EndLoad    (    char* initString			/* string to be parsed */    )    {    DM9000_END_DEVICE	*pDrvCtrl;    if (initString == NULL)        return (NULL);	    if (initString[0] == '\0')        {        bcopy((char *)DM9000_DEV_NAME, initString, DM9000_DEV_NAME_LEN);        return (0);        }     /* allocate the device structure */    pDrvCtrl = (DM9000_END_DEVICE *)calloc (sizeof (DM9000_END_DEVICE), 1);    if (pDrvCtrl == NULL)	goto errorExit;    /* parse the init string, filling in the device structure */    if (dm9000InitParse (pDrvCtrl, initString) == ERROR)    	{    	printf("index error.\n\r");	goto errorExit;    	}     /* Have the BSP hand us our address. *//*	pDrvCtrl->enetAddr[0] = 0x00;	pDrvCtrl->enetAddr[1] = 0x00;	pDrvCtrl->enetAddr[2] = 0x3e;	pDrvCtrl->enetAddr[3] = 0x26;	pDrvCtrl->enetAddr[4] = 0x0a;	pDrvCtrl->enetAddr[5] = 0x00;*/    dm9000EnetAddrGet (pDrvCtrl, (char*) &(pDrvCtrl->enetAddr));/*     printf ( "ENET Addr: %x:%x:%x:%x:%x:%x \n",             pDrvCtrl->enetAddr[0], pDrvCtrl->enetAddr[1], 	     pDrvCtrl->enetAddr[2], pDrvCtrl->enetAddr[3], 	     pDrvCtrl->enetAddr[4], pDrvCtrl->enetAddr[5]);*/    /* initialize the END and MIB2 parts of the structure */    if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, DM9000_DEV_NAME,		    pDrvCtrl->unit, &dm9000FuncTable,                      "dm9000 Network Driver") == ERROR     || END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd,                      &pDrvCtrl->enetAddr[0], DM9000_EADR_LEN, ETHERMTU,                      DM9000_SPEED)		    == ERROR)	goto errorExit;    /* Perform memory allocation */    if (dm9000InitMem (pDrvCtrl) == ERROR)	{	goto errorExit;	}    /* set the flags to indicate readiness */    END_OBJ_READY (&pDrvCtrl->endObj,                   IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);    /* save the device address */    dmfe_probe(pDrvCtrl);    temp = pDrvCtrl;#if 1      return (&pDrvCtrl->endObj);errorExit:    dm9000Unload (pDrvCtrl);    return NULL;	#endif    }/********************************************************************************* ns83902InitParse - parse the initialization string** Parse the input string and fill in values in the driver control structure.** RETURNS: OK, or ERROR if any arguments are invalid.*/LOCAL STATUS dm9000InitParse    (    DM9000_END_DEVICE * pDrvCtrl,    char * initString    )    {    char *	tok;    char *	pHolder = NULL;        /* Parse the initString */    /* Unit number. */    tok = strtok_r (initString, ":", &pHolder);    if (tok == NULL)	return ERROR;    pDrvCtrl->unit = atoi (tok);    return OK;    }/********************************************************************************* ns83902InitMem - initialize memory for NIC chip** Using data in the control structure, setup and initialize the memory* areas needed.  If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/LOCAL STATUS dm9000InitMem    (    DM9000_END_DEVICE * pDrvCtrl		/* device to be initialized */    )    {    /* allocate netpool */    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)        return (ERROR);    /* Set number of M-Blks and CL-Blks*/    /* Calculate the total memory for all the M-Blks and CL-Blks. */    dm9000MclBlkConfig.memSize = dm9000MclBlkConfig.mBlkNum * 				   (MSIZE + sizeof (long)) +				  dm9000MclBlkConfig.clBlkNum * 				   (CL_BLK_SZ + sizeof(long));    /* allocate memory for M-Blks and CL-Blks */    dm9000MclBlkConfig.memArea	= (char *) memalign (sizeof(long),				   dm9000MclBlkConfig.memSize);    if (dm9000MclBlkConfig.memArea == NULL)	return (ERROR);        /* Calculate the memory size of all the clusters. */    dm9000ClDescTbl[0].memSize = sizeof(long) + dm9000ClDescTbl[0].clNum * 				  (dm9000ClDescTbl[0].clSize + 8);    /* Allocate memory for clusters */    dm9000ClDescTbl[0].memArea = (char *) memalign (sizeof(long),				   dm9000ClDescTbl[0].memSize);       if (dm9000ClDescTbl[0].memArea == NULL)	{		return (ERROR);	}    /* Save clusters start address for later use */    /* Initialize the net buffer pool with buffers */    if (netPoolInit (pDrvCtrl->endObj.pNetPool, &dm9000MclBlkConfig, 		     &dm9000ClDescTbl[0], dm9000ClDescTblNumEnt, NULL) == ERROR)	{	return (ERROR);	}        /* Store the cluster pool id as others need it later. */    pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool, 					  dm9000ClDescTbl[0].clSize, FALSE);    if (pDrvCtrl->pClPoolId  == NULL)	return (ERROR);    return (OK);    }/********************************************************************************* ns83902EnetAddrGet - get the Ethernet address.** Get ethernet address from the BSP.** RETURNS: N/A.*/LOCAL void dm9000EnetAddrGet    (    DM9000_END_DEVICE*	pDrvCtrl,     char*		addr    )    {#if _BYTE_ORDER == _BIG_ENDIAN    /* For big endian we need to swap byte order */    int			i;    char 		bytes[6];    SYS_ENET_ADDR_GET (pDrvCtrl, bytes);    for (i=0; i<6; i++)	*addr++ = bytes[5-i];#else  /* _BYTE_ORDER == _LITTLE_ENDIAN  */    /* Little endian is in correct order */    SYS_ENET_ADDR_GET (pDrvCtrl, addr);#endif /* _BYTE_ORDER == _BIG_ENDIAN */    }/********************************************************************************* ns83902Start - start the device

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -