📄 halw90p710mac.c
字号:
/*
* 修改记录:
* 20060310 创建该文件。
* 20040518 M4修正更新。
*
*/
/**
* @file halw90p710mac.h
* @brief
* <li>功能: 实现W90P710MAC设备的HAL,该HAL目前仅支持网络组件的DLL</li>
* @date 20060925
*/
/**************************** 引用部分 *****************************************/
#include <board.h>
#include <delta.h>
#include "stdlib.h"
#include "halw90p710mac.h"
/*************************** 前向声明部分 ****************************************/
T_MODULE T_BOOL Probe(T_HAL_W90P710MAC_DEV_DATA *vpEtherDevData);
T_MODULE T_VOID init_rxtx_rings(T_HAL_W90P710MAC_DEV_DATA *vpEtherDevData);
T_VOID ResetMAC(T_HAL_W90P710MAC_DEV_DATA *vpEtherDevData);
T_VOID p710_WriteCam(T_WORD which,T_WORD x, T_UBYTE *pval);
T_VOID ResetP(T_WORD num);
T_WORD MiiStationWrite(T_WORD num,T_UWORD PhyInAddr,T_UWORD PhyAddr,T_UWORD PhyWrData);
T_UWORD MiiStationRead(T_WORD num, T_UWORD PhyInAddr, T_UWORD PhyAddr);
T_WORD ResetPhyChip(T_WORD num);
/**************************** 定义部分 *****************************************/
/* Global variables used for MAC driver */
T_MODULE T_UWORD gMCMDR = MCMDR_SPCRC | MCMDR_EnMDC | MCMDR_ACP ;//|MCMDR_LBK;
T_MODULE T_UWORD gMIEN = EnTXINTR | EnRXINTR | EnRXGD | EnTXCP |
EnTxBErr | EnRxBErr | EnTXABT;//| EnTXEMP;//EnDEN
/**************************** 实现部分 *****************************************/
/**
* @brief
* 确认设备的存在,对于需要动态获得系统参数的设备
* 需要在此处把系统资源占用信息更新。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功 。
* FALSE 失败。
*/
T_BOOL W90P710MAC_Find(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
T_WORD retval;
// 确认W90P710MACMAC的存在,更新配置表项
retval = Probe(tpEtherDevDataTable);
return retval;
}
/**
* @brief
* 该接口用来获取HAL管理该设备需要的资源(主要指内存)
* HAL不应该再再别的地方进行资源的获取工作,该接口获得的资源将都被传给HAL中其他接口使用。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功 (始终返回该值)。
*/
T_BOOL W90P710MAC_GetResource(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
static int which=0; //Only one mac for W90P710
tpEtherDevDataTable->p710_priv = malloc(sizeof(T_EiStatus));
if( tpEtherDevDataTable->p710_priv == NULL )
{
return FALSE;
}
tpEtherDevDataTable->p710_priv->which = which;
tpEtherDevDataTable->p710_priv->cur_tx_entry = 0;
tpEtherDevDataTable->p710_priv->cur_rx_entry = 0;
return TRUE;
}
/**
* @brief
* 关闭设备的中断。工作就是屏蔽在ChipIntEnable中使能的中断类型。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功(始终返回该值)。
*/
T_BOOL W90P710MAC_ChipIntDisable(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
int which ;
which= tpEtherDevDataTable->p710_priv->which;
p710_WriteReg(MIEN ,0,which); // MAC Interrupt Enable Register TX/RX Disable
return TRUE;
}
/**
* @brief
* 启动设备的运行,对设备进行基本初始化工作.主要工作包括:
* 1.获取HAL为了驱动该设备所需要的系统资源,一般指内存空间;
* 2.设置设备寄存器,让设备工作在正常状态下;
* 3.注意该接口不要关心设备的中断开关状态。
*
* @param[in] pEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return
* FALSE 失败
* TRUE 成功
*/
T_BOOL W90P710MAC_Start(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
int which ;
which= tpEtherDevDataTable->p710_priv->which;
/*设置MAC地址*/
tpEtherDevDataTable->p710_priv->devmac[0] = tpEtherDevDataTable->mac0;
tpEtherDevDataTable->p710_priv->devmac[1] = tpEtherDevDataTable->mac1;
tpEtherDevDataTable->p710_priv->devmac[2] = tpEtherDevDataTable->mac2;
tpEtherDevDataTable->p710_priv->devmac[3] = tpEtherDevDataTable->mac3;
tpEtherDevDataTable->p710_priv->devmac[4] = tpEtherDevDataTable->mac4;
tpEtherDevDataTable->p710_priv->devmac[5] = tpEtherDevDataTable->mac5;
init_rxtx_rings(tpEtherDevDataTable);
ResetMAC(tpEtherDevDataTable);
tpEtherDevDataTable->p710_priv->rx_ptr= tpEtherDevDataTable->p710_priv->start_rx_ptr ;
tpEtherDevDataTable->p710_priv->tx_ptr= tpEtherDevDataTable->p710_priv->start_tx_ptr ;
p710_WriteReg(FIFOTHD,0x10000,which); //0x10100
p710_WriteReg(FIFOTHD,0x100300,which); //0x10100
p710_WriteReg(RXDLSA,tpEtherDevDataTable->p710_priv->start_rx_ptr,which);
p710_WriteReg(TXDLSA,tpEtherDevDataTable->p710_priv->start_tx_ptr,which);
p710_WriteReg(DMARFC,2000,which);
p710_WriteCam(tpEtherDevDataTable->p710_priv->which,0,tpEtherDevDataTable->p710_priv->devmac);
p710_WriteReg(CAMEN, p710_ReadReg(CAMEN,tpEtherDevDataTable->p710_priv->which) | 1,tpEtherDevDataTable->p710_priv->which);
p710_WriteReg(CAMCMR,CAMCMR_ECMP|CAMCMR_ABP|CAMCMR_AMP,which);
//p710_WriteReg(CAMCMR,CAMCMR_ECMP|CAMCMR_ABP|CAMCMR_AMP|CAMCMR_AUP,which);
p710_WriteReg(MCMDR,1<<19,which);
ResetP(which);
if(ResetPhyChip(which)==1)
{
tpEtherDevDataTable->p710_priv->plugout=1;
return FALSE;
}
else
tpEtherDevDataTable->p710_priv->plugout=0;
/* Configure the MAC control registers. */
p710_WriteReg(MIEN,gMIEN,which);
p710_WriteReg(MCMDR,p710_ReadReg(MCMDR,which)|gMCMDR,which);
p710_WriteReg(MCMDR,p710_ReadReg(MCMDR,which)|MCMDR_RXON,which);
tpEtherDevDataTable->p710_priv->mcmdr=p710_ReadReg(MCMDR,which);
tpEtherDevDataTable->p710_priv->bInit=1;
tpEtherDevDataTable->p710_priv->rx_packets=0;
tpEtherDevDataTable->p710_priv->rx_bytes=0;
p710_WriteReg(RSDR ,0,which);
return TRUE;
}
/**
* @brief
* 使能设备中断。设备也许有多种类型的中断,网络组件只关心发送和接收中断而已
* 其他中断类型的处理将由HAL本身负责解释并响应。所以此处使能的中断类型应该包括
* 发送中断和接收中断,其他类型中断由HAL自行决定。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功(始终返回该值)。
*/
T_BOOL W90P710MAC_ChipIntEnable(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
int which ;
which= tpEtherDevDataTable->p710_priv->which;
//Enable_Int(INT_EMCTXINT0);
//Enable_Int(INT_EMCRXINT0);
p710_WriteReg(MIEN,gMIEN,which); // MAC Interrupt Enable Register TX/RX enable
return TRUE;
}
/**
* @brief
* 发送数据包,把从DLL传来的数据包发送出去。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[in] bpKtBuf 数据包所在的缓存指针。
* @param[in] wKtLen 数据包大小。
*
* @return
* FALSE 失败
* TRUE 成功
*/
T_BOOL W90P710MAC_SendPkt(T_VOID *vpEtherDevData, T_CHAR *bpKtBuf, T_WORD wKtLen)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
int which;
TXBD *txbd;
which = tpEtherDevDataTable->p710_priv->which;;
txbd=( TXBD *)tpEtherDevDataTable->p710_priv->tx_ptr;
//Check Frame Length
if(wKtLen>1514)
{
wKtLen=1514;
}
txbd->SL = wKtLen & 0xFFFF;
memcpy((void *)txbd->buffer,bpKtBuf,wKtLen);
txbd->mode=(PaddingMode | CRCMode | MACTxIntEn);
txbd->mode|= TXfOwnership_DMA;
{
int val=p710_ReadReg(MCMDR,which);
if(!(val & MCMDR_TXON))
{
//printk("****p710_WriteReg(MCMDR\n");
p710_WriteReg(MCMDR,val|MCMDR_TXON,which);
}
p710_WriteReg(TSDR ,0,which);
}
txbd=(TXBD *)txbd->next;
tpEtherDevDataTable->p710_priv->tx_ptr=(unsigned long)txbd;
return TRUE;
}
/**
* @brief
* 获取中断类型。当设备发生中断时,该接口将被调用。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[in] uwVector 产生中断的中断向量。
* @param[out] *wpIntInfo 设备的中断信息,当返回的中断类型中包括"其他中断类型"
时,该参数将被传给HandleOtherIntType的HAL接口。
*
* @return 当发生多种中断类型时,把如下的返回值采用‘位或’运算后再返回。
* DEV_NO_INTERRUPT 该设备没有发生中断。
* DEV_INT_HAD_HANDLED 设备发生了中断,但已经被处理了。
* DEV_RECEIVE_INTERRUPT 设备发生了接收中断。
* DEV_SENDOVER_INTERRUPT 设备发生了发生中断。
* DEV_OHER_INTTYPE 设备发生了其他的中断类型。
*/
T_UWORD W90P710MAC_GetIntType(T_VOID *vpEtherDevData, T_UWORD uwVector, T_WORD *wpIntInfo)
{
T_UWORD ret = 0;
T_WORD IntStatus;
TXBD *txbd;
unsigned long cur_ptr;
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
int which ;
which= tpEtherDevDataTable->p710_priv->which;
IntStatus = p710_ReadReg(MISTA,which); //get interrupt status;
//printk("Instatus=%d\n", IntStatus);
if (IntStatus == 0)
{
return DEV_NO_INTERRUPT;
}
if (IntStatus & (MISTA_RXGD | MISTA_RDU | MISTA_RxBErr) )
{
ret |= DEV_RECEIVE_INTERRUPT;
p710_WriteReg(MISTA,IntStatus,which);
if(IntStatus&MISTA_RxBErr)
{
printk("MISTA_RxBErr\n");
}
}
if (IntStatus & MISTA_TXCP )
{
cur_ptr=p710_ReadReg(CTXDSA,which);
cur_ptr &= ~NON_CACHE_FLAG;
while((&(tpEtherDevDataTable->p710_priv->tx_desc[tpEtherDevDataTable->p710_priv->cur_tx_entry]) != cur_ptr))
{
txbd =(TXBD *)&(tpEtherDevDataTable->p710_priv->tx_desc[tpEtherDevDataTable->p710_priv->cur_tx_entry]);
tpEtherDevDataTable->p710_priv->cur_tx_entry = (tpEtherDevDataTable->p710_priv->cur_tx_entry+1)%(TX_DESC_SIZE);
//printf("*txbd->SL %x\n",txbd->SL);
//printf("priv->tx_ptr %x cru_ptr =%x\n",txbd,cur_ptr);
txbd->SL=0;
txbd->mode=0;
}
ret |= DEV_SENDOVER_INTERRUPT;
}
p710_WriteReg(MISTA,IntStatus,which); //clear interrupt
return ret;
}
/**
* @brief
* 获取设备当前接收到的数据包长度。当设备发生接收中断时,该接口将被调用。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[out] wKtLen数据包的长度。
*
* @return
* FALSE 失败。
* TRUE 成功 。
*/
T_BOOL W90P710MAC_GetPktLen(T_VOID *vpEtherDevData, T_WORD *wKtLen)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
RXBD *rxbd;
rxbd = (RXBD *)tpEtherDevDataTable->p710_priv->rx_ptr;
*wKtLen = rxbd->SL & 0xFFFF;
return TRUE;
}
/**
* @brief
* 获取设备当前接收到的数据包的数据。当设备发生接收中断,
* 且GetPktLen接口返回的数据包长度大于0时该接口将被调用。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[in] wKtLen 数据包的长度 ,该参数即GetPktLen的返回值。
*
* @return TRUE 成功 (始终返回该值) 。
*/
T_BOOL W90P710MAC_GetPktData(T_VOID *vpEtherDevData, T_CHAR * bpKtBuf, T_WORD wKtLen)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
RXBD *rxbd;
int which ;
//int i=0;
which= tpEtherDevDataTable->p710_priv->which;
rxbd = (RXBD *)tpEtherDevDataTable->p710_priv->rx_ptr;
memcpy(bpKtBuf,(unsigned char *)rxbd->buffer,wKtLen);
#if 0
for(i=0;i<wKtLen;i+=10)
printf("%2x %2x %2x %2x %2x %2x %2x %2x %2x %2x\n",*(bpKtBuf+i),*(bpKtBuf+i+1),
*(bpKtBuf+i+2),*(bpKtBuf+i+3),*(bpKtBuf+i+4),*(bpKtBuf+i+5),*(bpKtBuf+i+6),
*(bpKtBuf+i+7),*(bpKtBuf+i+8),*(bpKtBuf+i+9));
printf("\n");
#endif
rxbd->SL =RXfOwnership_DMA;
rxbd->reserved = 0;
tpEtherDevDataTable->p710_priv->rx_ptr=(unsigned long)rxbd->next;
rxbd=(RXBD *)tpEtherDevDataTable->p710_priv->rx_ptr;
return TRUE;
}
/**
* @brief
* 处理其他的中断类型。中断类型参数intInfo即在GetIntType中返回的中断。
* 状态信息。该信息由HAL自己负责定义和解释。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
* @param[in] wpIntInfo 中断状态信息。
*
* @return TRUE 成功 (始终返回该值)。
*/
T_BOOL W90P710MAC_HandleOtherIsrType(T_VOID *vpEtherDevData, T_WORD wIntInfo)
{
return TRUE;
}
/**
* @brief
* 停止(或暂停)设备的运行,就是让该IO设备不能(正常)输入输出。
* 该函数一般就是要设置DISABLE位,或者把该设备设置为内循环模式
* 等。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功 (始终返回该值)。
*/
T_BOOL W90P710MAC_Stop(T_VOID *vpEtherDevData)
{
T_HAL_W90P710MAC_DEV_DATA *tpEtherDevDataTable = (T_HAL_W90P710MAC_DEV_DATA *)vpEtherDevData;
T_WORD which ;
which= tpEtherDevDataTable->p710_priv->which;
p710_WriteReg(MCMDR,0,which);
return TRUE;
}
/**
* @brief
* 释放HAL占用的资源(主要指在GetResource中获取到的资源)。
*
* @param[in] vpEtherDevData 设备数据块指针,该结构的类型由HAL定义。
*
* @return TRUE 成功 (始终返回该值)。
*/
T_BOOL W90P710MAC_ReleaseResource(T_VOID *vpEtherDevData)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -