X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/b9fa24dba2ddfb044869f2a6bc9a8d46bd857cb0..d29edcf013f273ebb64d5d065d7b3925a1993689:/target/linux/generic/files/drivers/net/phy/ar8216.c diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c index 13a874e41..485cb5205 100644 --- a/target/linux/generic/files/drivers/net/phy/ar8216.c +++ b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -36,6 +36,16 @@ #define AR8X16_MAX_VLANS 128 #define AR8X16_PROBE_RETRIES 10 +struct ar8216_priv; + +struct ar8xxx_chip { + int (*hw_init)(struct ar8216_priv *priv); + void (*init_port)(struct ar8216_priv *priv, int port); + void (*setup_port)(struct ar8216_priv *priv, int port, u32 egress, + u32 ingress, u32 members, u32 pvid); + int (*atu_flush)(struct ar8216_priv *priv); +}; + struct ar8216_priv { struct switch_dev dev; struct phy_device *phy; @@ -45,6 +55,7 @@ struct ar8216_priv { struct net_device_ops ndo; struct mutex reg_mutex; int chip_type; + const struct ar8xxx_chip *chip; bool initialized; bool port4_phy; char buf[80]; @@ -471,6 +482,18 @@ ar8216_vtu_op(struct ar8216_priv *priv, u32 op, u32 val) priv->write(priv, AR8216_REG_VTU, op); } +static int +ar8216_atu_flush(struct ar8216_priv *priv) +{ + int ret; + + ret = ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0); + if (!ret) + priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH); + + return ret; +} + static void ar8216_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress, u32 members, u32 pvid) @@ -583,12 +606,8 @@ ar8216_hw_apply(struct switch_dev *dev) ingress = AR8216_IN_PORT_ONLY; } - if (priv->chip_type == AR8236) - ar8236_setup_port(priv, i, egress, ingress, portmask[i], - pvid); - else - ar8216_setup_port(priv, i, egress, ingress, portmask[i], - pvid); + priv->chip->setup_port(priv, i, egress, ingress, portmask[i], + pvid); } mutex_unlock(&priv->reg_mutex); return 0; @@ -736,6 +755,27 @@ ar8216_init_port(struct ar8216_priv *priv, int port) } } +static const struct ar8xxx_chip ar8216_chip = { + .hw_init = ar8216_hw_init, + .init_port = ar8216_init_port, + .setup_port = ar8216_setup_port, + .atu_flush = ar8216_atu_flush, +}; + +static const struct ar8xxx_chip ar8236_chip = { + .hw_init = ar8236_hw_init, + .init_port = ar8216_init_port, + .setup_port = ar8236_setup_port, + .atu_flush = ar8216_atu_flush, +}; + +static const struct ar8xxx_chip ar8316_chip = { + .hw_init = ar8316_hw_init, + .init_port = ar8216_init_port, + .setup_port = ar8216_setup_port, + .atu_flush = ar8216_atu_flush, +}; + static int ar8216_reset_switch(struct switch_dev *dev) { @@ -751,7 +791,7 @@ ar8216_reset_switch(struct switch_dev *dev) /* Configure all ports */ for (i = 0; i < AR8216_NUM_PORTS; i++) - ar8216_init_port(priv, i); + priv->chip->init_port(priv, i); ar8216_init_globals(priv); mutex_unlock(&priv->reg_mutex); @@ -810,13 +850,16 @@ ar8216_id_chip(struct ar8216_priv *priv) switch (id) { case 0x0101: priv->chip_type = AR8216; + priv->chip = &ar8216_chip; break; case 0x0301: priv->chip_type = AR8236; + priv->chip = &ar8236_chip; break; case 0x1000: case 0x1001: priv->chip_type = AR8316; + priv->chip = &ar8316_chip; break; default: printk(KERN_DEBUG @@ -927,14 +970,7 @@ ar8216_config_init(struct phy_device *pdev) priv->init = true; - ret = 0; - if (priv->chip_type == AR8216) - ret = ar8216_hw_init(priv); - else if (priv->chip_type == AR8236) - ret = ar8236_hw_init(priv); - else if (priv->chip_type == AR8316) - ret = ar8316_hw_init(priv); - + ret = priv->chip->hw_init(priv); if (ret) goto err_free_priv; @@ -996,9 +1032,7 @@ ar8216_read_status(struct phy_device *phydev) /* flush the address translation unit */ mutex_lock(&priv->reg_mutex); - ret = ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0); - if (!ret) - priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH); + ret = priv->chip->atu_flush(priv); mutex_unlock(&priv->reg_mutex); phydev->state = PHY_RUNNING;