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

📄 mac.c

📁 台湾亚信电子ASIX11015以太网驱动.AX系列单片机带TCP/IP协议栈,和适合网络应用.希望和大家一起探讨
💻 C
字号:
/*
 ******************************************************************************
 *     Copyright (c) 2006	ASIX Electronic Corporation      All rights reserved.
 *
 *     This is unpublished proprietary source code of ASIX Electronic Corporation
 *
 *     The copyright notice above does not evidence any actual or intended
 *     publication of such source code.
 ******************************************************************************
 */
/*=============================================================================
 * Module Name: mac.c
 * Purpose:  
 * Author:
 * Date:
 * Notes:
 * $Log: mac.c,v $
 * Revision 1.1.1.1  2006/02/23 00:55:10  borbin
 * no message
 *
 *=============================================================================
 */

/* INCLUDE FILE DECLARATIONS */
#include "reg80390.h"
#include "mac.h"
#include "stoe.h"

/* GLOBAL VARIABLES DECLARATIONS */
static U8_T XDATA mac_InterruptStatus = 0;

/* LOCAL SUBPROGRAM DECLARATIONS */
static void mac_InterruptEnable(void);
static void mac_StartOperate(void);

/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_ReadReg
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_ReadReg(U8_T regaddr, U8_T XDATA* pbuf, U8_T length)
{
	U8_T	isr;

	isr = EA;
	EA = 0;
	MCIR = regaddr;
	while (length--)
		pbuf[length] = MDR;
	EA = isr;

} /* End of mac_ReadReg */

/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_WriteReg
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_WriteReg(U8_T regaddr, U8_T XDATA* pbuf, U8_T length)
{
	U8_T	isr;

	isr = EA;
	EA = 0;
	while (length--)
		MDR = pbuf[length];
	MCIR = regaddr;
	EA = isr;

} /* End of mac_WriteReg */

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_Init
 * Purpose: initial all registers and variables of MAC.
 * Params: network_type -0: auto- negotiation
 *						-1: fixed 100 full speed.
 *						-2: fixed 100 half speed.
 *						-3: fixed 10 full speed.
 *						-4: fixed 10 half speed.
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_Init(U8_T network_type)
{
	U8_T XDATA	temp;

	/* read MAC address*/
	mac_ReadReg(MAC_ADDR_REG, PNetStation->CurrStaAddr, MAC_ADDRESS_LEN);

	/* use internal phy */
	temp = (PHY_SELECT_EMBEDDED | PHY_INTERNAL_PHY_OPERA_STATE);
	mac_WriteReg(MAC_PHY_CTL_REG, &temp, 1);

	PBDP->MacInfo.MediumLinkType = MEDIUM_ENABLE_RECEIVE;
	PBDP->MacInfo.FullDuplex = 1;
	switch (network_type)
	{
	default:
	case AUTO_NEGOTIATION:
		PBDP->MacInfo.NetworkType = MAC_AUTO_NEGOTIATION;
		PBDP->MacInfo.MediumLinkType |=(MEDIUM_FULL_DUPLEX_MODE | MEDIUM_MII_100M_MODE |
			MEDIUM_ENABLE_TX_FLOWCTRL | MEDIUM_ENABLE_RX_FLOWCTRL);
		break;
	case FIXED_100_FULL:
		PBDP->MacInfo.NetworkType = (MAC_LINK_100M_SPEED | MAC_LINK_FULL_DUPLEX);
		PBDP->MacInfo.MediumLinkType |=(MEDIUM_FULL_DUPLEX_MODE | MEDIUM_MII_100M_MODE |
			MEDIUM_ENABLE_TX_FLOWCTRL | MEDIUM_ENABLE_RX_FLOWCTRL);
		break;
	case FIXED_100_HALF:
		PBDP->MacInfo.NetworkType = MAC_LINK_100M_SPEED;
		PBDP->MacInfo.MediumLinkType |= MEDIUM_MII_100M_MODE;
		break;
	case FIXED_10_FULL:
		PBDP->MacInfo.NetworkType = (MAC_LINK_10M_SPEED | MAC_LINK_FULL_DUPLEX);
		PBDP->MacInfo.MediumLinkType |= (MEDIUM_FULL_DUPLEX_MODE |
			MEDIUM_ENABLE_TX_FLOWCTRL | MEDIUM_ENABLE_RX_FLOWCTRL);
		break;
	case FIXED_10_HALF:
		PBDP->MacInfo.NetworkType = MAC_LINK_10M_SPEED;
		break;
	}
	/* set medium status */
	mac_WriteReg(MAC_MEDIUM_STATUS_MODE_REG, &PBDP->MacInfo.MediumLinkType, 1);

	/* set RX filter. */
	temp = BIT6;
	mac_WriteReg(MAC_RX_CTL_REG, &temp, 1);
	MAC_SetRxFilter(MAC_RCV_BROADCAST);

	PBDP->MacInfo.LinkSpeed = 0; // Ethernet not linkup.

	/* decide interrupt mask */
#if (MAC_GET_INTSTATUS_MODE == MAC_INTERRUPT_MODE) 
	PBDP->MacInfo.InterruptMask = PRIMARY_LINK_CHANGE_ENABLE;
#endif

	/* phy initialize. */
	PHY_Init(network_type);

} /* End of MAC_Init() */

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_Start
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_Start(void)
{
#if (MAC_GET_INTSTATUS_MODE == MAC_INTERRUPT_MODE) 
	U8_T XDATA	temp;

	/* clear mac interrupt status */
	mac_ReadReg(MAC_WAKEUP_LINK_INT_STATUS_REG, &temp, 1);

	/* enable mac interrupt */
	mac_InterruptEnable();
#endif

	/* start mac to receive/transmit packets */
	mac_StartOperate();

} /* End of MAC_Start() */

/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_StartOperate
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_StartOperate(void)
{
	U8_T XDATA	temp;

	mac_ReadReg(MAC_RX_CTL_REG, &temp, 1);

	/* set mac register to start receive/transmit packets. */
	temp |= START_OPERATION;
	mac_WriteReg(MAC_RX_CTL_REG, &temp, 1);

} /* End of mac_StartOperate */

#if 0
/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_StopOperate
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_StopOperate(void)
{
	U8_T XDATA	temp;

	mac_ReadReg(MAC_RX_CTL_REG, &temp, 1);

	temp &= ~START_OPERATION;
	mac_WriteReg(MAC_RX_CTL_REG, &temp, 1);

} /* End of mac_StopOperate */
#endif

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_SetRxFilter
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_SetRxFilter(U8_T filter)
{
	U8_T XDATA	temp;

	mac_ReadReg(MAC_RX_CTL_REG, &temp, 1);

	/* set rcv filter. */
	temp &= 0xc0;
	if (filter & MAC_RCV_PROMISCUOUS)
		temp |= PACKET_TYPE_PROMISCOUS;
	if (filter & MAC_RCV_ALL_MULTICAST)
		temp |= PACKET_TYPE_ALL_MULTI;
	if (filter & MAC_RCV_BROADCAST)
		temp |= PACKET_TYPE_BROADCAST;
	if (filter & MAC_RCV_MULTICAST)
		temp |= PACKET_TYPE_MULTICAST;

	mac_WriteReg(MAC_RX_CTL_REG, &temp, 1);

} /* End of MAC_SetRxFilter() */

#if (MAC_GET_INTSTATUS_MODE == MAC_INTERRUPT_MODE) 
/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_InterruptEnable
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_InterruptEnable(void)
{
	U8_T XDATA	temp;

	/* set link change interrupt enable */
	temp = PBDP->MacInfo.InterruptMask;
	mac_WriteReg(MAC_LINK_CHANGE_INT_ENABLE_REG, &temp, 1);

} /* End of mac_InterruptEnable */

#if 0
/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_InterruptDisable
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void mac_InterruptDisable(void)
{
	U8_T XDATA	temp;

	temp = 0;
	mac_WriteReg(MAC_LINK_CHANGE_INT_ENABLE_REG, &temp, 1);

} /* End of mac_InterruptDisable */

#endif

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_SetInterruptFlag
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_SetInterruptFlag(void)
{
	mac_ReadReg(MAC_WAKEUP_LINK_INT_STATUS_REG, &mac_InterruptStatus, 1);
	if (!(mac_InterruptStatus & STATUS_PRIMARY_LINK_CHANGE))
		mac_InterruptStatus = 0;

} /* End of MAC_SetInterruptFlag() */

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_GetInterruptFlag
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
U8_T MAC_GetInterruptFlag(void)
{
	U8_T flag;

	EA = 0;
	flag = mac_InterruptStatus;
	EA = 1;

	return flag;

} /* End of MAC_GetInterruptFlag() */
#endif

/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_GetMediaType
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
U8_T mac_GetMediaType(void)
{
	U16_T	phylinkstatus;

	phylinkstatus = PHY_CheckMediaType();

	PBDP->MacInfo.FullDuplex = TRUE;

	/* Determine if we're linked to 100 full duplex. */
	if (phylinkstatus & ANLPAR_100TXFD)
	{
		PBDP->MacInfo.LinkSpeed = 100;
		PBDP->MacInfo.MediumLinkType = (MEDIUM_FULL_DUPLEX_MODE | MEDIUM_ENABLE_RECEIVE |
			MEDIUM_MII_100M_MODE);
//		printf ("Link to 100 FULL.\n\r");
	}
	/* Determine if we're linked to 100 half duplex. */
	else if (phylinkstatus & ANLPAR_100TX)
	{
		PBDP->MacInfo.LinkSpeed = 100;
		PBDP->MacInfo.MediumLinkType = (MEDIUM_ENABLE_RECEIVE | MEDIUM_MII_100M_MODE);
		PBDP->MacInfo.FullDuplex = FALSE;
//		printf ("Link to 100 HALF.\n\r");
	} 
	/* Determine if we're linked to 10 full duplex. */
	else if (phylinkstatus & ANLPAR_10TFD)
	{
		PBDP->MacInfo.LinkSpeed = 10;
		PBDP->MacInfo.MediumLinkType = (MEDIUM_FULL_DUPLEX_MODE | MEDIUM_ENABLE_RECEIVE);
//		printf ("Link to 10 FULL.\n\r");
	}
	/* we're linked to 10 half duplex. */
	else
	{
		PBDP->MacInfo.LinkSpeed = 10;
		PBDP->MacInfo.MediumLinkType = MEDIUM_ENABLE_RECEIVE;
		PBDP->MacInfo.FullDuplex = FALSE;
//		printf ("Link to 10 HALF.\n\r");
	}

	if (PBDP->MacInfo.FullDuplex)
		PBDP->MacInfo.MediumLinkType |= (MEDIUM_ENABLE_TX_FLOWCTRL | MEDIUM_ENABLE_RX_FLOWCTRL);

	mac_WriteReg(MAC_MEDIUM_STATUS_MODE_REG, &PBDP->MacInfo.MediumLinkType, 1);

	return PBDP->MacInfo.LinkSpeed;

} /* End of mac_GetMediaType */

#if (MAC_GET_INTSTATUS_MODE == MAC_INTERRUPT_MODE)
/*
 * ----------------------------------------------------------------------------
 * Function Name: mac_LinkSpeedChk
 * Purpose:
 * Params: none
 * Returns:	100: Ethernet is link to 100M
 *			10 : Ethernet is link to 10M
 *			0  : not link
 * Note:
 * ----------------------------------------------------------------------------
 */
U8_T mac_LinkSpeedChk(void)
{
	if (mac_InterruptStatus & STATUS_PRIMARY_IS_LINK_UP)
	{
		if (PBDP->MacInfo.NetworkType == MAC_AUTO_NEGOTIATION)
			mac_GetMediaType();
	}
	else
	{
//		printf ("Ethernet is now unlink.\n\r");
		if (PBDP->MacInfo.LinkSpeed)
			PBDP->MacInfo.LinkSpeed = 0;
	}

	return PBDP->MacInfo.LinkSpeed;

} /* End of mac_LinkSpeedChk */

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_ProcessInterrupt
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_ProcessInterrupt(void)
{
	if (mac_InterruptStatus & STATUS_PRIMARY_LINK_CHANGE)
		mac_LinkSpeedChk();

	mac_InterruptStatus = 0;

} /* End of MAC_ProcessInterrupt */
#else
/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_LinkSpeedChk
 * Purpose:
 * Params: none
 * Returns:	100: Ethernet is link to 100M
 *			10 : Ethernet is link to 10M
 *			0  : not link
 * Note:
 * ----------------------------------------------------------------------------
 */
U8_T MAC_LinkSpeedChk(void)
{
	mac_ReadReg(MAC_WAKEUP_LINK_INT_STATUS_REG, &mac_InterruptStatus, 1);
	if (mac_InterruptStatus & STATUS_PRIMARY_IS_LINK_UP)
	{
		if (PBDP->MacInfo.LinkSpeed == 0)
		{
			if (PBDP->MacInfo.NetworkType == MAC_AUTO_NEGOTIATION)
				mac_GetMediaType();
			else
				PBDP->MacInfo.LinkSpeed = PBDP->MacInfo.NetworkType & 0x7f;
		}
	}
	else
	{
//		printf ("Ethernet is now unlink.\n\r");
		if (PBDP->MacInfo.LinkSpeed)
			PBDP->MacInfo.LinkSpeed = 0;
	}

	return PBDP->MacInfo.LinkSpeed;

} /* End of MAC_LinkSpeedChk */
#endif

#if (MAC_REMOTE_WAKEUP == MAC_SUPPORT)
/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_WakeupEnable
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_WakeupEnable(U8_T type)
{
	U8_T	temp = 0;

	if (type & MAC_PRIMARY_PHY_LINK_WAKEUP)
		temp |= WAKEUP_BY_PRIMARY_LINK_UP;
	if (type & MAC_MAGIC_PACKET_WAKEUP)
		temp |= WAKEUP_BY_MAGIC_PACKET;
	if (type & MAC_EXTERNAL_PIN_WAKEUP)
		temp |= WAKEUP_BY_EXTER_PIN_TRIG;
//	if (type & MAC_MS_FRAME_WAKEUP)
//		temp |= WAKEUP_BY_MICROSOFT_FRAME;

	mac_WriteReg(MAC_WAKEUP_INT_ENABLE_REG, &temp, 1);

} /* End of MAC_WakeupEnable() */
#endif

#if (MAC_MULTICAST_FILTER == MAC_SUPPORT)
/*
* -----------------------------------------------------------------------------
 * Function Name: mac_ComputeCrc32
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
U32_T mac_ComputeCrc32(U16_T length, U8_T* pbuf)
{
	U32_T	crc32 = 0xffffffff;
	U8_T	curByte, carry, j;
	
	for (; length; length--)
	{
		curByte = *pbuf++;
		for (j=0; j<8; j++)
		{
			carry = curByte & 1;
			if ( crc32 & 0x80000000 )
				carry ^= 1;
			crc32 <<= 1;
			curByte >>= 1;
			if (carry)
				crc32 ^= 0x04c11db7;
		}
	}
	return crc32;

} /* End of mac_ComputeCrc32() */

/*
 * ----------------------------------------------------------------------------
 * Function Name: MAC_MultiFilter
 * Purpose:
 * Params:
 * Returns:
 * Note:
 * ----------------------------------------------------------------------------
 */
void MAC_MultiFilter(U8_T* pbuf, U8_T len)
{
	U8_T	count = len/MAC_ADDRESS_LEN;
	U8_T	index, bitNum;
	U8_T 	filter[8] = {0};

	for (index = 0; index < count; index++)
	{
		if (!(pbuf[0] & 1))
			break;

		bitNum = (U8_T)((mac_ComputeCrc32(MAC_ADDRESS_LEN, pbuf)>>26)&0x3f);
		pbuf += MAC_ADDRESS_LEN;
		filter[7 - (bitNum/8)] |= (1 << (bitNum % 8));
	}

	mac_WriteReg(MAC_MULTICASE_REG, filter, 8);

} /* End of MAC_MultiFilter() */
#endif


/* End of mac.c */

⌨️ 快捷键说明

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