GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) LOTUS. All rights reserved.
|
||||
*/
|
||||
|
||||
|
||||
#include "bspeth.h"
|
||||
#include "mdio.h"
|
||||
#include "mii_drv.h"
|
||||
#include <config.h>
|
||||
|
||||
/* MDIO Bus Interface */
|
||||
static int bspeth_mdiobus_read(struct mii_dev *bus, int addr, int devad, int reg)
|
||||
{
|
||||
struct bspeth_netdev_local *ld = (struct bspeth_netdev_local *)bus->priv;
|
||||
|
||||
return bspeth_mdio_read(ld, addr, reg);
|
||||
}
|
||||
|
||||
static int bspeth_mdiobus_write(struct mii_dev *bus, int addr, int devad,
|
||||
int reg, u16 value)
|
||||
{
|
||||
struct bspeth_netdev_local *ld = (struct bspeth_netdev_local *)bus->priv;
|
||||
|
||||
bspeth_mdio_write(ld, addr, reg, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHY_ID_KSZ8051 0x00221550
|
||||
#define PHY_ID_KSZ8081 0x00221560
|
||||
#define PHY_ID_MASK 0xFFFFFFF0
|
||||
|
||||
static bool get_fephy_id(const char *devname, unsigned char phyaddr, u32 *phy_id)
|
||||
{
|
||||
u16 id1 = 0;
|
||||
u16 id2 = 0;
|
||||
|
||||
if (miiphy_read(devname, phyaddr, MII_PHYSID1, &id1)) {
|
||||
printf("%s,%d:PHY_PHYIDR1 read failed!\n", __func__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
if (miiphy_read(devname, phyaddr, MII_PHYSID2, &id2)) {
|
||||
printf("%s,%d:PHY_PHYIDR2 read failed!\n", __func__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
*phy_id = (id1 & 0xffff) << 16; /* high 16 bit */
|
||||
*phy_id |= (id2 & 0xffff);
|
||||
|
||||
/* If the phy_id is all Fs, there is no device there */
|
||||
if (*phy_id == 0xffffffff || *phy_id == 0 || *phy_id == 0xFFFF || *phy_id == 0xFFFF0000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool phy_detected(const char *devname, unsigned char phyaddr)
|
||||
{
|
||||
u32 phy_id = 0;
|
||||
|
||||
if (!get_fephy_id(devname, phyaddr, &phy_id)) return false;
|
||||
|
||||
/* run this at RMII mode */
|
||||
if (BSPETH_MII_RMII_MODE_U == 1) {
|
||||
/* PHY-KSZ8051RNL */
|
||||
if ((phy_id & PHY_ID_MASK) == PHY_ID_KSZ8051) {
|
||||
unsigned short reg = 0;
|
||||
|
||||
if (miiphy_read(devname, phyaddr, 0x1F, ®)) {
|
||||
printf("PHY 0x1F read failed\n");
|
||||
return false;
|
||||
}
|
||||
reg |= bit(7); /* bit7:set phy RMII 50MHz clk; */
|
||||
if (miiphy_write(devname, phyaddr, 0x1F, reg)) {
|
||||
printf("PHY 0x1F write failed\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (miiphy_read(devname, phyaddr, 0x16, ®)) {
|
||||
printf("PHY 0x16 read failed\n");
|
||||
return false;
|
||||
}
|
||||
reg |= bit(1); /* set phy RMII override; */
|
||||
if (miiphy_write(devname, phyaddr, 0x16, reg)) {
|
||||
printf("PHY 0x16 write failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* PHY-KSZ8081 */
|
||||
if ((phy_id & PHY_ID_MASK) == PHY_ID_KSZ8081) {
|
||||
unsigned short val = 0;
|
||||
|
||||
if (miiphy_read(devname, phyaddr, 0x1F, &val) != 0) {
|
||||
printf("PHY 0x1F read failed\n");
|
||||
return false;
|
||||
};
|
||||
val |= bit(7); /* bit7:set phy RMII 50MHz clk; */
|
||||
if (miiphy_write(devname, phyaddr, 0x1F, val) != 0) {
|
||||
printf("PHY 0x1F write failed\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int g_mdio_registered;
|
||||
|
||||
int bspeth_mdiobus_driver_init(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
memset(ld->mii_name, 0, MAX_PHY_NAME_LEN);
|
||||
snprintf(ld->mii_name, MAX_PHY_NAME_LEN, "mii_bspeth");
|
||||
ld->mdio_frqdiv = ETH_MDIO_FRQDIV;
|
||||
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
|
||||
if (!g_mdio_registered) {
|
||||
struct mii_dev *bus = mdio_alloc();
|
||||
|
||||
if (!bus) {
|
||||
printf("Failed to allocate MDIO bus\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
bus->priv = ld;
|
||||
bus->read = bspeth_mdiobus_read;
|
||||
bus->write = bspeth_mdiobus_write;
|
||||
snprintf(bus->name, sizeof(bus->name), ld->mii_name);
|
||||
|
||||
bspeth_mdio_init(ld);
|
||||
|
||||
if (mdio_register(bus)) {
|
||||
mdio_free(bus);
|
||||
return -1;
|
||||
}
|
||||
|
||||
miiphy_set_current_dev(ld->mii_name);
|
||||
g_mdio_registered = 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bspeth_mdiobus_driver_exit(struct bspeth_netdev_local *ld)
|
||||
{
|
||||
/* add this to avoid the first time to use eth will print 'No such device: XXXXX' message. */
|
||||
if (!miiphy_get_current_dev()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bspeth_mdio_exit(ld);
|
||||
}
|
||||
Reference in New Issue
Block a user