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

📄 8019drv.c

📁 rt8019的驱动程序源代码和驱动测试程序源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		PAGE0_RSAR1 = NICReadPtr;
		PAGE0_RBCR0 = i;
		PAGE0_RBCR1 = 0;
		CR = 0x0a;			// enable Remote DMA read
		i = _cror_(i, 1);	// need to loop half as many times because of word-wide transfers
		
		while (i--) {
			*p++ = REMOTE_DMA_PORT;
			*p++ = REMOTE_DMA_PORT;
		}
	
		#ifdef real_runtime
		waitRDMAOperationDone();
		#endif
		
		// analysis the Frame
		isFrameLegal = true;
		pFrm = (PETHF)(s + 4);							// pFrm point to first byte of the rxed ethernet frame
		
		pNIDP->len = lenLowByte - 18;					// 4 + 14(ETH_HEADER_LEN)
		pNIDP->offset = 18;
		
		if (pFrm->frmType == VLAN_ID) {
			// ignor VLAN ID field
			w = (word)*(&(pFrm->frmType) + 2);
			pNIDP->offset += VLAN_LEN;
			pNIDP->len -= VLAN_LEN;
		} else
			w = pFrm->frmType;
			
		if (w == EFT_IP && (*(word *)(pNIDP->db + pNIDP->offset + 20) ==  pNIFP->MSUDPPort)) {
			// if rxed Ethernet frame is Media stream, insert it to K-buffer directly
			freeNIDP(pNIDP);
			insKBuf(pNIDP->len - 28, pNIDP->db + pNIDP->offset + 28);
			return;
		} else {
			switch (w) {
				case EFT_IP:
					#ifdef debug_time
					TRACE("-- ethernet Type is IP(0x0800)\n\r");
					#endif
					desTaskID = TASK_IPIM;
					break;
				case EFT_ARP:
					#ifdef debug_time
					TRACE("-- ethernet Type is ARP(0x0806)\n\r");
					#endif
					desTaskID = TASK_ARPIM;
					break;
				default:
					// other protocol type, doesnot support, discard it simply
					isFrameLegal = false;
					break;
			}
					
			if (isFrameLegal) {
				#ifdef debug_time
				internalReport(ETH_RX_A_FRM);
				TRACE("NIC rx : %a\n\r", s, lenLowByte + 4);	// print [NIC rxed buffer Index + Ethernet frame(DA + SA +Type/len + PDU + CRC)]
				#endif
			
				memcpy(pNIDP->peerDevMAC, pFrm->SA, 6);
				memcpy(pNIDP->myMAC, pFrm->DA, 6);
						
				sendMail(desTaskID, TASK_NI_DRV, NIDP_IND, pNIDP);
			} else
				freeNIDP(pNIDP);
		}
		
		// move forword
		PAGE0_BNRY = nextPage;
		NICReadPtr = nextPage;
		
		canReadNICData = true;
	}
}

void NICRxBufOverflowProcess(void)
{
	bit 	reSend = false;
	byte	b;
	
	if (CR & 0x04)
		reSend = true;
	
	CR = 0x21;			// Issue the STOP command(CR = 0x21) to the NIC
	delayMsec(2);		// wait for at least 1.6ms
	
	// Clear Remote Byte Count Registers (RBCR0, RBCR1)
	PAGE0_RBCR0 = 0;
	PAGE0_RBCR1 = 0;
	
	if (reSend)
		if (PAGE0_ISR & 0x0a)
			reSend = false;
	
	setNICInLoopbackMode;
	selectInternalLoopbackMode;
	
	CR = 0x22;
	
	// NICRxFrame();
	
	// 2001-10-22 23:09
	setNICRegPage(1);
	b = PAGE1_CURR;
	setNICRegPage(0);
	PAGE0_BNRY = b;
		
	disableNICInLoopbackMode;
	
	if (reSend)
		CR = 0x26;
}

// void NICISR(void) interrupt 1
void NICISR(void)
{
	byte data	b;
	
	setNICRegPage(0);
	
	#ifdef debug_time
	TRACE("NICISR is invoked, PAGE0_ISR = %x\n\r", (int)PAGE0_ISR);
	#endif
	
	disableAllInt;
	
	b = PAGE0_ISR;
	
	// if (b & ISR_TallyCntMSBSet)
	
	if (b & ISR_RxBufferOverflow) {
		//#ifdef debug_time
		//internalReport(ETH_RXBUF_OVERFLOW);
		TRACE("NIC rx buffer overflow\n\r");
		//#endif
		NICRxBufOverflowProcess();
	}
		
	// #ifdef debug_time
	if (b & ISR_ErrorOnTx) {
		TRACE("NIC abort tx due to excessive collisions\n\r");	// report bad transmission
		// internalReport(ETH_TX_ERR);
	}
	
	if (b & ISR_ErrorOnRx) {
		// internalReport(ETH_RX_ERR);
		if (PAGE0_RSR & 0x10)
			TRACE("NIC rx a frame with Missed Packet\n\r");
		if (PAGE0_RSR & 0x04)
			TRACE("NIC rx a frame with Frame Aligment Error\n\r");
		if (PAGE0_RSR & 0x02)
			TRACE("NIC rx a frame with CRC error\n\r");
	}
	// #endif
	
	if (b & ISR_RxComplete) {
		// copy Rxed data in NIC Local Buffer to Host Memory
		 NICRxFrame();
	}
		
	// if (b & ISR_TxComplete)
		
	setNICRegPage(0);
	PAGE0_ISR = 0xff;				// clear ISR	
	enableAllInt;
}

// NIC Driver try to tx-out data from uper layer
void NICTxFrame(void)
{
	PMAIL 			data pMail;
	byte SPTR		data p;
	byte 			data i, len;
	PETHF			data pFrm;
	PNIDP			data pNIDP;

	#ifdef real_runtime
	if (CR & 0x04)
		return;					// read NIC command register, if it is transmitting something, wait
	#endif
	
	if ((pMail = getMail(TASK_NI_DRV)) == '\0')
		return;					// have no data to tx
	
	switch (pMail->header) {
		case NIDP_IND:
				
			/*-------------------------------------------------------------------------------*/
				
			/* assembly Ethernet frame */
			
			pNIDP = pMail->content.pNIDP;	
			len = pNIDP->len;
			p = pNIDP->db + pNIDP->offset;
							
			if (pNIDP->offset < ETH_HEADER_LEN || (len > (MAX_ETH_LEN - ETH_HEADER_LEN)))
			{
				// rxed Data Block from top layer is illegal, discard it
				#ifdef debug_time
				internalReport(ETH_TX_ERR);
				TRACE("NIC try to tx a frame, but failure due to the frame is illegal\n\r");
				TRACE("the frame is: %a\n\r", q, len);
				#endif
				
				freeNIDP(pNIDP);
				return;
			}
			
			pFrm = (PETHF)(p - ETH_HEADER_LEN);	
			
			// ethernet frame Type field
			switch(pMail->srcTaskID) {
				case TASK_IPIM:
					pFrm->frmType = EFT_IP;
					break;
				case TASK_ARPIM:
					pFrm->frmType = EFT_ARP;
					break;
				default:
					// rxed Data Block from top layer is illegal, discard it
					#ifdef debug_time
					internalReport(ETH_TX_ERR);
					TRACE("NIC try to tx a frame, but failure due to the frame's type is illegal\n\r");
					TRACE("the frame's type is: %x", (int)pFrm->frmType);
					#endif
					freeNIDP(pNIDP);
					return;			// other TASK's mail, discard
			}
				
			// SA field
			memcpy(pFrm->SA, pNIDP->myMAC, 6);
											
			// DA field
			memcpy(pFrm->DA, pNIDP->peerDevMAC, 6);
			
			break;
				
			/*-------------------------------------------------------------------------------*/
					
			default:
				return;			// other mail is meanless, so ignor it
	}
	
	if (len < 46) {
		p = p + pNIDP->offset + len;
		do {
			*p++ = 0x20;
		} while (++len < 46);
	}
	
	p = (byte SPTR)pFrm;
	len += ETH_HEADER_LEN;
	
	#ifdef debug_time
	internalReport(ETH_TRY_TO_TX_A_FRM);
	TRACE("NIC tx : %a\n\r", p, len);
	#endif
	
	disableAllInt;
	
	/*-------------------------------------------------------------------------------*/
	
	// copy data from Host memory to NIC local memory
	setNICRegPage(0);
	i = len + 1;
	i &= 0xfe;			// make even
	PAGE0_RSAR0 = 0;
	PAGE0_RSAR1 = NIC_TX_MIN_PAGE;
	PAGE0_RBCR0 = i;
	PAGE0_RBCR1 = 0;
	CR = 0x12;			// enable Remote DMA write
	i = _cror_(i, 1);	// need to loop half as many times because of word-wide transfers
	
	while (i--) {
		REMOTE_DMA_PORT = *p++;
		REMOTE_DMA_PORT = *p++;
	}
	
	#ifdef real_runtime
	waitRDMAOperationDone();
	#endif
			
	/*-------------------------------------------------------------------------------*/
	
	// enbale NIC to tx the frame
	
	PAGE0_TPSR = NIC_TX_MIN_PAGE;
	PAGE0_TBCR0 = len;	// in the project, length of all frame MUST less than 256 bytes
	PAGE0_TBCR1 = 0;
	CR = 0x26;			// NIC start transmission
	enableAllInt;
	
	freeNIDP(pNIDP);
	
	NICTxedFrameCnt++;
}

⌨️ 快捷键说明

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