generic: ar8216: add setup_port field to ar8xxx_chip
[openwrt.git] / target / linux / generic / files / drivers / net / phy / rtl8366s.c
index 8fa1ed1..7f9680a 100644 (file)
@@ -229,8 +229,8 @@ static int rtl8366s_reset_chip(struct rtl8366_smi *smi)
        int timeout = 10;
        u32 data;
 
-       rtl8366_smi_write_reg(smi, RTL8366S_RESET_CTRL_REG,
-                             RTL8366S_CHIP_CTRL_RESET_HW);
+       rtl8366_smi_write_reg_noack(smi, RTL8366S_RESET_CTRL_REG,
+                                   RTL8366S_CHIP_CTRL_RESET_HW);
        do {
                msleep(1);
                if (rtl8366_smi_read_reg(smi, RTL8366S_RESET_CTRL_REG, &data))
@@ -655,6 +655,49 @@ static int rtl8366s_sw_set_blinkrate(struct switch_dev *dev,
                                val->value.i);
 }
 
+static int rtl8366s_sw_get_max_length(struct switch_dev *dev,
+                                       const struct switch_attr *attr,
+                                       struct switch_val *val)
+{
+       struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
+       u32 data;
+
+       rtl8366_smi_read_reg(smi, RTL8366S_SGCR, &data);
+
+       val->value.i = ((data & (RTL8366S_SGCR_MAX_LENGTH_MASK)) >> 4);
+
+       return 0;
+}
+
+static int rtl8366s_sw_set_max_length(struct switch_dev *dev,
+                                       const struct switch_attr *attr,
+                                       struct switch_val *val)
+{
+       struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
+       char length_code;
+
+       switch (val->value.i) {
+               case 0:
+                       length_code = RTL8366S_SGCR_MAX_LENGTH_1522;
+                       break;
+               case 1:
+                       length_code = RTL8366S_SGCR_MAX_LENGTH_1536;
+                       break;
+               case 2:
+                       length_code = RTL8366S_SGCR_MAX_LENGTH_1552;
+                       break;
+               case 3:
+                       length_code = RTL8366S_SGCR_MAX_LENGTH_16000;
+                       break;
+               default:
+                       return -EINVAL;
+       }
+
+       return rtl8366_smi_rmwr(smi, RTL8366S_SGCR,
+                       RTL8366S_SGCR_MAX_LENGTH_MASK,
+                       length_code);
+}
+
 static int rtl8366s_sw_get_learning_enable(struct switch_dev *dev,
                                           const struct switch_attr *attr,
                                           struct switch_val *val)
@@ -689,59 +732,47 @@ static int rtl8366s_sw_set_learning_enable(struct switch_dev *dev,
        return 0;
 }
 
-
-static const char *rtl8366s_speed_str(unsigned speed)
-{
-       switch (speed) {
-       case 0:
-               return "10baseT";
-       case 1:
-               return "100baseT";
-       case 2:
-               return "1000baseT";
-       }
-
-       return "unknown";
-}
-
 static int rtl8366s_sw_get_port_link(struct switch_dev *dev,
-                                    const struct switch_attr *attr,
-                                    struct switch_val *val)
+                                    int port,
+                                    struct switch_port_link *link)
 {
        struct rtl8366_smi *smi = sw_to_rtl8366_smi(dev);
-       u32 len = 0, data = 0;
+       u32 data = 0;
+       u32 speed;
 
-       if (val->port_vlan >= RTL8366S_NUM_PORTS)
+       if (port >= RTL8366S_NUM_PORTS)
                return -EINVAL;
 
-       memset(smi->buf, '\0', sizeof(smi->buf));
-       rtl8366_smi_read_reg(smi, RTL8366S_PORT_LINK_STATUS_BASE +
-                            (val->port_vlan / 2), &data);
+       rtl8366_smi_read_reg(smi, RTL8366S_PORT_LINK_STATUS_BASE + (port / 2),
+                            &data);
 
-       if (val->port_vlan % 2)
+       if (port % 2)
                data = data >> 8;
 
-       if (data & RTL8366S_PORT_STATUS_LINK_MASK) {
-               len = snprintf(smi->buf, sizeof(smi->buf),
-                               "port:%d link:up speed:%s %s-duplex %s%s%s",
-                               val->port_vlan,
-                               rtl8366s_speed_str(data &
-                                         RTL8366S_PORT_STATUS_SPEED_MASK),
-                               (data & RTL8366S_PORT_STATUS_DUPLEX_MASK) ?
-                                       "full" : "half",
-                               (data & RTL8366S_PORT_STATUS_TXPAUSE_MASK) ?
-                                       "tx-pause ": "",
-                               (data & RTL8366S_PORT_STATUS_RXPAUSE_MASK) ?
-                                       "rx-pause " : "",
-                               (data & RTL8366S_PORT_STATUS_AN_MASK) ?
-                                       "nway ": "");
-       } else {
-               len = snprintf(smi->buf, sizeof(smi->buf), "port:%d link: down",
-                               val->port_vlan);
-       }
+       link->link = !!(data & RTL8366S_PORT_STATUS_LINK_MASK);
+       if (!link->link)
+               return 0;
 
-       val->value.s = smi->buf;
-       val->len = len;
+       link->duplex = !!(data & RTL8366S_PORT_STATUS_DUPLEX_MASK);
+       link->rx_flow = !!(data & RTL8366S_PORT_STATUS_RXPAUSE_MASK);
+       link->tx_flow = !!(data & RTL8366S_PORT_STATUS_TXPAUSE_MASK);
+       link->aneg = !!(data & RTL8366S_PORT_STATUS_AN_MASK);
+
+       speed = (data & RTL8366S_PORT_STATUS_SPEED_MASK);
+       switch (speed) {
+       case 0:
+               link->speed = SWITCH_PORT_SPEED_10;
+               break;
+       case 1:
+               link->speed = SWITCH_PORT_SPEED_100;
+               break;
+       case 2:
+               link->speed = SWITCH_PORT_SPEED_1000;
+               break;
+       default:
+               link->speed = SWITCH_PORT_SPEED_UNKNOWN;
+               break;
+       }
 
        return 0;
 }
@@ -863,18 +894,19 @@ static struct switch_attr rtl8366s_globals[] = {
                .set = rtl8366s_sw_set_blinkrate,
                .get = rtl8366s_sw_get_blinkrate,
                .max = 5
+       }, {
+               .type = SWITCH_TYPE_INT,
+               .name = "max_length",
+               .description = "Get/Set the maximum length of valid packets"
+               " (0 = 1522, 1 = 1536, 2 = 1552, 3 = 16000 (9216?))",
+               .set = rtl8366s_sw_set_max_length,
+               .get = rtl8366s_sw_get_max_length,
+               .max = 3,
        },
 };
 
 static struct switch_attr rtl8366s_port[] = {
        {
-               .type = SWITCH_TYPE_STRING,
-               .name = "link",
-               .description = "Get port link information",
-               .max = 1,
-               .set = NULL,
-               .get = rtl8366s_sw_get_port_link,
-       }, {
                .type = SWITCH_TYPE_NOVAL,
                .name = "reset_mib",
                .description = "Reset single port MIB counters",
@@ -933,6 +965,7 @@ static const struct switch_dev_ops rtl8366_ops = {
        .get_port_pvid = rtl8366_sw_get_port_pvid,
        .set_port_pvid = rtl8366_sw_set_port_pvid,
        .reset_switch = rtl8366s_sw_reset_switch,
+       .get_port_link = rtl8366s_sw_get_port_link,
 };
 
 static int rtl8366s_switch_init(struct rtl8366_smi *smi)
@@ -945,7 +978,7 @@ static int rtl8366s_switch_init(struct rtl8366_smi *smi)
        dev->ports = RTL8366S_NUM_PORTS;
        dev->vlans = RTL8366S_NUM_VIDS;
        dev->ops = &rtl8366_ops;
-       dev->devname = dev_name(smi->parent);
+       dev->alias = dev_name(smi->parent);
 
        err = register_switch(dev, NULL);
        if (err)
@@ -1076,6 +1109,9 @@ static int __devinit rtl8366s_probe(struct platform_device *pdev)
 
        smi->gpio_sda = pdata->gpio_sda;
        smi->gpio_sck = pdata->gpio_sck;
+       smi->clk_delay = 10;
+       smi->cmd_read = 0xa9;
+       smi->cmd_write = 0xa8;
        smi->ops = &rtl8366s_smi_ops;
        smi->cpu_port = RTL8366S_PORT_NUM_CPU;
        smi->num_ports = RTL8366S_NUM_PORTS;