]> git.enpas.org Git - openwrt.git/blobdiff - target/linux/generic/files/drivers/net/phy/rtl8306.c
kernel: rtl8306: cosmetic changes for swconfig
[openwrt.git] / target / linux / generic / files / drivers / net / phy / rtl8306.c
index 901b5b2f83ef578b011de83189c2c7a82207dcfb..1f27065a3331469dc65e20c2e478ff1c6f5b260e 100644 (file)
@@ -56,6 +56,7 @@ struct rtl_priv {
        int do_cpu;
        struct mii_bus *bus;
        char hwname[sizeof(RTL_NAME_UNKNOWN)];
+       bool fixup;
 };
 
 struct rtl_phyregs {
@@ -250,17 +251,15 @@ static const struct rtl_reg rtl_regs[] = {
 };
 
 
-/* IFXMIPS compat stuff - remove after PHY layer migration */
-static struct switch_dev rtldev;
-/* END IFXMIPS compat stuff */
-
-
 static inline void
 rtl_set_page(struct rtl_priv *priv, unsigned int page)
 {
        struct mii_bus *bus = priv->bus;
        u16 pgsel;
 
+       if (priv->fixup)
+               return;
+
        if (priv->page == page)
                return;
 
@@ -520,7 +519,7 @@ rtl_get_cpuport(struct switch_dev *dev, const struct switch_attr *attr, struct s
 #endif
 
 static int
-rtl_reset(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
+rtl_reset(struct switch_dev *dev)
 {
        rtl_hw_init(dev);
        return 0;
@@ -583,6 +582,27 @@ rtl_attr_get_port_int(struct switch_dev *dev, const struct switch_attr *attr, st
        return rtl_attr_get_int(dev, attr, val);
 }
 
+static int 
+rtl_get_port_link(struct switch_dev *dev, int port, struct switch_port_link *link)
+{
+       if (port >= RTL8306_NUM_PORTS)
+               return -EINVAL;
+
+       link->link = rtl_get(dev, RTL_PORT_REG(port, LINK));
+       if (!link->link)
+               return 0;
+
+       link->duplex = rtl_get(dev, RTL_PORT_REG(port, DUPLEX));
+       link->aneg = rtl_get(dev, RTL_PORT_REG(port, NWAY));
+
+       if (rtl_get(dev, RTL_PORT_REG(port, SPEED)))
+               link->speed = SWITCH_PORT_SPEED_100;
+       else
+               link->speed = SWITCH_PORT_SPEED_10;
+
+       return 0;
+}
+
 static int
 rtl_attr_set_vlan_int(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
 {
@@ -615,7 +635,8 @@ rtl_get_ports(struct switch_dev *dev, struct switch_val *val)
 
                port = &val->value.ports[val->len];
                port->id = i;
-               port->flags = 0;
+               if (rtl_get(dev, RTL_PORT_REG(i, TAG_INSERT)) == 2 || i == dev->cpu_port)
+                       port->flags = (1 << SWITCH_PORT_FLAG_TAGGED);
                val->len++;
        }
 
@@ -654,7 +675,8 @@ rtl_set_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct swit
 static int
 rtl_get_vlan(struct switch_dev *dev, const struct switch_attr *attr, struct switch_val *val)
 {
-       return rtl_get(dev, RTL_REG_VLAN_ENABLE);
+       val->value.i = rtl_get(dev, RTL_REG_VLAN_ENABLE);
+       return 0;
 }
 
 static int
@@ -706,71 +728,7 @@ rtl_set_ports(struct switch_dev *dev, struct switch_val *val)
        return 0;
 }
 
-static int
-rtl8306_config_init(struct phy_device *pdev)
-{
-       struct net_device *netdev = pdev->attached_dev;
-       struct rtl_priv *priv = pdev->priv;
-       struct switch_dev *dev = &priv->dev;
-       struct switch_val val;
-       unsigned int chipid, chipver, chiptype;
-       int err;
-
-       /* Only init the switch for the primary PHY */
-       if (pdev->addr != 0)
-               return 0;
-
-       val.value.i = 1;
-       memcpy(&priv->dev, &rtldev, sizeof(struct switch_dev));
-       priv->do_cpu = 0;
-       priv->page = -1;
-       priv->bus = pdev->bus;
-
-       dev->priv = priv;
-
-       chipid = rtl_get(dev, RTL_REG_CHIPID);
-       chipver = rtl_get(dev, RTL_REG_CHIPVER);
-       chiptype = rtl_get(dev, RTL_REG_CHIPTYPE);
-       switch(chiptype) {
-       case 0:
-       case 2:
-               strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname));
-               priv->type = RTL_TYPE_S;
-               break;
-       case 1:
-               strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname));
-               priv->type = RTL_TYPE_SD;
-               break;
-       case 3:
-               strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname));
-               priv->type = RTL_TYPE_SDM;
-               break;
-       default:
-               strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname));
-               break;
-       }
-
-       dev->name = priv->hwname;
-       rtl_hw_init(dev);
-
-       printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver);
-
-       err = register_switch(dev, netdev);
-       if (err < 0) {
-               kfree(priv);
-               return err;
-       }
-
-       return 0;
-}
-
 static struct switch_attr rtl_globals[] = {
-       {
-               .type = SWITCH_TYPE_INT,
-               .name = "reset",
-               .description = "Reset the switch",
-               .set = rtl_reset,
-       },
        {
                .type = SWITCH_TYPE_INT,
                .name = "enable_vlan",
@@ -841,13 +799,6 @@ static struct switch_attr rtl_port[] = {
                .description = "Port VLAN ID",
                .max = RTL8306_NUM_VLANS - 1,
        },
-       {
-               RTL_PORT_REGATTR(LINK),
-               .name = "link",
-               .description = "get the current link state",
-               .max = 1,
-               .set = NULL,
-       },
 #ifdef DEBUG
        {
                RTL_PORT_REGATTR(NULL_VID_REPLACE),
@@ -874,34 +825,18 @@ static struct switch_attr rtl_port[] = {
                .max = 3,
        },
 #endif
-       {
-               RTL_PORT_REGATTR(SPEED),
-               .name = "speed",
-               .description = "current link speed",
-               .max = 1,
-       },
-       {
-               RTL_PORT_REGATTR(NWAY),
-               .name = "nway",
-               .description = "enable autonegotiation",
-               .max = 1,
-       },
 };
 
 static struct switch_attr rtl_vlan[] = {
        {
                RTL_VLAN_REGATTR(VID),
                .name = "vid",
-               .description = "VLAN ID",
+               .description = "VLAN ID (1-4095)",
                .max = 4095,
        },
 };
 
-/* template */
-static struct switch_dev rtldev = {
-       .cpu_port = RTL8306_PORT_CPU,
-       .ports = RTL8306_NUM_PORTS,
-       .vlans = RTL8306_NUM_VLANS,
+static const struct switch_dev_ops rtl8306_ops = {
        .attr_global = {
                .attr = rtl_globals,
                .n_attr = ARRAY_SIZE(rtl_globals),
@@ -918,8 +853,69 @@ static struct switch_dev rtldev = {
        .get_vlan_ports = rtl_get_ports,
        .set_vlan_ports = rtl_set_ports,
        .apply_config = rtl_hw_apply,
+       .reset_switch = rtl_reset,
+       .get_port_link = rtl_get_port_link,
 };
 
+static int
+rtl8306_config_init(struct phy_device *pdev)
+{
+       struct net_device *netdev = pdev->attached_dev;
+       struct rtl_priv *priv = pdev->priv;
+       struct switch_dev *dev = &priv->dev;
+       struct switch_val val;
+       unsigned int chipid, chipver, chiptype;
+       int err;
+
+       /* Only init the switch for the primary PHY */
+       if (pdev->addr != 0)
+               return 0;
+
+       val.value.i = 1;
+       priv->dev.cpu_port = RTL8306_PORT_CPU;
+       priv->dev.ports = RTL8306_NUM_PORTS;
+       priv->dev.vlans = RTL8306_NUM_VLANS;
+       priv->dev.ops = &rtl8306_ops;
+       priv->do_cpu = 0;
+       priv->page = -1;
+       priv->bus = pdev->bus;
+
+       chipid = rtl_get(dev, RTL_REG_CHIPID);
+       chipver = rtl_get(dev, RTL_REG_CHIPVER);
+       chiptype = rtl_get(dev, RTL_REG_CHIPTYPE);
+       switch(chiptype) {
+       case 0:
+       case 2:
+               strncpy(priv->hwname, RTL_NAME_S, sizeof(priv->hwname));
+               priv->type = RTL_TYPE_S;
+               break;
+       case 1:
+               strncpy(priv->hwname, RTL_NAME_SD, sizeof(priv->hwname));
+               priv->type = RTL_TYPE_SD;
+               break;
+       case 3:
+               strncpy(priv->hwname, RTL_NAME_SDM, sizeof(priv->hwname));
+               priv->type = RTL_TYPE_SDM;
+               break;
+       default:
+               strncpy(priv->hwname, RTL_NAME_UNKNOWN, sizeof(priv->hwname));
+               break;
+       }
+
+       dev->name = priv->hwname;
+       rtl_hw_init(dev);
+
+       printk(KERN_INFO "Registering %s switch with Chip ID: 0x%04x, version: 0x%04x\n", priv->hwname, chipid, chipver);
+
+       err = register_switch(dev, netdev);
+       if (err < 0) {
+               kfree(priv);
+               return err;
+       }
+
+       return 0;
+}
+
 
 static int
 rtl8306_fixup(struct phy_device *pdev)
@@ -931,6 +927,8 @@ rtl8306_fixup(struct phy_device *pdev)
        if (pdev->addr != 0 && pdev->addr != 4)
                return 0;
 
+       memset(&priv, 0, sizeof(priv));
+       priv.fixup = true;
        priv.page = -1;
        priv.bus = pdev->bus;
        chipid = rtl_get(&priv.dev, RTL_REG_CHIPID);