📄 rtlmiiapi.c
字号:
/** * file relMiAPIi.c * * * * brief realtek MII control functions * */#include <stdio.h>#include "IxOsServices.h"#include "IxEthAcc.h"#include "IxEthAcc_p.h"#include "IxTypes.h"#include "IxEthAccMac_p.h"#include "IxEthAccMii_p.h"#include "rtlMiiAPI.h"/* realtek8305 vlan register definitions - */PRIVATE VLAN_register_t RTL_PORT_PVID_REGISTER[]={{RTL8305_PHY0,0x21}, {RTL8305_PHY0,0x21}, {RTL8305_PHY0,0x21}, {RTL8305_PHY0,0x21}, {RTL8305_PHY0,0x22}, };PRIVATE VLAN_register_t RTL_VLAN_MEMBER_REGISTER[]= {{RTL8305_PHY1,0x25}, {RTL8305_PHY1,0x26}, {RTL8305_PHY1,0x28}, {RTL8305_PHY1,0x29}, {RTL8305_PHY1,0x31},};PRIVATE VLAN_register_t RTL_VLANA_IDENTIFIER_REGISTER={RTL8305_PHY1,0x24};PRIVATE VLAN_register_t RTL_VLANB_IDENTIFIER_LOWER_REGISTER={RTL8305_PHY1,0x25};PRIVATE VLAN_register_t RTL_VLANB_IDENTIFIER_UPPER_REGISTER={RTL8305_PHY1,0x26};PRIVATE VLAN_register_t RTL_VLANC_IDENTIFIER_REGISTER={RTL8305_PHY1,0x27};PRIVATE VLAN_register_t RTL_VLAND_IDENTIFIER_LOWER_REGISTER={RTL8305_PHY1,0x28};PRIVATE VLAN_register_t RTL_VLAND_IDENTIFIER_UPPER_REGISTER={RTL8305_PHY1,0x29};PRIVATE VLAN_register_t RTL_VLANE_IDENTIFIER_REGISTER={RTL8305_PHY1,0x30};PRIVATE VLAN_register_t RTL_PRIORITY_CTRL_REGISTER={RTL8305_PHY2,0x16};PRIVATE VLAN_register_t RTL_VLAN_CTRL_REGISTER={RTL8305_PHY2,0x17};PRIVATE VLAN_register_t RTL_PORT_CTRL_REGISTER={RTL8305_PHY3, 0x16};PRIVATE IxMutex rtlmiiAccessLock;PRIVATE voidrealtekMdioCmdWrite(UINT32 port, UINT32 mdioCommand){ UINT32 baseAddress; if (port == PORTA ) baseAddress = IX_ETH_ACC_MAC_0_BASE; else if ( port == PORTB ) baseAddress = IX_ETH_ACC_MAC_1_BASE; else return; REG_WRITE(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_1, mdioCommand & 0xff); REG_WRITE(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_2, (mdioCommand >> 8) & 0xff); REG_WRITE(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_3, (mdioCommand >> 16) & 0xff); REG_WRITE(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_4, (mdioCommand >> 24) & 0xff);}PRIVATE voidrealtekMdioCmdRead(UINT32 port, UINT32 *data){ UINT32 regval; UINT32 baseAddress; if (port == PORTA ) baseAddress = IX_ETH_ACC_MAC_0_BASE; else if ( port == PORTB ) baseAddress = IX_ETH_ACC_MAC_1_BASE; else return; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_1, regval); *data = regval & 0xff; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_2, regval); *data |= (regval & 0xff) << 8; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_3, regval); *data |= (regval & 0xff) << 16; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_CMD_4, regval); *data |= (regval & 0xff) << 24; }PRIVATE voidrealtekMdioStatusRead(UINT32 port,UINT32 *data){ UINT32 regval; UINT32 baseAddress; if (port == PORTA ) baseAddress = IX_ETH_ACC_MAC_0_BASE; else if ( port == PORTB ) baseAddress = IX_ETH_ACC_MAC_1_BASE; else return; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_STS_1, regval); *data = regval & 0xff; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_STS_2, regval); *data |= (regval & 0xff) << 8; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_STS_3, regval); *data |= (regval & 0xff) << 16; REG_READ(baseAddress, IX_ETH_ACC_MAC_MDIO_STS_4, regval); *data |= (regval & 0xff) << 24; }/******************************************************************** * realtekMiiInit */IxEthAccStatusrealtekMiiInit(){ if(ixOsServMutexInit(&rtlmiiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } if(ixOsServMutexUnlock(&rtlmiiAccessLock)!= IX_SUCCESS) { return IX_ETH_ACC_FAIL; } return IX_ETH_ACC_SUCCESS;}/********************************************************************* * realtekMiiReadRtn - read a 16 bit value from realtek 8305SB */IxEthAccStatus realtekMiiReadRtn (UINT32 port,UINT8 phyAddr, UINT8 phyReg, UINT16 *value){ UINT32 mdioCommand; UINT32 regval; UINT32 miiTimeout; ixOsServMutexLock(&rtlmiiAccessLock); mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL | phyAddr << IX_ETH_ACC_MII_ADDR_SHL; mdioCommand |= IX_ETH_ACC_MII_GO; realtekMdioCmdWrite(port,mdioCommand); miiTimeout = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS; while(miiTimeout) { realtekMdioCmdRead(port,®val); if((regval & IX_ETH_ACC_MII_GO) == 0x0) { break; } /*Sleep for 10th of a second*/ ixOsServTaskSleep(IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS); miiTimeout--; } if(miiTimeout == 0) { ixOsServMutexUnlock(&rtlmiiAccessLock); return IX_ETH_ACC_FAIL; } realtekMdioStatusRead(port,®val); if(regval & IX_ETH_ACC_MII_READ_FAIL) { ixOsServMutexUnlock(&rtlmiiAccessLock); return IX_ETH_ACC_FAIL; } *value = regval & 0xffff; ixOsServMutexUnlock(&rtlmiiAccessLock); return IX_ETH_ACC_SUCCESS; }/********************************************************************* * realtekMiiWriteRtn - write a 16 bit value to realtek 8305SB */IxEthAccStatusrealtekMiiWriteRtn (UINT32 port,UINT8 phyAddr, UINT8 phyReg, UINT16 value){ UINT32 mdioCommand; UINT32 regval; UINT32 miiTimeout; ixOsServMutexLock(&rtlmiiAccessLock); mdioCommand = phyReg << IX_ETH_ACC_MII_REG_SHL | phyAddr << IX_ETH_ACC_MII_ADDR_SHL ; mdioCommand |= IX_ETH_ACC_MII_GO | IX_ETH_ACC_MII_WRITE | value; realtekMdioCmdWrite(port,mdioCommand); miiTimeout = IX_ETH_ACC_MII_TIMEOUT_10TH_SECS; while(miiTimeout--) { realtekMdioCmdRead(port,®val); /*The "GO" bit is reset to 0 when the write completes*/ if((regval & IX_ETH_ACC_MII_GO) == 0x0) { break; } /*Sleep for 100 milliseconds*/ ixOsServTaskSleep(IX_ETH_ACC_MII_10TH_SEC_IN_MILLIS); } ixOsServMutexUnlock(&rtlmiiAccessLock); if(miiTimeout == 0) { return IX_ETH_ACC_FAIL; } return IX_ETH_ACC_SUCCESS;}/************************************************************ * * Configure the rtl8305 at the specified address * */IxEthAccStatusrealtekMiiPhyConfig(UINT32 port,UINT32 phyAddr, BOOL speed100, BOOL fullDuplex, BOOL autonegotiate){ UINT16 regval=0; if(autonegotiate) { regval |= IX_ETH_ACC_MII_CR_AUTO_EN | IX_ETH_ACC_MII_CR_RESTART; } else { if(speed100) { regval |= IX_ETH_ACC_MII_CR_100; } if(fullDuplex) { regval |= IX_ETH_ACC_MII_CR_FDX; } } return realtekMiiWriteRtn(port,phyAddr, IX_ETH_ACC_MII_CTRL_REG, regval);}/********************************************************* * * Scan for rtl8305 on the MII bus. This function returns * an array of booleans, one for each PHY address. * If a PHY is found at a particular address, the * corresponding entry in the array is set to TRUE. * */IxEthAccStatusrealtekMiiPhyScan(BOOL *phyPresent[]){ UINT32 i; UINT16 regval; /*Search for PHYs on the MII*/ /*Search for extant phys on the MDIO bus*/ for(i=0;i<IXP425_ETH_ACC_MII_MAX_ADDR;i++) { if(realtekMiiReadRtn(PORTA,i,IX_ETH_ACC_MII_CTRL_REG,®val) ==IX_ETH_ACC_SUCCESS) { if((regval & 0xffff) != 0xffff) { phyPresent[PORTA][i] = TRUE; } else { phyPresent[PORTA][i] = FALSE; } } else { phyPresent[PORTA][i] = FALSE; } if(realtekMiiReadRtn(PORTB,i,IX_ETH_ACC_MII_CTRL_REG,®val) ==IX_ETH_ACC_SUCCESS) { if((regval & 0xffff) != 0xffff) { phyPresent[PORTB][i] = TRUE; } else { phyPresent[PORTB][i] = FALSE; } } else { phyPresent[PORTB][i] = FALSE; } } return IX_ETH_ACC_SUCCESS;}/****************************************************************** * * Reset the realtek8305 at the specified address */IxEthAccStatusrealtekMiiPhyReset(UINT32 port,UINT32 phyAddr){ realtekMiiWriteRtn(port,phyAddr, IX_ETH_ACC_MII_CTRL_REG, IX_ETH_ACC_MII_CR_RESET); ixOsServTaskSleep (IX_ETH_ACC_MII_RESET_DELAY_MS); realtekMiiWriteRtn(port,phyAddr, IX_ETH_ACC_MII_CTRL_REG, IX_ETH_ACC_MII_CR_NORM_EN); return IX_ETH_ACC_SUCCESS;}/************************************************************ * * Configure the rtl8305 port pvid at the specified address * */IxEthAccStatusrealtekPvidSetup(UINT32 port, UINT8 rtl8305port, UINT8 pvid){ UINT16 regval=0; UINT8 phyAddr=0; UINT8 vlanReg =0; if(port!=PORTB) return ERR_PORT_ERROR; if (rtl8305port >= 5 ) return ERR_PORT_ERROR; phyAddr = RTL_PORT_PVID_REGISTER[rtl8305port].PHY_address; vlanReg = RTL_PORT_PVID_REGISTER[rtl8305port].VLAN_register; realtekMiiReadRtn(port, phyAddr,vlanReg, ®val); realtekMiiReadRtn(port, phyAddr,vlanReg, ®val); pvid &= RTL_PVID_BIT_WITH;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -