GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) LOTUS. All rights reserved.
|
||||
*/
|
||||
|
||||
#define BSPETH_FEMAC
|
||||
|
||||
#include "bspeth.h"
|
||||
#include "mdio.h"
|
||||
|
||||
/* write mdio registers reset value */
|
||||
static void mdio_reg_reset(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
bspeth_writel(ld, 0x00008000, MDIO_RWCTRL);
|
||||
bspeth_writel(ld, 0x00000001, U_MDIO_PHYADDR);
|
||||
bspeth_writel(ld, 0x00000001, D_MDIO_PHYADDR);
|
||||
bspeth_writel(ld, 0x04631EA9, U_MDIO_ANEG_CTRL);
|
||||
bspeth_writel(ld, 0x04631EA9, D_MDIO_ANEG_CTRL);
|
||||
bspeth_writel(ld, 0x00000000, U_MDIO_IRQENA);
|
||||
bspeth_writel(ld, 0x00000000, D_MDIO_IRQENA);
|
||||
}
|
||||
|
||||
static int wait_mdio_ready(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
int timeout_us = 5000;
|
||||
|
||||
while (--timeout_us && !test_mdio_ready(ld))
|
||||
udelay(50); /* delay 50us */
|
||||
|
||||
return timeout_us;
|
||||
}
|
||||
|
||||
int bspeth_mdio_read(struct bspeth_netdev_local *ld, int phy_addr, unsigned int regnum)
|
||||
{
|
||||
int val = 0;
|
||||
bspeth_assert((!((unsigned int)phy_addr & (~0x1F))) && (!(regnum & (~0x1F))));
|
||||
|
||||
local_lock(ld);
|
||||
|
||||
if (!wait_mdio_ready(ld)) {
|
||||
bspeth_error("mdio busy");
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
mdio_start_phyread(ld, (unsigned int)phy_addr, regnum);
|
||||
|
||||
if (wait_mdio_ready(ld) != 0) {
|
||||
val = mdio_get_phyread_val(ld);
|
||||
} else {
|
||||
bspeth_error("read timeout");
|
||||
}
|
||||
|
||||
error_exit:
|
||||
|
||||
local_unlock(ld);
|
||||
|
||||
bspeth_trace(BSPETH_TRACE_MDIO, "phy_addr = %d, regnum = %d, val = 0x%04x", phy_addr,
|
||||
(int)regnum, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int bspeth_mdio_write(struct bspeth_netdev_local *ld, int phy_addr, int regnum, int val)
|
||||
{
|
||||
bspeth_assert((!((unsigned int)phy_addr & (~0x1F))) && (!((unsigned int)regnum & (~0x1F))));
|
||||
|
||||
bspeth_trace(BSPETH_TRACE_MDIO, "phy_addr = %d, regnum = %d", phy_addr, regnum);
|
||||
|
||||
local_lock(ld);
|
||||
|
||||
if (!wait_mdio_ready(ld)) {
|
||||
bspeth_error("mdio busy");
|
||||
val = -1;
|
||||
goto error_exit;
|
||||
}
|
||||
|
||||
mdio_phywrite(ld, (unsigned int)phy_addr, (unsigned int)regnum, (unsigned int)val);
|
||||
|
||||
error_exit:
|
||||
|
||||
local_unlock(ld);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int bspeth_mdio_reset(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
mdio_reg_reset(ld);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bspeth_mdio_init(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
local_lock_init(ld);
|
||||
|
||||
bspeth_mdio_reset(ld);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bspeth_mdio_exit(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
local_lock_exit(ld);
|
||||
}
|
||||
Reference in New Issue
Block a user