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

📄 if_5120.c

📁 Boot code for ADM5120 with serial console for Edimax router.
💻 C
📖 第 1 页 / 共 2 页
字号:
}/************************************************//* SendPacketsL:								*//*     Send a low priority packet and try       *//*     to transmit all the packets in the low   *//*     priority transmitting queue.             *//************************************************/void SendPacketsL(PDRV_PACKET_DESC Pkt){	UINT32 Idx, IdxNext, reg;	UINT32 TxCnt = 0;	TX_DESC_T *TxDesc;	UINT8 *buf;	char str[] = "XXXXXXXXXXXX";	char protocol[] = "XXXX";	if (ifp->TxL_QueueHead != NULL) {		//The txL Queue has some packets ready so send them first...		ENQUEUE_TX_PACKET_AT_TAIL(ifp->TxL_QueueHead, ifp->TxL_QueueTail, Pkt);		DEQUEUE_TX_PACKET(ifp->TxL_QueueHead, ifp->TxL_QueueTail, Pkt);	}	Idx = IdxNext = ifp->TxIdxL_Head;	// Try to transmit queued packets.	while (Pkt!= NULL) {		// Check if the Tx queue is full.		// There is always one descriptor kept empty for queue full detection.		if ((++IdxNext) >= ifp->NumTxDescL)			IdxNext = 0;		if (IdxNext == ifp->TxIdxL_Tail) {			ifp->TxL_FullCnt ++;			break; 				}		TxDesc = &ifp->HwTxDescL[Idx];		// If there is any free Tx DESC		if (TxDesc->buf1cntl & OWN_BIT)			break;		// Transmit the packet		ifp->DrvTxDescL[Idx].Pkt = Pkt;		if (ifp->CtrlFlag & PKT_SOFTWARE_CRC)			Pkt->PktLen += ETH_CRC_LEN;		if(Pkt->PktLen <= Pkt->buf1len) {			TxDesc->buf2cntl = 0;			TxDesc->buflen = Pkt->PktLen;		} else {			TxDesc->buflen = Pkt->buf1len;			TxDesc->buf2cntl = BUF2_EN | ((UINT32) (Pkt->Buf + Pkt->buf2off) & BUF_ADDR_MASK);		}		Pkt->Dst = (ADM5120_SW_REG(PHY_st_REG) & PORT_LINK_MASK) << 8;		buf = Pkt->Buf + Pkt->buf2off;		TxDesc->pktcntl = (Pkt->PktLen << PKT_LEN_SHIFT) | Pkt->Dst;		TxDesc->buf1cntl = (TxDesc->buf1cntl & END_OF_RING)							| OWN_BIT							| ((UINT32) (Pkt->Buf + Pkt->buf1off) & BUF_ADDR_MASK);		Idx = IdxNext;		if (++TxCnt >= ifp->NumTxDescL)			Pkt = NULL;		else			DEQUEUE_TX_PACKET(ifp->TxL_QueueHead, ifp->TxL_QueueTail, Pkt);	}	ifp->TxIdxL_Head = Idx;	// Start the transmitting mechanism...	ADM5120_SW_REG(Send_trig_REG) = SEND_TRIG_LOW;	// Requeue the last packet if it was not transmitted...	ENQUEUE_TX_PACKET_AT_FRONT(ifp->TxL_QueueHead, ifp->TxL_QueueTail, Pkt);}/****************************************************************//* NOTE:    This entire routine was already commented out		*//****************************************************************//*void ProcessLinkInt(PAM5120CONTEXT ifp){	UINT32 link_change, link_status;	int i = 0;	buart_print("+P");	link_status = ADM5120_SW_REG(PHY_st_REG) & PORT_LINK_MASK;	// Flip PORT_MII_LINK_DOWN bit.	link_status ^= PORT_MII_LINKFAIL;	link_change = link_status ^ ifp->link_status;	ifp->link_status = link_status;	while (link_change) {		if(link_change & 0x1) {			buart_put(i + 0x30);			if (link_status & (1 << i))				buart_put('u');			else				buart_put('d');		}		link_change >> =1;		i++;	}}*//****************************//* Make Packet Align:		*//****************************/inline void SetPktAlign(PDRV_PACKET_DESC Pkt){	UINT32 buf2off;	// Set buffer1 offset	if (ifp->Buf1Off == BUF1_OFFSET_RAND) {		// Buffer1 offset random		Pkt->buf1off = rand() & BUF1_OFFSET_MAX;	} else		Pkt->buf1off = ifp->Buf1Off;	if (ifp->CtrlFlag & SW_TWOBUF_PER_DESC) {		// Two buffers per descriptor		// Set Buffer 1 length		if (ifp->Buf1Len == BUF1_LEN_RAND)			Pkt->buf1len = BUF1_LEN_MIN + (rand() & BUF1_LEN_RAND_MAX);		else			Pkt->buf1len = ifp->Buf1Len;		// Set buffer 2 offset		buf2off = (Pkt->buf1off + Pkt->buf1len + BUF_GUARD_BAND) & ~(ADM5120_CACHE_LINE_SIZE - 1);		if (ifp->Buf2Off == BUF2_OFFSET_RAND)			Pkt->buf2off = buf2off + (rand() & BUF2_OFFSET_MAX);		else			Pkt->buf2off = buf2off + ifp->Buf2Off;		// Set buffer 2 length		Pkt->buf2len = PKT_BUFFER_SIZE - Pkt->buf2off;	} else {		// One buffer per descriptor		Pkt->buf1len = PKT_BUFFER_SIZE - Pkt->buf1off;		Pkt->buf2len = Pkt->buf2off = 0;	}}/**********  Exported Functions  ***********//************************//* if5120_init:			*//************************/int if5120_init(void){	int i;	static int init = 0;	UINT32 reg1, reg2;	UINT8 MacAddr[8];	// was 6	// Install exception handler	install_exception();	// Init IRQ	sys_irq_init();	// Per-port PHY reset and enable auto-negotiation	ADM5120_SW_REG(PHY_cntl2_REG) |= SW_PHY_AN_MASK | SW_PHY_NORMAL_MASK;	// Enable MII AN monitor via MDIO	// i.e. Dumb Mode	ADM5120_SW_REG(Port_conf2_REG) |= SW_GMII_AN_EN;	// Allocate the driver context	ifp = (PAM5120CONTEXT) MemAlloc(sizeof(AM5120CONTEXT), TRUE);	if (ifp == NULL)		return -1;	// Disable Switch Interrupts	ADM5120_SW_REG(SW_Int_mask_REG) = 0xFFFFFFF;	// DE - note only 7	// Set PHY control values	ADM5120_SW_REG(PHY_cntl4_REG) = PHY_VOLT23 | PHY_ROMCODE_25;	if (DrvAllocateResource() != 0)		buart_print("\r\nSwitch allocate resource error.");	// Hardware initialization starts here	// Initialize the ifp Desc	ADM5120_SW_REG(Send_HBaddr_REG) = (UINT32) ifp->HwTxDescH;	ADM5120_SW_REG(Send_LBaddr_REG) = (UINT32) ifp->HwTxDescL;	ADM5120_SW_REG(Recv_HBaddr_REG) = (UINT32) ifp->HwRxDescH;	ADM5120_SW_REG(Recv_LBaddr_REG) = (UINT32) ifp->HwRxDescL;	if (ifp->CtrlFlag & PKT_SOFTWARE_CRC)		ADM5120_SW_REG(CPUp_conf_REG) = CPU_PORT_DEFAULT;	else		ADM5120_SW_REG(CPUp_conf_REG) = CPU_PORT_DEFAULT | SW_PADING_CRC;    // Daniel fix	// Disable all port, enable MC, BP and FC 	ADM5120_SW_REG(Port_conf0_REG) = SW_DISABLE_PORT_MASK										| SW_EN_MC_MASK										| SW_EN_BP_MASK										| SW_EN_FC_MASK;	// Init VLAN group Regs, VLAN_GI & VLAN_GII	reg1 = PORT_ALL;	reg2 = PORT_NONE;	ADM5120_SW_REG(VLAN_G1_REG) = reg1;	ADM5120_SW_REG(VLAN_G2_REG) = reg2;	if ( ! (ADM5120_SW_REG(Global_St_REG) & ALLMEM_TEST_DONE)) {		buart_print("\r\nWaiting for switch memory test...");		while ( ! (ADM5120_SW_REG(Global_St_REG) & ALLMEM_TEST_DONE))			;		buart_print("\r\nSwitch memory test done!\r\n");		for (i = 0; i < 2000; i++)			;	}	// Program VLAN0 MAC address	bsp_GetMAC(MacAddr);	ProgramMac(VLAN0,MacAddr);	// Clear all interrupt status bits if any were set	reg1 = ADM5120_SW_REG(SW_Int_st_REG);	ADM5120_SW_REG(SW_Int_st_REG) = reg1;	// Connect Interrupt	irqConnect(INT_LVL_SWITCH, IRQ_INT_MODE, (IRQ_HANDLER)Am5120Isr, 0, 0);	IrqEnable(INT_LVL_SWITCH);	// Enable CPU port	reg1 = ADM5120_SW_REG(CPUp_conf_REG) & (~SW_CPU_PORT_DISABLE);	ADM5120_SW_REG(CPUp_conf_REG) = reg1;	// Enable VLAN0 port	reg1 = ADM5120_SW_REG(Port_conf0_REG) & (~PORT_DISABLE_MASK); 	ADM5120_SW_REG(Port_conf0_REG) = reg1;	// Clear Watchdog 1 counter	reg1 = ADM5120_SW_REG(Watchdog1_REG);	ADM5120_SW_REG(Watchdog1_REG) = (5 << WATCHDOG_TIMER_SET_SHIFT);	ifp->IntMask = AM5120_INT_MASK;	ifp->link_status = 0;	// Enable switch interrupts	ADM5120_SW_REG(SW_Int_mask_REG) = ~(ifp->IntMask);	return 0;}/****************************//* Shutdown Switch: 		*//****************************/void if5120shutdown(void){	int i, s;    s = mips_int_lock();	ADM5120_SW_REG(Port_conf0_REG) |= SW_DISABLE_PORT_MASK;	ADM5120_SW_REG(CPUp_conf_REG) |= SW_CPU_PORT_DISABLE;    mips_int_unlock(s);	for (i = 0; i < 1000000; i++)	// 1 million		;}/****************************//* Turn On Switch:			*//****************************/void if5120turnon(void){	int i, s;	UINT32 reg;	s = mips_int_lock();	// Re-enable ports	reg = ADM5120_SW_REG(Port_conf0_REG) & ~SW_DISABLE_PORT_MASK;	ADM5120_SW_REG(Port_conf0_REG) = reg;	// Re-enable CPU port	reg = ADM5120_SW_REG(CPUp_conf_REG) & ~SW_CPU_PORT_DISABLE;	ADM5120_SW_REG(CPUp_conf_REG) = reg;    mips_int_unlock(s);	for (i = 0; i < 1000000; i++)	// 1 million		;}/****************************//* Am5120_GetFreePkt:		*//****************************/PDRV_PACKET_DESC Am5120_GetFreePkt(void){	PDRV_PACKET_DESC Pkt = NULL;	int s;    s = mips_int_lock();	if (ifp->FreePktList != NULL) {		Pkt = ifp->FreePktList;		ifp->FreePktList = Pkt->Next;		ifp->FreePktCnt--;		Pkt->Next = NULL;	}    mips_int_unlock(s);	return Pkt;}void Am5120_RefreePkt(PDRV_PACKET_DESC Pkt){	int irq_state;	irq_state = mips_int_lock();	Pkt->Next = ifp->FreePktList;	ifp->FreePktList = Pkt;	ifp->FreePktCnt++;	mips_int_unlock(irq_state);}/***** Switch Interrupt Handler *****//****************************//* ProcessAm5120Pkt:		*//****************************/void Am5120Isr(int intLev){	UINT32 IntReg, IntMask, reg;	int	LoopCnt = 0, RxFull = 0;	// Disable Switch Interrupts	ADM5120_SW_REG(SW_Int_mask_REG) = 0xFFFFFFF;	// Clear watchdot timer 1// 	reg = ADM5120_SW_REG(Watchdog1_REG);	// was already commented out	// Ack all interrupts	IntReg = ADM5120_SW_REG(SW_Int_st_REG);	ADM5120_SW_REG(SW_Int_st_REG) = IntReg;	IntReg = ifp->IntStatus | (IntReg & AM5120_INT_MASK);	while (IntReg && LoopCnt<MAX_INT_LOOP_CNT) {// These next 2 statements were already commented out//		if(IntReg &  GLOBAL_QUE_FULL_INT) ifp->DropFlag = TRUE;//		buart_put('I');		if (IntReg & LINK_INT)			//ProcessLinkInt(ifp);	// already commented out			;		if (IntReg & TX_H_INT)			//ProcessTxHInt(ifp);	// already commented out			;		if (IntReg & TX_L_INT)			ProcessTxLInt();		if (IntReg & RX_H_INT) {			if(ProcessRxHInt() != 0)				RxFull |= RX_H_FULL_INT;		}		if (IntReg & RX_L_INT) {			if(ProcessRxLInt() != 0)				RxFull |= RX_L_FULL_INT;		}//		if (IntReg & MUST_DROP_INT)	// already commented out//			buart_put('d');			// already commented out		IntReg = ADM5120_SW_REG(SW_Int_st_REG);		// Acknowledge interrupts		ADM5120_SW_REG(SW_Int_st_REG) = IntReg;		IntReg &= AM5120_INT_MASK;		LoopCnt++;	}	// Record unhandled interrupts	ifp->IntStatus = IntReg | RxFull;	// If the rx H/L descriptor is still full, mask its	// interrupt temporarily.  If it is not masked, the	// interrupt will be asserted immediately after  the	// switch's IRQ being re-enabled. This will block the	// system from doing anything other than servicing the	// switch's ISR/DSR routine. However, the ISR/DSR is	// waiting the system to return some of its buffers for	// receiving.  A deadlock situation is entered.	IntMask = ~ifp->IntMask | RxFull;	// Enable switch interrupts	ADM5120_SW_REG(SW_Int_mask_REG) = IntMask;	ifp->IntCnt ++;}

⌨️ 快捷键说明

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