📄 ln97xend.c
字号:
SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, PCI_SWAP (value));
CACHE_PIPE_FLUSH ();
intUnlock (level);
}
/*******************************************************************************
*
* ln97xCsrRead - select and read a CSR register
*
* This routine selects a register to read, through the RAP register and
* then reads the CSR value from the RDP register.
*
* RETURNS: N/A
*/
LOCAL UINT32 ln97xCsrRead
(
LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */
int reg /* register to select */
)
{
int level;
UINT32 result;
level = intLock ();
SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));
CACHE_PIPE_FLUSH ();
SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result);
intUnlock (level);
return (PCI_SWAP (result) & 0x0000FFFF);
}
/*******************************************************************************
*
* ln97xBcrWrite - select and write a BCR register
*
* This routine writes the bus configuration register. It first selects the
* BCR register to write through the RAP register and then it writes the value
* to the BDP register.
*
* RETURNS: N/A
*/
LOCAL void ln97xBcrWrite
(
LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */
int reg, /* BCR register to select */
UINT32 value /* BCR value to write */
)
{
int level;
reg &= 0xff;
value &=0xffff;
level = intLock ();
SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP(reg));
CACHE_PIPE_FLUSH ();
SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pBdp, PCI_SWAP(value));
intUnlock (level);
}
/*******************************************************************************
*
* ln97xBcrRead - select and read a BCR register
*
* This routine reads the bus configuration register. It first selects the
* BCR register to read through the RAP register and then it reads the value
* from the BDP register.
*
* RETURNS: N/A
*/
LOCAL UINT32 ln97xBcrRead
(
LN_97X_DRV_CTRL * pDrvCtrl, /* driver control */
int reg /* register to select */
)
{
int level;
UINT32 result;
level = intLock ();
SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg));
SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pBdp, result);
intUnlock (level);
return (PCI_SWAP (result) & 0x0000FFFF);
}
/*******************************************************************************
*
* ln97xRestartSetup - setup memory descriptors and turn on chip
*
* This routine initializes all the shared memory structures and turns on
* the chip.
*
* RETURNS OK/ERROR
*/
LOCAL STATUS ln97xRestartSetup
(
LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
int rsize; /* recv ring length */
int tsize; /* xmit ring length */
LN_TMD * pTmd;
/* reset the device */
ln97xReset (pDrvCtrl);
/* setup Rx buffer descriptors - align on 000 boundary */
rsize = pDrvCtrl->rringLen;
/*
* setup Tx buffer descriptors -
* save unaligned location and align on 000 boundary
*/
pTmd = pDrvCtrl->pTring;
tsize = pDrvCtrl->tringLen;
/* setup the initialization block */
pDrvCtrl->ib = (LN_IB *)pDrvCtrl->pShMem;
DRV_LOG (DRV_DEBUG_LOAD, "Init block @ 0x%X\n",
(int)(pDrvCtrl->ib), 2, 3, 4, 5, 6);
bcopy ((char *) END_HADDR(&pDrvCtrl->endObj), pDrvCtrl->ib->lnIBPadr, 6);
CACHE_PIPE_FLUSH ();
/* point to Rx ring */
LN_ADDR_TO_IB_RMD (pDrvCtrl->pRring, pDrvCtrl->ib, rsize);
/* point to Tx ring */
LN_ADDR_TO_IB_TMD (pDrvCtrl->pTring, pDrvCtrl->ib, tsize);
DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);
/* reconfigure the device */
ln97xConfig (pDrvCtrl);
return (OK);
}
/*******************************************************************************
*
* ln97xRestart - restart the device after a fatal error
*
* This routine takes care of all the messy details of a restart. The device
* is reset and re-initialized. The driver state is re-synchronized.
*
* RETURNS: N/A
*/
LOCAL void ln97xRestart
(
LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
ln97xReset (pDrvCtrl);
ln97xRestartSetup (pDrvCtrl);
/* set the flags to indicate readiness */
END_OBJ_READY (&pDrvCtrl->endObj,
IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST
| IFF_MULTICAST);
}
/******************************************************************************
*
* ln97xConfig - reconfigure the interface under us.
*
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A
*/
LOCAL void ln97xConfig
(
LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
UINT16 stat;
void * pTemp;
LN_RMD * pRmd;
LN_TMD * pTmd;
int ix;
int timeoutCount = 0;
UINT32 dataTemp;
/*UINT32 tCSRValue[126]; */
/************************************/
/* Set promiscuous mode if it's asked for. */
if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_PROMISC)
{
DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode on!\n",
1, 2, 3, 4, 5, 6);
/* chip will be in promiscuous mode */
pDrvCtrl->ib->lnIBMode |= 0x00800000;
}
else
{
DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\n",
1, 2, 3, 4, 5, 6);
}
dataTemp = PCI_SWAP (pDrvCtrl->ib->lnIBMode);
dataTemp |= 0x00000180;
pDrvCtrl->ib->lnIBMode = PCI_SWAP (dataTemp);
/**********************************/
CACHE_PIPE_FLUSH ();
ln97xCsrWrite (pDrvCtrl, 0, CSR0_STOP); /* set the stop bit */
/* Set up address filter for multicasting. */
if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0)
{
ln97xAddrFilterSet (pDrvCtrl);
}
/* set the bus mode to little endian */
ln97xCsrWrite (pDrvCtrl, 3, pDrvCtrl->csr3B);
/* set the Bus Timeout to a long time */
/* This allows other stuff to hog the bus a bit more */
ln97xCsrWrite (pDrvCtrl, 100, BUS_LATENCY_COUNT );
ln97xBcrWrite (pDrvCtrl, BCR(22), (MAX_LAT_COUNT<<8) | MIN_GNT_COUNT);
ln97xCsrWrite(pDrvCtrl, CSR(80), (CSR80_RCVFW<<12)|(CSR80_XMSTP<<10)|(CSR80_XMTFW<<8));
dataTemp = ln97xBcrRead(pDrvCtrl, BCR(18));
dataTemp |=(BCR18_BREADE| BCR18_BWRITE |BCR18_MEMCMD);
ln97xBcrWrite (pDrvCtrl, BCR(18), dataTemp);
/***************************************/
/* Setup LED controls */
dataTemp = ln97xBcrRead (pDrvCtrl, BCR(2));
dataTemp = dataTemp & 0xff7f;
ln97xBcrWrite (pDrvCtrl, BCR(2), (dataTemp |BCR2_LEDPE));
ln97xBcrWrite (pDrvCtrl, BCR(4), 0x00c0);
ln97xBcrWrite (pDrvCtrl, BCR(5), 0x0084);
ln97xBcrWrite (pDrvCtrl, BCR(6), 0x1088);
ln97xBcrWrite (pDrvCtrl, BCR(7), 0x0090);
ln97xBcrWrite (pDrvCtrl, BCR(2), (dataTemp &(~BCR2_LEDPE)));
/***************************************/
pRmd = pDrvCtrl->pRring;
for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++)
{
LN_CLEAN_RXD (pRmd);
}
pDrvCtrl->rmdIndex = 0;
pTmd = pDrvCtrl->pTring;
for (ix = 0; ix < pDrvCtrl->tringSize; ix++, pTmd++)
{
pTmd->tBufAddr = 0; /* no message byte count yet */
pTemp = (void *)(TMD1_CNST | TMD1_ENP | TMD1_STP);
pTmd->tBufTmd1 = (UINT32) PCI_SWAP (pTemp);
LN_TMD_CLR_ERR (pTmd);
}
pDrvCtrl->tmdIndex = 0;
pDrvCtrl->tmdIndexC = 0;
/* Point the device to the initialization block */
pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->ib);
pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));
ln97xCsrWrite (pDrvCtrl, CSR(2), (((ULONG)pTemp >> 16) & 0x0000ffff));
ln97xCsrWrite (pDrvCtrl, CSR(1), ((ULONG)pTemp & 0x0000ffff));
ln97xCsrWrite (pDrvCtrl, CSR(0), CSR0_INIT); /* init chip (read IB) */
/* hang until Initialization DONe, ERRor, or timeout */
while (((stat = ln97xCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0)
{
if (timeoutCount++ > 0x100)
break;
taskDelay (2 * timeoutCount);
}
DRV_LOG (DRV_DEBUG_LOAD, "Timeoutcount %d\n", timeoutCount,
2, 3, 4, 5, 6);
/* log chip initialization failure */
if (((stat & CSR0_ERR) == CSR0_ERR) || (timeoutCount >= 0x10000))
{
DRV_LOG (DRV_DEBUG_LOAD, "%s: Device initialization failed\n",
(int)END_DEV_NAME(&pDrvCtrl->endObj), 0,0,0,0,0);
return;
}
if (!(pDrvCtrl->flags & LS_POLLING))
ln97xCsrWrite (pDrvCtrl, 0, CSR0_INTMASK | CSR0_STRT);
else
ln97xCsrWrite (pDrvCtrl, 0, CSR0_STRT);
}
/******************************************************************************
*
* ln97xAddrFilterSet - set the address filter for multicast addresses
*
* This routine goes through all of the multicast addresses on the list
* of addresses (added with the ln97xAddrAdd() routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A
*/
LOCAL void ln97xAddrFilterSet
(
LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */
)
{
ETHER_MULTI * pCurr;
LN_IB * pIb;
UINT8 * pCp;
UINT8 byte;
UINT32 crc;
int len;
int count;
pIb = pDrvCtrl->ib;
LN_ADDRF_CLEAR (pIb);
pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->endObj);
while (pCurr != NULL)
{
pCp = (UINT8 *)&pCurr->addr;
crc = 0xffffffff;
for (len = LN_LA_LEN; --len >= 0;)
{
byte = *pCp++;
for (count = 0; count < LN_LAF_LEN; count++)
{
if ((byte & 0x01) ^ (crc & 0x01))
{
crc >>= 1;
crc = crc ^ LN_CRC_POLYNOMIAL;
}
else
{
crc >>= 1;
}
byte >>= 1;
}
}
/* Just want the 6 most significant bits. */
crc = LN_CRC_TO_LAF_IX (crc);
/* Turn on the corresponding bit in the filter. */
LN_ADDRF_SET (pIb, crc);
pCurr = END_MULTI_LST_NEXT(pCurr);
}
}
/*******************************************************************************
*
* ln97xPollReceive - routine to receive a packet in polled mode.
*
* This routine is called by a user to try and get a packet from the
* device. This routine return OK if it is successful in getting the packet
*
* RETURNS: OK or EAGAIN.
*/
LOCAL STATUS ln97xPollReceive
(
LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */
M_BLK_ID pMblk
)
{
LN_RMD * pRmd;
UINT16 stat;
char * pPacket;
int len;
DRV_LOG (DRV_DEBUG_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -