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

📄 gnlend.c

📁 vxwork平台下网卡驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
	}
	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 + -