generic: ar8216: add init_port field to ar8xxx_chip
[openwrt.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index 13a874e..485cb52 100644 (file)
 #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;
This page took 0.032786 seconds and 4 git commands to generate.