ar71xx: make the rtl8306 switch attach to eth0 instead of eth1 on the wrt160nl, fixes...
[openwrt.git] / target / linux / generic-2.6 / files / drivers / net / phy / ar8216.c
index f629058..92cc9f3 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;
@@ -186,7 +186,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);
@@ -264,7 +264,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,
@@ -439,7 +439,8 @@ ar8216_hw_apply(struct switch_dev *dev)
                        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));
 
@@ -488,6 +489,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 +527,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 +546,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))
@@ -582,8 +590,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.032463 seconds and 4 git commands to generate.