ar8216: fix the mtu register definition
[openwrt.git] / target / linux / generic-2.6 / files / drivers / net / phy / ar8216.c
index f629058..0a6eed9 100644 (file)
 
 
 struct ar8216_priv {
-       int (*hardstart)(struct sk_buff *skb, struct net_device *dev);
-
        struct switch_dev dev;
        struct phy_device *phy;
        u32 (*read)(struct ar8216_priv *priv, int reg);
        void (*write)(struct ar8216_priv *priv, int reg, u32 val);
+       const struct net_device_ops *ndo_old;
+       struct net_device_ops ndo;
 
        /* all fields below are cleared on reset */
        bool vlan;
-       u8 vlan_id[AR8216_NUM_VLANS];
+       u16 vlan_id[AR8216_NUM_VLANS];
        u8 vlan_table[AR8216_NUM_VLANS];
        u8 vlan_tagged;
        u16 pvid[AR8216_NUM_PORTS];
@@ -133,6 +133,12 @@ static int
 ar8216_set_pvid(struct switch_dev *dev, int port, int vlan)
 {
        struct ar8216_priv *priv = to_ar8216(dev);
+
+       /* make sure no invalid PVIDs get set */
+
+       if (vlan >= AR8216_NUM_VLANS)
+               return -EINVAL;
+
        priv->pvid[port] = vlan;
        return 0;
 }
@@ -186,7 +192,7 @@ ar8216_mangle_tx(struct sk_buff *skb, struct net_device *dev)
        buf[1] = 0x80;
 
 send:
-       return priv->hardstart(skb, dev);
+       return priv->ndo_old->ndo_start_xmit(skb, dev);
 
 error:
        dev_kfree_skb_any(skb);
@@ -228,7 +234,7 @@ ar8216_mangle_rx(struct sk_buff *skb, int napi)
                goto recv;
 
        /* lookup port vid from local table, the switch passes an invalid vlan id */
-       vlan = priv->pvid[port];
+       vlan = priv->vlan_id[priv->pvid[port]];
 
        buf[14 + 2] &= 0xf0;
        buf[14 + 2] |= vlan >> 8;
@@ -264,7 +270,7 @@ ar8216_netif_receive_skb(struct sk_buff *skb)
 static struct switch_attr ar8216_globals[] = {
        {
                .type = SWITCH_TYPE_INT,
-               .name = "vlan",
+               .name = "enable_vlan",
                .description = "Enable VLAN mode",
                .set = ar8216_set_vlan,
                .get = ar8216_get_vlan,
@@ -282,7 +288,7 @@ static struct switch_attr ar8216_vlan[] = {
                .description = "VLAN ID",
                .set = ar8216_set_vid,
                .get = ar8216_get_vid,
-               .max = 4095,
+               .max = 4094,
        },
 };
 
@@ -396,9 +402,6 @@ ar8216_hw_apply(struct switch_dev *dev)
                                        portmask[i] |= vp & ~mask;
                        }
 
-                       if (!priv->vlan_table[j])
-                               continue;
-
                        ar8216_vtu_op(priv,
                                AR8216_VTU_OP_LOAD |
                                (priv->vlan_id[j] << AR8216_VTU_VID_S),
@@ -432,14 +435,19 @@ ar8216_hw_apply(struct switch_dev *dev)
                } else {
                        egress = AR8216_OUT_STRIP_VLAN;
                }
-               ingress = AR8216_IN_SECURE;
+               if (priv->vlan) {
+                       ingress = AR8216_IN_SECURE;
+               } else {
+                       ingress = AR8216_IN_PORT_ONLY;
+               }
 
                ar8216_rmw(priv, AR8216_REG_PORT_CTRL(i),
                        AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE |
                        AR8216_PORT_CTRL_SINGLE_VLAN | AR8216_PORT_CTRL_STATE |
                        AR8216_PORT_CTRL_HEADER | AR8216_PORT_CTRL_LEARN_LOCK,
                        AR8216_PORT_CTRL_LEARN |
-                         (i == AR8216_PORT_CPU ? AR8216_PORT_CTRL_HEADER : 0) |
+                         (priv->vlan && i == AR8216_PORT_CPU ?
+                          AR8216_PORT_CTRL_HEADER : 0) |
                          (egress << AR8216_PORT_CTRL_VLAN_MODE_S) |
                          (AR8216_PORT_STATE_FORWARD << AR8216_PORT_CTRL_STATE_S));
 
@@ -477,7 +485,7 @@ ar8216_reset_switch(struct switch_dev *dev)
                if (i == AR8216_PORT_CPU) {
                        priv->write(priv, AR8216_REG_PORT_STATUS(i),
                                AR8216_PORT_STATUS_LINK_UP |
-                               AR8216_PORT_STATUS_SPEED |
+                               AR8216_PORT_SPEED_100M |
                                AR8216_PORT_STATUS_TXMAC |
                                AR8216_PORT_STATUS_RXMAC |
                                AR8216_PORT_STATUS_DUPLEX);
@@ -488,6 +496,10 @@ ar8216_reset_switch(struct switch_dev *dev)
        }
        /* XXX: undocumented magic from atheros, required! */
        priv->write(priv, 0x38, 0xc000050e);
+
+       ar8216_rmw(priv, AR8216_REG_GLOBAL_CTRL,
+               AR8216_GCTRL_MTU, 1518 + 8 + 2);
+
        return ar8216_hw_apply(dev);
 }
 
@@ -522,10 +534,13 @@ ar8216_config_init(struct phy_device *pdev)
 
        dev->phy_ptr = priv;
        pdev->pkt_align = 2;
-       priv->hardstart = dev->hard_start_xmit;
        pdev->netif_receive_skb = ar8216_netif_receive_skb;
        pdev->netif_rx = ar8216_netif_rx;
-       dev->hard_start_xmit = ar8216_mangle_tx;
+
+       priv->ndo_old = dev->netdev_ops;
+       memcpy(&priv->ndo, priv->ndo_old, sizeof(struct net_device_ops));
+       priv->ndo.ndo_start_xmit = ar8216_mangle_tx;
+       dev->netdev_ops = &priv->ndo;
 
 done:
        return ret;
@@ -538,7 +553,7 @@ ar8216_read_status(struct phy_device *phydev)
 
        phydev->speed = SPEED_100;
        phydev->duplex = DUPLEX_FULL;
-       phydev->state = PHY_UP;
+       phydev->link = 1;
 
        /* flush the address translation unit */
        if (ar8216_wait_bit(priv, AR8216_REG_ATU, AR8216_ATU_ACTIVE, 0))
@@ -546,6 +561,10 @@ ar8216_read_status(struct phy_device *phydev)
 
        priv->write(priv, AR8216_REG_ATU, AR8216_ATU_OP_FLUSH);
 
+       phydev->state = PHY_RUNNING;
+       netif_carrier_on(phydev->attached_dev);
+       phydev->adjust_link(phydev->attached_dev);
+
        return 0;
 }
 
@@ -565,8 +584,8 @@ ar8216_probe(struct phy_device *pdev)
 
        priv.phy = pdev;
        val = ar8216_mii_read(&priv, AR8216_REG_CTRL);
-       rev = val & 0xff;
-       id = (val >> 8) & 0xff;
+       rev = val & AR8216_CTRL_REVISION;
+       id = (val & AR8216_CTRL_VERSION) >> AR8216_CTRL_VERSION_S;
        if ((id != 1) || (rev != 1))
                return -ENODEV;
 
@@ -582,8 +601,8 @@ ar8216_remove(struct phy_device *pdev)
        if (!priv)
                return;
 
-       if (priv->hardstart && dev)
-               dev->hard_start_xmit = priv->hardstart;
+       if (priv->ndo_old && dev)
+               dev->netdev_ops = priv->ndo_old;
        unregister_switch(&priv->dev);
        kfree(priv);
 }
This page took 0.027153 seconds and 4 git commands to generate.