generic: revert workarounds for AR8337 switch
[openwrt/staging/wigyori.git] / target / linux / generic / files / drivers / net / phy / ar8327.c
index 72e0abc9d67c1887f5a0362bb8e85b8af4bcc878..74f0a08d76e837dc6576a4be84a976fc86b685ef 100644 (file)
@@ -619,11 +619,11 @@ ar8327_hw_init(struct ar8xxx_priv *priv)
        if (!priv->chip_data)
                return -ENOMEM;
 
-       if (priv->phy->dev.of_node)
-               ret = ar8327_hw_config_of(priv, priv->phy->dev.of_node);
+       if (priv->phy->mdio.dev.of_node)
+               ret = ar8327_hw_config_of(priv, priv->phy->mdio.dev.of_node);
        else
                ret = ar8327_hw_config_pdata(priv,
-                                            priv->phy->dev.platform_data);
+                                            priv->phy->mdio.dev.platform_data);
 
        if (ret)
                return ret;
@@ -885,10 +885,19 @@ ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 
        t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
        t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
+       if (priv->vlan && priv->port_vlan_prio[port]) {
+               u32 prio = priv->port_vlan_prio[port];
+
+               t |= prio << AR8327_PORT_VLAN0_DEF_SPRI_S;
+               t |= prio << AR8327_PORT_VLAN0_DEF_CPRI_S;
+       }
        ar8xxx_write(priv, AR8327_REG_PORT_VLAN0(port), t);
 
        t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
        t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
+       if (priv->vlan && priv->port_vlan_prio[port])
+               t |= AR8327_PORT_VLAN1_VLAN_PRI_PROP;
+
        ar8xxx_write(priv, AR8327_REG_PORT_VLAN1(port), t);
 
        t = members;
@@ -1033,14 +1042,15 @@ ar8327_wait_atu_ready(struct ar8xxx_priv *priv, u16 r2, u16 r1)
 {
        int timeout = 20;
 
-       while (ar8xxx_mii_read32(priv, r2, r1) & AR8327_ATU_FUNC_BUSY && --timeout)
-                udelay(10);
+       while (ar8xxx_mii_read32(priv, r2, r1) & AR8327_ATU_FUNC_BUSY && --timeout) {
+               udelay(10);
+               cond_resched();
+       }
 
        if (!timeout)
                pr_err("ar8327: timeout waiting for atu to become ready\n");
 }
 
-#if 0
 static void ar8327_get_arl_entry(struct ar8xxx_priv *priv,
                                 struct arl_entry *a, u32 *status, enum arl_op op)
 {
@@ -1100,7 +1110,6 @@ static void ar8327_get_arl_entry(struct ar8xxx_priv *priv,
                break;
        }
 }
-#endif
 
 static int
 ar8327_sw_hw_apply(struct switch_dev *dev)
@@ -1229,6 +1238,37 @@ ar8327_sw_set_igmp_v3(struct switch_dev *dev,
        return 0;
 }
 
+static int
+ar8327_sw_set_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr,
+                            struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int port = val->port_vlan;
+
+       if (port >= dev->ports)
+               return -EINVAL;
+       if (port == 0 || port == 6)
+               return -EOPNOTSUPP;
+       if (val->value.i < 0 || val->value.i > 7)
+               return -EINVAL;
+
+       priv->port_vlan_prio[port] = val->value.i;
+
+       return 0;
+}
+
+static int
+ar8327_sw_get_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr,
+                  struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int port = val->port_vlan;
+
+       val->value.i = priv->port_vlan_prio[port];
+
+       return 0;
+}
+
 static const struct switch_attr ar8327_sw_attr_globals[] = {
        {
                .type = SWITCH_TYPE_INT,
@@ -1275,7 +1315,7 @@ static const struct switch_attr ar8327_sw_attr_globals[] = {
                .set = ar8xxx_sw_set_mirror_source_port,
                .get = ar8xxx_sw_get_mirror_source_port,
                .max = AR8327_NUM_PORTS - 1
-       },
+       },
        {
                .type = SWITCH_TYPE_INT,
                .name = "arl_age_time",
@@ -1350,6 +1390,14 @@ static const struct switch_attr ar8327_sw_attr_port[] = {
                .get = ar8327_sw_get_port_igmp_snooping,
                .max = 1
        },
+       {
+               .type = SWITCH_TYPE_INT,
+               .name = "vlan_prio",
+               .description = "Port VLAN default priority (VLAN PCP) (0-7)",
+               .set = ar8327_sw_set_port_vlan_prio,
+               .get = ar8327_sw_get_port_vlan_prio,
+               .max = 7,
+       },
 };
 
 static const struct switch_dev_ops ar8327_sw_ops = {
@@ -1372,6 +1420,16 @@ static const struct switch_dev_ops ar8327_sw_ops = {
        .apply_config = ar8327_sw_hw_apply,
        .reset_switch = ar8xxx_sw_reset_switch,
        .get_port_link = ar8xxx_sw_get_port_link,
+/* The following op is disabled as it hogs the CPU and degrades performance.
+   An implementation has been attempted in 4d8a66d but reading MIB data is slow
+   on ar8xxx switches.
+
+   The high CPU load has been traced down to the ar8xxx_reg_wait() call in
+   ar8xxx_mib_op(), which has to usleep_range() till the MIB busy flag set by
+   the request to update the MIB counter is cleared. */
+#if 0
+       .get_port_stats = ar8xxx_sw_get_port_stats,
+#endif
 };
 
 const struct ar8xxx_chip ar8327_chip = {
@@ -1401,9 +1459,7 @@ const struct ar8xxx_chip ar8327_chip = {
        .vtu_load_vlan = ar8327_vtu_load_vlan,
        .phy_fixup = ar8327_phy_fixup,
        .set_mirror_regs = ar8327_set_mirror_regs,
-#if 0
        .get_arl_entry = ar8327_get_arl_entry,
-#endif
        .sw_hw_apply = ar8327_sw_hw_apply,
 
        .num_mibs = ARRAY_SIZE(ar8236_mibs),
@@ -1438,9 +1494,7 @@ const struct ar8xxx_chip ar8337_chip = {
        .vtu_load_vlan = ar8327_vtu_load_vlan,
        .phy_fixup = ar8327_phy_fixup,
        .set_mirror_regs = ar8327_set_mirror_regs,
-#if 0
        .get_arl_entry = ar8327_get_arl_entry,
-#endif
        .sw_hw_apply = ar8327_sw_hw_apply,
 
        .num_mibs = ARRAY_SIZE(ar8236_mibs),