📄 secend.c
字号:
/* secEnd.c - END style SAMSUNG S3C2500 Ethernet network interface driver */
/* Copyright 2002 SAMSUNG ELECTRONICS */
/*
modification history
--------------------
01a,08feb02,jmLee created.
*/
#include "vxWorks.h"
#include "intLib.h"
#include "errno.h"
#include "net/mbuf.h"
#include "net/unixLib.h"
#include "net/protosw.h"
#include "sys/socket.h"
#include "sys/ioctl.h"
#include "net/route.h"
#include "cacheLib.h"
#include "logLib.h"
#include "netLib.h"
#include "stdio.h"
#include "stdlib.h"
#include "sysLib.h"
#include "taskLib.h"
#include "net/systm.h"
#include "sys/times.h"
#include "net/if_subr.h"
#undef ETHER_MAP_IP_MULTICAST
#include "etherMultiLib.h"
#include "end.h"
#include "semLib.h"
#define END_MACROS
#include "endLib.h"
#include "miiLib.h"
#include "lstLib.h"
#include "config.h"
#include "drv/end/secEnd.h"
/* Defines */
#undef DEBUG_TRACE
#define DEBUG_LOG(x, p1, p2, p3, p4, p5, p6) \
logMsg(x, (int)(UINT32)(p1), (int)(UINT32)(p2), (int)(UINT32)(p3), (int)(UINT32)(p4), (int)(UINT32)(p5), (int)(UINT32)(p6))
/* Forward Function Declarations */
LOCAL STATUS secEndInitParse(DRV_CTRL *pDrvCtrl, char *initString);
LOCAL STATUS secEndInitMem(DRV_CTRL *pDrvCtrl);
LOCAL STATUS secEndUnload(DRV_CTRL *pDrvCtrl);
LOCAL STATUS secEndStart(DRV_CTRL *pDrvCtrl);
LOCAL STATUS secEndStop(DRV_CTRL *pDrvCtrl);
LOCAL STATUS secEndUnload(DRV_CTRL *pDrvCtrl);
LOCAL int secEndIoctl(DRV_CTRL *pDrvCtrl, int cmd, caddr_t data);
LOCAL STATUS secEndSend(DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
LOCAL STATUS secEndMCastAddrAdd(DRV_CTRL *pDrvCtrl, UCHAR *pAddr);
LOCAL STATUS secEndMCastAddrDel(DRV_CTRL *pDrvCtrl, UCHAR *pAddr);
LOCAL STATUS secEndMCastAddrGet(DRV_CTRL *pDrvCtrl, MULTI_TABLE *pTable);
LOCAL STATUS secEndPollSend(DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
LOCAL STATUS secEndPollReceive(DRV_CTRL *pDrvCtrl, M_BLK_ID pMblk);
/* Declare our function table. This is static across all driver instances. */
LOCAL NET_FUNCS endFuncTable = {
(FUNCPTR)secEndStart, /* start func. */
(FUNCPTR)secEndStop, /* stop func. */
(FUNCPTR)secEndUnload, /* unload func. */
(FUNCPTR)secEndIoctl, /* ioctl func. */
(FUNCPTR)secEndSend, /* send func. */
(FUNCPTR)secEndMCastAddrAdd, /* multicast add func. */
(FUNCPTR)secEndMCastAddrDel, /* multicast delete func. */
(FUNCPTR)secEndMCastAddrGet, /* multicast get fun. */
(FUNCPTR)secEndPollSend, /* polling send func. */
(FUNCPTR)secEndPollReceive, /* polling receive func. */
endEtherAddressForm, /* put address info into a NET_BUFFER */
(FUNCPTR)endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
(FUNCPTR)endEtherPacketAddrGet /* Get packet addresses */
};
/*******************************************************************************
*
* secEndLoad - 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 the initString.
*
* The string contains the target specific parameters like this:
*
* "unit number:"
*
* RETURNS: An END object pointer or NULL on error.
*/
END_OBJ* secEndLoad(
char *initString /* parameter string */
)
{
DRV_CTRL *pDrvCtrl; /* pointer to DRV_CTRL structure */
UCHAR enetAddr[SEC_END_ADDR_LEN]; /* ethernet address */
#ifdef DEBUG_TRACE
printf("secEnd Load, %s\n", initString);
#endif /* DEBUG_TRACE */
if (initString == NULL)
{
printf("secEnd Error: NULL parameter string\n");
return NULL;
}
if (initString[0] == 0)
{
bcopy((char *)SEC_END_DEV_NAME, (char *)initString, SEC_END_DEV_NAME_LEN);
#ifdef DEBUG_TRACE
printf("secEnd Load, %s\n", initString);
#endif /* DEBUG_TRACE */
return NULL;
}
/* Allocate the device structure. */
pDrvCtrl = (DRV_CTRL *)calloc(sizeof(DRV_CTRL), 1);
if (pDrvCtrl == NULL)
{
printf("secEnd Error: Failed to allocate DRV_CTRL\n");
return (NULL);
}
while (1)
{
/* Parse InitString. */
if (secEndInitParse(pDrvCtrl, initString) != OK)
{
break;
}
/* Memory initialization. */
if (secEndInitMem(pDrvCtrl) != OK)
{
break;
}
/* Initialize physical device. */
if (DRV_INIT(pDrvCtrl) != OK)
{
break;
}
/* Initialize END object. */
if (END_OBJ_INIT(
&pDrvCtrl->endObj,
(DEV_OBJ *)pDrvCtrl,
SEC_END_DEV_NAME,
pDrvCtrl->unit,
&endFuncTable,
SEC_END_DEV_DESCRIPTION
) == ERROR)
{
printf("secEnd%d Error: Failed to initialize END_OBJ\n", pDrvCtrl->unit);
break;
}
/* Get ethernet hardware address. */
sysSecEnetAddrGet(pDrvCtrl->unit, enetAddr);
/* Initialize MIB. */
if (END_MIB_INIT(
&pDrvCtrl->endObj,
M2_ifType_ethernet_csmacd,
enetAddr,
SEC_END_ADDR_LEN,
ETHERMTU,
pDrvCtrl->phyInfo.phySpeed
) == ERROR)
{
printf("secEnd%d Error: Failed to initialize END_MIB\n", pDrvCtrl->unit);
break;
}
/* Mark the device ready. */
END_OBJ_READY(&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST);
return (&pDrvCtrl->endObj);
}
secEndUnload(pDrvCtrl);
return NULL;
}
/******************************************************************************
*
* secEndUnload - unload a driver from the system
*
* This function first brings down the device, and then frees any stuff that was
* allocated by the driver in the load function.
*
* RETURNS: OK or ERROR.
*/
STATUS secEndUnload(
DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */
)
{
#ifdef DEBUG_TRACE
printf("secEnd%d Unload\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
if (pDrvCtrl == NULL)
{
return ERROR;
}
/* Uninitialize END object. */
END_OBJ_UNLOAD(&pDrvCtrl->endObj);
/* Free buffer descriptor pool if necessary. */
if (pDrvCtrl->pBdArea != NULL)
{
cacheDmaFree(pDrvCtrl->pBdArea);
}
/* Free cluster pool if necessary. */
if (pDrvCtrl->pClArea != NULL)
{
free(pDrvCtrl->pClArea);
}
/* Free mBlk/clBlk pool if necessary. */
if (pDrvCtrl->pMblkArea != NULL)
{
free(pDrvCtrl->pMblkArea);
}
/* Free netPool if necessary. */
if (pDrvCtrl->endObj.pNetPool != NULL)
{
free(pDrvCtrl->endObj.pNetPool);
}
/* Free the device structure. */
cfree((char *)pDrvCtrl);
return OK;
}
/*******************************************************************************
*
* secEndStart - start the device
*
* This function calls BSP functions to connect interrupts and start the device
* running in interrupt mode.
*
* RETURNS: OK or ERROR
*
*/
LOCAL STATUS secEndStart(
DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */
)
{
#ifdef DEBUG_TRACE
printf("secEnd%d Start\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
/* Mark the interface as up. */
END_FLAGS_SET(&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
return DRV_START(pDrvCtrl);
}
/*******************************************************************************
*
* secEndStop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop the device
* from operating in interrupt mode.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS secEndStop(
DRV_CTRL *pDrvCtrl /* pointer to DRV_CTRL structure */
)
{
#ifdef DEBUG_TRACE
printf("secEnd%d Stop\n", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
/* Mark the interface as down. */
END_FLAGS_CLR(&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));
return DRV_STOP(pDrvCtrl);
}
/*******************************************************************************
*
* secEndIoctl - the driver I/O control routine
*
* Process an ioctl request.
*
* RETURNS: A command specific response, usually OK or ERROR.
*/
LOCAL int secEndIoctl(
DRV_CTRL *pDrvCtrl, /* pointer to DRV_CTRL structure */
int cmd, /* command to process */
caddr_t data /* pointer to data */
)
{
int error = OK;
END_OBJ *pEndObj = &pDrvCtrl->endObj;
long value;
#ifdef DEBUG_TRACE
printf("secEnd%d Ioctl: ", pDrvCtrl->unit);
#endif /* DEBUG_TRACE */
switch (cmd)
{
case EIOCSADDR:
#ifdef DEBUG_TRACE
printf("EIOCSADDR\n");
#endif /* DEBUG_TRACE */
/* Stop the device. */
DRV_STOP(pDrvCtrl);
/* Save the enet address. */
bcopy ((char *)data, END_HADDR(pEndObj), SEC_END_ADDR_LEN);
/* Program the individual enet address. */
error = DRV_ADDR_SET(pDrvCtrl);
/* Restart the device. */
DRV_START(pDrvCtrl);
break;
case EIOCGADDR:
#ifdef DEBUG_TRACE
printf("EIOCGADDR\n");
#endif /* DEBUG_TRACE */
/* Retrieve the enet address. */
bcopy (END_HADDR(pEndObj), (char *)data, SEC_END_ADDR_LEN);
break;
case EIOCSFLAGS:
#ifdef DEBUG_TRACE
printf("EIOCSFLAGS\n");
#endif /* DEBUG_TRACE */
value = (long)data;
if (value < 0)
{
value = -value;
value--;
END_FLAGS_CLR(pEndObj, value);
}
else
{
END_FLAGS_SET(pEndObj, value);
}
/* Set device flags. */
error = DRV_FLAGS_SET(pDrvCtrl);
break;
case EIOCGFLAGS:
#ifdef DEBUG_TRACE
printf("EIOCGFLAGS\n");
#endif /* DEBUG_TRACE */
/* Get device flags. */
*(long *)data = END_FLAGS_GET(pEndObj);
break;
case EIOCMULTIADD:
#ifdef DEBUG_TRACE
printf("EIOCMULTIADD\n");
#endif /* DEBUG_TRACE */
/* Add multicast address. */
error = secEndMCastAddrAdd(pDrvCtrl, (UCHAR *)data);
break;
case EIOCMULTIDEL:
#ifdef DEBUG_TRACE
printf("EIOCMULTIDEL\n");
#endif /* DEBUG_TRACE */
/* Delete multicast address. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -