u32 val, newval;
struct mii_bus *bus;
- val = priv->read(priv, 0x8);
+ val = priv->read(priv, AR8316_REG_POSTRIP);
if (priv->phy->interface == PHY_INTERFACE_MODE_RGMII) {
if (priv->port4_phy) {
if (val == newval)
goto out;
- priv->write(priv, 0x8, newval);
+ priv->write(priv, AR8316_REG_POSTRIP, newval);
/* Initialize the ports */
bus = priv->mii_bus;
if (!priv->mib_stats)
return -ENOMEM;
- mutex_init(&priv->mib_lock);
- INIT_DELAYED_WORK(&priv->mib_work, ar8xxx_mib_work_func);
-
return 0;
}
kfree(priv->mib_stats);
}
+static struct ar8216_priv *
+ar8xxx_create(void)
+{
+ struct ar8216_priv *priv;
+
+ priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ mutex_init(&priv->reg_mutex);
+ mutex_init(&priv->mib_lock);
+ INIT_DELAYED_WORK(&priv->mib_work, ar8xxx_mib_work_func);
+
+ return priv;
+}
+
+static struct ar8216_priv *
+ar8xxx_create_mii(struct mii_bus *bus)
+{
+ struct ar8216_priv *priv;
+
+ priv = ar8xxx_create();
+ if (priv) {
+ priv->mii_bus = bus;
+ priv->read = ar8216_mii_read;
+ priv->write = ar8216_mii_write;
+ }
+
+ return priv;
+}
+
static int
ar8216_config_init(struct phy_device *pdev)
{
int ret;
if (!priv) {
- priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
+ priv = ar8xxx_create_mii(pdev->bus);
if (priv == NULL)
return -ENOMEM;
- }
- priv->mii_bus = pdev->bus;
- priv->read = ar8216_mii_read;
- priv->write = ar8216_mii_write;
+ ret = ar8216_id_chip(priv);
+ if (ret)
+ goto err_free_priv;
+ }
priv->phy = pdev;
- ret = ar8216_id_chip(priv);
- if (ret)
- goto err_free_priv;
-
if (ar8xxx_has_gige(priv))
pdev->supported = SUPPORTED_1000baseT_Full;
else
return 0;
}
- mutex_init(&priv->reg_mutex);
-
pdev->priv = priv;
swdev = &priv->dev;
if (ret)
goto err_unregister_switch;
- dev->phy_ptr = priv;
-
/* VID fixup only needed on ar8216 */
- if (chip_is_ar8216(priv) && pdev->addr == 0) {
+ if (chip_is_ar8216(priv)) {
+ dev->phy_ptr = priv;
dev->priv_flags |= IFF_NO_IP_ALIGN;
dev->eth_mangle_rx = ar8216_mangle_rx;
dev->eth_mangle_tx = ar8216_mangle_tx;
return genphy_config_aneg(phydev);
}
+static const u32 ar8xxx_phy_ids[] = {
+ 0x004dd033,
+ 0x004dd041,
+ 0x004dd042,
+};
+
+static bool
+ar8xxx_phy_match(u32 phy_id)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ar8xxx_phy_ids); i++)
+ if (phy_id == ar8xxx_phy_ids[i])
+ return true;
+
+ return false;
+}
+
+static bool
+ar8xxx_is_possible(struct mii_bus *bus)
+{
+ unsigned i;
+
+ for (i = 0; i < 4; i++) {
+ u32 phy_id;
+
+ phy_id = mdiobus_read(bus, i, MII_PHYSID1) << 16;
+ phy_id |= mdiobus_read(bus, i, MII_PHYSID2);
+ if (!ar8xxx_phy_match(phy_id)) {
+ pr_debug("ar8xxx: unknown PHY at %s:%02x id:%08x\n",
+ dev_name(&bus->dev), i, phy_id);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static int
ar8216_probe(struct phy_device *pdev)
{
struct ar8216_priv *priv;
int ret;
- priv = kzalloc(sizeof(struct ar8216_priv), GFP_KERNEL);
+ /* skip PHYs at unused adresses */
+ if (pdev->addr != 0 && pdev->addr != 4)
+ return -ENODEV;
+
+ if (!ar8xxx_is_possible(pdev->bus))
+ return -ENODEV;
+
+ priv = ar8xxx_create_mii(pdev->bus);
if (priv == NULL)
return -ENOMEM;
- priv->mii_bus = pdev->bus;
- priv->read = ar8216_mii_read;
- priv->write = ar8216_mii_write;
priv->phy = pdev;
ret = ar8216_id_chip(priv);