📄 gnlend.c
字号:
}
return (error);
}
/*****************************************************************************
*
* gnlEndReset - hardware reset of chip (stop it)
*
* DESCRIPTION
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void gnlEndReset (END_OBJ * pEnd)
{
}
/*****************************************************************************
*
* gnlEndRestartSetup - setup memory descriptors and turn on chip
*
* DESCRIPTION
* Initializes all the shared memory structures and turns on the chip.
*
* RETURNS: OK
*
* NOMANUAL
*/
LOCAL STATUS gnlEndRestartSetup (END_OBJ * pEnd)
{
/* reset the device */
gnlEndReset (pEnd);
DRV_PRINT (DRV_DEBUG_LOAD, ("Memory setup complete\n"));
/* reconfigure the device */
gnlEndConfig (pEnd);
return (OK);
}
/*****************************************************************************
*
* gnlEndConfig - reconfigure the interface under us.
*
* DESCRIPTION
* Reconfigure the interface setting promiscuous mode, and changing the
* multicast interface list.
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void gnlEndConfig (END_OBJ * pEnd)
{
/* Set promiscuous mode if it's asked for. */
if (END_FLAGS_GET (pEnd) & IFF_PROMISC)
{
DRV_PRINT (DRV_DEBUG_LOAD, ("Setting promiscuous mode on!\n"));
}
else
{
DRV_PRINT (DRV_DEBUG_LOAD, ("Setting promiscuous mode off!\n"));
}
CACHE_PIPE_FLUSH ();
/* Set up address filter for multicasting. */
if (END_MULTI_LST_CNT (pEnd) > 0)
{
gnlEndAddrFilterSet (pEnd);
}
}
/*****************************************************************************
*
* gnlEndAddrFilterSet - set the address filter for multicast addresses
*
* DESCRIPTION
* This routine goes through all of the multicast addresses on the list
* of addresses (added with the gnlAddrAdd() routine) and sets the
* device's filter correctly.
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL void gnlEndAddrFilterSet (END_OBJ * pEnd)
{
}
/*****************************************************************************
*
* gnlEndMCastAddrAdd - add a multicast address for the device
*
* DESCRIPTION
* This routine adds a multicast address to whatever the driver
* is already listening for. It then resets the address filter.
*
* RETURNS: N/A
*
* NOMANUAL
*/
/*LOCAL*/ STATUS gnlEndMCastAddrAdd /*lirui 2001-12-21 */
(END_OBJ * pEnd, char *pAddress)
{
int error;
error = etherMultiAdd (&pEnd->multiList, pAddress);
if (error == ENETRESET)
gnlEndConfig (pEnd);
return (OK);
}
/*****************************************************************************
*
* gnlEndMCastAddrDel - delete a multicast address for the device
*
* DESCRIPTION
* This routine removes a multicast address from whatever the driver
* is listening for. It then resets the address filter.
*
* RETURNS: N/A
*
* NOMANUAL
*/
LOCAL STATUS gnlEndMCastAddrDel (END_OBJ * pEnd, char *pAddress)
{
int error;
error = etherMultiDel (&pEnd->multiList, (char *) pAddress);
if (error == ENETRESET)
gnlEndConfig (pEnd);
return (OK);
}
/*****************************************************************************
*
* gnlEndMCastAddrGet - get the multicast address list for the device
*
* DESCRIPTION
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OR or ERROR
*
* NOMANUAL
*/
LOCAL STATUS gnlEndMCastAddrGet (END_OBJ * pEnd, MULTI_TABLE * pTable)
{
int error;
error = etherMultiGet (&pEnd->multiList, pTable);
return (error);
}
/*****************************************************************************
*
* gnlPollSend - Polling Send routine (not Used)
*
* DESCRIPTION
* Polling Send function.
*
* RETURNS: OK or EAGAIN
*/
LOCAL STATUS gnlPollSend (END_OBJ * pEnd, M_BLK_ID pMblk)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) pEnd->devObject.pDevice;
pDrvCtrl = pDrvCtrl;
netMblkClChainFree (pMblk);
return (OK);
}
/*****************************************************************************
*
* gnlPollReceive - Polling Receive routine not used.
*
* DESCRIPTION
* Poll a packet off the interface (not used).
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS gnlPollReceive (END_OBJ * pEnd, M_BLK_ID pMblk)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) pEnd->devObject.pDevice;
pDrvCtrl = pDrvCtrl;
return (EAGAIN);
}
/*****************************************************************************
*
* gnlEndStop - stop the device
*
* DESCRIPTION
* This function calls swDrv functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS gnlEndStop (END_OBJ * pEnd)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) pEnd->devObject.pDevice;
M_BLK_ID pMblk;
int oldLevel;
if (pDrvCtrl->recvQueueHead)
{
oldLevel = intLock ();
while ((pMblk = pDrvCtrl->recvQueueHead))
{
pDrvCtrl->recvQueueHead = pMblk->m_nextpkt;
pMblk->m_nextpkt = NULL;
netMblkClChainFree (pMblk);
}
pDrvCtrl->recvQueueHead = NULL;
pDrvCtrl->recvQueueTail = NULL;
pDrvCtrl->recvCnt = NULL;
intUnlock (oldLevel);
}
return (OK);
}
/*****************************************************************************
*
* gnlEndUnload - unload a driver from the system
*
* DESCRIPTION
* This function first brings down the device, and then frees any
* memory that was allocated by the driver in the load function.
*
* RETURNS: OK or ERROR
*/
LOCAL STATUS gnlEndUnload (END_OBJ * pEnd)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) pEnd->devObject.pDevice;
M_BLK_ID pMblk;
int oldLevel;
int i;
if (pDrvCtrl->recvQueueHead)
{
oldLevel = intLock ();
while ((pMblk = pDrvCtrl->recvQueueHead))
{
pDrvCtrl->recvQueueHead = pMblk->m_nextpkt;
pMblk->m_nextpkt = NULL;
netMblkClChainFree (pMblk);
}
pDrvCtrl->recvQueueHead = NULL;
pDrvCtrl->recvQueueTail = NULL;
pDrvCtrl->recvCnt = NULL;
intUnlock (oldLevel);
}
END_OBJECT_UNLOAD (pEnd);
/*subEndDestroy( pEnd ); *//*lirui 2001-10-29 */
for (i = 0; i < NUM_CLUSTER_POOLS; i++)
{
if (pDrvCtrl->clDescTbl[i].memArea != NULL)
cacheDmaFree (pDrvCtrl->clDescTbl[i].memArea);
}
if (pDrvCtrl->mclConfig.memArea != NULL)
cfree (pDrvCtrl->mclConfig.memArea);
if (pDrvCtrl->endObj.pNetPool != NULL)
cfree ((char *) pDrvCtrl->endObj.pNetPool);
cfree ((char *) pDrvCtrl);
return (OK);
}
/*******************************************************************************
*
* gnlEndMblkSGListGet - Create a scatter-Gather list from Mblk pointer.
*
* DESCRIPTION
* This routine modifies a user sgList_t array with data pointers
* and lengths of each Mblk data fragment. The list will have a null as
* a terminator in the mData member of the array. This means the
* sgList_t must be one larger than needed to hold the max number of fragments.
*
* RETURNS: The number of bytes in the packet or -1 if ERROR.
*/
int gnlEndMblkSGListGet (M_BLK_ID pMblk, /* pointer to an mBlk */
sgList_t * sgList, int mlist /* Length of sgList array size. */
)
{
int mlen, nlist;
if (pMblk == (M_BLK_ID) 0)
return -1;
/* Must be at least two because of the null terminator. */
if (mlist <= 1)
return -1;
nlist = mlen = 0;
while (pMblk != NULL)
{
if (nlist >= mlist)
return -1;
if (pMblk->m_len > 0)
{
sgList->mData = pMblk->m_data;
sgList->mLen = pMblk->m_len;
mlen += pMblk->m_len;
sgList++;
nlist++;
}
pMblk = pMblk->m_next;
}
sgList->mData = (char *) 0;
sgList->mLen = 0;
return mlen;
}
/*******************************************************************************
*
* gnlEndMblkAlloc - Allocate a RX Mblk Cluster Chain for the swDrv driver.
*
* DESCRIPTION
* Routine to Allocate a Mblk Cluster Chain from a given gnlEnd pool.
*
* RETURNS: N/A
*/
M_BLK_ID gnlEndMblkAlloc (END_OBJ * pEnd, int recvLen)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) pEnd->devObject.pDevice;
M_BLK_ID pMblk;
dbgPrintf (2, ("gnlEndMblkAlloc: Entry %d\n\r", recvLen));
pMblk = netTupleGet (pEnd->pNetPool, recvLen + pDrvCtrl->adjustLength, M_DONTWAIT, MT_DATA, FALSE); /*lirui 2002-11-18 TRUE to FALSE */
if (pMblk != NULL)
{
/* make the packet data coherent */
GNL_CACHE_INVALIDATE (pMblk->m_data, recvLen + pDrvCtrl->adjustLength);
/* Align the packet for IP. */
pMblk->m_data += pDrvCtrl->adjustLength;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkHdr.mLen = recvLen;
pMblk->mBlkPktHdr.len = recvLen;
}
dbgPrintf (2, ("gnlEndMblkAlloc: pMblk %08x\n\r", (int) pMblk));
return pMblk;
}
/*******************************************************************************
*
* gnlEndMblkFree - Free a Mblk Cluster Chain from the swDrv driver.
*
* DESCRIPTION
* Routine to free the Mblk Cluster Chain.
*
* RETURNS: N/A
*/
STATUS gnlEndMblkFree (END_OBJ * pEnd, M_BLK_ID pMblk)
{
/* Not Used */
pEnd = pEnd;
netMblkClChainFree (pMblk);
return OK;
}
/*******************************************************************************
*
* gnlEndPoolShow - Show the driver MBLK pool information.
*
* DESCRIPTION
* A debug routine to display the Mblk Pool information for a gnlEnd driver.
*
* RETURNS: N/A
*/
STATUS gnlEndPoolShow (int unit /* unit number of the gnlEnd */
)
{
GNLDEV_OBJ *pDrvCtrl = (GNLDEV_OBJ *) endFindByName (HW_DEVICE_NAME, unit);
netPoolShow (pDrvCtrl->endObj.pNetPool);
printf (" RecvQueue Head %08x Tail %08x Cnt %d\n",
(int) pDrvCtrl->recvQueueHead, (int) pDrvCtrl->recvQueueTail,
(int) pDrvCtrl->recvCnt);
return OK;
}
/*lirui add 2003-2-20 for transmit */
/*******************************************************************************
*
* GalNet48303Send - 驱动程序发送例程
*
* This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.
* The buffer must already have the addressing information properly installed
* in it. This is done by a higher layer. The last arguments are a free
* routine to be called when the device is done with the buffer and a pointer
* to the argument to pass to the free routine.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS GalNetipdslamSend (END_OBJ * pEnd, /* pointer to END_OBJ structure */
M_BLK_ID pMblk, /* Data to send */
char *dstMacAddr, /* destination MAC address */
long netType, /* type of the network service invoking us */
void *pSpare /* any optional data passed */
)
{
int len = 0;
char *pBuf;
char *pOrig;
STATUS retVal = OK;
GNLDEV_OBJ *pDrvCtrl = gnlpDrvCtrl;
pOrig = pBuf =
netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId[0]);
pBuf += pDrvCtrl->offset;
len = netMblkToBufCopy (pMblk, pBuf, NULL);
netMblkClChainFree (pMblk);
len = max (len, ETHERSMALL);
/*retVal = transmitPacket (pBuf, len, 1);*/
netClFree (pDrvCtrl->endObj.pNetPool, pOrig);
/* Bump the statistic counter. */
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);
return (retVal);
}
#if 0
/**************************/
/* netdevice interface */
/*************************/
extern int NOS_console_fd; /*lirui add 2003-1-25 for debug */
int dev_sendto_MUX (char *dest, int datalen, void *pvoid)
{
M_BLK_ID pMblk;
char *pNewCluster;
CL_BLK_ID pClBlk;
GNLDEV_OBJ *pDrvCtrl = gnlpDrvCtrl;
char buf[20];
#ifdef CONFIG_FAST_ROUTE /*added by martin */
pNewCluster = dest;
#else
pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);
if (pNewCluster == NULL)
{
semGive (pDrvCtrl->rxBlock);
return NULL;
}
#endif /*CONFIG_FAST_ROUTE */
if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)
{
netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);
return NULL;
}
if ((pMblk =
mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
{
netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);
netClFree (pDrvCtrl->endObj.pNetPool, pNewCluster);
return NULL;
}
END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);
#ifndef CONFIG_FAST_ROUTE /*added by martin */
bcopy (dest, pNewCluster, datalen);
#endif /*CONFIG_FAST_ROUTE */
netClBlkJoin (pClBlk, pNewCluster, datalen, NULL, 0, 0, 0);
netMblkClJoin (pMblk, pClBlk);
pMblk->mBlkHdr.mData += pDrvCtrl->offset;
pMblk->mBlkHdr.mLen = datalen;
pMblk->mBlkHdr.mFlags |= M_PKTHDR;
pMblk->mBlkPktHdr.len = datalen;
/* Call the upper layer's receive routine. */
END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -