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

📄 if_5120.c

📁 Boot code for ADM5120 with serial console for Edimax router.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************;;   (C) Unpublished Work of ADMtek Incorporated.  All Rights Reserved.;;       THIS WORK IS AN UNPUBLISHED WORK AND CONTAINS CONFIDENTIAL,;       PROPRIETARY AND TRADESECRET INFORMATION OF ADMTEK INCORPORATED.;       ACCESS TO THIS WORK IS RESTRICTED TO (I) ADMTEK EMPLOYEES WHO HAVE A;       NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF THEIR ASSIGNMENTS;       AND (II) ENTITIES OTHER THAN ADMTEK WHO HAVE ENTERED INTO APPROPRIATE;       LICENSE AGREEMENTS.  NO PART OF THIS WORK MAY BE USED, PRACTICED,;       PERFORMED, COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED,;       ABBRIDGED, CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,;       TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF ADMTEK.;       ANY USE OR EXPLOITATION OF THIS WORK WITHOUT AUTHORIZATION COULD;       SUBJECT THE PERPERTRATOR TO CRIMINAL AND CIVIL LIABILITY.;;------------------------------------------------------------------------------;;    Project : ADM5120;    Creator : David Weng;    File    : if_5120.c;    Abstract: ;;Modification History:; ;;*****************************************************************************/#include <ctype.h>#include <adm5120.h>#include <irqlib.h>#include <mips4kc.h>#include <cachelib.h>#include <memlib.h>#include <if_5120.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 multiply 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);#ifdef DBG_OUT_SUPPORTextern void DbgUartPutStr(const char *);extern void DbgUartPutChar(char);#else#define DbgUartPutStr#define DbgUartPutChar#endifstatic PAM5120CONTEXT ifp;/***********************  Local Funcitons  ******************************************//**********************************************************************************//* 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;	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;	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++) {		//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++) {		//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("\n\rNot support High priority receive and send!!");	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 statistic 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;

⌨️ 快捷键说明

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