|
|
@@ -202,12 +202,6 @@ struct rtl838x_eth_priv {
|
|
|
u32 lastEvent;
|
|
|
u16 rxrings;
|
|
|
u16 rxringlen;
|
|
|
- int smi_bus[RTMDIO_MAX_PORT];
|
|
|
- u8 smi_addr[RTMDIO_MAX_PORT];
|
|
|
- u32 sds_id[RTMDIO_MAX_PORT];
|
|
|
- bool smi_bus_isc45[RTMDIO_MAX_SMI_BUS];
|
|
|
- bool phy_is_internal[RTMDIO_MAX_PORT];
|
|
|
- phy_interface_t interfaces[RTMDIO_MAX_PORT];
|
|
|
};
|
|
|
|
|
|
extern int rtl838x_phy_init(struct rtl838x_eth_priv *priv);
|
|
|
@@ -1708,11 +1702,18 @@ static int rtl838x_set_link_ksettings(struct net_device *ndev,
|
|
|
*/
|
|
|
|
|
|
struct rtmdio_bus_priv {
|
|
|
- struct rtl838x_eth_priv *eth_priv;
|
|
|
+ u16 id;
|
|
|
+ u16 family_id;
|
|
|
int extaddr;
|
|
|
int rawpage;
|
|
|
int page[RTMDIO_MAX_PORT];
|
|
|
bool raw[RTMDIO_MAX_PORT];
|
|
|
+ int smi_bus[RTMDIO_MAX_PORT];
|
|
|
+ u8 smi_addr[RTMDIO_MAX_PORT];
|
|
|
+ u32 sds_id[RTMDIO_MAX_PORT];
|
|
|
+ bool smi_bus_isc45[RTMDIO_MAX_SMI_BUS];
|
|
|
+ bool phy_is_internal[RTMDIO_MAX_PORT];
|
|
|
+ phy_interface_t interfaces[RTMDIO_MAX_PORT];
|
|
|
int (*read_mmd_phy)(u32 port, u32 addr, u32 reg, u32 *val);
|
|
|
int (*write_mmd_phy)(u32 port, u32 addr, u32 reg, u32 val);
|
|
|
int (*read_phy)(u32 port, u32 page, u32 reg, u32 *val);
|
|
|
@@ -1814,16 +1815,16 @@ int phy_port_read_paged(struct phy_device *phydev, int port, int page, u32 regnu
|
|
|
|
|
|
static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err, val;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- err = (*bus_priv->read_mmd_phy)(addr, devnum, regnum, &val);
|
|
|
+ err = (*priv->read_mmd_phy)(addr, devnum, regnum, &val);
|
|
|
pr_debug("rd_MMD(adr=%d, dev=%d, reg=%d) = %d, err = %d\n",
|
|
|
addr, devnum, regnum, val, err);
|
|
|
return err ? err : val;
|
|
|
@@ -1831,75 +1832,73 @@ static int rtmdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum
|
|
|
|
|
|
static int rtmdio_83xx_read(struct mii_bus *bus, int addr, int regnum)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err, val;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380)
|
|
|
+ if (addr >= 24 && addr <= 27 && priv->id == 0x8380)
|
|
|
return rtl838x_read_sds_phy(addr, regnum);
|
|
|
|
|
|
- if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr])
|
|
|
+ if (priv->family_id == RTL8390_FAMILY_ID && priv->phy_is_internal[addr])
|
|
|
return rtl839x_read_sds_phy(addr, regnum);
|
|
|
|
|
|
- if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage)
|
|
|
- return bus_priv->page[addr];
|
|
|
+ if (regnum == RTMDIO_PAGE_SELECT && priv->page[addr] != priv->rawpage)
|
|
|
+ return priv->page[addr];
|
|
|
|
|
|
- bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage);
|
|
|
- err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val);
|
|
|
+ priv->raw[addr] = (priv->page[addr] == priv->rawpage);
|
|
|
+ err = (*priv->read_phy)(addr, priv->page[addr], regnum, &val);
|
|
|
pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n",
|
|
|
- addr, bus_priv->page[addr], regnum, val, err);
|
|
|
+ addr, priv->page[addr], regnum, val, err);
|
|
|
return err ? err : val;
|
|
|
}
|
|
|
|
|
|
static int rtmdio_93xx_read(struct mii_bus *bus, int addr, int regnum)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err, val;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- if (regnum == RTMDIO_PAGE_SELECT && bus_priv->page[addr] != bus_priv->rawpage)
|
|
|
- return bus_priv->page[addr];
|
|
|
+ if (regnum == RTMDIO_PAGE_SELECT && priv->page[addr] != priv->rawpage)
|
|
|
+ return priv->page[addr];
|
|
|
|
|
|
- bus_priv->raw[addr] = (bus_priv->page[addr] == bus_priv->rawpage);
|
|
|
- if (eth_priv->phy_is_internal[addr]) {
|
|
|
- if (eth_priv->family_id == RTL9300_FAMILY_ID)
|
|
|
- return rtl930x_read_sds_phy(eth_priv->sds_id[addr],
|
|
|
- bus_priv->page[addr], regnum);
|
|
|
+ priv->raw[addr] = (priv->page[addr] == priv->rawpage);
|
|
|
+ if (priv->phy_is_internal[addr]) {
|
|
|
+ if (priv->family_id == RTL9300_FAMILY_ID)
|
|
|
+ return rtl930x_read_sds_phy(priv->sds_id[addr],
|
|
|
+ priv->page[addr], regnum);
|
|
|
else
|
|
|
- return rtl931x_read_sds_phy(eth_priv->sds_id[addr],
|
|
|
- bus_priv->page[addr], regnum);
|
|
|
+ return rtl931x_read_sds_phy(priv->sds_id[addr],
|
|
|
+ priv->page[addr], regnum);
|
|
|
}
|
|
|
|
|
|
- err = (*bus_priv->read_phy)(addr, bus_priv->page[addr], regnum, &val);
|
|
|
+ err = (*priv->read_phy)(addr, priv->page[addr], regnum, &val);
|
|
|
pr_debug("rd_PHY(adr=%d, pag=%d, reg=%d) = %d, err = %d\n",
|
|
|
- addr, bus_priv->page[addr], regnum, val, err);
|
|
|
+ addr, priv->page[addr], regnum, val, err);
|
|
|
return err ? err : val;
|
|
|
}
|
|
|
|
|
|
static int rtmdio_write_c45(struct mii_bus *bus, int addr, int devnum, int regnum, u16 val)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- err = (*bus_priv->write_mmd_phy)(addr, devnum, regnum, val);
|
|
|
+ err = (*priv->write_mmd_phy)(addr, devnum, regnum, val);
|
|
|
pr_debug("wr_MMD(adr=%d, dev=%d, reg=%d, val=%d) err = %d\n",
|
|
|
addr, devnum, regnum, val, err);
|
|
|
return err;
|
|
|
@@ -1907,87 +1906,85 @@ static int rtmdio_write_c45(struct mii_bus *bus, int addr, int devnum, int regnu
|
|
|
|
|
|
static int rtmdio_83xx_write(struct mii_bus *bus, int addr, int regnum, u16 val)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err, page, offset = 0;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
|
|
|
|
|
|
if (regnum == RTMDIO_PORT_SELECT) {
|
|
|
- bus_priv->extaddr = (s16)val;
|
|
|
+ priv->extaddr = (s16)val;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- page = bus_priv->page[addr];
|
|
|
+ page = priv->page[addr];
|
|
|
|
|
|
- if (addr >= 24 && addr <= 27 && eth_priv->id == 0x8380) {
|
|
|
+ if (addr >= 24 && addr <= 27 && priv->id == 0x8380) {
|
|
|
if (addr == 26)
|
|
|
offset = 0x100;
|
|
|
sw_w32(val, RTL838X_SDS4_FIB_REG0 + offset + (regnum << 2));
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (eth_priv->family_id == RTL8390_FAMILY_ID && eth_priv->phy_is_internal[addr])
|
|
|
+ if (priv->family_id == RTL8390_FAMILY_ID && priv->phy_is_internal[addr])
|
|
|
return rtl839x_write_sds_phy(addr, regnum, val);
|
|
|
|
|
|
if (regnum == RTMDIO_PAGE_SELECT)
|
|
|
- bus_priv->page[addr] = val;
|
|
|
+ priv->page[addr] = val;
|
|
|
|
|
|
- if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) {
|
|
|
- bus_priv->raw[addr] = (page == bus_priv->rawpage);
|
|
|
- err = (*bus_priv->write_phy)(addr, page, regnum, val);
|
|
|
+ if (!priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == priv->rawpage)) {
|
|
|
+ priv->raw[addr] = (page == priv->rawpage);
|
|
|
+ err = (*priv->write_phy)(addr, page, regnum, val);
|
|
|
pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n",
|
|
|
addr, page, regnum, val, err);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
- bus_priv->raw[addr] = false;
|
|
|
+ priv->raw[addr] = false;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static int rtmdio_93xx_write(struct mii_bus *bus, int addr, int regnum, u16 val)
|
|
|
{
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
int err, page;
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *eth_priv = bus_priv->eth_priv;
|
|
|
|
|
|
if (regnum == RTMDIO_PORT_SELECT) {
|
|
|
- bus_priv->extaddr = (s16)val;
|
|
|
+ priv->extaddr = (s16)val;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- if (bus_priv->extaddr >= 0)
|
|
|
- addr = bus_priv->extaddr;
|
|
|
+ if (priv->extaddr >= 0)
|
|
|
+ addr = priv->extaddr;
|
|
|
|
|
|
if (addr >= RTMDIO_MAX_PORT)
|
|
|
return -ENODEV;
|
|
|
|
|
|
- page = bus_priv->page[addr];
|
|
|
+ page = priv->page[addr];
|
|
|
|
|
|
if (regnum == RTMDIO_PAGE_SELECT)
|
|
|
- bus_priv->page[addr] = val;
|
|
|
+ priv->page[addr] = val;
|
|
|
|
|
|
- if (!bus_priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == bus_priv->rawpage)) {
|
|
|
- bus_priv->raw[addr] = (page == bus_priv->rawpage);
|
|
|
- if (eth_priv->phy_is_internal[addr]) {
|
|
|
- if (eth_priv->family_id == RTL9300_FAMILY_ID)
|
|
|
- return rtl930x_write_sds_phy(eth_priv->sds_id[addr],
|
|
|
+ if (!priv->raw[addr] && (regnum != RTMDIO_PAGE_SELECT || page == priv->rawpage)) {
|
|
|
+ priv->raw[addr] = (page == priv->rawpage);
|
|
|
+ if (priv->phy_is_internal[addr]) {
|
|
|
+ if (priv->family_id == RTL9300_FAMILY_ID)
|
|
|
+ return rtl930x_write_sds_phy(priv->sds_id[addr],
|
|
|
page, regnum, val);
|
|
|
else
|
|
|
- return rtl931x_write_sds_phy(eth_priv->sds_id[addr],
|
|
|
+ return rtl931x_write_sds_phy(priv->sds_id[addr],
|
|
|
page, regnum, val);
|
|
|
}
|
|
|
|
|
|
- err = (*bus_priv->write_phy)(addr, page, regnum, val);
|
|
|
+ err = (*priv->write_phy)(addr, page, regnum, val);
|
|
|
pr_debug("wr_PHY(adr=%d, pag=%d, reg=%d, val=%d) err = %d\n",
|
|
|
addr, page, regnum, val, err);
|
|
|
}
|
|
|
|
|
|
- bus_priv->raw[addr] = false;
|
|
|
+ priv->raw[addr] = false;
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
@@ -2025,8 +2022,7 @@ u8 mac_type_bit[RTL930X_CPU_PORT] = {0, 0, 0, 0, 2, 2, 2, 2, 4, 4, 4, 4, 6, 6, 6
|
|
|
|
|
|
static int rtmdio_930x_reset(struct mii_bus *bus)
|
|
|
{
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *priv = bus_priv->eth_priv;
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
u32 c45_mask = 0;
|
|
|
u32 poll_sel[2];
|
|
|
u32 poll_ctrl = 0;
|
|
|
@@ -2131,8 +2127,7 @@ static int rtmdio_930x_reset(struct mii_bus *bus)
|
|
|
|
|
|
static int rtmdio_931x_reset(struct mii_bus *bus)
|
|
|
{
|
|
|
- struct rtmdio_bus_priv *bus_priv = bus->priv;
|
|
|
- struct rtl838x_eth_priv *priv = bus_priv->eth_priv;
|
|
|
+ struct rtmdio_bus_priv *priv = bus->priv;
|
|
|
u32 c45_mask = 0;
|
|
|
u32 poll_sel[4];
|
|
|
u32 poll_ctrl = 0;
|
|
|
@@ -2230,10 +2225,10 @@ static int rtl931x_chip_init(struct rtl838x_eth_priv *priv)
|
|
|
|
|
|
static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
|
|
|
{
|
|
|
- struct device_node *mii_np, *dn;
|
|
|
struct rtmdio_bus_priv *bus_priv;
|
|
|
- u32 pn;
|
|
|
+ struct device_node *mii_np, *dn;
|
|
|
int i, ret;
|
|
|
+ u32 pn;
|
|
|
|
|
|
pr_debug("%s called\n", __func__);
|
|
|
mii_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
|
|
|
@@ -2255,7 +2250,8 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
|
|
|
}
|
|
|
|
|
|
bus_priv = priv->mii_bus->priv;
|
|
|
- bus_priv->eth_priv = priv;
|
|
|
+ bus_priv->id = soc_info.id;
|
|
|
+ bus_priv->family_id = soc_info.family;
|
|
|
for (i=0; i < RTMDIO_MAX_PORT; i++) {
|
|
|
bus_priv->page[i] = 0;
|
|
|
bus_priv->raw[i] = false;
|
|
|
@@ -2323,30 +2319,30 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- if (of_property_read_u32(dn, "sds", &priv->sds_id[pn]))
|
|
|
- priv->sds_id[pn] = -1;
|
|
|
+ if (of_property_read_u32(dn, "sds", &bus_priv->sds_id[pn]))
|
|
|
+ bus_priv->sds_id[pn] = -1;
|
|
|
else
|
|
|
- pr_info("set sds port %d to %d\n", pn, priv->sds_id[pn]);
|
|
|
+ pr_info("set sds port %d to %d\n", pn, bus_priv->sds_id[pn]);
|
|
|
|
|
|
if (of_property_read_u32_array(dn, "rtl9300,smi-address", &smi_addr[0], 2)) {
|
|
|
- priv->smi_bus[pn] = 0;
|
|
|
- priv->smi_addr[pn] = pn;
|
|
|
+ bus_priv->smi_bus[pn] = 0;
|
|
|
+ bus_priv->smi_addr[pn] = pn;
|
|
|
} else {
|
|
|
- priv->smi_bus[pn] = smi_addr[0];
|
|
|
- priv->smi_addr[pn] = smi_addr[1];
|
|
|
+ bus_priv->smi_bus[pn] = smi_addr[0];
|
|
|
+ bus_priv->smi_addr[pn] = smi_addr[1];
|
|
|
}
|
|
|
|
|
|
- if (priv->smi_bus[pn] >= RTMDIO_MAX_SMI_BUS) {
|
|
|
- pr_err("%s: illegal SMI bus number %d\n", __func__, priv->smi_bus[pn]);
|
|
|
+ if (bus_priv->smi_bus[pn] >= RTMDIO_MAX_SMI_BUS) {
|
|
|
+ pr_err("%s: illegal SMI bus number %d\n", __func__, bus_priv->smi_bus[pn]);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- priv->phy_is_internal[pn] = of_property_read_bool(dn, "phy-is-integrated");
|
|
|
+ bus_priv->phy_is_internal[pn] = of_property_read_bool(dn, "phy-is-integrated");
|
|
|
|
|
|
- if (priv->phy_is_internal[pn] && priv->sds_id[pn] >= 0)
|
|
|
- priv->smi_bus[pn]= -1;
|
|
|
+ if (bus_priv->phy_is_internal[pn] && bus_priv->sds_id[pn] >= 0)
|
|
|
+ bus_priv->smi_bus[pn]= -1;
|
|
|
else if (of_device_is_compatible(dn, "ethernet-phy-ieee802.3-c45"))
|
|
|
- priv->smi_bus_isc45[priv->smi_bus[pn]] = true;
|
|
|
+ bus_priv->smi_bus_isc45[bus_priv->smi_bus[pn]] = true;
|
|
|
}
|
|
|
|
|
|
dn = of_find_compatible_node(NULL, NULL, "realtek,rtl83xx-switch");
|
|
|
@@ -2361,9 +2357,10 @@ static int rtl838x_mdio_init(struct rtl838x_eth_priv *priv)
|
|
|
pr_debug("%s Looking at port %d\n", __func__, pn);
|
|
|
if (pn > priv->cpu_port)
|
|
|
continue;
|
|
|
- if (of_get_phy_mode(dn, &priv->interfaces[pn]))
|
|
|
- priv->interfaces[pn] = PHY_INTERFACE_MODE_NA;
|
|
|
- pr_debug("%s phy mode of port %d is %s\n", __func__, pn, phy_modes(priv->interfaces[pn]));
|
|
|
+ if (of_get_phy_mode(dn, &bus_priv->interfaces[pn]))
|
|
|
+ bus_priv->interfaces[pn] = PHY_INTERFACE_MODE_NA;
|
|
|
+ pr_debug("%s phy mode of port %d is %s\n",
|
|
|
+ __func__, pn, phy_modes(bus_priv->interfaces[pn]));
|
|
|
}
|
|
|
|
|
|
snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%pOFn", mii_np);
|