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

📄 f91mac.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
📖 第 1 页 / 共 2 页
字号:
 /*
 * Copyright 2001, Metro Link, Inc.
 * All Rights Reserved
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Metro Link, Inc. and may
 * contain proprietary, confidential and trade secret information of
 * Metro Link, Inc. and/or its partners.
 *  
 * The contents of this file may not be disclosed to third parties, copied or
 * duplicated in any form, in whole or in part, without the prior written
 * permission of Metro Link, Inc.
 *
 */
/*
* File			:	F91mac.c
*
* Description	:	Driver source file for ez80F91 ethernet controller
*					
* 
* Copyright 2004 ZiLOG Inc.  ALL RIGHTS RESERVED.
*
* This file contains unpublished confidential and proprietary information
* of ZiLOG, Inc.
* NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED 
* IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
* This is not a license and no use of any kind of this work is authorized
* in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's 
* sole discretion 
*/


#include <stdio.h>
#include <string.h>
#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZTimer.h"
#include "ZMessageQ.h"
#include "ZInterrupt.h"
#include "ZDevice.h"
#include "ZSemaphore.h"
#include "_ez80.h"
#include "emacF91.h"
#include "EtherMgr.h"
#include "AMD79C874_phy.h"
#include "wdt.h"  //gym add

#define ETH_PKT_ADD_LEN 	6

extern void SetPDState(int bitindex,short int level);//gym add
extern	void		emacisr(void) ;
extern	void*	RZKMemcpy(void *, const void *, RZK_LENGTH_t) ;
extern	INT		phyInit(void) ;
extern	UINT	rxBlockTime ;
extern	UINT8	EMAC_Task_Stack[] ;
extern	UINT8	EMAC_TASK_PRIO ;
extern	UINT	EMAC_THD_STACK_SIZE ;
extern	UINT16	EMAC_MQ_SIZE ;
extern	UINT8	EMAC_Message_Buff[] ;

extern	RZK_MESSAGEQHANDLE_t rxQueueHandle ; /* receive queue handle */
extern	const F91_EMAC_CONF_t F91_emac_config ;

extern void emacConnThd(void) ;

QUEUE_REF_t txQueueReference = { (QUEUE_NODE_t*)NULL, (QUEUE_NODE_t*)NULL}; 
INT8	* pInternalSramBase;	// 24-bit address of internal MAC SRAM

/*
 * Pointers into EMAC shared memory for buffer management.
*/
DESC_TBL_t *			twp;	/* Transmit write pointer */
DESC_TBL_t *			trp;	/* Transmit read pointer */
DESC_TBL_t *			rwp;	/* Receive write pointer */
DESC_TBL_t *			rrp;	/* Receive read pointer */
DESC_TBL_t *			tlbp;	/* Transmit low boundary pointer */
DESC_TBL_t *			bp;	/* Boundary Pointer */
DESC_TBL_t *			rhbp;	/* Receive high boundary pointer */

UINT16					bufMask;
UINT16					bufSize;
UINT16					bufSizeShift;

UINT16					txBufsLeft;	/* counts tx pkt buffers left */
UINT16					rxBufsLeft;	/* counts rx pkt buffers left*/

static INT32 			crc; /* For crc calculation */
static UINT32			polynomial;

/* Common to all drivers */
ETH_DEV_STRUCT_t       	emac[1];
void					(*	rxnotifyfunc)(void);
INT8              		bRxCount = 0; /* Received packet count */

/* Error counters */
UINT16       			crcErrors ;					
UINT16       			runtErrors	;
UINT16       			excessLengthErrors	;
UINT16       			rxMissCount	;
UINT16       			txColCount	;

INT8 					doingTx = RZK_FALSE; /* Transmit busy flag */
ETH_PKT_t*				txPepNext;
QUEUE_NODE_t			emacTxQueue;

/* These can be added to the device structure */
RZK_THREADHANDLE_t		emacInterruptThdHdl ;	/* emac interrupt thread handle */
RZK_THREADHANDLE_t		emacConnChkThdHdl ;	

//UINT8 EMAC_Conn_Stack[512] ;
RZK_SEMAPHOREHANDLE_t g_MacSem;

DDF_STATUS_t EthPktTransmit (ETH_PKT_t *	pep )
{

DDF_STATUS_t  status = pep->ethPktLen ;

	if( pep->ethPktLen <= (MAX_DATA_SIZE + HEADER_SIZE) ) 
	{

//		status = EMACDEV_ERR_TX_WAITING;
//		stat = RZKDisablePreemption();
		RZKAcquireSemaphore(g_MacSem,MAX_INFINITE_SUSPEND);
		PutToQueue(&txQueueReference, &pep->link) ;
		TransmitNextPkt();
		RZKReleaseSemaphore(g_MacSem);
//		RZKRestorePreemption(stat);
	}
	else
	{
		status = EMACDEV_ERR_PKTTOOBIG ;
	}

	return( status );

}


void TransmitNextPkt ()
{


	if( doingTx == RZK_FALSE )
	{
		txPepNext = (ETH_PKT_t*)GetFromQueue(&txQueueReference) ;
		if( txPepNext )
		{
			doingTx = RZK_TRUE;
			SendNow( (EMAC_FRAME_t *) &txPepNext->ethPktOrder );
		}
	}

}


void SendNow(EMAC_FRAME_t* databuff)
{
	DESC_TBL_t * 	NextPkt;
	UINT16					Len = databuff->length;
	UINT16					WrapLen;
	INT8 *				pSrc;
	INT8 *				pDst;


	/*
	 * Calculate the address of the emac packet buffer that will immediately 
	 * follow the one about to transmitted. Before giving the current
	 * packet to the emac HW, set the ownership of the next packet buffer to
	 * Host Owns so the emac HW does not try to transmit the frame.
	 *
	 * Note: this implementation only sends 1 packet at a time and the the 
	 * init routine has already verified that a max sized frame can fit in the 
	 * emac Tx buffer.  Therefore there is no need to track how many ehternet 
	 * buffers remain.
	 */
	NextPkt = (DESC_TBL_t*) ((INT8*)twp + ((Len+bufSize-1+DATA_OS) & (bufMask)));
	if( NextPkt >= bp )
	{
		NextPkt = (DESC_TBL_t*)((INT8*)tlbp + ((INT8*)NextPkt - (INT8*)bp));
	}
	NextPkt->stat = HOST_OWNS;

	twp->np = NextPkt;
	twp->pktsz = Len;
//	asm("\tdi") ;
	/*
	 * Copy packet data into the emac Tx buffer.  Check to see if the data will
	 * wrap around the end of the transmit buffer.
	 */
   pSrc = (INT8*)&databuff->dstAddr[0];
	pDst = (INT8*)twp+DATA_OS;

	WrapLen = (INT8*)bp - pDst;

	if( WrapLen >= Len )
	{	// No wrap
		RZKMemcpy( pDst, pSrc, Len );
	}
	else
	{	// Wrap
		RZKMemcpy( pDst, pSrc, WrapLen );
		RZKMemcpy( tlbp, &pSrc[WrapLen], (Len-WrapLen) );
	}
//	asm("\tei") ;
	/*
	 * Set the status to Emac owns so the HW will begin trnamitting the frame.
	 */
	twp->stat = EMAC_OWNS;
	twp = NextPkt;
}



void EthTransmit(void)
{
	DESC_TBL_t * 				HW_TRP;


//	stat = RZKDisablePreemption();
	RZKAcquireSemaphore(g_MacSem,MAX_INFINITE_SUSPEND);
	EMAC_ISTAT = TXDONE;

	/*
	 * Determine the location of HW Transmit Read Poiter
	 */
	HW_TRP = (DESC_TBL_t*)(pInternalSramBase + EMAC_TRP_L + ((UINT16)EMAC_TRP_H<<8));

	/*
	 * Verify the current tx frame was sent
	 */
	if( trp->stat & TxAbort )
	{
		// Give the frame back to the MAC
		trp = HW_TRP;
		SendNow( (EMAC_FRAME_t *) &txPepNext->ethPktOrder );
	}
	else
	{
		trp = HW_TRP;
		doingTx = RZK_FALSE;
		TransmitNextPkt();
	}
	RZKReleaseSemaphore(g_MacSem);
//	RZKRestorePreemption(stat);
}








//Receive Packet Processing
void ReceiveEthPkt(EMAC_FRAME_t * databuff)
{
	UINT16        temp;
	INT8*     psrc;
	INT8*     pdst;
	UINT16        txferSz;

   txferSz = rrp->pktsz - CRCSIZE;

	// set databuff->Flags from rx descriptor status
	databuff->flags  = rrp->stat;
	databuff->length = txferSz;
      
	// move the data from the rx ring buffers into system buffer
	pdst = (INT8*)&databuff->dstAddr[0];
	psrc = (INT8*)rrp+DATA_OS;


	if (psrc+txferSz > (INT8*)rhbp)
	{
		temp = (INT8*)rhbp - psrc;
		RZKMemcpy(pdst, psrc, temp);
		RZKMemcpy(&pdst[temp], bp, txferSz-temp);
   }
   else
   {
      RZKMemcpy(pdst, psrc, txferSz);
   }			
}







//Receive Interrupt Processing
void EthReceive(void) 
{

//	struct ETH_DEV_STRUCT_t	*	ped=&(emac[0]);
//	ETH_PKT_t *	pep;                    // Commented during IAR Porting
//	ETH_DEV_STRUCT_t	*ped=&emac[0];  // Commented during IAR Porting
	UINT16 temp;
//	RZK_STATUS_t status ;   // Commented during IAR Porting
   

	if( rrp->np == ((DESC_TBL_t*)(pInternalSramBase + EMAC_RWP_L + ((UINT16)EMAC_RWP_H<<8))) )
	{
		EMAC_ISTAT = RXDONE;//rx_stat;
	}

	// update error/event counters
	temp = rrp->stat;

	if( temp & RxCrcError )
		/*CRCErrors++*/;

	if (rrp->pktsz < MINFRAMESIZE)
	{
		/*RuntErrors++;*/
		temp &= ~RxOK;
	}
	if (rrp->pktsz > MAXFRAMESIZE)
	{
		/*ExcessLengthErrors++;*/
		temp &= ~RxOK;
	}

	if( (rxnotifyfunc != 0) && (temp & RxOK) )
	{
		rxnotifyfunc();
	}
   
   if(temp & (UINT16)RxOVR)
   {
//      kprintf( "F91 emac Rx Overrun.\n" );
      EMAC_ISTAT = RXOVRRUN;
   }   
   
	// update rrp to next pkt
	rrp = rrp->np;
	
	// update rrp i/o reg - for h/w rx buffer counting
	// must do this or we'll run outofbufs.
	EmacRrp = (UINT32)rrp;

}




void F91EmacTask( void )
{
	INT8								bIntStat;
	UINTRMASK intmask ;
	
//	KE_DisableMI();
	
	while( 1 )
	{
//		KE_EnableMI();
		bIntStat = EMAC_ISTAT & (RXDONE | RXOVRRUN | TXDONE);

		while( bIntStat )
		{
			if( bIntStat & RXDONE )
			{
				EthReceive();
			}

			if( bIntStat & TXDONE )
			{
				EthTransmit();
			}

			bIntStat = EMAC_ISTAT & (RXDONE | RXOVRRUN | TXDONE);
		}

		intmask = RZKDisableInterrupts() ;
		EMAC_IEN = RXDONEIEN | TXDONEIEN;									
		RZKSuspendInterruptThread() ;
		RZKEnableInterrupts(intmask) ;

	}
}








/***************************************************************************************************/
/* Accessory Functions */



//writing into the AMD 79C874 PHY registers.
UINT16 WritePhyReg(UINT16 phy_reg, UINT16 data)
{
	// write the phy reg
	EmacCtld= data;
	EMAC_RGAD = phy_reg;
	EMAC_MIIMGT |= LCTLD;
	// wait for mii done
	while(EMAC_MIISTAT & MGTBUSY);
	return EMACDEV_ERR_SUCCESS ;

⌨️ 快捷键说明

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