📄 mac.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 + -