blob: 3ff7ded7d605de55f44b71b996350723ca77c7fe [file] [log] [blame]
/* FILE NAME: an8855_mdio.c
* PURPOSE:
* It provides an8855 registers and PHY mdio access.
*
* NOTES:
*
*/
/* INCLUDE FILE DECLARATIONS
*/
#include "an8855_reg.h"
#include "an8855_mdio.h"
/* NAMING CONSTANT DECLARATIONS
*/
/* MACRO FUNCTION DECLARATIONS
*/
#define AN8855_SMI_ADDR (1)
/* DATA TYPE DECLARATIONS
*/
/* GLOBAL VARIABLE DECLARATIONS
*/
/* LOCAL SUBPROGRAM DECLARATIONS
*/
/* STATIC VARIABLE DECLARATIONS
*/
u32 g_smi_addr = AN8855_SMI_ADDR;
static AIR_MII_READ_FUNC_T g_mii_read = NULL;
static AIR_MII_WRITE_FUNC_T g_mii_write = NULL;
static AIR_MII_C45_READ_FUNC_T g_mii_c45_read = NULL;
static AIR_MII_C45_WRITE_FUNC_T g_mii_c45_write = NULL;
/* EXPORTED SUBPROGRAM BODIES
*/
/* FUNCTION NAME: an8855_set_smi_addr
* PURPOSE:
* This API is used to set an8855 smi address.
* INPUT:
* smi_addr -- AN8855 smi address
* OUTPUT:
* RETURN:
* NOTES:
* None
*/
void
an8855_set_smi_addr(u32 smi_addr)
{
an8855_reg_write(0x1028C848, smi_addr);
g_smi_addr = smi_addr;
}
/* FUNCTION NAME: an8855_set_mii_callback
* PURPOSE:
* This API is used to set an8855 mii access callbacks.
* INPUT:
* mii_read -- mii read api function
* mii_write -- mii write api function
* mii_c45_read -- mii c45 read api function
* mii_c45_write -- mii c45 write api function
* OUTPUT:
* RETURN:
* 0 -- Successfully set callback.
* -1 -- Setting callback failed.
* NOTES:
* None
*/
int
an8855_set_mii_callback(
AIR_MII_READ_FUNC_T mii_read,
AIR_MII_WRITE_FUNC_T mii_write,
AIR_MII_C45_READ_FUNC_T mii_c45_read,
AIR_MII_C45_WRITE_FUNC_T mii_c45_write)
{
if (!mii_read || !mii_write || !mii_c45_read || !mii_c45_write)
return -1;
g_mii_read = mii_read;
g_mii_write = mii_write;
g_mii_c45_read = mii_c45_read;
g_mii_c45_write = mii_c45_write;
return 0;
}
/* FUNCTION NAME: an8855_reg_read
* PURPOSE:
* This API is used read an8855 registers.
* INPUT:
* reg -- register offset
* OUTPUT:
* RETURN:
* Register value
* NOTES:
* Attention!! Customer should implement mdio mutex
* lock in this func
*/
u32
an8855_reg_read(u32 reg)
{
u16 data_h = 0;
u16 data_l = 0;
int ret = 0;
g_mii_write(g_smi_addr, 0x1F, 0x4);
g_mii_write(g_smi_addr, 0x10, 0x0);
g_mii_write(g_smi_addr, 0x15, ((reg >> 16) & 0xFFFF));
g_mii_write(g_smi_addr, 0x16, (reg & 0xFFFF));
ret = g_mii_read(g_smi_addr, 0x17, &data_h);
if(ret != 0)
{
printf("read reg 0x%x 0x17 fail\n", reg);
}
ret = g_mii_read(g_smi_addr, 0x18, &data_l);
if(ret != 0)
{
printf("read reg 0x%x 0x18 fail\n", reg);
}
g_mii_write(g_smi_addr, 0x1F, 0x0);
g_mii_write(g_smi_addr, 0x10, 0x0);
//printf("read reg:0x%08x data:0x%08x\n", reg, ((data_h << 16) | (data_l & 0xffff)));
return ((data_h << 16) | (data_l & 0xffff));
}
/* FUNCTION NAME: an8855_reg_write
* PURPOSE:
* This API is used write an8855 registers.
* INPUT:
* reg -- register offset
* val -- register value
* OUTPUT:
* RETURN:
* NOTES:
* Attention!! Customer should implement mdio mutex
* lock in this func
*/
void
an8855_reg_write(u32 reg, u32 val)
{
g_mii_write(g_smi_addr, 0x1F, 0x4);
g_mii_write(g_smi_addr, 0x10, 0x0);
g_mii_write(g_smi_addr, 0x11, ((reg >> 16) & 0xFFFF));
g_mii_write(g_smi_addr, 0x12, (reg & 0xFFFF));
g_mii_write(g_smi_addr, 0x13, ((val >> 16) & 0xFFFF));
g_mii_write(g_smi_addr, 0x14, (val & 0xFFFF));
g_mii_write(g_smi_addr, 0x1F, 0x0);
g_mii_write(g_smi_addr, 0x10, 0x0);
//printf("write reg:0x%08x data:0x%08x\n", reg, val);
}
/* FUNCTION NAME: an8855_phy_read
* PURPOSE:
* This API is used read an8855 phy registers.
* INPUT:
* port_num -- port number, 0~4
* reg -- phy register offset
* OUTPUT:
* p_val -- phy register value
* RETURN:
* 0 -- read success
* -1 -- read failure
* NOTES:
* Attention!! Customer should implement mii mutex
* lock in this func
*/
int
an8855_phy_read(u32 port_num, u32 reg, u32 *p_val)
{
u32 phy = 0, data = 0;
if (port_num >= AN8855_PHY_NUM)
return -1;
phy = g_smi_addr + port_num;
g_mii_read(phy, reg, &data);
*p_val = data & 0x0000FFFF;
return 0;
}
/* FUNCTION NAME: an8855_phy_write
* PURPOSE:
* This API is used write an8855 phy registers.
* INPUT:
* port_num -- port number, 0~4
* reg -- phy register offset
* val -- phy register value
* OUTPUT:
* RETURN:
* 0 -- write success
* -1 -- write failure
* NOTES:
* Attention!! Customer should implement mii mutex
* lock in this func
*/
int
an8855_phy_write(u32 port_num, u32 reg, u32 val)
{
u32 phy = 0, data = 0;
if (port_num >= AN8855_PHY_NUM)
return -1;
phy = g_smi_addr + port_num;
data = val & 0x0000FFFF;
g_mii_write(phy, reg, data);
return 0;
}
/* FUNCTION NAME: an8855_phy_read_cl45
* PURPOSE:
* This API is used read an8855 phy registers.
* INPUT:
* port_num -- port number, 0~4
* dev_addr -- phy device type
* reg_addr -- phy register offset
* OUTPUT:
* p_val -- phy register value
* RETURN:
* 0 -- read success
* -1 -- read failure
* NOTES:
* Attention!! Customer should implement mii mutex
* lock in this func or before/after calling this func
*/
u32
an8855_phy_read_cl45(u32 port_num, u32 dev_addr, u32 reg_addr, u32 *p_val)
{
u32 phy = 0, data = 0;
if (port_num >= AN8855_PHY_NUM)
return -1;
phy = g_smi_addr + port_num;
g_mii_c45_read(phy, dev_addr, reg_addr, &data);
*p_val = data & 0x0000FFFF;
return 0;
}
/* FUNCTION NAME: an8855_phy_write_cl45
* PURPOSE:
* This API is used write an8855 phy registers.
* INPUT:
* port_num -- port number, 0~4
* dev_addr -- phy device type
* reg_addr -- phy register offset
* val -- phy register value
* OUTPUT:
* RETURN:
* 0 -- write success
* -1 -- write failure
* NOTES:
* Attention!! Customer should implement mii mutex
* lock in this func or before/after calling this func
*/
int
an8855_phy_write_cl45(u32 port_num, u32 dev_addr, u32 reg_addr, u32 val)
{
u32 phy = 0, data = 0;
if (port_num >= AN8855_PHY_NUM)
return -1;
phy = g_smi_addr + port_num;
data = val & 0x0000FFFF;
g_mii_c45_write(phy, dev_addr, reg_addr, data);
return 0;
}