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

📄 if_5120.c

📁 Boot code for ADM5120 with serial console for Edimax router.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************;;    Project : ADM5120;    Creator : David Weng;    File    : if_5120.c;    Abstract: ;;*****************************************************************************/#include <ctype.h>#include <adm5120.h>#include <irqlib.h>#include <mips4kc.h>#include <cachelib.h>#include <memlib.h>#include <if_5120.h>#include <param.h>#include <buart.h>#include <buart_extra.h>#include <test_def.h>/********************  Some Constants *****************/#define NUM_TX_H_DESC		0	// Number of the Transmitting descriptors of high priority #define NUM_TX_L_DESC		16	// Number of the Transmitting descriptors of low priority#define NUM_RX_H_DESC		0	// Number of the Receiving descriptors of high priority#define NUM_RX_L_DESC		32	// Number of the Receiving descriptors of low priority#define NUM_FREE_PKT		48	// Number of the Free packets#define MAX_INT_LOOP_CNT	1#define PKT_BUFFER_SIZE		1792	// Size of the packet buffer.									// This number should be a multiple of CACHE_LINE_SIZE.#define PKT_BUFFER_ALIGN	(ADM5120_CACHE_LINE_SIZE - 1)	 #define DEF_CTRL_FLAG		(PKT_HARDWARE_CRC | SW_ONEBUF_PER_DESC)#define DEF_BUF1_OFFSET		0#define DEF_BUF1_LEN		BUF1_LEN_FULL#define DEF_BUF2_OFFSET		0/**********************  Macros  *********************/#define ENQUEUE_TX_PACKET_AT_TAIL(_h, _t, _Pkt)	{					\					if((_Pkt) != NULL)	{							\						if((_t) == NULL)	(_h) = (_t) = (_Pkt);	\						else {										\							(_t)->Next = (_Pkt);					\							(_t) = (_Pkt);							\						}											\						(_Pkt)->Next =	NULL;						\					}												\				}				#define ENQUEUE_TX_PACKET_AT_FRONT(_h, _t, _Pkt) {					\					if(_Pkt != NULL)								\					{												\						(_Pkt)->Next = (_h);						\						if((_h) == NULL) 	(_h) = (_t) = (_Pkt);	\						else {										\							(_h) = (_Pkt);							\						}											\					}												\				}#define DEQUEUE_TX_PACKET(_h, _t, _Pkt)		{						\					(_Pkt) = (_h);									\					if((_h) != NULL)								\					{												\						if((_h) == (_t)) (_h) = (_t) = NULL;		\						else	(_h) = (_Pkt)->Next;				\						(_Pkt)->Next = NULL;						\					}												\				}/********  Local Funcitons  Prototypes  *************/static int DrvAllocateResource(void);int ProgramMac(int vlan, UINT8 *Mac);static int ProcessRxHInt(void);static int ProcessRxLInt(void);static void ProcessTxLInt(void);void SendPacketsL(PDRV_PACKET_DESC Pkt);inline void SetPktAlign(PDRV_PACKET_DESC Pkt);static void Am5120Isr(int intLev);extern void panic(void);static PAM5120CONTEXT ifp;/****************************//* DrvAllocateResource:		*//****************************/static int DrvAllocateResource(void){	unsigned int i, PktIdx, TotalPktRequired;	UINT8 *Buf;	UINT32 memsz, membk;	PDRV_PACKET_DESC Pkt;	if (ifp == NULL)		return -1;	ifp->NumRxDescH = NUM_RX_H_DESC;	ifp->NumRxDescL = NUM_RX_L_DESC;	ifp->NumTxDescH = NUM_TX_H_DESC;	ifp->NumTxDescL = NUM_TX_L_DESC;	ifp->NumFreePkt = NUM_FREE_PKT;		ifp->CtrlFlag = DEF_CTRL_FLAG;	ifp->Buf1Off = DEF_BUF1_OFFSET;	ifp->Buf1Len = DEF_BUF1_LEN;	ifp->Buf2Off = DEF_BUF2_OFFSET;	//  Allocate HwTxDesc/HwRxDesc	memsz = sizeof(TX_DESC_T) * (ifp->NumTxDescH + ifp->NumTxDescL) + TX_DESC_ALIGN;	/*	Had a little problem here.  SharedMemAlloc should return an address in Kseg1		unmapped and uncached or else none of the networking code will work! */	if ((membk = (UINT32) SharedMemAlloc(memsz, TRUE)) == 0)		return -1;	if (membk & (TX_DESC_ALIGN - 1))		ifp->HwTxDescH = (TX_DESC_T *) ((membk + TX_DESC_ALIGN - 1) & ~(TX_DESC_ALIGN - 1));	else		ifp->HwTxDescH = (TX_DESC_T *) membk;	ifp->HwTxDescL = &ifp->HwTxDescH[ifp->NumTxDescH];	memsz = sizeof(RX_DESC_T) * (ifp->NumRxDescH + ifp->NumRxDescL) + RX_DESC_ALIGN;	/*	Had a little problem here.  SharedMemAlloc should return an address in Kseg1		unmapped and uncached or else none of the networking code will work! */	if ((membk = (UINT32) SharedMemAlloc(memsz, TRUE)) == 0)		return -1;	if (membk & (RX_DESC_ALIGN-1))		ifp->HwRxDescH = (RX_DESC_T *) ((membk + RX_DESC_ALIGN - 1) & ~(RX_DESC_ALIGN - 1));	else		ifp->HwRxDescH = (RX_DESC_T *) membk;	ifp->HwRxDescL = &ifp->HwRxDescH[ifp->NumRxDescH];	// Allocate DrvTxDesc/DrvRxDesc	ifp->DrvTxDescH = MemAlloc(sizeof(DRV_TX_DESC)*ifp->NumTxDescH, FALSE);	ifp->DrvTxDescL = MemAlloc(sizeof(DRV_TX_DESC)*ifp->NumTxDescL, FALSE);	ifp->DrvRxDescH = MemAlloc(sizeof(DRV_RX_DESC)*ifp->NumRxDescH, FALSE);	ifp->DrvRxDescL = MemAlloc(sizeof(DRV_RX_DESC)*ifp->NumRxDescL, FALSE);	TotalPktRequired = ifp->NumRxDescH + ifp->NumRxDescL + ifp->NumFreePkt;	// Allocate Packet pool	ifp->PktPool = MemAlloc(sizeof(DRV_PACKET_DESC)*TotalPktRequired, FALSE);	// Allocate Buffer pool	ifp->BufPool = MemAlloc(PKT_BUFFER_SIZE*TotalPktRequired + PKT_BUFFER_ALIGN, FALSE);	// Align to PKT_BUFFER_ALIGN boundry	if ((UINT32) ifp->BufPool & PKT_BUFFER_ALIGN) 		ifp->BufPool = (UINT8 *)(((UINT32) ifp->BufPool + PKT_BUFFER_ALIGN) & (~PKT_BUFFER_ALIGN));	// Initialize Packet Descriptors	for (Buf = ifp->BufPool, i = 0; i < TotalPktRequired; i++) {		Pkt = &ifp->PktPool[i];		Pkt->Next = NULL;		Pkt->Buf = Buf;		SetPktAlign(Pkt);		Buf += PKT_BUFFER_SIZE;	}	// Initialize the TxDescH	for (i = 0; i < ifp->NumTxDescH; i++) {		/* All except the last were already commented out */		//ifp->HwTxDescH[i].buf1ctnt = 0;		//ifp->HwTxDescH[i].buf2cntl = 0;		//ifp->HwTxDescH[i].buflen = 0;		//ifp->HwTxDescH[i].pktcntl = 0;		ifp->DrvTxDescH[i].Pkt = NULL;	}	ifp->HwTxDescH[--i].buf1cntl |= END_OF_RING;	// Initialize the TxDescL	for (i = 0; i < ifp->NumTxDescL; i++) {		/* All except the last were already commented out */		//ifp->HwTxDescL[i].buf1ctnt = 0;		//ifp->HwTxDescL[i].buf2cntl = 0;		//ifp->HwTxDescL[i].buflen = 0;		//ifp->HwTxDescL[i].pktcntl = 0;		ifp->DrvTxDescL[i].Pkt = NULL;	}	ifp->HwTxDescL[--i].buf1cntl |= END_OF_RING;	// Initialize the RxDescH	for (i = 0, PktIdx = 0; i < ifp->NumRxDescH; i++) {		Pkt = ifp->DrvRxDescH[i].Pkt= &ifp->PktPool[PktIdx++];		if (Pkt->buf2len != 0)			ifp->HwRxDescH[i].buf2cntl = BUF2_EN | ((UINT32) (Pkt->Buf+Pkt->buf2off) & BUF_ADDR_MASK);		else			ifp->HwRxDescH[i].buf2cntl = 0;		ifp->HwRxDescH[i].buflen = Pkt->buf1len;		ifp->HwRxDescH[i].buf1cntl = OWN_BIT | ((UINT32) (Pkt->Buf+Pkt->buf1off) & BUF_ADDR_MASK);	}	ifp->HwRxDescH[--i].buf1cntl |= END_OF_RING;	// Initialize the RxDescL	for (i = 0; i < ifp->NumRxDescL; i++) {		Pkt = ifp->DrvRxDescL[i].Pkt= &ifp->PktPool[PktIdx++];		if (Pkt->buf2len != 0)			ifp->HwRxDescL[i].buf2cntl = BUF2_EN | ((UINT32) (Pkt->Buf+Pkt->buf2off) & BUF_ADDR_MASK);		else			ifp->HwRxDescL[i].buf2cntl = 0;		ifp->HwRxDescL[i].buflen = Pkt->buf1len;		ifp->HwRxDescL[i].buf1cntl = OWN_BIT | ((UINT32) (Pkt->Buf+Pkt->buf1off) & BUF_ADDR_MASK);	}	ifp->HwRxDescL[--i].buf1cntl |= END_OF_RING;	// Initialize FreePktList	ifp->FreePktList = &ifp->PktPool[PktIdx];	for ( ; PktIdx < (TotalPktRequired - 1); PktIdx++) {		ifp->PktPool[PktIdx].Next = &ifp->PktPool[PktIdx+1];	}	ifp->FreePktCnt = ifp->NumFreePkt;	// Initialize Rx/Tx Indices	ifp->RxIdxH = ifp->RxIdxL = 0;	ifp->TxIdxH_Head = ifp->TxIdxH_Tail = ifp->TxIdxL_Head = ifp->TxIdxL_Tail = 0;	// Initialize the Tx queues	ifp->TxH_QueueHead = ifp->TxH_QueueTail = ifp->TxL_QueueHead = ifp->TxL_QueueTail = NULL;	return 0;}/********************//* ProgramMac		*//*********************/int ProgramMac(int vlan, UINT8 *Mac){	UINT32 Reg0, Reg1;		if (vlan < 0 || vlan > 6)		return -1;	Reg0 = (((UINT32) Mac[1] << 24) + ((UINT32) Mac[0] << 16))			| (vlan << SW_MAC_VLANID_SHIFT)			| SW_MAC_AGE_VALID			| SW_MAC_WRITE			| SW_MAC_VLANID_EN;	Reg1 = ((UINT32) Mac[5] << 24)			+ ((UINT32) Mac[4] << 16)			+ ((UINT32)Mac[3] << 8)			+ Mac[2];	ADM5120_SW_REG(MAC_wt1_REG) = Reg1;	ADM5120_SW_REG(MAC_wt0_REG) = Reg0;	while ( ! (ADM5120_SW_REG(MAC_wt0_REG) & SW_MAC_WRITE_DONE))		;	return 0;}/************************//* ProcessRxHInt:		*//************************/static int ProcessRxHInt(void){		buart_print("\r\nHigh-priority send/receive not supported!");	return FALSE;	}/************************//* ProcessRxLInt:		*//************************/static int ProcessRxLInt(void){	UINT32 LoopCnt=0, idx, RxStatus;	PDRV_PACKET_DESC Pkt, FreePkt;	RX_DESC_T *RxDesc;	PORT_STAT *pstat;	idx = ifp->RxIdxL;	RxDesc = &ifp->HwRxDescL[idx];	while ( ! (RxDesc->buf1cntl & OWN_BIT)) {		if (ifp->FreePktList == NULL) {			ifp->RxIdxL = idx;			ifp->RxL_PktCnt += LoopCnt;			return TRUE;		}		// Store the received packet		Pkt = ifp->DrvRxDescL[idx].Pkt;		if ((RxStatus = RxDesc->status) == 0) {			// Reuse the Pkt buffer			RxDesc->status = 0;			RxDesc->buf1cntl = RxDesc->buf1cntl | OWN_BIT;			if (++idx >= ifp->NumRxDescL)				idx = 0;			RxDesc = &ifp->HwRxDescL[idx];			continue;		}		Pkt->SrcPort = (RxStatus & SRC_PORT_MASK) >> SRC_PORT_SHIFT;		Pkt->PktLen = ((RxStatus & PKT_LEN_MASK) >> PKT_LEN_SHIFT) - ETH_CRC_LEN;		Pkt->flag = RxStatus & RX_PKT_FLAG_MASK;		// Get another free packet for the receive descriptor		FreePkt = ifp->DrvRxDescL[idx].Pkt = ifp->FreePktList;		ifp->FreePktList = FreePkt->Next;		ifp->FreePktCnt--;		FreePkt->Next = NULL;		// Set the descriptor and release it to switch		RxDesc->status = 0;		if (FreePkt->buf2len != 0)			RxDesc->buf2cntl = BUF2_EN | (((UINT32) FreePkt->Buf + FreePkt->buf2off) & BUF_ADDR_MASK);		else			RxDesc->buf2cntl = 0;		RxDesc->buflen = FreePkt->buf1len;		RxDesc->buf1cntl = (RxDesc->buf1cntl & END_OF_RING)							| OWN_BIT							| (((UINT32) FreePkt->Buf + FreePkt->buf1off) & BUF_ADDR_MASK);		if (Pkt->PktLen <= Pkt->buf1len)			dcache_invalidate_block(Pkt->Buf + Pkt->buf1off, Pkt->PktLen);		else {				dcache_invalidate_block(Pkt->Buf+Pkt->buf1off, Pkt->buf1len);			dcache_invalidate_block(Pkt->Buf+Pkt->buf2off, Pkt->PktLen-Pkt->buf1len);		}		// Collect statistical information		pstat = &ifp->portstat[Pkt->SrcPort];		if (Pkt->flag & RX_FRAME_BC) {			ifp->RxL_BCCnt ++;			++pstat->RxBCPkt;		} else if (Pkt->flag & RX_FRAME_MC) {			ifp->RxL_MCCnt++;			++pstat->RxMCPkt;		} else {			ifp->RxL_UCCnt++;			++pstat->RxUCPkt;		}		pstat->RxPktCnt++;		pstat->RxBytes += Pkt->PktLen;        IndicateRxPacketL(Pkt);		if (++idx >= ifp->NumRxDescL)			idx = 0;		if (++LoopCnt > ifp->NumRxDescL)			break;		RxDesc = &ifp->HwRxDescL[idx];	}	ifp->RxIdxL = idx;	ifp->RxL_PktCnt += LoopCnt;	return FALSE;	}/************************//* ProcessTxLInt:		*//************************/static void ProcessTxLInt(void){	UINT32 LoopCnt = 0, idx;	PDRV_PACKET_DESC Pkt;	idx = ifp->TxIdxL_Tail;	while ( ! (ifp->HwTxDescL[idx].buf1cntl & OWN_BIT) && (idx != ifp->TxIdxL_Head)) {		Pkt = ifp->DrvTxDescL[idx].Pkt;		ifp->DrvTxDescL[idx].Pkt = NULL;		// Return the Packet to the Free Packet List		SetPktAlign(Pkt);		Pkt->Next = ifp->FreePktList;		ifp->FreePktList = Pkt;		ifp->FreePktCnt++;		if (++idx == ifp->NumTxDescL)			idx = 0;		if (++LoopCnt > ifp->NumTxDescL)			break;	}	ifp->TxIdxL_Tail = idx;	ifp->TxL_PktCnt += LoopCnt;	// Try to send the packets in the transmitting queue.	if (ifp->TxL_QueueHead != NULL)		SendPacketsL(NULL);

⌨️ 快捷键说明

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