📄 rtl81x9.c
字号:
}
#endif /* SYS_IN_SHORT*/
#ifndef SYS_OUT_BYTE
#define SYS_OUT_BYTE(pDrvCtrl,addr,value) \
{ \
*((UCHAR *)(addr)) = (value); \
}
#endif /* SYS_OUT_BYTE */
#ifndef SYS_IN_BYTE
#define SYS_IN_BYTE(pDrvCtrl,addr,data) \
{ \
((data) = *((UCHAR *)(addr))); \
}
#endif /* SYS_IN_BYTE */
#ifndef SYS_OUT_SHORT_CSR
#define SYS_OUT_SHORT_CSR(pDrvCtrl,addr,value) \
{ \
*(USHORT *)addr = value; \
}
#endif /*SYS_OUT_SHORT_CSR*/
#ifndef SYS_IN_SHORT_CSR
#define SYS_IN_SHORT_CSR(pDrvCtrl,addr,pData) \
(*(USHORT *)pData = *(USHORT *)addr)
#endif /*SYS_IN_SHORT_CSR*/
#define SYS_DELAY(count) { \
volatile int cx = 0; \
for (cx = 0; cx < (count); cx++); \
}
#ifndef SYS_ENET_ADDR_GET
#define SYS_ENET_ADDR_GET(pDrvCtrl, pAddress) \
{ \
IMPORT STATUS sysRtl81x9EnetAddrGet (RTL81X9END_DEVICE *pDrvCtrl, \
char * enetAdrs); \
sysRtl81x9EnetAddrGet (pDrvCtrl, pAddress); \
}
#endif /* SYS_ENET_ADDR_GET */
/* Cache macros */
#define RTL_CACHE_INVALIDATE(address, len) \
CACHE_DRV_INVALIDATE (&pDrvCtrl->cacheFuncs, (address), (len))
#define RTL_CACHE_VIRT_TO_PHYS(address) \
CACHE_DRV_VIRT_TO_PHYS (&pDrvCtrl->cacheFuncs, (address))
/*
* MII access routines are provided for the 8129, which
* doesn't have a built-in PHY. For the 8139, we fake things
* up by diverting rl_phy_readreg()/rl_phy_writereg() to the
* direct access PHY registers.
*/
#define MII_SET(x) \
rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII, \
rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) | x, RTL_WIN_0 )
#define MII_CLR(x) \
rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_MII, \
rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_MII, RTL_WIN_0) & ~x, RTL_WIN_0 )
/* EEPROM Macros */
#define EE_SET(x) \
rtl81x9CsrWriteByte (pDrvCtrl, RTL_REGS_CFG_9346, \
rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) | x, RTL_WIN_0)
#define EE_CLR(x) \
rtl81x9CsrWriteByte(pDrvCtrl, RTL_REGS_CFG_9346, \
rtl81x9CsrReadByte(pDrvCtrl, RTL_REGS_CFG_9346, RTL_WIN_0) & ~x, RTL_WIN_0)
/***** LOCALS *****/
LOCAL int rtlRsize = RTL_RMD_RLEN; /* recv ring size */
/* forward static functions */
LOCAL STATUS rtl81x9Reset ();
LOCAL void rtl81x9Int (RTL81X9END_DEVICE *);
LOCAL void rtl81x9HandleRecvInt(RTL81X9END_DEVICE *);
LOCAL void rtl81x9HandleTxInt (RTL81X9END_DEVICE *);
LOCAL void rtl81x9Restart (RTL81X9END_DEVICE *);
LOCAL STATUS rtl81x9RestartSetup (RTL81X9END_DEVICE *);
LOCAL void rtl81x9Config (RTL81X9END_DEVICE *);
LOCAL void rtl81x9AddrFilterSet(RTL81X9END_DEVICE *);
/* END Specific interfaces. */
/* This is the only externally visible interface. */
END_OBJ * rtl81x9EndLoad (char *initString);
LOCAL STATUS rtl81x9Start (RTL81X9END_DEVICE *);
LOCAL STATUS rtl81x9Stop (RTL81X9END_DEVICE *);
LOCAL STATUS rtl81x9Unload (RTL81X9END_DEVICE *);
LOCAL int rtl81x9Ioctl (RTL81X9END_DEVICE *, int, caddr_t);
LOCAL STATUS rtl81x9Send (RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS rtl81x9MCastAddrAdd (RTL81X9END_DEVICE *, char *);
LOCAL STATUS rtl81x9MCastAddrDel (RTL81X9END_DEVICE *, char *);
LOCAL STATUS rtl81x9MCastAddrGet (RTL81X9END_DEVICE *, MULTI_TABLE *);
LOCAL STATUS rtl81x9PollSend (RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS rtl81x9PollReceive (RTL81X9END_DEVICE *, M_BLK *);
LOCAL STATUS rtl81x9PollStart (RTL81X9END_DEVICE *);
LOCAL STATUS rtl81x9PollStop (RTL81X9END_DEVICE *);
LOCAL STATUS rtl81x9InitParse (RTL81X9END_DEVICE *, char *);
LOCAL STATUS rtl81x9InitMem (RTL81X9END_DEVICE *);
LOCAL void rtl81x9LowPowerMode (RTL81X9END_DEVICE *);
LOCAL UCHAR rtl81x9CsrReadByte (RTL81X9END_DEVICE *, USHORT, int);
LOCAL USHORT rtl81x9CsrReadWord (RTL81X9END_DEVICE *, USHORT, int);
LOCAL ULONG rtl81x9CsrReadLong (RTL81X9END_DEVICE *, USHORT, int);
LOCAL void rtl81x9CsrWriteByte (RTL81X9END_DEVICE *, USHORT, UCHAR, int);
LOCAL void rtl81x9CsrWriteWord (RTL81X9END_DEVICE *, USHORT, USHORT, int);
LOCAL void rtl81x9CsrWriteLong (RTL81X9END_DEVICE *, USHORT, ULONG, int);
LOCAL void rtl81x9ReadEEPROM (RTL81X9END_DEVICE *, UCHAR *, ULONG, ULONG, ULONG);
LOCAL void rtl81x9EEPROMPutByte(RTL81X9END_DEVICE *, ULONG);
LOCAL void rtl81x9EEPROMGetWord(RTL81X9END_DEVICE *, ULONG, USHORT*);
LOCAL void rtl81x9Phy_writereg (RTL81X9END_DEVICE *, int, int);
LOCAL USHORT rtl81x9Phy_readreg (RTL81X9END_DEVICE *, int);
LOCAL int rtl81x9MII_writereg (RTL81X9END_DEVICE *, RTL_MII_FRAME *);
LOCAL void rtl81x9MII_sync (RTL81X9END_DEVICE *);
LOCAL void rtl81x9MII_send (RTL81X9END_DEVICE *, ULONG, int);
LOCAL int rtl81x9MII_readreg (RTL81X9END_DEVICE *, RTL_MII_FRAME *);
LOCAL void rtl81x9AutoNegTx (RTL81X9END_DEVICE *);
LOCAL int rtl81x9MII_autoneg (RTL81X9END_DEVICE *);
LOCAL int rtl81x9MediaSet (RTL81X9END_DEVICE *, int);
LOCAL int rtl81x9MediaConfig (RTL81X9END_DEVICE *);
void eepromInit(RTL81X9END_DEVICE *pDrvCtrl);
/*
* Define the device function table. This is static across all driver
* instances.
*/
LOCAL NET_FUNCS rtlFuncTable =
{
(FUNCPTR)rtl81x9Start, /* start func. */
(FUNCPTR)rtl81x9Stop, /* stop func. */
(FUNCPTR)rtl81x9Unload, /* unload func. */
(FUNCPTR)rtl81x9Ioctl, /* ioctl func. */
(FUNCPTR)rtl81x9Send, /* send func. */
(FUNCPTR)rtl81x9MCastAddrAdd, /* multicast add func. */
(FUNCPTR)rtl81x9MCastAddrDel, /* multicast delete func. */
(FUNCPTR)rtl81x9MCastAddrGet, /* multicast get fun. */
(FUNCPTR)rtl81x9PollSend, /* polling send func. */
(FUNCPTR)rtl81x9PollReceive, /* polling receive func. */
endEtherAddressForm, /* put address info into a NET_BUFFER */
endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */
endEtherPacketAddrGet /* Get packet addresses. */
};
/*数据接收任务0*/
void rtlRecvTask0(RTL81X9END_DEVICE * pDrvCtrl)
{
FOREVER
{
/* wait for somebody to wake us up */
semTake (rtlNetTaskSemId0, WAIT_FOREVER);
rtl81x9HandleRecvInt(pDrvCtrl);
}
}
/*数据接收任务1*/
void rtlRecvTask1(RTL81X9END_DEVICE * pDrvCtrl)
{
FOREVER
{
/* wait for somebody to wake us up */
semTake (rtlNetTaskSemId1, WAIT_FOREVER);
rtl81x9HandleRecvInt(pDrvCtrl);
}
}
void rtl8139IntTimer(RTL81X9END_DEVICE *pDrvCtrl)
{
unsigned long oldLev;
while(1)
{
oldLev = intLock();
if(pDrvCtrl->freeDesc<=0)
{
if(netJobAdd ((FUNCPTR)rtl81x9HandleTxInt, (int) pDrvCtrl,
0, 0, 0, 0) != OK)
{
logMsg("netJobAdd:rtl8139IntTimer error!\n",0,0,0,0,0,0);
}
}
intUnlock(oldLev);
taskDelay(20);
}
}
void addTimer(RTL81X9END_DEVICE *pDrvCtrl)
{
/*clockid_tint CLOCK_REALTIME;*/
timer_t mytimer;
int value = 200;
WDOG_ID WdId1;
WdId1 = wdCreate();
wdStart(WdId1 , 20, (FUNCPTR)rtl8139IntTimer, pDrvCtrl);
#if 0
if(timer_create(CLOCK_REALTIME,0,&mytimer)==ERROR)
{
return (ERROR);
}
if(timer_connect(mytimer,(VOIDFUNCPTR)rtl8139IntTimer,pDrvCtrl)==ERROR)
{
return (ERROR);
}
if(timer_settime(mytimer,0,&value,0)==ERROR)
{
return (ERROR);
}
#endif
}
/*******************************************************************************
*
* rtl81x9EndLoad - 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>, which
* expects a string of the following format:
*
* <unit>:<CSR_reg_addr>:<RAP_reg_addr>:<int_vector>:<int_level>:<shmem_addr>:
* <shmem_size>:<shmem_width>
*
* 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, "rtl") 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* rtl81x9EndLoad
(
char* initString /* string to be parse by the driver */
)
{
RTL81X9END_DEVICE *pDrvCtrl;
USHORT rtl_dev_id = 0;
int speed;
int i;
DRV_LOG (DRV_DEBUG_LOAD, "Loading rtl...\n", 1, 2, 3, 4, 5, 6);
if (initString == NULL)
return (NULL);
if (initString[0] == NULL)
{
bcopy((char *)RTL_DEV_NAME, initString, RTL_DEV_NAME_LEN);
return (0);
}
/* allocate the device structure */
pDrvCtrl = (RTL81X9END_DEVICE *)calloc (sizeof (RTL81X9END_DEVICE), 1);
if (pDrvCtrl == NULL)
goto errorExit;
/* parse the init string, filling in the device structure */
if (rtl81x9InitParse (pDrvCtrl, initString) == ERROR)
goto errorExit;
/* Reset the adaptor */
rtl81x9Reset (pDrvCtrl);
#if 0
eepromInit(pDrvCtrl);/*初始化EEPROM*/
/* Read the station address */
for (i=0; i < 6; i++)
{
pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
}
#endif
#if 1/*没有EEPROM*/
if(pDrvCtrl->unit== 0)
{
rtl81x9CsrWriteByte(pDrvCtrl,0x50,0xc0,0);
rtl81x9CsrWriteByte(pDrvCtrl,0x52,0x7f,0);
rtl81x9CsrWriteWord(pDrvCtrl,0,0xe000,0);
rtl81x9CsrWriteWord(pDrvCtrl,2,0xaa4d,0);
rtl81x9CsrWriteWord(pDrvCtrl,4,0x60bb,0);
for (i=0; i < 6; i++)
{
pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
}
/*
pDrvCtrl->enetAddr[0] = 0;
pDrvCtrl->enetAddr[1] = 0x08;
pDrvCtrl->enetAddr[2] = 0x00;
pDrvCtrl->enetAddr[3] = 0x00;
pDrvCtrl->enetAddr[4] = 0x08;
pDrvCtrl->enetAddr[5] = 0x00;
*/
}
else
{
rtl81x9CsrWriteByte(pDrvCtrl,0x50,0xc0,0);
rtl81x9CsrWriteWord(pDrvCtrl,0,0xe000,0);
rtl81x9CsrWriteWord(pDrvCtrl,2,0xaa4d,0);
rtl81x9CsrWriteWord(pDrvCtrl,4,0x58bb,0);
for (i=0; i < 6; i++)
{
pDrvCtrl->enetAddr[i] = rtl81x9CsrReadByte (pDrvCtrl, RTL_REGS_IDR0 + i, RTL_WIN_0);
}
}
#endif
/*
* Now read the exact device type from the EEPROM to find
* out if it's an 8129 or 8139.
*/
rtl81x9ReadEEPROM (pDrvCtrl, (UCHAR *) &rtl_dev_id, RTL_EE_PCI_DID, 1, 0);
DRV_LOG (DRV_DEBUG_LOAD, "rtl_dev_id= 0x%x\n", rtl_dev_id, 2, 3, 4, 5, 6);
rtl_dev_id = 0x8139;
/* Perform memory allocation */
if (rtl81x9InitMem (pDrvCtrl) == ERROR)
goto errorExit;
if (rtl_dev_id == RTL_DEVICEID_8139 || rtl_dev_id == ACCTON_DEVICEID_5030 ||
rtl_dev_id == DELTA_DEVICEID_8139 || rtl_dev_id == ADDTRON_DEVICEID_8139)
{
if ((rtl81x9CsrReadLong (pDrvCtrl, RTL_REGS_TX_CONFIG, NONE) & RTL_TXCG_BLID))/*vicadd*/
pDrvCtrl->devType = RTL_DEV_8139A;
else
pDrvCtrl->devType = RTL_DEV_8139B;
}
else if (rtl_dev_id == RTL_DEVICEID_8129)
pDrvCtrl->devType = RTL_DEV_8129;
else {
DRV_LOG (DRV_DEBUG_LOAD, "rtl: unknown device ID: %x\n", rtl_dev_id, 2, 3, 4, 5, 6);
goto errorExit;
}
/*speed = rtl81x9MediaConfig (pDrvCtrl);*/
speed = 100000000;
pDrvCtrl->nextDesc = 0;
pDrvCtrl->freeDesc = RTL_NUM_TX_DESC;
for (i=0; i < RTL_NUM_TX_DESC; i++)
pDrvCtrl->pDescMem[i] = NULL;
/* Perform memory distribution and reset and reconfigure the device */
if (rtl81x9RestartSetup (pDrvCtrl) == ERROR)
goto errorExit;
/* initialize the END and MIB2 parts of the structure */
if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, RTL_DEV_NAME,
pDrvCtrl->unit, &rtlFuncTable,
"RTL 81x9 Fast Ethernet Enhanced Network Driver") == ERROR
|| END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd,
&pDrvCtrl->enetAddr[0], 6, ETHERMTU,
speed)
== ERROR)
goto errorExit;
/* set the flags to indicate readiness */
END_OBJ_READY (&pDrvCtrl->end,
IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
| IFF_MULTICAST | IFF_SIMPLEX);
DRV_LOG (DRV_DEBUG_LOAD, ("rtl81x9EndLoad...\n
ADRR: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n "),
pDrvCtrl->enetAddr[0],
pDrvCtrl->enetAddr[1],
pDrvCtrl->enetAddr[2],
pDrvCtrl->enetAddr[3],
pDrvCtrl->enetAddr[4],
pDrvCtrl->enetAddr[5]);
DRV_LOG (DRV_DEBUG_LOAD, "Done loading rtl...\n", 1, 2, 3, 4, 5, 6);
return (&pDrvCtrl->end);
errorExit:
if (pDrvCtrl != NULL)
free ((char *)pDrvCtrl);
return NULL;
}
/*******************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -