diff options
4 files changed, 133 insertions, 43 deletions
| diff --git a/target/linux/atheros/patches-2.6.23/200-ar2313_enable_mvswitch.patch b/target/linux/atheros/patches-2.6.23/200-ar2313_enable_mvswitch.patch index b209aee0c..09c17977d 100644 --- a/target/linux/atheros/patches-2.6.23/200-ar2313_enable_mvswitch.patch +++ b/target/linux/atheros/patches-2.6.23/200-ar2313_enable_mvswitch.patch @@ -1,32 +1,41 @@  Index: linux-2.6.23.16/drivers/net/ar2313/ar2313.c  =================================================================== ---- linux-2.6.23.16.orig/drivers/net/ar2313/ar2313.c	2008-04-20 10:26:15.000000000 +0200 -+++ linux-2.6.23.16/drivers/net/ar2313/ar2313.c	2008-04-20 10:26:16.000000000 +0200 -@@ -955,7 +955,7 @@ +--- linux-2.6.23.16.orig/drivers/net/ar2313/ar2313.c	2008-04-29 14:51:39.000000000 +0200 ++++ linux-2.6.23.16/drivers/net/ar2313/ar2313.c	2008-04-29 14:52:14.000000000 +0200 +@@ -219,7 +219,7 @@ + 	dev->do_ioctl = &ar2313_ioctl; +  + 	// SAMEER: do we need this? +-	dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA; ++	dev->features |= NETIF_F_HIGHDMA | NETIF_F_HW_CSUM; +  + 	tasklet_init(&sp->rx_tasklet, rx_tasklet_func, (unsigned long) dev); + 	tasklet_disable(&sp->rx_tasklet); +@@ -953,9 +953,9 @@ + 						((status >> DMA_RX_LEN_SHIFT) & 0x3fff) - CRC_LEN); +    				dev->stats.rx_bytes += skb->len; - 				skb->protocol = eth_type_trans(skb, dev); +-				skb->protocol = eth_type_trans(skb, dev); ++   				/* pass the packet to upper layers */  -				netif_rx(skb);  +				sp->rx(skb);   				skb_new->dev = dev;   				/* 16 bit align */ -@@ -1370,6 +1370,11 @@ +@@ -1370,6 +1370,8 @@   		return PTR_ERR(phydev);   	} -+	if (phydev->netif_rx) -+		sp->rx = phydev->netif_rx; -+	else -+		sp->rx = netif_rx; ++	sp->rx = phydev->netif_rx;  +   	/* mask with MAC supported features */   	phydev->supported &= (SUPPORTED_10baseT_Half   		| SUPPORTED_10baseT_Full  Index: linux-2.6.23.16/drivers/net/ar2313/ar2313.h  =================================================================== ---- linux-2.6.23.16.orig/drivers/net/ar2313/ar2313.h	2008-04-20 10:26:15.000000000 +0200 -+++ linux-2.6.23.16/drivers/net/ar2313/ar2313.h	2008-04-20 10:26:16.000000000 +0200 +--- linux-2.6.23.16.orig/drivers/net/ar2313/ar2313.h	2008-04-29 14:51:39.000000000 +0200 ++++ linux-2.6.23.16/drivers/net/ar2313/ar2313.h	2008-04-29 14:52:15.000000000 +0200  @@ -107,6 +107,8 @@    */   struct ar2313_private { diff --git a/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.c b/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.c index cb0d377d2..f28df4398 100644 --- a/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.c +++ b/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.c @@ -30,6 +30,10 @@  #include <asm/uaccess.h>  #include "mvswitch.h" +/* Undefine this to use trailer mode instead. + * I don't know if header mode works with all chips */ +#define HEADER_MODE	1 +  MODULE_DESCRIPTION("Marvell 88E6060 Switch driver");  MODULE_AUTHOR("Felix Fietkau");  MODULE_LICENSE("GPL"); @@ -55,11 +59,11 @@ w16(struct phy_device *phydev, int addr, int reg, u16 val)  	phydev->bus->write(phydev->bus, addr, reg, val);  } +  static int  mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)  {  	struct mvswitch_priv *priv; -	struct vlan_ethhdr *eh;  	char *buf = NULL;  	u16 vid; @@ -70,30 +74,34 @@ mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)  	if (unlikely(skb->len < 16))  		goto error; -	eh = (struct vlan_ethhdr *) skb->data; -	if (be16_to_cpu(eh->h_vlan_proto) != 0x8100) +#ifdef HEADER_MODE +	if (__vlan_hwaccel_get_tag(skb, &vid)) +		goto error; + +	if ((skb->len <= 62) || (skb_headroom(skb) < MV_HEADER_SIZE)) { +		if (pskb_expand_head(skb, MV_HEADER_SIZE, 0, GFP_ATOMIC)) +			goto error_expand; +		if (skb->len < 62) +			skb->len = 62; +	} +	buf = skb_push(skb, MV_HEADER_SIZE); +#else +	if (__vlan_get_tag(skb, &vid))  		goto error; -	vid = be16_to_cpu(eh->h_vlan_TCI) & VLAN_VID_MASK;  	if (unlikely((vid > 15 || !priv->vlans[vid])))  		goto error;  	if (skb->len <= 64) { -		if (pskb_expand_head(skb, 0, 68 - skb->len, GFP_ATOMIC)) { -			if (net_ratelimit()) -				printk("%s: failed to expand/update skb for the switch\n", dev->name); -			goto error; -		} +		if (pskb_expand_head(skb, 0, 64 + MV_TRAILER_SIZE - skb->len, GFP_ATOMIC)) +			goto error_expand;  		buf = skb->data + 64; -		skb->len = 68; +		skb->len = 64 + MV_TRAILER_SIZE;  	} else {  		if (skb_cloned(skb) || unlikely(skb_tailroom(skb) < 4)) { -			if (pskb_expand_head(skb, 0, 4, GFP_ATOMIC)) { -				if (net_ratelimit()) -					printk("%s: failed to expand/update skb for the switch\n", dev->name); -				goto error; -			} +			if (pskb_expand_head(skb, 0, 4, GFP_ATOMIC)) +				goto error_expand;  		}  		buf = skb_put(skb, 4);  	} @@ -103,18 +111,32 @@ mvswitch_mangle_tx(struct sk_buff *skb, struct net_device *dev)  	skb->data += 4;  	skb->len -= 4;  	skb->mac_header += 4; +#endif  	if (!buf)  		goto error; -	/* append the tag */ -	*((u32 *) buf) = ( -		(0x80 << 24) | -		((priv->vlans[vid] & 0x1f) << 16) + +#ifdef HEADER_MODE +	/* prepend the tag */ +	*((__be16 *) buf) = cpu_to_be16( +		((vid << MV_HEADER_VLAN_S) & MV_HEADER_VLAN_M) | +		((priv->vlans[vid] << MV_HEADER_PORTS_S) & MV_HEADER_PORTS_M)  	); +#else +	/* append the tag */ +	*((__be32 *) buf) = cpu_to_be32(( +		(MV_TRAILER_OVERRIDE << MV_TRAILER_FLAGS_S) | +		((priv->vlans[vid] & MV_TRAILER_PORTS_M) << MV_TRAILER_PORTS_S) +	)); +#endif  	return priv->hardstart(skb, dev); +error_expand: +	if (net_ratelimit()) +		printk("%s: failed to expand/update skb for the switch\n", dev->name); +  error:  	/* any errors? drop the packet! */  	dev_kfree_skb_any(skb); @@ -141,9 +163,14 @@ mvswitch_mangle_rx(struct sk_buff *skb, int napi)  	if (!priv->grp)  		goto error; -	buf = skb->data + skb->len - 4; +#ifdef HEADER_MODE +	buf = skb->data; +	skb_pull(skb, MV_HEADER_SIZE); +#else +	buf = skb->data + skb->len - MV_TRAILER_SIZE;  	if (buf[0] != 0x80)  		goto error; +#endif  	/* look for the vlan matching the incoming port */  	for (i = 0; i < ARRAY_SIZE(priv->vlans); i++) { @@ -154,6 +181,8 @@ mvswitch_mangle_rx(struct sk_buff *skb, int napi)  	if (vlan == -1)  		goto error; +	skb->protocol = eth_type_trans(skb, skb->dev); +  	if (napi)  		return vlan_hwaccel_receive_skb(skb, priv->grp, vlan);  	else @@ -234,9 +263,13 @@ mvswitch_config_init(struct phy_device *pdev)  	/* initialize the cpu port */  	w16(pdev, MV_PORTREG(CONTROL, MV_CPUPORT), -		MV_PORTCTRL_ENABLED | +#ifdef HEADER_MODE +		MV_PORTCTRL_HEADER | +#else  		MV_PORTCTRL_RXTR | -		MV_PORTCTRL_TXTR +		MV_PORTCTRL_TXTR | +#endif +		MV_PORTCTRL_ENABLED  	);  	/* wait for the phy change to settle in */  	msleep(2); @@ -300,7 +333,11 @@ mvswitch_config_init(struct phy_device *pdev)  	pdev->netif_rx = mvswitch_netif_rx;  	dev->hard_start_xmit = mvswitch_mangle_tx;  	dev->vlan_rx_register = mvswitch_vlan_rx_register; +#ifdef HEADER_MODE +	dev->features |= NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX; +#else  	dev->features |= NETIF_F_HW_VLAN_RX; +#endif  	return 0;  } diff --git a/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.h b/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.h index b51e84a73..81516b708 100644 --- a/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.h +++ b/target/linux/generic-2.6/files/drivers/net/phy/mvswitch.h @@ -9,6 +9,19 @@  #ifndef __MVSWITCH_H  #define __MVSWITCH_H +#define MV_HEADER_SIZE	2 +#define MV_HEADER_PORTS_M	0x001f +#define MV_HEADER_PORTS_S	0 +#define MV_HEADER_VLAN_M	0xf000 +#define MV_HEADER_VLAN_S	12 + +#define MV_TRAILER_SIZE	4 +#define MV_TRAILER_PORTS_M	0x1f +#define MV_TRAILER_PORTS_S	16 +#define MV_TRAILER_FLAGS_S	24 +#define MV_TRAILER_OVERRIDE	0x80 + +  #define MV_PORTS	5  #define MV_WANPORT	4  #define MV_CPUPORT	5 @@ -36,7 +49,7 @@ enum {  	MV_PHY_INTR_EN      = 0x12,  	MV_PHY_INTR_STATUS  = 0x13,  	MV_PHY_INTR_PORT    = 0x14, -	MV_PHY_RECV_COUNTER = 0x15, +	MV_PHY_RECV_COUNTER = 0x16,  	MV_PHY_LED_PARALLEL = 0x16,  	MV_PHY_LED_STREAM   = 0x17,  	MV_PHY_LED_CTRL     = 0x18, @@ -64,6 +77,7 @@ enum {  	MV_PORTCTRL_ENABLED =  (3 << 0),  	MV_PORTCTRL_VLANTUN =  (1 << 7),	/* Enforce VLANs on packets */  	MV_PORTCTRL_RXTR    =  (1 << 8),	/* Enable Marvell packet trailer for ingress */ +	MV_PORTCTRL_HEADER	= (1 << 11),	/* Enable Marvell packet header mode for port */  	MV_PORTCTRL_TXTR    = (1 << 14),	/* Enable Marvell packet trailer for egress */  	MV_PORTCTRL_FORCEFL = (1 << 15),	/* force flow control */  }; @@ -89,6 +103,17 @@ enum {  #define MV_SWITCHREG(_type) MV_SWITCHREGS, MV_SWITCH_##_type  enum { +	MV_SWITCHCTL_EEIE   =  (1 << 0),	/* EEPROM interrupt enable */ +	MV_SWITCHCTL_PHYIE  =  (1 << 1),	/* PHY interrupt enable */ +	MV_SWITCHCTL_ATUDONE=  (1 << 2),	/* ATU done interrupt enable */ +	MV_SWITCHCTL_ATUIE  =  (1 << 3),	/* ATU interrupt enable */ +	MV_SWITCHCTL_CTRMODE=  (1 << 8),	/* statistics for rx and tx errors */ +	MV_SWITCHCTL_RELOAD =  (1 << 9),	/* reload registers from eeprom */ +	MV_SWITCHCTL_MSIZE  = (1 << 10),	/* increase maximum frame size */ +	MV_SWITCHCTL_DROP   = (1 << 13),	/* discard frames with excessive collisions */ +}; + +enum {  #define MV_ATUCTL_AGETIME(_n)	((((_n) / 16) & 0xff) << 4)  	MV_ATUCTL_ATU_256   = (0 << 12),  	MV_ATUCTL_ATU_512   = (1 << 12), diff --git a/target/linux/generic-2.6/patches-2.6.23/630-phy_packets.patch b/target/linux/generic-2.6/patches-2.6.23/630-phy_packets.patch index 5d7f97195..930139b55 100644 --- a/target/linux/generic-2.6/patches-2.6.23/630-phy_packets.patch +++ b/target/linux/generic-2.6/patches-2.6.23/630-phy_packets.patch @@ -1,20 +1,39 @@  Index: linux-2.6.23.16/drivers/net/phy/phy_device.c  =================================================================== ---- linux-2.6.23.16.orig/drivers/net/phy/phy_device.c	2008-02-11 07:06:32.000000000 +0100 -+++ linux-2.6.23.16/drivers/net/phy/phy_device.c	2008-04-20 05:42:28.000000000 +0200 -@@ -67,6 +67,8 @@ +--- linux-2.6.23.16.orig/drivers/net/phy/phy_device.c	2008-04-20 10:16:21.000000000 +0200 ++++ linux-2.6.23.16/drivers/net/phy/phy_device.c	2008-04-29 14:20:03.000000000 +0200 +@@ -44,6 +44,18 @@ + extern int mdio_bus_init(void); + extern void mdio_bus_exit(void); +  ++static int generic_receive_skb(struct sk_buff *skb) ++{ ++	skb->protocol = eth_type_trans(skb, skb->dev); ++	return netif_receive_skb(skb); ++} ++ ++static int generic_rx(struct sk_buff *skb) ++{ ++	skb->protocol = eth_type_trans(skb, skb->dev); ++	return netif_rx(skb); ++} ++ + struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) + { + 	struct phy_device *dev; +@@ -67,6 +79,8 @@   	dev->bus = bus;   	dev->state = PHY_DOWN; -+	dev->netif_receive_skb = &netif_receive_skb; -+	dev->netif_rx = &netif_rx; ++	dev->netif_receive_skb = &generic_receive_skb; ++	dev->netif_rx = &generic_rx;   	spin_lock_init(&dev->lock);  Index: linux-2.6.23.16/include/linux/phy.h  =================================================================== ---- linux-2.6.23.16.orig/include/linux/phy.h	2008-04-20 04:40:31.000000000 +0200 -+++ linux-2.6.23.16/include/linux/phy.h	2008-04-20 05:53:21.000000000 +0200 +--- linux-2.6.23.16.orig/include/linux/phy.h	2008-04-20 10:16:21.000000000 +0200 ++++ linux-2.6.23.16/include/linux/phy.h	2008-04-20 10:17:58.000000000 +0200  @@ -289,6 +289,17 @@   	void (*adjust_link)(struct net_device *dev); @@ -35,8 +54,8 @@ Index: linux-2.6.23.16/include/linux/phy.h  Index: linux-2.6.23.16/include/linux/netdevice.h  =================================================================== ---- linux-2.6.23.16.orig/include/linux/netdevice.h	2008-02-11 07:06:32.000000000 +0100 -+++ linux-2.6.23.16/include/linux/netdevice.h	2008-04-20 06:33:25.000000000 +0200 +--- linux-2.6.23.16.orig/include/linux/netdevice.h	2008-04-20 10:16:21.000000000 +0200 ++++ linux-2.6.23.16/include/linux/netdevice.h	2008-04-20 10:17:58.000000000 +0200  @@ -426,6 +426,7 @@   	void			*ax25_ptr;	/* AX.25 specific data */   	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data, | 
