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

📄 halrtl8019as.c

📁 包含8139
💻 C
📖 第 1 页 / 共 3 页
字号:
 * @param[in] vMultiMacChain 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是 *							typedef struct ether_multi{ *											char haddr[6];							//组播地址 *											unsigned short emc_users;   //该组播地址的用户数,对于驱动,不需要关心该参数 *											struct ether_multi * next;  //指向下一节点 *										}ETHER_MULTI; * *							typedef struct macforhash{ *											unsigned char macaddr[6];		//要操作的组播MAC地址 * 											ETHER_MULTI * chainpointer;	//该设备需要设置的组播地址链 *										}T_MACHASH; *						multiMacChian为 T_MACHASH 指针类型,该参数的使用是可选的. *						即,HAL中,增加组播地址的实现既可仅根据macaddr参数进行操作, *								也可以根据multiMacChain来全部重新设定网卡组播地址 * * @return * 		FALSE 	失败 *		TRUE		成功 */T_BOOL RTL8019AS_AddMultiAddr( T_VOID *vpHalDevData, T_CHAR *bMacAddr, T_VOID *vMultiMacChain){	return TRUE;}/** * @brief *	  删除该网卡的一个组播地址 * * @param[in] vpHalDevData 设备数据块指针,该结构的类型由HAL定义 * * @param[in] bMacAddr 指向一个6字节的存储空间,内容为需要删除的组播MAC地址 * * @param[in] vMultiMacChain 指向一个组播地址链,该链上的组播地址应该都被设置进入该网卡.该链的结构是 *							typedef struct ether_multi{ *											char haddr[6];							//组播地址 *											unsigned short emc_users;   //该组播地址的用户数,对于驱动,不需要关心该参数 *											struct ether_multi * next;  //指向下一节点 *										}ETHER_MULTI; * *							typedef struct macforhash{ *											unsigned char macaddr[6];		//要操作的组播MAC地址 * 											ETHER_MULTI * chainpointer;	//该设备需要设置的组播地址链 *										}T_MACHASH; *						multiMacChian为 T_MACHASH 指针类型,该参数的使用是可选的. *						即,HAL中,删除组播地址的实现既可仅根据macaddr参数进行操作, *								也可以根据multiMacChain来全部重新设定网卡组播地址 * * @return * 		FALSE 	失败 *		TRUE		成功 */T_BOOL RTL8019AS_DelMultiAddr( T_VOID *vpHalDevData, T_CHAR *bMacAddr, T_VOID * vMultiMacChain){	return TRUE;}/** * @brief *		从网卡缓存(芯片RAM)中将数据读取到用户自定义BUF中,远端DMA读。 * * @param[in] wCount:要读取的字符个数 * @param[in] uwRingOffset:起始地址 * @param[out] bpBuf:用户自定义的BUF指针 * * @return * 		0 	:DMA读失败。 *		>0	:DMA读成功。 */T_MODULE T_WORD RTL8019AS_BlockInput(T_WORD wCount,T_BYTE* bpBuf,T_UWORD uwRingOffset,T_HAL_RTL8019AS_DEV_DATA *pDevData){	T_WORD wait = 0;	T_BYTE isr;	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_START);//设置命令寄存器:无DMA,寄存器页为0页,打开包接收/发送。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTLO, wCount & 0xff);                      //设置远端DMA读出数据字节数。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTHI, wCount >> 8);                        //设置远端DMA读出数据字节数。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RSARLO, uwRingOffset & 0xff);                //设置远端DMA开始地址(低8位)。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RSARHI, uwRingOffset >> 8);                  //设置远端DMA开始地址(高8位)。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_RREAD + ENCMD_START);              //设置命令寄存器:远端DMA读,启动。	BSP_InHWords(pDevData->IoBaseAddr + EN_DATAPORT,(short  *)bpBuf,wCount>>1);         //CPU从网卡芯片RAM读取数据到buf。	if (wCount & 0x01)	{		BSP_InByte(pDevData->IoBaseAddr + EN_DATAPORT,bpBuf[wCount-1]);	}    BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isr);	while((!(isr && ENISR_RDC)) && (wait < 5000))                                  //等待远端DMA读完成(通过获取远端DMA操作完成中断状态实现)。	{		BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isr);		wait++;	}	BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isr);	if (!(isr && ENISR_RDC))                 //远端DMA读失败。	{		return 0;	}	return (wCount);}/** * @brief *		计算和调整页面位置 * * @param[in] pDevData:设备数据块指针,该结构的类型由HAL定义 * @param[in] wPositionValue:位置状态值,判断现在位置指针是否已经循环 * * @return temp:当前指针位置 */T_MODULE T_WORD RTL8019AS_RingIndex(T_HAL_RTL8019AS_DEV_DATA* pDevData, T_WORD wPositionValue){	T_WORD temp ;	temp = wPositionValue - pDevData->rxStartPage;	if (temp < 0)	{		temp = -temp;	}	temp = temp % (pDevData->stopPage - pDevData->rxStartPage);//设定循环。	temp = pDevData->rxStartPage + temp ;                      //确定指针位置。	return temp ;}/** * @brief *		本地DMA发送,将数据由网卡缓存(芯片RAM)发送到网络。 * * @param[in] pDevData: 设备数据块指针,该结构的类型由HAL定义 * @param[in] uwLength 将要发送的数据长度 * * @return *		0 成功 *      -1 失败 */T_MODULE T_WORD RTL8019AS_TriggerSend(T_HAL_RTL8019AS_DEV_DATA *pDevData, T_UWORD uwLength){	T_WORD 	 wait = 0;	T_UBYTE keepCmd;	T_UBYTE cmd;	BSP_InByte(pDevData->IoBaseAddr,keepCmd);                                         //读出命令寄存器的值并保存。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);            //设置命令寄存器:无DMA,寄存器页为0页。    BSP_InByte(pDevData->IoBaseAddr + EN_CMD,cmd);	while((cmd & ENCMD_TXP) && (wait <= 5000))                                   //等待上一次发送操作结束。	{		BSP_InByte(pDevData->IoBaseAddr + EN_CMD,cmd);		wait++;	}    BSP_InByte(pDevData->IoBaseAddr + EN_CMD,cmd);	if(cmd & ENCMD_TXP)                                                           //上一次发送操作未结束。	{		BSP_OutByte(pDevData->IoBaseAddr, keepCmd);                                    //恢复先前保存的命令寄存器的值。		return -1;                                                                //退出,发送失败。	}	BSP_OutByte(pDevData->IoBaseAddr + EN0_TCNTLO, uwLength & 0xff);                   //设置数据包长度。	BSP_OutByte(pDevData->IoBaseAddr + EN0_TCNTHI, uwLength >> 8);                     //设置数据包长度。	BSP_OutByte(pDevData->IoBaseAddr + EN0_TPSR, pDevData->txStartPage);               //设置发送数据包在网卡缓存(芯片RAM)中的起始地址(发送缓冲区首地址)。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_TXP + ENCMD_START); //设置命令寄存器:无DMA,发送,启动。	BSP_OutByte(pDevData->IoBaseAddr,  keepCmd);                                       //恢复先前保存的命令寄存器的值。	return 0;}/** * @brief *		CPU写数据到网卡缓存(芯片RAM)中,远端DMA写。 * * @param[in] wCount:要写入的字符个数。 * @param[in] wStartOffset:起始地址。 * @param[in] bpBuf:用户自定义的BUF指针。 * @param[in] pDevData:设备数据块指针,该结构的类型由HAL定义 * @return * 		-1 	:DMA写失败。 *		0	:DMA写成功。 */T_MODULE T_WORD RTL8019AS_BlockOutput(T_HAL_RTL8019AS_DEV_DATA *pDevData,T_WORD wCount,T_BYTE *bpBuf,T_WORD wStartOffset){	T_WORD  i;	T_UBYTE keepCmd;	T_UBYTE isr;	if (pDevData->word16 && (wCount & 0x01))	{		wCount++;	}	BSP_InByte(pDevData->IoBaseAddr,keepCmd);                                           //读出命令寄存器的值并保存。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_PAGE0 + ENCMD_START + ENCMD_NODMA);//设置命令寄存器:寄存器页为0页,启动,无DMA。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTLO, wCount & 0xff);                      //设置远端DMA写入数据字节数。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTHI, wCount >> 8);                        //设置远端DMA写入数据字节数。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RSARLO, wStartOffset & 0xff);                //设置远端DMA开始地址(低8位)。	BSP_OutByte(pDevData->IoBaseAddr + EN0_RSARHI, wStartOffset >> 8);                  //设置远端DMA开始地址(高8位)。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_RWRITE + ENCMD_START);             //设置命令寄存器:远端DMA写,启动。	if (pDevData->word16)	{		BSP_OutHWords(pDevData->IoBaseAddr + EN_DATAPORT,(T_BYTE *)bpBuf, wCount >> 1);//CPU将buf中的数据写入网卡芯片RAM。	}	else	{		BSP_OutBytes(pDevData->IoBaseAddr + EN_DATAPORT ,(T_BYTE *)bpBuf, wCount);	}	for(i=0;i<5000;i++)	{		BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isr);		if(isr && ENISR_RDC)                                                       //等待远端DMA写完成(通过获取远端DMA操作完成中断状态实现)。		{			break;		}	}	BSP_OutByte(pDevData->IoBaseAddr,  keepCmd);                                        //恢复先前保存的命令寄存器的值。	if(i>=5000)	{		return -1;                                                                 //远端DMA写失败。	}	return 0;}/** * @brief *	    网卡接收缓冲区溢出中断处理。 * * @param[in] 	pDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @return	无。 */T_MODULE T_VOID RTL8019AS_HandlerOverflow(T_HAL_RTL8019AS_DEV_DATA *pDevData){	T_WORD  i;	T_WORD  j;	T_UBYTE wasTxing;	T_UBYTE mustResend = 0;	T_UBYTE txCompleted;	T_UWORD rxingPage;    T_UBYTE isr;    T_UBYTE cmd;    BSP_InByte(pDevData->IoBaseAddr + EN_CMD,cmd);	wasTxing = (cmd & ENCMD_TXP);                                                     //判断网卡是否在DMA传送。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_STOP);    //设置命令寄存器:无DMA,寄存器页为0页,停止包接收/发送。	for(i=0;i<1000;i++)	{		j = i+1;                                                                      //等待,标准为1.6ms。	}    BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTLO, 0x00);                                  //清远端DMA数据长度寄存器。    BSP_OutByte(pDevData->IoBaseAddr + EN0_RCNTHI, 0x00);                                  //清远端DMA数据长度寄存器。	if (wasTxing)                                                                     //网卡在DMA传送。	{		BSP_InByte(pDevData->IoBaseAddr + EN0_ISR,isr);		txCompleted = (isr & (ENISR_PTX + ENISR_TXE));//判断发送是否完成		if (!txCompleted)		{			mustResend = 1;		}	}    BSP_OutByte(pDevData->IoBaseAddr + EN0_TXCR, ENTXCR_TXLOOKL);                          //设置传输配置寄存器:内部lookback。    BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_START);   //设置命令寄存器:无DMA,寄存器页为0页,打开包接收/发送。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE1);                 //设置命令寄存器:无DMA,寄存器页为1页。	BSP_InByte(pDevData->IoBaseAddr + EN1_CURPAG,rxingPage);                               //重新获取接收页面。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);    BSP_OutByte(pDevData->IoBaseAddr + EN0_BOUNDARY, rxingPage - 1);                       //设置接收缓冲读指针。	BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR, ENISR_OVW);                                //清中断状态寄存器。    BSP_OutByte(pDevData->IoBaseAddr + EN0_TXCR, ENTXCR_TXCONFIG);                         //设置传输配置寄存器:使能冲突补偿。	if (mustResend)                                                                   //发送未完成,重发数据包。	{		BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0 + ENCMD_START + ENCMD_TXP);	}}/** * @brief *	    检查接收到的数据包是否为好包。 * * @param[in] 	pDevData:指针,指向HAL数据表(T_HAL_RTL8019AS_DEV_DATA)。 * @param[in]   uwCurrFrame:接收到的数据包的起始地址。 * @param[in]   tpRcvFrame:包头。 * @return	TRUE:好包。 *          FALSE:坏包。 */T_MODULE T_WORD RTL8019AS_CheckFrame(T_HAL_RTL8019AS_DEV_DATA *pDevData,T_UWORD uwCurrFrame,EN_PKTHEADER_T *tpRcvFrame){	T_WORD tmp ;	if(tpRcvFrame->count > 1518 || tpRcvFrame->count < 64)//数据包长度不符合标准。	{		return FALSE;                                    //坏包。	}	if((tpRcvFrame->next > pDevData->stopPage) ||	   (tpRcvFrame->next < pDevData->rxStartPage))        //数据包的下一页地址大于缓冲区停止页或小于开始页。	{		return FALSE ;                                   //坏包。	}	tmp = ((tpRcvFrame->count-1) & 0x0ff00)>>8;	tmp = RTL8019AS_RingIndex(pDevData, uwCurrFrame + tmp + 1);	if (tpRcvFrame->next != tmp)	{		tmp++;		tmp = RTL8019AS_RingIndex(pDevData, tmp) ;		if (tpRcvFrame->next != tmp )			return FALSE;	}	return TRUE;}/** * @brief *	    刷新网络记数器。 * * @return	无。 */T_MODULE T_VOID RTL8019AS_UpdateCounters(T_HAL_RTL8019AS_DEV_DATA *pDevData){	T_UBYTE keepCmd;	T_WORD  a;	T_WORD  b;	T_WORD  c;	T_WORD  d;	T_UBYTE cnt;	a = 0;	b = 0;	c = 0;	d = 0;	BSP_InByte(pDevData->IoBaseAddr,keepCmd);                             //读出命令寄存器的值并保存。	BSP_OutByte(pDevData->IoBaseAddr + EN_CMD, ENCMD_NODMA + ENCMD_PAGE0);//设置命令寄存器:无DMA,寄存器页为0页。	BSP_InByte(pDevData->IoBaseAddr + EN0_COUNTER0,cnt);                  //读记录接收错误队列计数器。	a += cnt;	BSP_InByte(pDevData->IoBaseAddr + EN0_COUNTER1,cnt);                  //读接收的CRC 错误计数器。	b += cnt;	BSP_InByte(pDevData->IoBaseAddr + EN0_COUNTER2,cnt);                  //读接收丢失计数器。	c += cnt;	d++;	BSP_OutByte(pDevData->IoBaseAddr + EN0_ISR,ENISR_CNT);                //清中断状态寄存器。	BSP_OutByte(pDevData->IoBaseAddr, keepCmd);                           //恢复先前保存的命令寄存器的值。}

⌨️ 快捷键说明

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