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

📄 cs8900aend.c

📁 s3c2410x板 vxworks开发bsp包
💻 C
📖 第 1 页 / 共 4 页
字号:
 * * Use default system buffers, or create device specific buffer pools. * * Use contiguous buffers for device frame descriptors and the data, or * use descriptor buffers separate from the data buffers. * * Use the same buffering scheme for Rx and Tx, or each side uses it's * own buffering scheme. * * RETURNS: OK or ERROR. */LOCAL STATUS cs8900aMemInit	(		END_DEVICE * pDrvCtrl	/* device to be initialized */	){	/* Set up an END netPool using netBufLib(1). */	cs8900aMclBlkConfig.mBlkNum  = 128;	cs8900aClDescTbl[0].clNum    = 128;	cs8900aClDescTbl[0].clSize   = 2048;	cs8900aMclBlkConfig.clBlkNum = cs8900aClDescTbl[0].clNum;	/* Calculate the total memory for all the M-Blks and CL-Blks. */	cs8900aMclBlkConfig.memSize = ((cs8900aMclBlkConfig.mBlkNum * (MSIZE + sizeof (long)))				    +  (cs8900aMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))));	/* allocate mbuf/Cluster blocks from normal memory */	cs8900aMclBlkConfig.memArea = (char *)memalign(sizeof(long),cs8900aMclBlkConfig.memSize);	if(cs8900aMclBlkConfig.memArea == NULL)return ERROR;	/* Calculate the memory size of all the clusters. */	cs8900aClDescTbl[0].memSize = (cs8900aClDescTbl[0].clNum * (cs8900aClDescTbl[0].clSize + 8));	/* Allocate the memory for the clusters from cache safe memory. */	cs8900aClDescTbl[0].memArea = (char*)cacheDmaMalloc(cs8900aClDescTbl[0].memSize);	if(cs8900aClDescTbl[0].memArea == NULL)	{		DRV_LOG(DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6);		return ERROR;	}	/* TODO - allocate and initialize any shared memory areas */	if((pDrvCtrl->end.pNetPool = malloc(sizeof(NET_POOL))) == NULL) return ERROR;	/* Initialize the memory pool. */	if(netPoolInit(			pDrvCtrl->end.pNetPool,			&cs8900aMclBlkConfig,			&cs8900aClDescTbl[0],			cs8900aClDescTblNumEnt,			NULL) == ERROR)        {		DRV_LOG(DRV_DEBUG_LOAD, "Could not init buffering\n", 1, 2, 3, 4, 5, 6);		return ERROR;	}	DRV_LOG(DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);	return OK;}/* * cs8900aStart - 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 cs8900aStart	(		END_DEVICE* pDrvCtrl	/* device ID */	){	/* TODO  - start the device, enabling interrupts */	/* enable pins for net interrupt. */	cs8900a_pin_enable();	/* clear any interrupt. */	while(cs_pp_r(pDrvCtrl, CS_PKTPG_ISQ) != 0);	cs_chip_int_enable(pDrvCtrl);	/* install isr. */	if(intConnect(INUM_TO_IVEC(pDrvCtrl->ivec), cs8900aInt, (int)pDrvCtrl) == ERROR)	{		return ERROR;	}		DRV_LOG(DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);	/* enable interrupt. */	intEnable(pDrvCtrl->ilevel);	DRV_LOG(DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);	END_FLAGS_SET(&pDrvCtrl->end, IFF_UP | IFF_RUNNING);	return OK;}/* * cs8900aInt - handle controller interrupt * * This routine is called at interrupt level in response to an interrupt from * the controller. * * RETURNS: N/A. */void cs8900aInt(END_DEVICE * pDrvCtrl){	USHORT stat = 0;	int recv_len = 0;	volatile char * p_char = NULL;	volatile char * p_src = (char *)(CS_CHIP_MEM_BASE + CS_PKTPG_RX_FRAME);	volatile char temp_char1, temp_char2;	int i;	DRV_LOG(DRV_DEBUG_INT, "Got an interrupt!\n", 1, 2, 3, 4, 5, 6);	while(1)	{		/* Read the device status register */		stat = *((USHORT *)(CS_CHIP_MEM_BASE + CS_PKTPG_ISQ));		if(stat == 0) break;		switch(stat & CS_REG_NUM_MASK)		{		case CS_REG_NUM_RX_EVENT:			if(CS_RX_EVENT_CRC_ERR & stat)			{				if(display_net_event) printf("recv-data CRC error!\n");				cs_chip_rx_frame_drop(pDrvCtrl, 1);				break;			}			if(CS_RX_EVENT_RUNT & stat)			{				if(display_net_event) printf("error, recv-data too short!\n");				cs_chip_rx_frame_drop(pDrvCtrl, 1);				break;			}			if(CS_RX_EVENT_X_DATA & stat)			{				if(display_net_event) printf("error, recv-data too long!\n");				cs_chip_rx_frame_drop(pDrvCtrl, 1);				break;			}			if(CS_RX_EVENT_RX_OK & stat)			{				pDrvCtrl->rxHandling = TRUE;				p_char = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->end.pNetPool->clTbl[0]);				if(p_char != NULL)				{					recv_len = cs_pp_r(pDrvCtrl, CS_PKTPG_RX_LENGTH);					bcopyBytes((char *)p_src, (char *)(p_char + 2), recv_len);					/* for(i = 0; i < recv_len; i++)					{						temp_char1 = p_src[i];						while((temp_char1 & 0x40)&&(i < (recv_len - 4))&&(i < 80)) {							temp_char2 = p_src[i];							if(temp_char1 == temp_char2) break;							temp_char1 = temp_char2;						}						p_char[i+2] = temp_char1;					} */					recv_len += 2;				}				/* netJobAdd ((FUNCPTR)cs8900aHandleRcvInt, (int)pDrvCtrl, (int)p_char,recv_len,0,0); */				netJobAdd ((FUNCPTR)cs8900aRecv, (int)pDrvCtrl, (int)p_char,recv_len,0,0);			}			break;		case CS_REG_NUM_TX_EVENT:			if(CS_TX_EVENT_JABBER & stat);			if(CS_TX_EVENT_LOSS_CRS & stat);			if(CS_TX_EVENT_OUT_WIN & stat);			if(CS_TX_EVENT_SQE_ERR & stat);			if(CS_TX_EVENT_TX_OK & stat)			{				if(display_net_event) printf("tx_ok\n");			}			break;		case CS_REG_NUM_BUF_EVENT:			break;		case CS_REG_NUM_RX_MISS:			if(display_net_event) printf("Warning, net-rx miss!\n");			break;		case CS_REG_NUM_TX_COL:			if(display_net_event) printf("Warning, net-tx collision!\n");			break;		default:;		}	}	return ;}/* * cs8900aRecv - process the next incoming packet * * Handle one incoming packet.  The packet is checked for errors. * * RETURNS: N/A. */LOCAL void cs8900aRecv	(		END_DEVICE *	pDrvCtrl,	/* device structure */		char*		pNewCluster,		int		len	){	char *		temp_buf = NULL;	int		temp_count = 0;	M_BLK_ID	pMblk;	CL_BLK_ID	pClBlk;	int i = 0;	pDrvCtrl->rxHandling = TRUE;	/* TODO - Packet must be checked for errors. */	END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_UCAST, +1);	/*	 * We implicitly are loaning here, if copying is necessary this	 * step may be skipped, but the data must be copied before being	 * passed up to the protocols.	 */	/* pDrvCtrl->pClPoolId); */	if(pNewCluster == NULL)        {		DRV_LOG(DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);		goto cleanRXD;        }	/* Grab a cluster block to marry to the cluster we received. */	if(((pClBlk = netClBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL)	||(len <= 0))	{		netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);		DRV_LOG(DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);		goto cleanRXD;	}	if((pMblk = mBlkGet(pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL)	{		netClBlkFree(pDrvCtrl->end.pNetPool, pClBlk);		netClFree(pDrvCtrl->end.pNetPool, (UCHAR *)pNewCluster);		DRV_LOG(DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_ERRS, +1);		goto cleanRXD;	}	/* Join the cluster to the MBlock */	netClBlkJoin(pClBlk, pNewCluster, len, NULL, 0, 0, 0);	netMblkClJoin(pMblk, pClBlk);	/* TODO - Invalidate any RFD dma buffers */	pMblk->mBlkHdr.mLen = len;	pMblk->mBlkHdr.mFlags |= M_PKTHDR;	pMblk->mBlkPktHdr.len = len;	pMblk->mBlkHdr.mData += 2;	DRV_LOG(DRV_DEBUG_RX, "Calling upper layer!\n", 1, 2, 3, 4, 5, 6);	/* TODO - Done with processing, clean up and pass it up. */	/* Call the upper layer's receive routine. */	END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);cleanRXD:	pDrvCtrl->rxHandling = FALSE;	return;}/* * cs8900aSend - the driver send routine * * 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, ERROR, or END_ERR_BLOCK. */LOCAL STATUS cs8900aSend	(		END_DEVICE*	pDrvCtrl,	/* device ptr */		M_BLK_ID	pMblk		/* data to send */	){	static UCHAR p_src_buf[CS_CHIP_FRAME_BUF_SIZE];	int	old_level = 0;	int	length = 0;	STATUS	tx_status = ERROR; 	if(pDrvCtrl->resetting)	return END_ERR_BLOCK;	if(!(pDrvCtrl->flags & cs8900a_POLLING))	{		END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER);	}	/* Get data from Mblk to tx buffer. */	length = netMblkToBufCopy(pMblk, (char*)p_src_buf, NULL);	/* lock interrupt. */	if(!(pDrvCtrl->flags & cs8900a_POLLING))	{		old_level = intLock();	}	/* transmit it. */	tx_status = cs_chip_send_frame(pDrvCtrl, (USHORT *)p_src_buf, length);	/* unlock interrupt. */	if(!(pDrvCtrl->flags & cs8900a_POLLING))	{		intUnlock (old_level);	}	if(!(pDrvCtrl->flags & cs8900a_POLLING))	{		END_TX_SEM_GIVE(&pDrvCtrl->end);	}	/* Bump the statistics counters. */	END_ERR_ADD(&pDrvCtrl->end, MIB2_OUT_UCAST, +1);	if(tx_status == ERROR)	{		/* transmit failed. */		return END_ERR_BLOCK;	}	/*	 * Cleanup.  If the driver copied the data from the mblks to a different	 * buffer, then free the mblks now.  Otherwise, free the mblk chain	 * after the device is finished with the TFD.	 */	netMblkClChainFree(pMblk);	return OK;}/* * cs8900aIoctl - the driver I/O control routine * * Process an ioctl request. * * RETURNS: A command specific response, usually OK or ERROR. */LOCAL int cs8900aIoctl	(		END_DEVICE* pDrvCtrl,	/* device receiving command */		int cmd,		/* ioctl command code */		caddr_t data		/* command argument */	){	int error = 0;	long value;	switch((unsigned)cmd)	{	case EIOCSADDR:		/* set MAC address */		if (data == NULL) return EINVAL;		bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end), END_HADDR_LEN(&pDrvCtrl->end));		break;	case EIOCGADDR:		/* get MAC address */		if(data == NULL) return EINVAL;		bcopy((char *)END_HADDR(&pDrvCtrl->end), (char *)data, END_HADDR_LEN(&pDrvCtrl->end));		break;	case EIOCSFLAGS:	/* set (or clear) flags */		value = (long)data;		if(value < 0)		{			value = -value;			value--;			END_FLAGS_CLR(&pDrvCtrl->end, value);		}		else		{			END_FLAGS_SET(&pDrvCtrl->end, value);		}		cs8900aConfig (pDrvCtrl);		break;	case EIOCGFLAGS:	/* get flags */		*(int *)data = END_FLAGS_GET(&pDrvCtrl->end);		break;	case EIOCPOLLSTART:	/* Begin polled operation */		cs8900aPollStart(pDrvCtrl);		break;	case EIOCPOLLSTOP:	/* End polled operation */		cs8900aPollStop(pDrvCtrl);		break;	case EIOCGMIB2233:	case EIOCGMIB2:		/* return MIB information */		if(data == NULL) return EINVAL;		bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data, sizeof(pDrvCtrl->end.mib2Tbl));		break;	case EIOCGFBUF:		/* return minimum First Buffer for chaining */		if(data == NULL) return EINVAL;		*(int *)data = cs8900a_MIN_FBUF;		break;        case EIOCGHDRLEN:		if(data == NULL) return EINVAL;		*(int *)data = EH_SIZE;		break;	default:		/* unknown request */		error = EINVAL;	}	return error;}/* * cs8900aConfig - reconfigure the interface under us. * * Reconfigure the interface setting promiscuous mode, and changing the * multicast interface list. * * RETURNS: N/A. */LOCAL void cs8900aConfig	(		END_DEVICE* pDrvCtrl	/* device to be re-configured */	){	/* Set promiscuous mode if it's asked for. */	if(END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)	{		DRV_LOG(DRV_DEBUG_IOCTL, "Setting promiscuous mode on!\n", 1, 2, 3, 4, 5, 6);	}	else	{		DRV_LOG(DRV_DEBUG_IOCTL, "Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6);	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -