summaryrefslogtreecommitdiffstats
path: root/target/linux/generic/files/drivers/net/phy/mvswitch.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2012-05-06 21:19:14 +0000
committerFelix Fietkau <nbd@openwrt.org>2012-05-06 21:19:14 +0000
commit0ff3c396d39e762cb0230eb84b9bd1d29dddc520 (patch)
tree25a23535641b48d2b83e90e007c977404cade1b7 /target/linux/generic/files/drivers/net/phy/mvswitch.c
parentc3f0b757a3bd952f8d85753cd975618a3008ab36 (diff)
downloadmaster-31e0f0ae-0ff3c396d39e762cb0230eb84b9bd1d29dddc520.tar.gz
master-31e0f0ae-0ff3c396d39e762cb0230eb84b9bd1d29dddc520.tar.bz2
master-31e0f0ae-0ff3c396d39e762cb0230eb84b9bd1d29dddc520.zip
kernel: rewrite the phy packet hook, put it in the network stack to avoid having to keep non-upstream ethernet driver changes
SVN-Revision: 31637
Diffstat (limited to 'target/linux/generic/files/drivers/net/phy/mvswitch.c')
-rw-r--r--target/linux/generic/files/drivers/net/phy/mvswitch.c74
1 files changed, 20 insertions, 54 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/mvswitch.c b/target/linux/generic/files/drivers/net/phy/mvswitch.c
index 1324a80a60..d754951aca 100644
--- a/target/linux/generic/files/drivers/net/phy/mvswitch.c
+++ b/target/linux/generic/files/drivers/net/phy/mvswitch.c
@@ -41,8 +41,7 @@ MODULE_LICENSE("GPL");
#define MVSWITCH_MAGIC 0x88E6060
struct mvswitch_priv {
- const struct net_device_ops *ndo_old;
- struct net_device_ops ndo;
+ netdev_features_t orig_features;
u8 vlans[16];
};
@@ -61,8 +60,8 @@ w16(struct phy_device *phydev, int addr, int reg, u16 val)
}
-static int
-mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)
+static struct sk_buff *
+mvswitch_mangle_tx(struct net_device *dev, struct sk_buff *skb)
{
struct mvswitch_priv *priv;
char *buf = NULL;
@@ -132,7 +131,7 @@ mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)
));
#endif
- return priv->ndo_old->ndo_start_xmit(skb, dev);
+ return skb;
error_expand:
if (net_ratelimit())
@@ -141,25 +140,20 @@ error_expand:
error:
/* any errors? drop the packet! */
dev_kfree_skb_any(skb);
- return 0;
+ return NULL;
}
-static int
-mvswitch_mangle_rx(struct sk_buff *skb, int napi)
+static void
+mvswitch_mangle_rx(struct net_device *dev, struct sk_buff *skb)
{
struct mvswitch_priv *priv;
- struct net_device *dev;
- int vlan = -1;
unsigned char *buf;
+ int vlan = -1;
int i;
- dev = skb->dev;
- if (!dev)
- goto error;
-
priv = dev->phy_ptr;
- if (!priv)
- goto error;
+ if (WARN_ON_ONCE(!priv))
+ return;
#ifdef HEADER_MODE
buf = skb->data;
@@ -167,7 +161,7 @@ mvswitch_mangle_rx(struct sk_buff *skb, int napi)
#else
buf = skb->data + skb->len - MV_TRAILER_SIZE;
if (buf[0] != 0x80)
- goto error;
+ return;
#endif
/* look for the vlan matching the incoming port */
@@ -177,33 +171,9 @@ mvswitch_mangle_rx(struct sk_buff *skb, int napi)
}
if (vlan == -1)
- goto error;
-
- skb->protocol = eth_type_trans(skb, skb->dev);
+ return;
__vlan_hwaccel_put_tag(skb, vlan);
- if (napi)
- return netif_receive_skb(skb);
- else
- return netif_rx(skb);
-
-error:
- /* no vlan? eat the packet! */
- dev_kfree_skb_any(skb);
- return 0;
-}
-
-
-static int
-mvswitch_netif_rx(struct sk_buff *skb)
-{
- return mvswitch_mangle_rx(skb, 0);
-}
-
-static int
-mvswitch_netif_receive_skb(struct sk_buff *skb)
-{
- return mvswitch_mangle_rx(skb, 1);
}
@@ -331,16 +301,12 @@ mvswitch_config_init(struct phy_device *pdev)
MV_SWITCHCTL_DROP
);
- /* hook into the tx function */
- priv->ndo_old = dev->netdev_ops;
- memcpy(&priv->ndo, priv->ndo_old, sizeof(struct net_device_ops));
- priv->ndo.ndo_start_xmit = mvswitch_mangle_tx;
- dev->netdev_ops = &priv->ndo;
+ dev->eth_mangle_rx = mvswitch_mangle_rx;
+ dev->eth_mangle_tx = mvswitch_mangle_tx;
+ priv->orig_features = dev->features;
- pdev->pkt_align = 2;
- pdev->netif_receive_skb = mvswitch_netif_receive_skb;
- pdev->netif_rx = mvswitch_netif_rx;
#ifdef HEADER_MODE
+ dev->priv_flags |= IFF_NO_IP_ALIGN;
dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX;
#else
dev->features |= NETIF_F_HW_VLAN_RX;
@@ -387,11 +353,11 @@ mvswitch_remove(struct phy_device *pdev)
struct mvswitch_priv *priv = to_mvsw(pdev);
struct net_device *dev = pdev->attached_dev;
- /* restore old netdev ops */
- if (priv->ndo_old && dev)
- dev->netdev_ops = priv->ndo_old;
dev->phy_ptr = NULL;
- dev->features &= ~NETIF_F_HW_VLAN_RX;
+ dev->eth_mangle_rx = NULL;
+ dev->eth_mangle_tx = NULL;
+ dev->features = priv->orig_features;
+ dev->priv_flags &= ~IFF_NO_IP_ALIGN;
kfree(priv);
}