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;
buf[1] = 0x80;
send:
- return priv->hardstart(skb, dev);
+ return priv->ndo_old->ndo_start_xmit(skb, dev);
error:
dev_kfree_skb_any(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,
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));
}
/* 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);
}
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;
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))
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);
}