Bläddra i källkod

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (235 commits)
  [NETFILTER]: Add H.323 conntrack/NAT helper
  [TG3]: Don't mark tg3_test_registers() as returning const.
  [IPV6]: Cleanups for net/ipv6/addrconf.c (kzalloc, early exit) v2
  [IPV6]: Nearly complete kzalloc cleanup for net/ipv6
  [IPV6]: Cleanup of net/ipv6/reassambly.c
  [BRIDGE]: Remove duplicate const from is_link_local() argument type.
  [DECNET]: net/decnet/dn_route.c: fix inconsequent NULL checking
  [TG3]: make drivers/net/tg3.c:tg3_request_irq() static
  [BRIDGE]: use LLC to send STP
  [LLC]: llc_mac_hdr_init const arguments
  [BRIDGE]: allow show/store of group multicast address
  [BRIDGE]: use llc for receiving STP packets
  [BRIDGE]: stp timer to jiffies cleanup
  [BRIDGE]: forwarding remove unneeded preempt and bh diasables
  [BRIDGE]: netfilter inline cleanup
  [BRIDGE]: netfilter VLAN macro cleanup
  [BRIDGE]: netfilter dont use __constant_htons
  [BRIDGE]: netfilter whitespace
  [BRIDGE]: optimize frame pass up
  [BRIDGE]: use kzalloc
  ...
Linus Torvalds 19 år sedan
förälder
incheckning
3d1f337b3e
100 ändrade filer med 2622 tillägg och 1219 borttagningar
  1. 3 2
      Documentation/connector/connector.txt
  2. 47 2
      Documentation/networking/ip-sysctl.txt
  3. 1 1
      drivers/atm/suni.c
  4. 4 3
      drivers/connector/connector.c
  5. 1 15
      drivers/infiniband/ulp/ipoib/ipoib_main.c
  6. 1 1
      drivers/net/8139too.c
  7. 173 304
      drivers/net/bnx2.c
  8. 23 14
      drivers/net/bnx2.h
  9. 20 20
      drivers/net/cassini.c
  10. 1 1
      drivers/net/cassini.h
  11. 1 1
      drivers/net/e1000/e1000_main.c
  12. 8 0
      drivers/net/irda/Kconfig
  13. 1 0
      drivers/net/irda/Makefile
  14. 1 1
      drivers/net/irda/donauboe.c
  15. 7 4
      drivers/net/irda/ep7211_ir.c
  16. 10 9
      drivers/net/irda/irtty-sir.c
  17. 251 69
      drivers/net/irda/nsc-ircc.c
  18. 1 1
      drivers/net/irda/nsc-ircc.h
  19. 10 9
      drivers/net/irda/sir_dongle.c
  20. 375 0
      drivers/net/irda/toim3232-sir.c
  21. 1 1
      drivers/net/irda/vlsi_ir.c
  22. 2 2
      drivers/net/ppp_generic.c
  23. 1 2
      drivers/net/pppoe.c
  24. 19 18
      drivers/net/sungem.c
  25. 3 3
      drivers/net/sungem.h
  26. 512 89
      drivers/net/tg3.c
  27. 17 2
      drivers/net/tg3.h
  28. 1 2
      drivers/net/wan/sbni.c
  29. 1 1
      include/asm-sparc/socket.h
  30. 82 50
      include/linux/dccp.h
  31. 22 22
      include/linux/dn.h
  32. 9 2
      include/linux/icmpv6.h
  33. 23 3
      include/linux/if.h
  34. 1 0
      include/linux/in.h
  35. 1 0
      include/linux/inetdevice.h
  36. 14 0
      include/linux/ipv6.h
  37. 10 0
      include/linux/ipv6_route.h
  38. 1 0
      include/linux/irda.h
  39. 24 0
      include/linux/list.h
  40. 4 0
      include/linux/net.h
  41. 37 4
      include/linux/netdevice.h
  42. 9 0
      include/linux/netfilter.h
  43. 1 0
      include/linux/netfilter/nfnetlink.h
  44. 6 0
      include/linux/netfilter/nfnetlink_log.h
  45. 31 6
      include/linux/netfilter/x_tables.h
  46. 58 0
      include/linux/netfilter/xt_policy.h
  47. 0 27
      include/linux/netfilter_bridge.h
  48. 2 0
      include/linux/netfilter_ipv4/ip_conntrack.h
  49. 30 0
      include/linux/netfilter_ipv4/ip_conntrack_h323.h
  50. 1 1
      include/linux/netfilter_ipv4/ip_nat.h
  51. 16 53
      include/linux/netfilter_ipv4/ipt_policy.h
  52. 16 53
      include/linux/netfilter_ipv6/ip6t_policy.h
  53. 1 0
      include/linux/netlink.h
  54. 6 0
      include/linux/pci_ids.h
  55. 10 13
      include/linux/rtnetlink.h
  56. 19 6
      include/linux/security.h
  57. 19 28
      include/linux/skbuff.h
  58. 1 0
      include/linux/socket.h
  59. 1 1
      include/linux/sunrpc/svcsock.h
  60. 27 0
      include/linux/sysctl.h
  61. 6 0
      include/linux/tcp.h
  62. 30 0
      include/linux/xfrm.h
  63. 2 1
      include/net/af_unix.h
  64. 52 53
      include/net/dn.h
  65. 44 44
      include/net/dn_dev.h
  66. 11 11
      include/net/dn_fib.h
  67. 2 2
      include/net/dn_neigh.h
  68. 36 36
      include/net/dn_nsp.h
  69. 6 6
      include/net/dn_route.h
  70. 4 4
      include/net/flow.h
  71. 0 3
      include/net/if_inet6.h
  72. 26 0
      include/net/inet_connection_sock.h
  73. 4 0
      include/net/ip.h
  74. 22 2
      include/net/ip6_route.h
  75. 22 0
      include/net/ipv6.h
  76. 1 1
      include/net/llc.h
  77. 2 0
      include/net/ndisc.h
  78. 1 1
      include/net/neighbour.h
  79. 34 22
      include/net/netfilter/nf_conntrack.h
  80. 6 4
      include/net/scm.h
  81. 10 0
      include/net/sctp/structs.h
  82. 12 0
      include/net/sock.h
  83. 16 0
      include/net/tcp.h
  84. 58 4
      include/net/xfrm.h
  85. 1 3
      net/802/psnap.c
  86. 27 16
      net/8021q/vlan.c
  87. 2 4
      net/8021q/vlan_dev.c
  88. 1 1
      net/atm/clip.c
  89. 2 2
      net/atm/common.c
  90. 8 7
      net/atm/ioctl.c
  91. 17 15
      net/atm/resources.c
  92. 2 1
      net/atm/resources.h
  93. 5 3
      net/bluetooth/rfcomm/core.c
  94. 1 0
      net/bridge/Kconfig
  95. 12 0
      net/bridge/br.c
  96. 1 2
      net/bridge/br_device.c
  97. 2 4
      net/bridge/br_fdb.c
  98. 4 5
      net/bridge/br_if.c
  99. 26 17
      net/bridge/br_input.c
  100. 126 99
      net/bridge/br_netfilter.c

+ 3 - 2
Documentation/connector/connector.txt

@@ -69,10 +69,11 @@ Unregisters new callback with connector core.
 
 struct cb_id *id 		- unique connector's user identifier.
 
-void cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);
+int cn_netlink_send(struct cn_msg *msg, u32 __groups, int gfp_mask);
 
 Sends message to the specified groups.  It can be safely called from
-any context, but may silently fail under strong memory pressure.
+softirq context, but may silently fail under strong memory pressure.
+If there are no listeners for given group -ESRCH can be returned.
 
 struct cn_msg *			- message header(with attached data).
 u32 __group			- destination group.

+ 47 - 2
Documentation/networking/ip-sysctl.txt

@@ -355,6 +355,13 @@ somaxconn - INTEGER
 	Defaults to 128.  See also tcp_max_syn_backlog for additional tuning
 	for TCP sockets.
 
+tcp_workaround_signed_windows - BOOLEAN
+	If set, assume no receipt of a window scaling option means the
+	remote TCP is broken and treats the window as a signed quantity.
+	If unset, assume the remote TCP is not broken even if we do
+	not receive a window scaling option from them.
+	Default: 0
+
 IP Variables:
 
 ip_local_port_range - 2 INTEGERS
@@ -619,6 +626,11 @@ arp_ignore - INTEGER
 	The max value from conf/{all,interface}/arp_ignore is used
 	when ARP request is received on the {interface}
 
+arp_accept - BOOLEAN
+	Define behavior when gratuitous arp replies are received:
+	0 - drop gratuitous arp frames
+	1 - accept gratuitous arp frames
+
 app_solicit - INTEGER
 	The maximum number of probes to send to the user space ARP daemon
 	via netlink before dropping back to multicast probes (see
@@ -717,6 +729,33 @@ accept_ra - BOOLEAN
 	Functional default: enabled if local forwarding is disabled.
 			    disabled if local forwarding is enabled.
 
+accept_ra_defrtr - BOOLEAN
+	Learn default router in Router Advertisement.
+
+	Functional default: enabled if accept_ra is enabled.
+			    disabled if accept_ra is disabled.
+
+accept_ra_pinfo - BOOLEAN
+	Learn Prefix Inforamtion in Router Advertisement.
+
+	Functional default: enabled if accept_ra is enabled.
+			    disabled if accept_ra is disabled.
+
+accept_ra_rt_info_max_plen - INTEGER
+	Maximum prefix length of Route Information in RA.
+
+	Route Information w/ prefix larger than or equal to this
+	variable shall be ignored.
+
+	Functional default: 0 if accept_ra_rtr_pref is enabled.
+			    -1 if accept_ra_rtr_pref is disabled.
+
+accept_ra_rtr_pref - BOOLEAN
+	Accept Router Preference in RA.
+
+	Functional default: enabled if accept_ra is enabled.
+			    disabled if accept_ra is disabled.
+
 accept_redirects - BOOLEAN
 	Accept Redirects.
 
@@ -727,8 +766,8 @@ autoconf - BOOLEAN
 	Autoconfigure addresses using Prefix Information in Router 
 	Advertisements.
 
-	Functional default: enabled if accept_ra is enabled.
-			    disabled if accept_ra is disabled.
+	Functional default: enabled if accept_ra_pinfo is enabled.
+			    disabled if accept_ra_pinfo is disabled.
 
 dad_transmits - INTEGER
 	The amount of Duplicate Address Detection probes to send.
@@ -771,6 +810,12 @@ mtu - INTEGER
 	Default Maximum Transfer Unit
 	Default: 1280 (IPv6 required minimum)
 
+router_probe_interval - INTEGER
+	Minimum interval (in seconds) between Router Probing described
+	in RFC4191.
+
+	Default: 60
+
 router_solicitation_delay - INTEGER
 	Number of seconds to wait after interface is brought up
 	before sending Router Solicitations.

+ 1 - 1
drivers/atm/suni.c

@@ -188,7 +188,7 @@ static int suni_ioctl(struct atm_dev *dev,unsigned int cmd,void __user *arg)
 		case SONET_GETDIAG:
 			return get_diag(dev,arg);
 		case SONET_SETFRAMING:
-			if (arg != SONET_FRAME_SONET) return -EINVAL;
+			if ((int)(unsigned long)arg != SONET_FRAME_SONET) return -EINVAL;
 			return 0;
 		case SONET_GETFRAMING:
 			return put_user(SONET_FRAME_SONET,(int __user *)arg) ?

+ 4 - 3
drivers/connector/connector.c

@@ -97,6 +97,9 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
 		group = __group;
 	}
 
+	if (!netlink_has_listeners(dev->nls, group))
+		return -ESRCH;
+
 	size = NLMSG_SPACE(sizeof(*msg) + msg->len);
 
 	skb = alloc_skb(size, gfp_mask);
@@ -111,9 +114,7 @@ int cn_netlink_send(struct cn_msg *msg, u32 __group, gfp_t gfp_mask)
 
 	NETLINK_CB(skb).dst_group = group;
 
-	netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);
-
-	return 0;
+	return netlink_broadcast(dev->nls, skb, 0, group, gfp_mask);
 
 nlmsg_failure:
 	kfree_skb(skb);

+ 1 - 15
drivers/infiniband/ulp/ipoib/ipoib_main.c

@@ -253,7 +253,6 @@ static void path_free(struct net_device *dev, struct ipoib_path *path)
 		if (neigh->ah)
 			ipoib_put_ah(neigh->ah);
 		*to_ipoib_neigh(neigh->neighbour) = NULL;
-		neigh->neighbour->ops->destructor = NULL;
 		kfree(neigh);
 	}
 
@@ -531,7 +530,6 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 err:
 	*to_ipoib_neigh(skb->dst->neighbour) = NULL;
 	list_del(&neigh->list);
-	neigh->neighbour->ops->destructor = NULL;
 	kfree(neigh);
 
 	++priv->stats.tx_dropped;
@@ -770,21 +768,9 @@ static void ipoib_neigh_destructor(struct neighbour *n)
 		ipoib_put_ah(ah);
 }
 
-static int ipoib_neigh_setup(struct neighbour *neigh)
-{
-	/*
-	 * Is this kosher?  I can't find anybody in the kernel that
-	 * sets neigh->destructor, so we should be able to set it here
-	 * without trouble.
-	 */
-	neigh->ops->destructor = ipoib_neigh_destructor;
-
-	return 0;
-}
-
 static int ipoib_neigh_setup_dev(struct net_device *dev, struct neigh_parms *parms)
 {
-	parms->neigh_setup = ipoib_neigh_setup;
+	parms->neigh_destructor = ipoib_neigh_destructor;
 
 	return 0;
 }

+ 1 - 1
drivers/net/8139too.c

@@ -1605,7 +1605,7 @@ static void rtl8139_thread (void *_data)
 	if (tp->watchdog_fired) {
 		tp->watchdog_fired = 0;
 		rtl8139_tx_timeout_task(_data);
-	} else if (rtnl_shlock_nowait() == 0) {
+	} else if (rtnl_trylock()) {
 		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
 		rtnl_unlock ();
 	} else {

+ 173 - 304
drivers/net/bnx2.c

@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.4.31"
-#define DRV_MODULE_RELDATE	"January 19, 2006"
+#define DRV_MODULE_VERSION	"1.4.38"
+#define DRV_MODULE_RELDATE	"February 10, 2006"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -360,6 +360,8 @@ bnx2_netif_start(struct bnx2 *bp)
 static void
 bnx2_free_mem(struct bnx2 *bp)
 {
+	int i;
+
 	if (bp->stats_blk) {
 		pci_free_consistent(bp->pdev, sizeof(struct statistics_block),
 				    bp->stats_blk, bp->stats_blk_mapping);
@@ -378,19 +380,23 @@ bnx2_free_mem(struct bnx2 *bp)
 	}
 	kfree(bp->tx_buf_ring);
 	bp->tx_buf_ring = NULL;
-	if (bp->rx_desc_ring) {
-		pci_free_consistent(bp->pdev,
-				    sizeof(struct rx_bd) * RX_DESC_CNT,
-				    bp->rx_desc_ring, bp->rx_desc_mapping);
-		bp->rx_desc_ring = NULL;
-	}
-	kfree(bp->rx_buf_ring);
+	for (i = 0; i < bp->rx_max_ring; i++) {
+		if (bp->rx_desc_ring[i])
+			pci_free_consistent(bp->pdev,
+					    sizeof(struct rx_bd) * RX_DESC_CNT,
+					    bp->rx_desc_ring[i],
+					    bp->rx_desc_mapping[i]);
+		bp->rx_desc_ring[i] = NULL;
+	}
+	vfree(bp->rx_buf_ring);
 	bp->rx_buf_ring = NULL;
 }
 
 static int
 bnx2_alloc_mem(struct bnx2 *bp)
 {
+	int i;
+
 	bp->tx_buf_ring = kmalloc(sizeof(struct sw_bd) * TX_DESC_CNT,
 				     GFP_KERNEL);
 	if (bp->tx_buf_ring == NULL)
@@ -404,18 +410,23 @@ bnx2_alloc_mem(struct bnx2 *bp)
 	if (bp->tx_desc_ring == NULL)
 		goto alloc_mem_err;
 
-	bp->rx_buf_ring = kmalloc(sizeof(struct sw_bd) * RX_DESC_CNT,
-				     GFP_KERNEL);
+	bp->rx_buf_ring = vmalloc(sizeof(struct sw_bd) * RX_DESC_CNT *
+				  bp->rx_max_ring);
 	if (bp->rx_buf_ring == NULL)
 		goto alloc_mem_err;
 
-	memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT);
-	bp->rx_desc_ring = pci_alloc_consistent(bp->pdev,
-					        sizeof(struct rx_bd) *
-						RX_DESC_CNT,
-						&bp->rx_desc_mapping);
-	if (bp->rx_desc_ring == NULL)
-		goto alloc_mem_err;
+	memset(bp->rx_buf_ring, 0, sizeof(struct sw_bd) * RX_DESC_CNT *
+				   bp->rx_max_ring);
+
+	for (i = 0; i < bp->rx_max_ring; i++) {
+		bp->rx_desc_ring[i] =
+			pci_alloc_consistent(bp->pdev,
+					     sizeof(struct rx_bd) * RX_DESC_CNT,
+					     &bp->rx_desc_mapping[i]);
+		if (bp->rx_desc_ring[i] == NULL)
+			goto alloc_mem_err;
+
+	}
 
 	bp->status_blk = pci_alloc_consistent(bp->pdev,
 					      sizeof(struct status_block),
@@ -1520,7 +1531,7 @@ bnx2_alloc_rx_skb(struct bnx2 *bp, u16 index)
 	struct sk_buff *skb;
 	struct sw_bd *rx_buf = &bp->rx_buf_ring[index];
 	dma_addr_t mapping;
-	struct rx_bd *rxbd = &bp->rx_desc_ring[index];
+	struct rx_bd *rxbd = &bp->rx_desc_ring[RX_RING(index)][RX_IDX(index)];
 	unsigned long align;
 
 	skb = dev_alloc_skb(bp->rx_buf_size);
@@ -1656,23 +1667,30 @@ static inline void
 bnx2_reuse_rx_skb(struct bnx2 *bp, struct sk_buff *skb,
 	u16 cons, u16 prod)
 {
-	struct sw_bd *cons_rx_buf = &bp->rx_buf_ring[cons];
-	struct sw_bd *prod_rx_buf = &bp->rx_buf_ring[prod];
-	struct rx_bd *cons_bd = &bp->rx_desc_ring[cons];
-	struct rx_bd *prod_bd = &bp->rx_desc_ring[prod];
+	struct sw_bd *cons_rx_buf, *prod_rx_buf;
+	struct rx_bd *cons_bd, *prod_bd;
+
+	cons_rx_buf = &bp->rx_buf_ring[cons];
+	prod_rx_buf = &bp->rx_buf_ring[prod];
 
 	pci_dma_sync_single_for_device(bp->pdev,
 		pci_unmap_addr(cons_rx_buf, mapping),
 		bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 
-	prod_rx_buf->skb = cons_rx_buf->skb;
-	pci_unmap_addr_set(prod_rx_buf, mapping,
-			pci_unmap_addr(cons_rx_buf, mapping));
+	bp->rx_prod_bseq += bp->rx_buf_use_size;
 
-	memcpy(prod_bd, cons_bd, 8);
+	prod_rx_buf->skb = skb;
 
-	bp->rx_prod_bseq += bp->rx_buf_use_size;
+	if (cons == prod)
+		return;
 
+	pci_unmap_addr_set(prod_rx_buf, mapping,
+			pci_unmap_addr(cons_rx_buf, mapping));
+
+	cons_bd = &bp->rx_desc_ring[RX_RING(cons)][RX_IDX(cons)];
+	prod_bd = &bp->rx_desc_ring[RX_RING(prod)][RX_IDX(prod)];
+	prod_bd->rx_bd_haddr_hi = cons_bd->rx_bd_haddr_hi;
+	prod_bd->rx_bd_haddr_lo = cons_bd->rx_bd_haddr_lo;
 }
 
 static int
@@ -1699,14 +1717,19 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
 		u32 status;
 		struct sw_bd *rx_buf;
 		struct sk_buff *skb;
+		dma_addr_t dma_addr;
 
 		sw_ring_cons = RX_RING_IDX(sw_cons);
 		sw_ring_prod = RX_RING_IDX(sw_prod);
 
 		rx_buf = &bp->rx_buf_ring[sw_ring_cons];
 		skb = rx_buf->skb;
-		pci_dma_sync_single_for_cpu(bp->pdev,
-			pci_unmap_addr(rx_buf, mapping),
+
+		rx_buf->skb = NULL;
+
+		dma_addr = pci_unmap_addr(rx_buf, mapping);
+
+		pci_dma_sync_single_for_cpu(bp->pdev, dma_addr,
 			bp->rx_offset + RX_COPY_THRESH, PCI_DMA_FROMDEVICE);
 
 		rx_hdr = (struct l2_fhdr *) skb->data;
@@ -1747,8 +1770,7 @@ bnx2_rx_int(struct bnx2 *bp, int budget)
 			skb = new_skb;
 		}
 		else if (bnx2_alloc_rx_skb(bp, sw_ring_prod) == 0) {
-			pci_unmap_single(bp->pdev,
-				pci_unmap_addr(rx_buf, mapping),
+			pci_unmap_single(bp->pdev, dma_addr,
 				bp->rx_buf_use_size, PCI_DMA_FROMDEVICE);
 
 			skb_reserve(skb, bp->rx_offset);
@@ -1794,8 +1816,6 @@ reuse_rx:
 		rx_pkt++;
 
 next_rx:
-		rx_buf->skb = NULL;
-
 		sw_cons = NEXT_RX_BD(sw_cons);
 		sw_prod = NEXT_RX_BD(sw_prod);
 
@@ -3340,27 +3360,35 @@ bnx2_init_rx_ring(struct bnx2 *bp)
 	bp->hw_rx_cons = 0;
 	bp->rx_prod_bseq = 0;
 		
-	rxbd = &bp->rx_desc_ring[0];
-	for (i = 0; i < MAX_RX_DESC_CNT; i++, rxbd++) {
-		rxbd->rx_bd_len = bp->rx_buf_use_size;
-		rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
-	}
+	for (i = 0; i < bp->rx_max_ring; i++) {
+		int j;
 
-	rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping >> 32;
-	rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping & 0xffffffff;
+		rxbd = &bp->rx_desc_ring[i][0];
+		for (j = 0; j < MAX_RX_DESC_CNT; j++, rxbd++) {
+			rxbd->rx_bd_len = bp->rx_buf_use_size;
+			rxbd->rx_bd_flags = RX_BD_FLAGS_START | RX_BD_FLAGS_END;
+		}
+		if (i == (bp->rx_max_ring - 1))
+			j = 0;
+		else
+			j = i + 1;
+		rxbd->rx_bd_haddr_hi = (u64) bp->rx_desc_mapping[j] >> 32;
+		rxbd->rx_bd_haddr_lo = (u64) bp->rx_desc_mapping[j] &
+				       0xffffffff;
+	}
 
 	val = BNX2_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
 	val |= BNX2_L2CTX_CTX_TYPE_SIZE_L2;
 	val |= 0x02 << 8;
 	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_CTX_TYPE, val);
 
-	val = (u64) bp->rx_desc_mapping >> 32;
+	val = (u64) bp->rx_desc_mapping[0] >> 32;
 	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_HI, val);
 
-	val = (u64) bp->rx_desc_mapping & 0xffffffff;
+	val = (u64) bp->rx_desc_mapping[0] & 0xffffffff;
 	CTX_WR(bp, GET_CID_ADDR(RX_CID), BNX2_L2CTX_NX_BDHADDR_LO, val);
 
-	for ( ;ring_prod < bp->rx_ring_size; ) {
+	for (i = 0; i < bp->rx_ring_size; i++) {
 		if (bnx2_alloc_rx_skb(bp, ring_prod) < 0) {
 			break;
 		}
@@ -3374,6 +3402,29 @@ bnx2_init_rx_ring(struct bnx2 *bp)
 	REG_WR(bp, MB_RX_CID_ADDR + BNX2_L2CTX_HOST_BSEQ, bp->rx_prod_bseq);
 }
 
+static void
+bnx2_set_rx_ring_size(struct bnx2 *bp, u32 size)
+{
+	u32 num_rings, max;
+
+	bp->rx_ring_size = size;
+	num_rings = 1;
+	while (size > MAX_RX_DESC_CNT) {
+		size -= MAX_RX_DESC_CNT;
+		num_rings++;
+	}
+	/* round to next power of 2 */
+	max = MAX_RX_RINGS;
+	while ((max & num_rings) == 0)
+		max >>= 1;
+
+	if (num_rings != max)
+		max <<= 1;
+
+	bp->rx_max_ring = max;
+	bp->rx_max_ring_idx = (bp->rx_max_ring * RX_DESC_CNT) - 1;
+}
+
 static void
 bnx2_free_tx_skbs(struct bnx2 *bp)
 {
@@ -3419,7 +3470,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
 	if (bp->rx_buf_ring == NULL)
 		return;
 
-	for (i = 0; i < RX_DESC_CNT; i++) {
+	for (i = 0; i < bp->rx_max_ring_idx; i++) {
 		struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
 		struct sk_buff *skb = rx_buf->skb;
 
@@ -3506,74 +3557,9 @@ bnx2_test_registers(struct bnx2 *bp)
 		{ 0x0c00, 0, 0x00000000, 0x00000001 },
 		{ 0x0c04, 0, 0x00000000, 0x03ff0001 },
 		{ 0x0c08, 0, 0x0f0ff073, 0x00000000 },
-		{ 0x0c0c, 0, 0x00ffffff, 0x00000000 },
-		{ 0x0c30, 0, 0x00000000, 0xffffffff },
-		{ 0x0c34, 0, 0x00000000, 0xffffffff },
-		{ 0x0c38, 0, 0x00000000, 0xffffffff },
-		{ 0x0c3c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c40, 0, 0x00000000, 0xffffffff },
-		{ 0x0c44, 0, 0x00000000, 0xffffffff },
-		{ 0x0c48, 0, 0x00000000, 0x0007ffff },
-		{ 0x0c4c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c50, 0, 0x00000000, 0xffffffff },
-		{ 0x0c54, 0, 0x00000000, 0xffffffff },
-		{ 0x0c58, 0, 0x00000000, 0xffffffff },
-		{ 0x0c5c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c60, 0, 0x00000000, 0xffffffff },
-		{ 0x0c64, 0, 0x00000000, 0xffffffff },
-		{ 0x0c68, 0, 0x00000000, 0xffffffff },
-		{ 0x0c6c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c70, 0, 0x00000000, 0xffffffff },
-		{ 0x0c74, 0, 0x00000000, 0xffffffff },
-		{ 0x0c78, 0, 0x00000000, 0xffffffff },
-		{ 0x0c7c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c80, 0, 0x00000000, 0xffffffff },
-		{ 0x0c84, 0, 0x00000000, 0xffffffff },
-		{ 0x0c88, 0, 0x00000000, 0xffffffff },
-		{ 0x0c8c, 0, 0x00000000, 0xffffffff },
-		{ 0x0c90, 0, 0x00000000, 0xffffffff },
-		{ 0x0c94, 0, 0x00000000, 0xffffffff },
-		{ 0x0c98, 0, 0x00000000, 0xffffffff },
-		{ 0x0c9c, 0, 0x00000000, 0xffffffff },
-		{ 0x0ca0, 0, 0x00000000, 0xffffffff },
-		{ 0x0ca4, 0, 0x00000000, 0xffffffff },
-		{ 0x0ca8, 0, 0x00000000, 0x0007ffff },
-		{ 0x0cac, 0, 0x00000000, 0xffffffff },
-		{ 0x0cb0, 0, 0x00000000, 0xffffffff },
-		{ 0x0cb4, 0, 0x00000000, 0xffffffff },
-		{ 0x0cb8, 0, 0x00000000, 0xffffffff },
-		{ 0x0cbc, 0, 0x00000000, 0xffffffff },
-		{ 0x0cc0, 0, 0x00000000, 0xffffffff },
-		{ 0x0cc4, 0, 0x00000000, 0xffffffff },
-		{ 0x0cc8, 0, 0x00000000, 0xffffffff },
-		{ 0x0ccc, 0, 0x00000000, 0xffffffff },
-		{ 0x0cd0, 0, 0x00000000, 0xffffffff },
-		{ 0x0cd4, 0, 0x00000000, 0xffffffff },
-		{ 0x0cd8, 0, 0x00000000, 0xffffffff },
-		{ 0x0cdc, 0, 0x00000000, 0xffffffff },
-		{ 0x0ce0, 0, 0x00000000, 0xffffffff },
-		{ 0x0ce4, 0, 0x00000000, 0xffffffff },
-		{ 0x0ce8, 0, 0x00000000, 0xffffffff },
-		{ 0x0cec, 0, 0x00000000, 0xffffffff },
-		{ 0x0cf0, 0, 0x00000000, 0xffffffff },
-		{ 0x0cf4, 0, 0x00000000, 0xffffffff },
-		{ 0x0cf8, 0, 0x00000000, 0xffffffff },
-		{ 0x0cfc, 0, 0x00000000, 0xffffffff },
-		{ 0x0d00, 0, 0x00000000, 0xffffffff },
-		{ 0x0d04, 0, 0x00000000, 0xffffffff },
 
 		{ 0x1000, 0, 0x00000000, 0x00000001 },
 		{ 0x1004, 0, 0x00000000, 0x000f0001 },
-		{ 0x1044, 0, 0x00000000, 0xffc003ff },
-		{ 0x1080, 0, 0x00000000, 0x0001ffff },
-		{ 0x1084, 0, 0x00000000, 0xffffffff },
-		{ 0x1088, 0, 0x00000000, 0xffffffff },
-		{ 0x108c, 0, 0x00000000, 0xffffffff },
-		{ 0x1090, 0, 0x00000000, 0xffffffff },
-		{ 0x1094, 0, 0x00000000, 0xffffffff },
-		{ 0x1098, 0, 0x00000000, 0xffffffff },
-		{ 0x109c, 0, 0x00000000, 0xffffffff },
-		{ 0x10a0, 0, 0x00000000, 0xffffffff },
 
 		{ 0x1408, 0, 0x01c00800, 0x00000000 },
 		{ 0x149c, 0, 0x8000ffff, 0x00000000 },
@@ -3585,111 +3571,9 @@ bnx2_test_registers(struct bnx2 *bp)
 		{ 0x14c4, 0, 0x00003fff, 0x00000000 },
 		{ 0x14cc, 0, 0x00000000, 0x00000001 },
 		{ 0x14d0, 0, 0xffffffff, 0x00000000 },
-		{ 0x1500, 0, 0x00000000, 0xffffffff },
-		{ 0x1504, 0, 0x00000000, 0xffffffff },
-		{ 0x1508, 0, 0x00000000, 0xffffffff },
-		{ 0x150c, 0, 0x00000000, 0xffffffff },
-		{ 0x1510, 0, 0x00000000, 0xffffffff },
-		{ 0x1514, 0, 0x00000000, 0xffffffff },
-		{ 0x1518, 0, 0x00000000, 0xffffffff },
-		{ 0x151c, 0, 0x00000000, 0xffffffff },
-		{ 0x1520, 0, 0x00000000, 0xffffffff },
-		{ 0x1524, 0, 0x00000000, 0xffffffff },
-		{ 0x1528, 0, 0x00000000, 0xffffffff },
-		{ 0x152c, 0, 0x00000000, 0xffffffff },
-		{ 0x1530, 0, 0x00000000, 0xffffffff },
-		{ 0x1534, 0, 0x00000000, 0xffffffff },
-		{ 0x1538, 0, 0x00000000, 0xffffffff },
-		{ 0x153c, 0, 0x00000000, 0xffffffff },
-		{ 0x1540, 0, 0x00000000, 0xffffffff },
-		{ 0x1544, 0, 0x00000000, 0xffffffff },
-		{ 0x1548, 0, 0x00000000, 0xffffffff },
-		{ 0x154c, 0, 0x00000000, 0xffffffff },
-		{ 0x1550, 0, 0x00000000, 0xffffffff },
-		{ 0x1554, 0, 0x00000000, 0xffffffff },
-		{ 0x1558, 0, 0x00000000, 0xffffffff },
-		{ 0x1600, 0, 0x00000000, 0xffffffff },
-		{ 0x1604, 0, 0x00000000, 0xffffffff },
-		{ 0x1608, 0, 0x00000000, 0xffffffff },
-		{ 0x160c, 0, 0x00000000, 0xffffffff },
-		{ 0x1610, 0, 0x00000000, 0xffffffff },
-		{ 0x1614, 0, 0x00000000, 0xffffffff },
-		{ 0x1618, 0, 0x00000000, 0xffffffff },
-		{ 0x161c, 0, 0x00000000, 0xffffffff },
-		{ 0x1620, 0, 0x00000000, 0xffffffff },
-		{ 0x1624, 0, 0x00000000, 0xffffffff },
-		{ 0x1628, 0, 0x00000000, 0xffffffff },
-		{ 0x162c, 0, 0x00000000, 0xffffffff },
-		{ 0x1630, 0, 0x00000000, 0xffffffff },
-		{ 0x1634, 0, 0x00000000, 0xffffffff },
-		{ 0x1638, 0, 0x00000000, 0xffffffff },
-		{ 0x163c, 0, 0x00000000, 0xffffffff },
-		{ 0x1640, 0, 0x00000000, 0xffffffff },
-		{ 0x1644, 0, 0x00000000, 0xffffffff },
-		{ 0x1648, 0, 0x00000000, 0xffffffff },
-		{ 0x164c, 0, 0x00000000, 0xffffffff },
-		{ 0x1650, 0, 0x00000000, 0xffffffff },
-		{ 0x1654, 0, 0x00000000, 0xffffffff },
 
 		{ 0x1800, 0, 0x00000000, 0x00000001 },
 		{ 0x1804, 0, 0x00000000, 0x00000003 },
-		{ 0x1840, 0, 0x00000000, 0xffffffff },
-		{ 0x1844, 0, 0x00000000, 0xffffffff },
-		{ 0x1848, 0, 0x00000000, 0xffffffff },
-		{ 0x184c, 0, 0x00000000, 0xffffffff },
-		{ 0x1850, 0, 0x00000000, 0xffffffff },
-		{ 0x1900, 0, 0x7ffbffff, 0x00000000 },
-		{ 0x1904, 0, 0xffffffff, 0x00000000 },
-		{ 0x190c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1914, 0, 0xffffffff, 0x00000000 },
-		{ 0x191c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1924, 0, 0xffffffff, 0x00000000 },
-		{ 0x192c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1934, 0, 0xffffffff, 0x00000000 },
-		{ 0x193c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1944, 0, 0xffffffff, 0x00000000 },
-		{ 0x194c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1954, 0, 0xffffffff, 0x00000000 },
-		{ 0x195c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1964, 0, 0xffffffff, 0x00000000 },
-		{ 0x196c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1974, 0, 0xffffffff, 0x00000000 },
-		{ 0x197c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1980, 0, 0x0700ffff, 0x00000000 },
-
-		{ 0x1c00, 0, 0x00000000, 0x00000001 },
-		{ 0x1c04, 0, 0x00000000, 0x00000003 },
-		{ 0x1c08, 0, 0x0000000f, 0x00000000 },
-		{ 0x1c40, 0, 0x00000000, 0xffffffff },
-		{ 0x1c44, 0, 0x00000000, 0xffffffff },
-		{ 0x1c48, 0, 0x00000000, 0xffffffff },
-		{ 0x1c4c, 0, 0x00000000, 0xffffffff },
-		{ 0x1c50, 0, 0x00000000, 0xffffffff },
-		{ 0x1d00, 0, 0x7ffbffff, 0x00000000 },
-		{ 0x1d04, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d0c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d14, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d1c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d24, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d2c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d34, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d3c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d44, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d4c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d54, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d5c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d64, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d6c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d74, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d7c, 0, 0xffffffff, 0x00000000 },
-		{ 0x1d80, 0, 0x0700ffff, 0x00000000 },
-
-		{ 0x2004, 0, 0x00000000, 0x0337000f },
-		{ 0x2008, 0, 0xffffffff, 0x00000000 },
-		{ 0x200c, 0, 0xffffffff, 0x00000000 },
-		{ 0x2010, 0, 0xffffffff, 0x00000000 },
-		{ 0x2014, 0, 0x801fff80, 0x00000000 },
-		{ 0x2018, 0, 0x000003ff, 0x00000000 },
 
 		{ 0x2800, 0, 0x00000000, 0x00000001 },
 		{ 0x2804, 0, 0x00000000, 0x00003f01 },
@@ -3707,16 +3591,6 @@ bnx2_test_registers(struct bnx2 *bp)
 		{ 0x2c00, 0, 0x00000000, 0x00000011 },
 		{ 0x2c04, 0, 0x00000000, 0x00030007 },
 
-		{ 0x3000, 0, 0x00000000, 0x00000001 },
-		{ 0x3004, 0, 0x00000000, 0x007007ff },
-		{ 0x3008, 0, 0x00000003, 0x00000000 },
-		{ 0x300c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3010, 0, 0xffffffff, 0x00000000 },
-		{ 0x3014, 0, 0xffffffff, 0x00000000 },
-		{ 0x3034, 0, 0xffffffff, 0x00000000 },
-		{ 0x3038, 0, 0xffffffff, 0x00000000 },
-		{ 0x3050, 0, 0x00000001, 0x00000000 },
-
 		{ 0x3c00, 0, 0x00000000, 0x00000001 },
 		{ 0x3c04, 0, 0x00000000, 0x00070000 },
 		{ 0x3c08, 0, 0x00007f71, 0x07f00000 },
@@ -3726,88 +3600,11 @@ bnx2_test_registers(struct bnx2 *bp)
 		{ 0x3c18, 0, 0x00000000, 0xffffffff },
 		{ 0x3c1c, 0, 0xfffff000, 0x00000000 },
 		{ 0x3c20, 0, 0xffffff00, 0x00000000 },
-		{ 0x3c24, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c28, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c2c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c30, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c34, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c38, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c3c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c40, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c44, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c48, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c4c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c50, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c54, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c58, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c5c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c60, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c64, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c68, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c6c, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c70, 0, 0xffffffff, 0x00000000 },
-		{ 0x3c74, 0, 0x0000003f, 0x00000000 },
-		{ 0x3c78, 0, 0x00000000, 0x00000000 },
-		{ 0x3c7c, 0, 0x00000000, 0x00000000 },
-		{ 0x3c80, 0, 0x3fffffff, 0x00000000 },
-		{ 0x3c84, 0, 0x0000003f, 0x00000000 },
-		{ 0x3c88, 0, 0x00000000, 0xffffffff },
-		{ 0x3c8c, 0, 0x00000000, 0xffffffff },
-
-		{ 0x4000, 0, 0x00000000, 0x00000001 },
-		{ 0x4004, 0, 0x00000000, 0x00030000 },
-		{ 0x4008, 0, 0x00000ff0, 0x00000000 },
-		{ 0x400c, 0, 0xffffffff, 0x00000000 },
-		{ 0x4088, 0, 0x00000000, 0x00070303 },
-
-		{ 0x4400, 0, 0x00000000, 0x00000001 },
-		{ 0x4404, 0, 0x00000000, 0x00003f01 },
-		{ 0x4408, 0, 0x7fff00ff, 0x00000000 },
-		{ 0x440c, 0, 0xffffffff, 0x00000000 },
-		{ 0x4410, 0, 0xffff,     0x0000 },
-		{ 0x4414, 0, 0xffff,     0x0000 },
-		{ 0x4418, 0, 0xffff,     0x0000 },
-		{ 0x441c, 0, 0xffff,     0x0000 },
-		{ 0x4428, 0, 0xffffffff, 0x00000000 },
-		{ 0x442c, 0, 0xffffffff, 0x00000000 },
-		{ 0x4430, 0, 0xffffffff, 0x00000000 },
-		{ 0x4434, 0, 0xffffffff, 0x00000000 },
-		{ 0x4438, 0, 0xffffffff, 0x00000000 },
-		{ 0x443c, 0, 0xffffffff, 0x00000000 },
-		{ 0x4440, 0, 0xffffffff, 0x00000000 },
-		{ 0x4444, 0, 0xffffffff, 0x00000000 },
-
-		{ 0x4c00, 0, 0x00000000, 0x00000001 },
-		{ 0x4c04, 0, 0x00000000, 0x0000003f },
-		{ 0x4c08, 0, 0xffffffff, 0x00000000 },
-		{ 0x4c0c, 0, 0x0007fc00, 0x00000000 },
-		{ 0x4c10, 0, 0x80003fe0, 0x00000000 },
-		{ 0x4c14, 0, 0xffffffff, 0x00000000 },
-		{ 0x4c44, 0, 0x00000000, 0x9fff9fff },
-		{ 0x4c48, 0, 0x00000000, 0xb3009fff },
-		{ 0x4c4c, 0, 0x00000000, 0x77f33b30 },
-		{ 0x4c50, 0, 0x00000000, 0xffffffff },
 
 		{ 0x5004, 0, 0x00000000, 0x0000007f },
 		{ 0x5008, 0, 0x0f0007ff, 0x00000000 },
 		{ 0x500c, 0, 0xf800f800, 0x07ff07ff },
 
-		{ 0x5400, 0, 0x00000008, 0x00000001 },
-		{ 0x5404, 0, 0x00000000, 0x0000003f },
-		{ 0x5408, 0, 0x0000001f, 0x00000000 },
-		{ 0x540c, 0, 0xffffffff, 0x00000000 },
-		{ 0x5410, 0, 0xffffffff, 0x00000000 },
-		{ 0x5414, 0, 0x0000ffff, 0x00000000 },
-		{ 0x5418, 0, 0x0000ffff, 0x00000000 },
-		{ 0x541c, 0, 0x0000ffff, 0x00000000 },
-		{ 0x5420, 0, 0x0000ffff, 0x00000000 },
-		{ 0x5428, 0, 0x000000ff, 0x00000000 },
-		{ 0x542c, 0, 0xff00ffff, 0x00000000 },
-		{ 0x5430, 0, 0x001fff80, 0x00000000 },
-		{ 0x5438, 0, 0xffffffff, 0x00000000 },
-		{ 0x543c, 0, 0xffffffff, 0x00000000 },
-		{ 0x5440, 0, 0xf800f800, 0x07ff07ff },
-
 		{ 0x5c00, 0, 0x00000000, 0x00000001 },
 		{ 0x5c04, 0, 0x00000000, 0x0003000f },
 		{ 0x5c08, 0, 0x00000003, 0x00000000 },
@@ -4794,6 +4591,64 @@ bnx2_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 	info->fw_version[5] = 0;
 }
 
+#define BNX2_REGDUMP_LEN		(32 * 1024)
+
+static int
+bnx2_get_regs_len(struct net_device *dev)
+{
+	return BNX2_REGDUMP_LEN;
+}
+
+static void
+bnx2_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *_p)
+{
+	u32 *p = _p, i, offset;
+	u8 *orig_p = _p;
+	struct bnx2 *bp = netdev_priv(dev);
+	u32 reg_boundaries[] = { 0x0000, 0x0098, 0x0400, 0x045c,
+				 0x0800, 0x0880, 0x0c00, 0x0c10,
+				 0x0c30, 0x0d08, 0x1000, 0x101c,
+				 0x1040, 0x1048, 0x1080, 0x10a4,
+				 0x1400, 0x1490, 0x1498, 0x14f0,
+				 0x1500, 0x155c, 0x1580, 0x15dc,
+				 0x1600, 0x1658, 0x1680, 0x16d8,
+				 0x1800, 0x1820, 0x1840, 0x1854,
+				 0x1880, 0x1894, 0x1900, 0x1984,
+				 0x1c00, 0x1c0c, 0x1c40, 0x1c54,
+				 0x1c80, 0x1c94, 0x1d00, 0x1d84,
+				 0x2000, 0x2030, 0x23c0, 0x2400,
+				 0x2800, 0x2820, 0x2830, 0x2850,
+				 0x2b40, 0x2c10, 0x2fc0, 0x3058,
+				 0x3c00, 0x3c94, 0x4000, 0x4010,
+				 0x4080, 0x4090, 0x43c0, 0x4458,
+				 0x4c00, 0x4c18, 0x4c40, 0x4c54,
+				 0x4fc0, 0x5010, 0x53c0, 0x5444,
+				 0x5c00, 0x5c18, 0x5c80, 0x5c90,
+				 0x5fc0, 0x6000, 0x6400, 0x6428,
+				 0x6800, 0x6848, 0x684c, 0x6860,
+				 0x6888, 0x6910, 0x8000 };
+
+	regs->version = 0;
+
+	memset(p, 0, BNX2_REGDUMP_LEN);
+
+	if (!netif_running(bp->dev))
+		return;
+
+	i = 0;
+	offset = reg_boundaries[0];
+	p += offset;
+	while (offset < BNX2_REGDUMP_LEN) {
+		*p++ = REG_RD(bp, offset);
+		offset += 4;
+		if (offset == reg_boundaries[i + 1]) {
+			offset = reg_boundaries[i + 2];
+			p = (u32 *) (orig_p + offset);
+			i += 2;
+		}
+	}
+}
+
 static void
 bnx2_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
@@ -4979,7 +4834,7 @@ bnx2_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
-	ering->rx_max_pending = MAX_RX_DESC_CNT;
+	ering->rx_max_pending = MAX_TOTAL_RX_DESC_CNT;
 	ering->rx_mini_max_pending = 0;
 	ering->rx_jumbo_max_pending = 0;
 
@@ -4996,17 +4851,28 @@ bnx2_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
-	if ((ering->rx_pending > MAX_RX_DESC_CNT) ||
+	if ((ering->rx_pending > MAX_TOTAL_RX_DESC_CNT) ||
 		(ering->tx_pending > MAX_TX_DESC_CNT) ||
 		(ering->tx_pending <= MAX_SKB_FRAGS)) {
 
 		return -EINVAL;
 	}
-	bp->rx_ring_size = ering->rx_pending;
+	if (netif_running(bp->dev)) {
+		bnx2_netif_stop(bp);
+		bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+		bnx2_free_skbs(bp);
+		bnx2_free_mem(bp);
+	}
+
+	bnx2_set_rx_ring_size(bp, ering->rx_pending);
 	bp->tx_ring_size = ering->tx_pending;
 
 	if (netif_running(bp->dev)) {
-		bnx2_netif_stop(bp);
+		int rc;
+
+		rc = bnx2_alloc_mem(bp);
+		if (rc)
+			return rc;
 		bnx2_init_nic(bp);
 		bnx2_netif_start(bp);
 	}
@@ -5360,6 +5226,8 @@ static struct ethtool_ops bnx2_ethtool_ops = {
 	.get_settings		= bnx2_get_settings,
 	.set_settings		= bnx2_set_settings,
 	.get_drvinfo		= bnx2_get_drvinfo,
+	.get_regs_len		= bnx2_get_regs_len,
+	.get_regs		= bnx2_get_regs,
 	.get_wol		= bnx2_get_wol,
 	.set_wol		= bnx2_set_wol,
 	.nway_reset		= bnx2_nway_reset,
@@ -5678,7 +5546,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
 	bp->mac_addr[5] = (u8) reg;
 
 	bp->tx_ring_size = MAX_TX_DESC_CNT;
-	bp->rx_ring_size = 100;
+	bnx2_set_rx_ring_size(bp, 100);
 
 	bp->rx_csum = 1;
 
@@ -5897,6 +5765,7 @@ bnx2_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (!netif_running(dev))
 		return 0;
 
+	flush_scheduled_work();
 	bnx2_netif_stop(bp);
 	netif_device_detach(dev);
 	del_timer_sync(&bp->timer);

+ 23 - 14
drivers/net/bnx2.h

@@ -23,6 +23,7 @@
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/init.h>
@@ -3792,8 +3793,10 @@ struct l2_fhdr {
 #define TX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct tx_bd))
 #define MAX_TX_DESC_CNT (TX_DESC_CNT - 1)
 
+#define MAX_RX_RINGS	4
 #define RX_DESC_CNT  (BCM_PAGE_SIZE / sizeof(struct rx_bd))
 #define MAX_RX_DESC_CNT (RX_DESC_CNT - 1)
+#define MAX_TOTAL_RX_DESC_CNT (MAX_RX_DESC_CNT * MAX_RX_RINGS)
 
 #define NEXT_TX_BD(x) (((x) & (MAX_TX_DESC_CNT - 1)) ==			\
 		(MAX_TX_DESC_CNT - 1)) ?				\
@@ -3805,8 +3808,10 @@ struct l2_fhdr {
 		(MAX_RX_DESC_CNT - 1)) ?				\
 	(x) + 2 : (x) + 1
 
-#define RX_RING_IDX(x) ((x) & MAX_RX_DESC_CNT)
+#define RX_RING_IDX(x) ((x) & bp->rx_max_ring_idx)
 
+#define RX_RING(x) (((x) & ~MAX_RX_DESC_CNT) >> 8)
+#define RX_IDX(x) ((x) & MAX_RX_DESC_CNT)
 
 /* Context size. */
 #define CTX_SHIFT                   7
@@ -3903,6 +3908,15 @@ struct bnx2 {
 	struct status_block	*status_blk;
 	u32 			last_status_idx;
 
+	u32			flags;
+#define PCIX_FLAG			1
+#define PCI_32BIT_FLAG			2
+#define ONE_TDMA_FLAG			4	/* no longer used */
+#define NO_WOL_FLAG			8
+#define USING_DAC_FLAG			0x10
+#define USING_MSI_FLAG			0x20
+#define ASF_ENABLE_FLAG			0x40
+
 	struct tx_bd		*tx_desc_ring;
 	struct sw_bd		*tx_buf_ring;
 	u32			tx_prod_bseq;
@@ -3920,19 +3934,22 @@ struct bnx2 {
 	u32			rx_offset;
 	u32			rx_buf_use_size;	/* useable size */
 	u32			rx_buf_size;		/* with alignment */
-	struct rx_bd		*rx_desc_ring;
-	struct sw_bd		*rx_buf_ring;
+	u32			rx_max_ring_idx;
+
 	u32			rx_prod_bseq;
 	u16			rx_prod;
 	u16			rx_cons;
 
 	u32			rx_csum;
 
+	struct sw_bd		*rx_buf_ring;
+	struct rx_bd		*rx_desc_ring[MAX_RX_RINGS];
+
 	/* Only used to synchronize netif_stop_queue/wake_queue when tx */
 	/* ring is full */
 	spinlock_t		tx_lock;
 
-	/* End of fileds used in the performance code paths. */
+	/* End of fields used in the performance code paths. */
 
 	char			*name;
 
@@ -3945,15 +3962,6 @@ struct bnx2 {
 	/* Used to synchronize phy accesses. */
 	spinlock_t		phy_lock;
 
-	u32			flags;
-#define PCIX_FLAG			1
-#define PCI_32BIT_FLAG			2
-#define ONE_TDMA_FLAG			4	/* no longer used */
-#define NO_WOL_FLAG			8
-#define USING_DAC_FLAG			0x10
-#define USING_MSI_FLAG			0x20
-#define ASF_ENABLE_FLAG			0x40
-
 	u32			phy_flags;
 #define PHY_SERDES_FLAG			1
 #define PHY_CRC_FIX_FLAG		2
@@ -4004,8 +4012,9 @@ struct bnx2 {
 	dma_addr_t		tx_desc_mapping;
 
 
+	int			rx_max_ring;
 	int			rx_ring_size;
-	dma_addr_t		rx_desc_mapping;
+	dma_addr_t		rx_desc_mapping[MAX_RX_RINGS];
 
 	u16			tx_quick_cons_trip;
 	u16			tx_quick_cons_trip_int;

+ 20 - 20
drivers/net/cassini.c

@@ -91,6 +91,7 @@
 #include <linux/mii.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
+#include <linux/mutex.h>
 
 #include <net/checksum.h>
 
@@ -3892,7 +3893,7 @@ static void cas_reset(struct cas *cp, int blkflag)
 	spin_unlock(&cp->stat_lock[N_TX_RINGS]);
 }
 
-/* Shut down the chip, must be called with pm_sem held.  */
+/* Shut down the chip, must be called with pm_mutex held.  */
 static void cas_shutdown(struct cas *cp)
 {
 	unsigned long flags;
@@ -4311,11 +4312,11 @@ static int cas_open(struct net_device *dev)
 	int hw_was_up, err;
 	unsigned long flags;
 
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 
 	hw_was_up = cp->hw_running;
 
-	/* The power-management semaphore protects the hw_running
+	/* The power-management mutex protects the hw_running
 	 * etc. state so it is safe to do this bit without cp->lock
 	 */
 	if (!cp->hw_running) {
@@ -4364,7 +4365,7 @@ static int cas_open(struct net_device *dev)
 	cas_unlock_all_restore(cp, flags);
 
 	netif_start_queue(dev);
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 	return 0;
 
 err_spare:
@@ -4372,7 +4373,7 @@ err_spare:
 	cas_free_rxds(cp);
 err_tx_tiny:
 	cas_tx_tiny_free(cp);
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 	return err;
 }
 
@@ -4382,7 +4383,7 @@ static int cas_close(struct net_device *dev)
 	struct cas *cp = netdev_priv(dev);
 
 	/* Make sure we don't get distracted by suspend/resume */
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 
 	netif_stop_queue(dev);
 
@@ -4399,7 +4400,7 @@ static int cas_close(struct net_device *dev)
 	cas_spare_free(cp);
 	cas_free_rxds(cp);
 	cas_tx_tiny_free(cp);
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 	return 0;
 }
 
@@ -4834,10 +4835,10 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	unsigned long flags;
 	int rc = -EOPNOTSUPP;
 	
-	/* Hold the PM semaphore while doing ioctl's or we may collide
+	/* Hold the PM mutex while doing ioctl's or we may collide
 	 * with open/close and power management and oops.
 	 */
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 	switch (cmd) {
 	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
 		data->phy_id = cp->phy_addr;
@@ -4867,7 +4868,7 @@ static int cas_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 		break;
 	};
 
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 	return rc;
 }
 
@@ -4994,7 +4995,7 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
 		spin_lock_init(&cp->tx_lock[i]);
 	}
 	spin_lock_init(&cp->stat_lock[N_TX_RINGS]);
-	init_MUTEX(&cp->pm_sem);
+	mutex_init(&cp->pm_mutex);
 
 	init_timer(&cp->link_timer);
 	cp->link_timer.function = cas_link_timer;
@@ -5116,10 +5117,10 @@ err_out_free_consistent:
 			    cp->init_block, cp->block_dvma);
 
 err_out_iounmap:
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 	if (cp->hw_running)
 		cas_shutdown(cp);
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 
 	iounmap(cp->regs);
 
@@ -5152,11 +5153,11 @@ static void __devexit cas_remove_one(struct pci_dev *pdev)
 	cp = netdev_priv(dev);
 	unregister_netdev(dev);
 
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 	flush_scheduled_work();
 	if (cp->hw_running)
 		cas_shutdown(cp);
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 
 #if 1
 	if (cp->orig_cacheline_size) {
@@ -5183,10 +5184,7 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct cas *cp = netdev_priv(dev);
 	unsigned long flags;
 
-	/* We hold the PM semaphore during entire driver
-	 * sleep time
-	 */
-	down(&cp->pm_sem);
+	mutex_lock(&cp->pm_mutex);
 	
 	/* If the driver is opened, we stop the DMA */
 	if (cp->opened) {
@@ -5206,6 +5204,7 @@ static int cas_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	if (cp->hw_running)
 		cas_shutdown(cp);
+	mutex_unlock(&cp->pm_mutex);
 
 	return 0;
 }
@@ -5217,6 +5216,7 @@ static int cas_resume(struct pci_dev *pdev)
 
 	printk(KERN_INFO "%s: resuming\n", dev->name);
 
+	mutex_lock(&cp->pm_mutex);
 	cas_hard_reset(cp);
 	if (cp->opened) {
 		unsigned long flags;
@@ -5229,7 +5229,7 @@ static int cas_resume(struct pci_dev *pdev)
 
 		netif_device_attach(dev);
 	}
-	up(&cp->pm_sem);
+	mutex_unlock(&cp->pm_mutex);
 	return 0;
 }
 #endif /* CONFIG_PM */

+ 1 - 1
drivers/net/cassini.h

@@ -4284,7 +4284,7 @@ struct cas {
 	 * (ie. not power managed) */
 	int hw_running;
 	int opened;
-	struct semaphore pm_sem; /* open/close/suspend/resume */
+	struct mutex pm_mutex; /* open/close/suspend/resume */
 
 	struct cas_init_block *init_block;
 	struct cas_tx_desc *init_txds[MAX_TX_RINGS];

+ 1 - 1
drivers/net/e1000/e1000_main.c

@@ -920,7 +920,7 @@ e1000_remove(struct pci_dev *pdev)
 	unregister_netdev(netdev);
 #ifdef CONFIG_E1000_NAPI
 	for (i = 0; i < adapter->num_rx_queues; i++)
-		__dev_put(&adapter->polling_netdev[i]);
+		dev_put(&adapter->polling_netdev[i]);
 #endif
 
 	if (!e1000_check_phy_reset_block(&adapter->hw))

+ 8 - 0
drivers/net/irda/Kconfig

@@ -64,6 +64,14 @@ config TEKRAM_DONGLE
 	  dongles you will have to start irattach like this:
 	  "irattach -d tekram".
 
+config TOIM3232_DONGLE
+	tristate "TOIM3232 IrDa dongle"
+	depends on DONGLE && IRDA
+	help
+	  Say Y here if you want to build support for the Vishay/Temic
+	  TOIM3232 and TOIM4232 based dongles.
+	  To compile it as a module, choose M here.
+
 config LITELINK_DONGLE
 	tristate "Parallax LiteLink dongle"
 	depends on DONGLE && IRDA

+ 1 - 0
drivers/net/irda/Makefile

@@ -43,6 +43,7 @@ obj-$(CONFIG_OLD_BELKIN_DONGLE)	+= old_belkin-sir.o
 obj-$(CONFIG_MCP2120_DONGLE)	+= mcp2120-sir.o
 obj-$(CONFIG_ACT200L_DONGLE)	+= act200l-sir.o
 obj-$(CONFIG_MA600_DONGLE)	+= ma600-sir.o
+obj-$(CONFIG_TOIM3232_DONGLE)	+= toim3232-sir.o
 
 # The SIR helper module
 sir-dev-objs := sir_dev.o sir_dongle.o sir_kthread.o

+ 1 - 1
drivers/net/irda/donauboe.c

@@ -1778,7 +1778,7 @@ static struct pci_driver donauboe_pci_driver = {
 static int __init
 donauboe_init (void)
 {
-  return pci_module_init(&donauboe_pci_driver);
+  return pci_register_driver(&donauboe_pci_driver);
 }
 
 static void __exit

+ 7 - 4
drivers/net/irda/ep7211_ir.c

@@ -8,6 +8,7 @@
 #include <linux/delay.h>
 #include <linux/tty.h>
 #include <linux/init.h>
+#include <linux/spinlock.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>
@@ -23,6 +24,8 @@ static void ep7211_ir_close(dongle_t *self);
 static int  ep7211_ir_change_speed(struct irda_task *task);
 static int  ep7211_ir_reset(struct irda_task *task);
 
+static DEFINE_SPINLOCK(ep7211_lock);
+
 static struct dongle_reg dongle = {
 	.type = IRDA_EP7211_IR,
 	.open = ep7211_ir_open,
@@ -36,7 +39,7 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
 {
 	unsigned int syscon1, flags;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&ep7211_lock, flags);
 
 	/* Turn on the SIR encoder. */
 	syscon1 = clps_readl(SYSCON1);
@@ -46,14 +49,14 @@ static void ep7211_ir_open(dongle_t *self, struct qos_info *qos)
 	/* XXX: We should disable modem status interrupts on the first
 		UART (interrupt #14). */
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&ep7211_lock, flags);
 }
 
 static void ep7211_ir_close(dongle_t *self)
 {
 	unsigned int syscon1, flags;
 
-	save_flags(flags); cli();
+	spin_lock_irqsave(&ep7211_lock, flags);
 
 	/* Turn off the SIR encoder. */
 	syscon1 = clps_readl(SYSCON1);
@@ -63,7 +66,7 @@ static void ep7211_ir_close(dongle_t *self)
 	/* XXX: If we've disabled the modem status interrupts, we should
 		reset them back to their original state. */
 
-	restore_flags(flags);
+	spin_unlock_irqrestore(&ep7211_lock, flags);
 }
 
 /*

+ 10 - 9
drivers/net/irda/irtty-sir.c

@@ -33,6 +33,7 @@
 #include <asm/uaccess.h>
 #include <linux/smp_lock.h>
 #include <linux/delay.h>
+#include <linux/mutex.h>
 
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>
@@ -338,7 +339,7 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
 /*****************************************************************/
 
 /* serialize ldisc open/close with sir_dev */
-static DECLARE_MUTEX(irtty_sem);
+static DEFINE_MUTEX(irtty_mutex);
 
 /* notifier from sir_dev when irda% device gets opened (ifup) */
 
@@ -348,11 +349,11 @@ static int irtty_start_dev(struct sir_dev *dev)
 	struct tty_struct *tty;
 
 	/* serialize with ldisc open/close */
-	down(&irtty_sem);
+	mutex_lock(&irtty_mutex);
 
 	priv = dev->priv;
 	if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) {
-		up(&irtty_sem);
+		mutex_unlock(&irtty_mutex);
 		return -ESTALE;
 	}
 
@@ -363,7 +364,7 @@ static int irtty_start_dev(struct sir_dev *dev)
 	/* Make sure we can receive more data */
 	irtty_stop_receiver(tty, FALSE);
 
-	up(&irtty_sem);
+	mutex_unlock(&irtty_mutex);
 	return 0;
 }
 
@@ -375,11 +376,11 @@ static int irtty_stop_dev(struct sir_dev *dev)
 	struct tty_struct *tty;
 
 	/* serialize with ldisc open/close */
-	down(&irtty_sem);
+	mutex_lock(&irtty_mutex);
 
 	priv = dev->priv;
 	if (unlikely(!priv || priv->magic!=IRTTY_MAGIC)) {
-		up(&irtty_sem);
+		mutex_unlock(&irtty_mutex);
 		return -ESTALE;
 	}
 
@@ -390,7 +391,7 @@ static int irtty_stop_dev(struct sir_dev *dev)
 	if (tty->driver->stop)
 		tty->driver->stop(tty);
 
-	up(&irtty_sem);
+	mutex_unlock(&irtty_mutex);
 
 	return 0;
 }
@@ -514,13 +515,13 @@ static int irtty_open(struct tty_struct *tty)
 	priv->dev = dev;
 
 	/* serialize with start_dev - in case we were racing with ifup */
-	down(&irtty_sem);
+	mutex_lock(&irtty_mutex);
 
 	dev->priv = priv;
 	tty->disc_data = priv;
 	tty->receive_room = 65536;
 
-	up(&irtty_sem);
+	mutex_unlock(&irtty_mutex);
 
 	IRDA_DEBUG(0, "%s - %s: irda line discipline opened\n", __FUNCTION__, tty->name);
 

+ 251 - 69
drivers/net/irda/nsc-ircc.c

@@ -12,6 +12,7 @@
  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1998 Lichen Wang, <lwang@actisys.com>
  *     Copyright (c) 1998 Actisys Corp., www.actisys.com
+ *     Copyright (c) 2000-2004 Jean Tourrilhes <jt@hpl.hp.com>
  *     All Rights Reserved
  *      
  *     This program is free software; you can redistribute it and/or 
@@ -53,14 +54,13 @@
 #include <linux/init.h>
 #include <linux/rtnetlink.h>
 #include <linux/dma-mapping.h>
+#include <linux/pnp.h>
+#include <linux/platform_device.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
 
-#include <linux/pm.h>
-#include <linux/pm_legacy.h>
-
 #include <net/irda/wrapper.h>
 #include <net/irda/irda.h>
 #include <net/irda/irda_device.h>
@@ -72,14 +72,27 @@
 
 static char *driver_name = "nsc-ircc";
 
+/* Power Management */
+#define NSC_IRCC_DRIVER_NAME                  "nsc-ircc"
+static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state);
+static int nsc_ircc_resume(struct platform_device *dev);
+
+static struct platform_driver nsc_ircc_driver = {
+	.suspend	= nsc_ircc_suspend,
+	.resume		= nsc_ircc_resume,
+	.driver		= {
+		.name	= NSC_IRCC_DRIVER_NAME,
+	},
+};
+
 /* Module parameters */
 static int qos_mtt_bits = 0x07;  /* 1 ms or more */
 static int dongle_id;
 
 /* Use BIOS settions by default, but user may supply module parameters */
-static unsigned int io[]  = { ~0, ~0, ~0, ~0 };
-static unsigned int irq[] = { 0, 0, 0, 0, 0 };
-static unsigned int dma[] = { 0, 0, 0, 0, 0 };
+static unsigned int io[]  = { ~0, ~0, ~0, ~0, ~0 };
+static unsigned int irq[] = {  0,  0,  0,  0,  0 };
+static unsigned int dma[] = {  0,  0,  0,  0,  0 };
 
 static int nsc_ircc_probe_108(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_probe_338(nsc_chip_t *chip, chipio_t *info);
@@ -87,6 +100,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info);
 static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info);
+static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id);
 
 /* These are the known NSC chips */
 static nsc_chip_t chips[] = {
@@ -101,11 +115,12 @@ static nsc_chip_t chips[] = {
 	/* Contributed by Jan Frey - IBM A30/A31 */
 	{ "PC8739x", { 0x2e, 0x4e, 0x0 }, 0x20, 0xea, 0xff, 
 	  nsc_ircc_probe_39x, nsc_ircc_init_39x },
+	{ "IBM", { 0x2e, 0x4e, 0x0 }, 0x20, 0xf4, 0xff,
+ 	  nsc_ircc_probe_39x, nsc_ircc_init_39x },
 	{ NULL }
 };
 
-/* Max 4 instances for now */
-static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
+static struct nsc_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL, NULL };
 
 static char *dongle_types[] = {
 	"Differential serial interface",
@@ -126,8 +141,24 @@ static char *dongle_types[] = {
 	"No dongle connected",
 };
 
+/* PNP probing */
+static chipio_t pnp_info;
+static const struct pnp_device_id nsc_ircc_pnp_table[] = {
+	{ .id = "NSC6001", .driver_data = 0 },
+	{ .id = "IBM0071", .driver_data = 0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table);
+
+static struct pnp_driver nsc_ircc_pnp_driver = {
+	.name = "nsc-ircc",
+	.id_table = nsc_ircc_pnp_table,
+	.probe = nsc_ircc_pnp_probe,
+};
+
 /* Some prototypes */
-static int  nsc_ircc_open(int i, chipio_t *info);
+static int  nsc_ircc_open(chipio_t *info);
 static int  nsc_ircc_close(struct nsc_ircc_cb *self);
 static int  nsc_ircc_setup(chipio_t *info);
 static void nsc_ircc_pio_receive(struct nsc_ircc_cb *self);
@@ -146,7 +177,10 @@ static int  nsc_ircc_net_open(struct net_device *dev);
 static int  nsc_ircc_net_close(struct net_device *dev);
 static int  nsc_ircc_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev);
-static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data);
+
+/* Globals */
+static int pnp_registered;
+static int pnp_succeeded;
 
 /*
  * Function nsc_ircc_init ()
@@ -158,28 +192,36 @@ static int __init nsc_ircc_init(void)
 {
 	chipio_t info;
 	nsc_chip_t *chip;
-	int ret = -ENODEV;
+	int ret;
 	int cfg_base;
 	int cfg, id;
 	int reg;
 	int i = 0;
 
+	ret = platform_driver_register(&nsc_ircc_driver);
+        if (ret) {
+                IRDA_ERROR("%s, Can't register driver!\n", driver_name);
+                return ret;
+        }
+
+ 	/* Register with PnP subsystem to detect disable ports */
+	ret = pnp_register_driver(&nsc_ircc_pnp_driver);
+
+ 	if (ret >= 0)
+ 		pnp_registered = 1;
+
+	ret = -ENODEV;
+
 	/* Probe for all the NSC chipsets we know about */
-	for (chip=chips; chip->name ; chip++) {
+	for (chip = chips; chip->name ; chip++) {
 		IRDA_DEBUG(2, "%s(), Probing for %s ...\n", __FUNCTION__,
 			   chip->name);
 		
 		/* Try all config registers for this chip */
-		for (cfg=0; cfg<3; cfg++) {
+		for (cfg = 0; cfg < ARRAY_SIZE(chip->cfg); cfg++) {
 			cfg_base = chip->cfg[cfg];
 			if (!cfg_base)
 				continue;
-			
-			memset(&info, 0, sizeof(chipio_t));
-			info.cfg_base = cfg_base;
-			info.fir_base = io[i];
-			info.dma = dma[i];
-			info.irq = irq[i];
 
 			/* Read index register */
 			reg = inb(cfg_base);
@@ -194,24 +236,65 @@ static int __init nsc_ircc_init(void)
 			if ((id & chip->cid_mask) == chip->cid_value) {
 				IRDA_DEBUG(2, "%s() Found %s chip, revision=%d\n",
 					   __FUNCTION__, chip->name, id & ~chip->cid_mask);
-				/* 
-				 * If the user supplies the base address, then
-				 * we init the chip, if not we probe the values
-				 * set by the BIOS
-				 */				
-				if (io[i] < 0x2000) {
-					chip->init(chip, &info);
-				} else
-					chip->probe(chip, &info);
 
-				if (nsc_ircc_open(i, &info) == 0)
-					ret = 0;
+				/*
+				 * If we found a correct PnP setting,
+				 * we first try it.
+				 */
+				if (pnp_succeeded) {
+					memset(&info, 0, sizeof(chipio_t));
+					info.cfg_base = cfg_base;
+					info.fir_base = pnp_info.fir_base;
+					info.dma = pnp_info.dma;
+					info.irq = pnp_info.irq;
+
+					if (info.fir_base < 0x2000) {
+						IRDA_MESSAGE("%s, chip->init\n", driver_name);
+						chip->init(chip, &info);
+					} else
+						chip->probe(chip, &info);
+
+					if (nsc_ircc_open(&info) >= 0)
+						ret = 0;
+				}
+
+				/*
+				 * Opening based on PnP values failed.
+				 * Let's fallback to user values, or probe
+				 * the chip.
+				 */
+				if (ret) {
+					IRDA_DEBUG(2, "%s, PnP init failed\n", driver_name);
+					memset(&info, 0, sizeof(chipio_t));
+					info.cfg_base = cfg_base;
+					info.fir_base = io[i];
+					info.dma = dma[i];
+					info.irq = irq[i];
+
+					/*
+					 * If the user supplies the base address, then
+					 * we init the chip, if not we probe the values
+					 * set by the BIOS
+					 */
+					if (io[i] < 0x2000) {
+						chip->init(chip, &info);
+					} else
+						chip->probe(chip, &info);
+
+					if (nsc_ircc_open(&info) >= 0)
+						ret = 0;
+				}
 				i++;
 			} else {
 				IRDA_DEBUG(2, "%s(), Wrong chip id=0x%02x\n", __FUNCTION__, id);
 			}
 		} 
-		
+	}
+
+	if (ret) {
+		platform_driver_unregister(&nsc_ircc_driver);
+		pnp_unregister_driver(&nsc_ircc_pnp_driver);
+		pnp_registered = 0;
 	}
 
 	return ret;
@@ -227,12 +310,17 @@ static void __exit nsc_ircc_cleanup(void)
 {
 	int i;
 
-	pm_unregister_all(nsc_ircc_pmproc);
-
-	for (i=0; i < 4; i++) {
+	for (i = 0; i < ARRAY_SIZE(dev_self); i++) {
 		if (dev_self[i])
 			nsc_ircc_close(dev_self[i]);
 	}
+
+	platform_driver_unregister(&nsc_ircc_driver);
+
+	if (pnp_registered)
+ 		pnp_unregister_driver(&nsc_ircc_pnp_driver);
+
+	pnp_registered = 0;
 }
 
 /*
@@ -241,16 +329,26 @@ static void __exit nsc_ircc_cleanup(void)
  *    Open driver instance
  *
  */
-static int __init nsc_ircc_open(int i, chipio_t *info)
+static int __init nsc_ircc_open(chipio_t *info)
 {
 	struct net_device *dev;
 	struct nsc_ircc_cb *self;
-        struct pm_dev *pmdev;
 	void *ret;
-	int err;
+	int err, chip_index;
 
 	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
 
+
+ 	for (chip_index = 0; chip_index < ARRAY_SIZE(dev_self); chip_index++) {
+		if (!dev_self[chip_index])
+			break;
+	}
+
+	if (chip_index == ARRAY_SIZE(dev_self)) {
+		IRDA_ERROR("%s(), maximum number of supported chips reached!\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+
 	IRDA_MESSAGE("%s, Found chip at base=0x%03x\n", driver_name,
 		     info->cfg_base);
 
@@ -271,8 +369,8 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
 	spin_lock_init(&self->lock);
    
 	/* Need to store self somewhere */
-	dev_self[i] = self;
-	self->index = i;
+	dev_self[chip_index] = self;
+	self->index = chip_index;
 
 	/* Initialize IO */
 	self->io.cfg_base  = info->cfg_base;
@@ -351,7 +449,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
 
 	/* Check if user has supplied a valid dongle id or not */
 	if ((dongle_id <= 0) ||
-	    (dongle_id >= (sizeof(dongle_types) / sizeof(dongle_types[0]))) ) {
+	    (dongle_id >= ARRAY_SIZE(dongle_types))) {
 		dongle_id = nsc_ircc_read_dongle_id(self->io.fir_base);
 		
 		IRDA_MESSAGE("%s, Found dongle: %s\n", driver_name,
@@ -364,11 +462,18 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
 	self->io.dongle_id = dongle_id;
 	nsc_ircc_init_dongle_interface(self->io.fir_base, dongle_id);
 
-        pmdev = pm_register(PM_SYS_DEV, PM_SYS_IRDA, nsc_ircc_pmproc);
-        if (pmdev)
-                pmdev->data = self;
+ 	self->pldev = platform_device_register_simple(NSC_IRCC_DRIVER_NAME,
+ 						      self->index, NULL, 0);
+ 	if (IS_ERR(self->pldev)) {
+ 		err = PTR_ERR(self->pldev);
+ 		goto out5;
+ 	}
+ 	platform_set_drvdata(self->pldev, self);
 
-	return 0;
+	return chip_index;
+
+ out5:
+ 	unregister_netdev(dev);
  out4:
 	dma_free_coherent(NULL, self->tx_buff.truesize,
 			  self->tx_buff.head, self->tx_buff_dma);
@@ -379,7 +484,7 @@ static int __init nsc_ircc_open(int i, chipio_t *info)
 	release_region(self->io.fir_base, self->io.fir_ext);
  out1:
 	free_netdev(dev);
-	dev_self[i] = NULL;
+	dev_self[chip_index] = NULL;
 	return err;
 }
 
@@ -399,6 +504,8 @@ static int __exit nsc_ircc_close(struct nsc_ircc_cb *self)
 
         iobase = self->io.fir_base;
 
+	platform_device_unregister(self->pldev);
+
 	/* Remove netdevice */
 	unregister_netdev(self->netdev);
 
@@ -806,6 +913,43 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info)
 	return 0;
 }
 
+/* PNP probing */
+static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id)
+{
+	memset(&pnp_info, 0, sizeof(chipio_t));
+	pnp_info.irq = -1;
+	pnp_info.dma = -1;
+	pnp_succeeded = 1;
+
+	/* There don't seem to be any way to get the cfg_base.
+	 * On my box, cfg_base is in the PnP descriptor of the
+	 * motherboard. Oh well... Jean II */
+
+	if (pnp_port_valid(dev, 0) &&
+		!(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED))
+		pnp_info.fir_base = pnp_port_start(dev, 0);
+
+	if (pnp_irq_valid(dev, 0) &&
+		!(pnp_irq_flags(dev, 0) & IORESOURCE_DISABLED))
+		pnp_info.irq = pnp_irq(dev, 0);
+
+	if (pnp_dma_valid(dev, 0) &&
+		!(pnp_dma_flags(dev, 0) & IORESOURCE_DISABLED))
+		pnp_info.dma = pnp_dma(dev, 0);
+
+	IRDA_DEBUG(0, "%s() : From PnP, found firbase 0x%03X ; irq %d ; dma %d.\n",
+		   __FUNCTION__, pnp_info.fir_base, pnp_info.irq, pnp_info.dma);
+
+	if((pnp_info.fir_base == 0) ||
+	   (pnp_info.irq == -1) || (pnp_info.dma == -1)) {
+		/* Returning an error will disable the device. Yuck ! */
+		//return -EINVAL;
+		pnp_succeeded = 0;
+	}
+
+	return 0;
+}
+
 /*
  * Function nsc_ircc_setup (info)
  *
@@ -2161,45 +2305,83 @@ static struct net_device_stats *nsc_ircc_net_get_stats(struct net_device *dev)
 	return &self->stats;
 }
 
-static void nsc_ircc_suspend(struct nsc_ircc_cb *self)
+static int nsc_ircc_suspend(struct platform_device *dev, pm_message_t state)
 {
-	IRDA_MESSAGE("%s, Suspending\n", driver_name);
+     	struct nsc_ircc_cb *self = platform_get_drvdata(dev);
+ 	int bank;
+	unsigned long flags;
+ 	int iobase = self->io.fir_base;
 
 	if (self->io.suspended)
-		return;
+		return 0;
 
-	nsc_ircc_net_close(self->netdev);
+	IRDA_DEBUG(1, "%s, Suspending\n", driver_name);
 
+	rtnl_lock();
+	if (netif_running(self->netdev)) {
+		netif_device_detach(self->netdev);
+		spin_lock_irqsave(&self->lock, flags);
+		/* Save current bank */
+		bank = inb(iobase+BSR);
+
+		/* Disable interrupts */
+		switch_bank(iobase, BANK0);
+		outb(0, iobase+IER);
+
+		/* Restore bank register */
+		outb(bank, iobase+BSR);
+
+		spin_unlock_irqrestore(&self->lock, flags);
+		free_irq(self->io.irq, self->netdev);
+		disable_dma(self->io.dma);
+	}
 	self->io.suspended = 1;
+	rtnl_unlock();
+
+	return 0;
 }
 
-static void nsc_ircc_wakeup(struct nsc_ircc_cb *self)
+static int nsc_ircc_resume(struct platform_device *dev)
 {
+ 	struct nsc_ircc_cb *self = platform_get_drvdata(dev);
+ 	unsigned long flags;
+
 	if (!self->io.suspended)
-		return;
+		return 0;
 
+	IRDA_DEBUG(1, "%s, Waking up\n", driver_name);
+
+	rtnl_lock();
 	nsc_ircc_setup(&self->io);
-	nsc_ircc_net_open(self->netdev);
-	
-	IRDA_MESSAGE("%s, Waking up\n", driver_name);
+	nsc_ircc_init_dongle_interface(self->io.fir_base, self->io.dongle_id);
 
+	if (netif_running(self->netdev)) {
+		if (request_irq(self->io.irq, nsc_ircc_interrupt, 0,
+				self->netdev->name, self->netdev)) {
+ 		    	IRDA_WARNING("%s, unable to allocate irq=%d\n",
+				     driver_name, self->io.irq);
+
+			/*
+			 * Don't fail resume process, just kill this
+			 * network interface
+			 */
+			unregister_netdevice(self->netdev);
+		} else {
+			spin_lock_irqsave(&self->lock, flags);
+			nsc_ircc_change_speed(self, self->io.speed);
+			spin_unlock_irqrestore(&self->lock, flags);
+			netif_device_attach(self->netdev);
+		}
+
+	} else {
+		spin_lock_irqsave(&self->lock, flags);
+		nsc_ircc_change_speed(self, 9600);
+		spin_unlock_irqrestore(&self->lock, flags);
+	}
 	self->io.suspended = 0;
-}
+	rtnl_unlock();
 
-static int nsc_ircc_pmproc(struct pm_dev *dev, pm_request_t rqst, void *data)
-{
-        struct nsc_ircc_cb *self = (struct nsc_ircc_cb*) dev->data;
-        if (self) {
-                switch (rqst) {
-                case PM_SUSPEND:
-                        nsc_ircc_suspend(self);
-                        break;
-                case PM_RESUME:
-                        nsc_ircc_wakeup(self);
-                        break;
-                }
-        }
-	return 0;
+ 	return 0;
 }
 
 MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");

+ 1 - 1
drivers/net/irda/nsc-ircc.h

@@ -269,7 +269,7 @@ struct nsc_ircc_cb {
 	__u32 new_speed;
 	int index;                 /* Instance index */
 
-        struct pm_dev *dev;
+	struct platform_device *pldev;
 };
 
 static inline void switch_bank(int iobase, int bank)

+ 10 - 9
drivers/net/irda/sir_dongle.c

@@ -16,6 +16,7 @@
 #include <linux/init.h>
 #include <linux/smp_lock.h>
 #include <linux/kmod.h>
+#include <linux/mutex.h>
 
 #include <net/irda/irda.h>
 
@@ -28,7 +29,7 @@
  */
 
 static LIST_HEAD(dongle_list);			/* list of registered dongle drivers */
-static DECLARE_MUTEX(dongle_list_lock);		/* protects the list */
+static DEFINE_MUTEX(dongle_list_lock);		/* protects the list */
 
 int irda_register_dongle(struct dongle_driver *new)
 {
@@ -38,25 +39,25 @@ int irda_register_dongle(struct dongle_driver *new)
 	IRDA_DEBUG(0, "%s : registering dongle \"%s\" (%d).\n",
 		   __FUNCTION__, new->driver_name, new->type);
 
-	down(&dongle_list_lock);
+	mutex_lock(&dongle_list_lock);
 	list_for_each(entry, &dongle_list) {
 		drv = list_entry(entry, struct dongle_driver, dongle_list);
 		if (new->type == drv->type) {
-			up(&dongle_list_lock);
+			mutex_unlock(&dongle_list_lock);
 			return -EEXIST;
 		}
 	}
 	list_add(&new->dongle_list, &dongle_list);
-	up(&dongle_list_lock);
+	mutex_unlock(&dongle_list_lock);
 	return 0;
 }
 EXPORT_SYMBOL(irda_register_dongle);
 
 int irda_unregister_dongle(struct dongle_driver *drv)
 {
-	down(&dongle_list_lock);
+	mutex_lock(&dongle_list_lock);
 	list_del(&drv->dongle_list);
-	up(&dongle_list_lock);
+	mutex_unlock(&dongle_list_lock);
 	return 0;
 }
 EXPORT_SYMBOL(irda_unregister_dongle);
@@ -75,7 +76,7 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
 		return -EBUSY;
 	
 	/* serialize access to the list of registered dongles */
-	down(&dongle_list_lock);
+	mutex_lock(&dongle_list_lock);
 
 	list_for_each(entry, &dongle_list) {
 		drv = list_entry(entry, struct dongle_driver, dongle_list);
@@ -109,14 +110,14 @@ int sirdev_get_dongle(struct sir_dev *dev, IRDA_DONGLE type)
 	if (!drv->open  ||  (err=drv->open(dev))!=0)
 		goto out_reject;		/* failed to open driver */
 
-	up(&dongle_list_lock);
+	mutex_unlock(&dongle_list_lock);
 	return 0;
 
 out_reject:
 	dev->dongle_drv = NULL;
 	module_put(drv->owner);
 out_unlock:
-	up(&dongle_list_lock);
+	mutex_unlock(&dongle_list_lock);
 	return err;
 }
 

+ 375 - 0
drivers/net/irda/toim3232-sir.c

@@ -0,0 +1,375 @@
+/*********************************************************************
+ *
+ * Filename:      toim3232-sir.c
+ * Version:       1.0
+ * Description:   Implementation of dongles based on the Vishay/Temic
+ * 		  TOIM3232 SIR Endec chipset. Currently only the
+ * 		  IRWave IR320ST-2 is tested, although it should work
+ * 		  with any TOIM3232 or TOIM4232 chipset based RS232
+ * 		  dongle with minimal modification.
+ * 		  Based heavily on the Tekram driver (tekram.c),
+ * 		  with thanks to Dag Brattli and Martin Diehl.
+ * Status:        Experimental.
+ * Author:        David Basden <davidb-irda@rcpt.to>
+ * Created at:    Thu Feb 09 23:47:32 2006
+ *
+ *     Copyright (c) 2006 David Basden.
+ *     Copyright (c) 1998-1999 Dag Brattli,
+ *     Copyright (c) 2002 Martin Diehl,
+ *     All Rights Reserved.
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     provide warranty for any of this software. This material is
+ *     provided "AS-IS" and at no charge.
+ *
+ ********************************************************************/
+
+/*
+ * This driver has currently only been tested on the IRWave IR320ST-2
+ *
+ * PROTOCOL:
+ *
+ * The protocol for talking to the TOIM3232 is quite easy, and is
+ * designed to interface with RS232 with only level convertors. The
+ * BR/~D line on the chip is brought high to signal 'command mode',
+ * where a command byte is sent to select the baudrate of the RS232
+ * interface and the pulse length of the IRDA output. When BR/~D
+ * is brought low, the dongle then changes to the selected baudrate,
+ * and the RS232 interface is used for data until BR/~D is brought
+ * high again. The initial speed for the TOIMx323 after RESET is
+ * 9600 baud.  The baudrate for command-mode is the last selected
+ * baud-rate, or 9600 after a RESET.
+ *
+ * The  dongle I have (below) adds some extra hardware on the front end,
+ * but this is mostly directed towards pariasitic power from the RS232
+ * line rather than changing very much about how to communicate with
+ * the TOIM3232.
+ *
+ * The protocol to talk to the TOIM4232 chipset seems to be almost
+ * identical to the TOIM3232 (and the 4232 datasheet is more detailed)
+ * so this code will probably work on that as well, although I haven't
+ * tested it on that hardware.
+ *
+ * Target dongle variations that might be common:
+ *
+ * DTR and RTS function:
+ *   The data sheet for the 4232 has a sample implementation that hooks the
+ *   DTR and RTS lines to the RESET and BaudRate/~Data lines of the
+ *   chip (through line-converters). Given both DTR and RTS would have to
+ *   be held low in normal operation, and the TOIMx232 requires +5V to
+ *   signal ground, most dongle designers would almost certainly choose
+ *   an implementation that kept at least one of DTR or RTS high in
+ *   normal operation to provide power to the dongle, but will likely
+ *   vary between designs.
+ *
+ * User specified command bits:
+ *  There are two user-controllable output lines from the TOIMx232 that
+ *  can be set low or high by setting the appropriate bits in the
+ *  high-nibble of the command byte (when setting speed and pulse length).
+ *  These might be used to switch on and off added hardware or extra
+ *  dongle features.
+ *
+ *
+ * Target hardware: IRWave IR320ST-2
+ *
+ * 	The IRWave IR320ST-2 is a simple dongle based on the Vishay/Temic
+ * 	TOIM3232 SIR Endec and the Vishay/Temic TFDS4500 SIR IRDA transciever.
+ * 	It uses a hex inverter and some discrete components to buffer and
+ * 	line convert the RS232 down to 5V.
+ *
+ * 	The dongle is powered through a voltage regulator, fed by a large
+ * 	capacitor. To switch the dongle on, DTR is brought high to charge
+ * 	the capacitor and drive the voltage regulator. DTR isn't associated
+ * 	with any control lines on the TOIM3232. Parisitic power is also taken
+ * 	from the RTS, TD and RD lines when brought high, but through resistors.
+ * 	When DTR is low, the circuit might lose power even with RTS high.
+ *
+ * 	RTS is inverted and attached to the BR/~D input pin. When RTS
+ * 	is high, BR/~D is low, and the TOIM3232 is in the normal 'data' mode.
+ * 	RTS is brought low, BR/~D is high, and the TOIM3232 is in 'command
+ * 	mode'.
+ *
+ * 	For some unknown reason, the RESET line isn't actually connected
+ * 	to anything. This means to reset the dongle to get it to a known
+ * 	state (9600 baud) you must drop DTR and RTS low, wait for the power
+ * 	capacitor to discharge, and then bring DTR (and RTS for data mode)
+ * 	high again, and wait for the capacitor to charge, the power supply
+ * 	to stabilise, and the oscillator clock to stabilise.
+ *
+ * 	Fortunately, if the current baudrate is known, the chipset can
+ * 	easily change speed by entering command mode without having to
+ * 	reset the dongle first.
+ *
+ * 	Major Components:
+ *
+ * 	- Vishay/Temic TOIM3232 SIR Endec to change RS232 pulse timings
+ * 	  to IRDA pulse timings
+ * 	- 3.6864MHz crystal to drive TOIM3232 clock oscillator
+ * 	- DM74lS04M Inverting Hex line buffer for RS232 input buffering
+ * 	  and level conversion
+ * 	- PJ2951AC 150mA voltage regulator
+ * 	- Vishay/Temic TFDS4500	SIR IRDA front-end transceiver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <net/irda/irda.h>
+
+#include "sir-dev.h"
+
+static int toim3232delay = 150;	/* default is 150 ms */
+module_param(toim3232delay, int, 0);
+MODULE_PARM_DESC(toim3232delay, "toim3232 dongle write complete delay");
+
+#if 0
+static int toim3232flipdtr = 0;	/* default is DTR high to reset */
+module_param(toim3232flipdtr, int, 0);
+MODULE_PARM_DESC(toim3232flipdtr, "toim3232 dongle invert DTR (Reset)");
+
+static int toim3232fliprts = 0;	/* default is RTS high for baud change */
+module_param(toim3232fliptrs, int, 0);
+MODULE_PARM_DESC(toim3232fliprts, "toim3232 dongle invert RTS (BR/D)");
+#endif
+
+static int toim3232_open(struct sir_dev *);
+static int toim3232_close(struct sir_dev *);
+static int toim3232_change_speed(struct sir_dev *, unsigned);
+static int toim3232_reset(struct sir_dev *);
+
+#define TOIM3232_115200 0x00
+#define TOIM3232_57600  0x01
+#define TOIM3232_38400  0x02
+#define TOIM3232_19200  0x03
+#define TOIM3232_9600   0x06
+#define TOIM3232_2400   0x0A
+
+#define TOIM3232_PW     0x10 /* Pulse select bit */
+
+static struct dongle_driver toim3232 = {
+	.owner		= THIS_MODULE,
+	.driver_name	= "Vishay TOIM3232",
+	.type		= IRDA_TOIM3232_DONGLE,
+	.open		= toim3232_open,
+	.close		= toim3232_close,
+	.reset		= toim3232_reset,
+	.set_speed	= toim3232_change_speed,
+};
+
+static int __init toim3232_sir_init(void)
+{
+	if (toim3232delay < 1  ||  toim3232delay > 500)
+		toim3232delay = 200;
+	IRDA_DEBUG(1, "%s - using %d ms delay\n",
+		toim3232.driver_name, toim3232delay);
+	return irda_register_dongle(&toim3232);
+}
+
+static void __exit toim3232_sir_cleanup(void)
+{
+	irda_unregister_dongle(&toim3232);
+}
+
+static int toim3232_open(struct sir_dev *dev)
+{
+	struct qos_info *qos = &dev->qos;
+
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
+	/* Pull the lines high to start with.
+	 *
+	 * For the IR320ST-2, we need to charge the main supply capacitor to
+	 * switch the device on. We keep DTR high throughout to do this.
+	 * When RTS, TD and RD are high, they will also trickle-charge the
+	 * cap. RTS is high for data transmission, and low for baud rate select.
+	 * 	-- DGB
+	 */
+	sirdev_set_dtr_rts(dev, TRUE, TRUE);
+
+	/* The TOI3232 supports many speeds between 1200bps and 115000bps.
+	 * We really only care about those supported by the IRDA spec, but
+	 * 38400 seems to be implemented in many places */
+	qos->baud_rate.bits &= IR_2400|IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
+
+	/* From the tekram driver. Not sure what a reasonable value is -- DGB */
+	qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
+	irda_qos_bits_to_value(qos);
+
+	/* irda thread waits 50 msec for power settling */
+
+	return 0;
+}
+
+static int toim3232_close(struct sir_dev *dev)
+{
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
+	/* Power off dongle */
+	sirdev_set_dtr_rts(dev, FALSE, FALSE);
+
+	return 0;
+}
+
+/*
+ * Function toim3232change_speed (dev, state, speed)
+ *
+ *    Set the speed for the TOIM3232 based dongle. Warning, this
+ *    function must be called with a process context!
+ *
+ *    Algorithm
+ *    1. keep DTR high but clear RTS to bring into baud programming mode
+ *    2. wait at least 7us to enter programming mode
+ *    3. send control word to set baud rate and timing
+ *    4. wait at least 1us
+ *    5. bring RTS high to enter DATA mode (RS232 is passed through to transceiver)
+ *    6. should take effect immediately (although probably worth waiting)
+ */
+
+#define TOIM3232_STATE_WAIT_SPEED	(SIRDEV_STATE_DONGLE_SPEED + 1)
+
+static int toim3232_change_speed(struct sir_dev *dev, unsigned speed)
+{
+	unsigned state = dev->fsm.substate;
+	unsigned delay = 0;
+	u8 byte;
+	static int ret = 0;
+
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
+	switch(state) {
+	case SIRDEV_STATE_DONGLE_SPEED:
+
+		/* Figure out what we are going to send as a control byte */
+		switch (speed) {
+		case 2400:
+			byte = TOIM3232_PW|TOIM3232_2400;
+			break;
+		default:
+			speed = 9600;
+			ret = -EINVAL;
+			/* fall thru */
+		case 9600:
+			byte = TOIM3232_PW|TOIM3232_9600;
+			break;
+		case 19200:
+			byte = TOIM3232_PW|TOIM3232_19200;
+			break;
+		case 38400:
+			byte = TOIM3232_PW|TOIM3232_38400;
+			break;
+		case 57600:
+			byte = TOIM3232_PW|TOIM3232_57600;
+			break;
+		case 115200:
+			byte = TOIM3232_115200;
+			break;
+		}
+
+		/* Set DTR, Clear RTS: Go into baud programming mode */
+		sirdev_set_dtr_rts(dev, TRUE, FALSE);
+
+		/* Wait at least 7us */
+		udelay(14);
+
+		/* Write control byte */
+		sirdev_raw_write(dev, &byte, 1);
+
+		dev->speed = speed;
+
+		state = TOIM3232_STATE_WAIT_SPEED;
+		delay = toim3232delay;
+		break;
+
+	case TOIM3232_STATE_WAIT_SPEED:
+		/* Have transmitted control byte * Wait for 'at least 1us' */
+		udelay(14);
+
+		/* Set DTR, Set RTS: Go into normal data mode */
+		sirdev_set_dtr_rts(dev, TRUE, TRUE);
+
+		/* Wait (TODO: check this is needed) */
+		udelay(50);
+		break;
+
+	default:
+		printk(KERN_ERR "%s - undefined state %d\n", __FUNCTION__, state);
+		ret = -EINVAL;
+		break;
+	}
+
+	dev->fsm.substate = state;
+	return (delay > 0) ? delay : ret;
+}
+
+/*
+ * Function toim3232reset (driver)
+ *
+ *      This function resets the toim3232 dongle. Warning, this function
+ *      must be called with a process context!!
+ *
+ * What we should do is:
+ * 	0. Pull RESET high
+ * 	1. Wait for at least 7us
+ * 	2. Pull RESET low
+ * 	3. Wait for at least 7us
+ * 	4. Pull BR/~D high
+ * 	5. Wait for at least 7us
+ * 	6. Send control byte to set baud rate
+ * 	7. Wait at least 1us after stop bit
+ * 	8. Pull BR/~D low
+ * 	9. Should then be in data mode
+ *
+ * Because the IR320ST-2 doesn't have the RESET line connected for some reason,
+ * we'll have to do something else.
+ *
+ * The default speed after a RESET is 9600, so lets try just bringing it up in
+ * data mode after switching it off, waiting for the supply capacitor to
+ * discharge, and then switch it back on. This isn't actually pulling RESET
+ * high, but it seems to have the same effect.
+ *
+ * This behaviour will probably work on dongles that have the RESET line connected,
+ * but if not, add a flag for the IR320ST-2, and implment the above-listed proper
+ * behaviour.
+ *
+ * RTS is inverted and then fed to BR/~D, so to put it in programming mode, we
+ * need to have pull RTS low
+ */
+
+static int toim3232_reset(struct sir_dev *dev)
+{
+	IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
+
+	/* Switch off both DTR and RTS to switch off dongle */
+	sirdev_set_dtr_rts(dev, FALSE, FALSE);
+
+	/* Should sleep a while. This might be evil doing it this way.*/
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(msecs_to_jiffies(50));
+
+	/* Set DTR, Set RTS (data mode) */
+	sirdev_set_dtr_rts(dev, TRUE, TRUE);
+
+	/* Wait at least 10 ms for power to stabilize again */
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(msecs_to_jiffies(10));
+
+	/* Speed should now be 9600 */
+	dev->speed = 9600;
+
+	return 0;
+}
+
+MODULE_AUTHOR("David Basden <davidb-linux@rcpt.to>");
+MODULE_DESCRIPTION("Vishay/Temic TOIM3232 based dongle driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("irda-dongle-12"); /* IRDA_TOIM3232_DONGLE */
+
+module_init(toim3232_sir_init);
+module_exit(toim3232_sir_cleanup);

+ 1 - 1
drivers/net/irda/vlsi_ir.c

@@ -1887,7 +1887,7 @@ static int __init vlsi_mod_init(void)
 		vlsi_proc_root->owner = THIS_MODULE;
 	}
 
-	ret = pci_module_init(&vlsi_irda_driver);
+	ret = pci_register_driver(&vlsi_irda_driver);
 
 	if (ret && vlsi_proc_root)
 		remove_proc_entry(PROC_DIR, NULL);

+ 2 - 2
drivers/net/ppp_generic.c

@@ -1691,8 +1691,8 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
 		    || ppp->npmode[npi] != NPMODE_PASS) {
 			kfree_skb(skb);
 		} else {
-			skb_pull(skb, 2);	/* chop off protocol */
-			skb_postpull_rcsum(skb, skb->data - 2, 2);
+			/* chop off protocol */
+			skb_pull_rcsum(skb, 2);
 			skb->dev = ppp->dev;
 			skb->protocol = htons(npindex_to_ethertype[npi]);
 			skb->mac.raw = skb->data;

+ 1 - 2
drivers/net/pppoe.c

@@ -337,8 +337,7 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
 	if (sk->sk_state & PPPOX_BOUND) {
 		struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
 		int len = ntohs(ph->length);
-		skb_pull(skb, sizeof(struct pppoe_hdr));
-		skb_postpull_rcsum(skb, ph, sizeof(*ph));
+		skb_pull_rcsum(skb, sizeof(struct pppoe_hdr));
 		if (pskb_trim_rcsum(skb, len))
 			goto abort_kfree;
 

+ 19 - 18
drivers/net/sungem.c

@@ -55,6 +55,7 @@
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
 #include <linux/bitops.h>
+#include <linux/mutex.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -2284,7 +2285,7 @@ static void gem_reset_task(void *data)
 {
 	struct gem *gp = (struct gem *) data;
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 
 	netif_poll_disable(gp->dev);
 
@@ -2311,7 +2312,7 @@ static void gem_reset_task(void *data)
 
 	netif_poll_enable(gp->dev);
 
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 }
 
 
@@ -2320,14 +2321,14 @@ static int gem_open(struct net_device *dev)
 	struct gem *gp = dev->priv;
 	int rc = 0;
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 
 	/* We need the cell enabled */
 	if (!gp->asleep)
 		rc = gem_do_start(dev);
 	gp->opened = (rc == 0);
 
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 
 	return rc;
 }
@@ -2340,13 +2341,13 @@ static int gem_close(struct net_device *dev)
 	 * our caller (dev_close) already did it for us
 	 */
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 
 	gp->opened = 0;	
 	if (!gp->asleep)
 		gem_do_stop(dev, 0);
 
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 	
 	return 0;
 }
@@ -2358,7 +2359,7 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct gem *gp = dev->priv;
 	unsigned long flags;
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 
 	netif_poll_disable(dev);
 
@@ -2391,11 +2392,11 @@ static int gem_suspend(struct pci_dev *pdev, pm_message_t state)
 	/* Stop the link timer */
 	del_timer_sync(&gp->link_timer);
 
-	/* Now we release the semaphore to not block the reset task who
+	/* Now we release the mutex to not block the reset task who
 	 * can take it too. We are marked asleep, so there will be no
 	 * conflict here
 	 */
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 
 	/* Wait for a pending reset task to complete */
 	while (gp->reset_task_pending)
@@ -2424,7 +2425,7 @@ static int gem_resume(struct pci_dev *pdev)
 
 	printk(KERN_INFO "%s: resuming\n", dev->name);
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 
 	/* Keep the cell enabled during the entire operation, no need to
 	 * take a lock here tho since nothing else can happen while we are
@@ -2440,7 +2441,7 @@ static int gem_resume(struct pci_dev *pdev)
 		 * still asleep, a new sleep cycle may bring it back
 		 */
 		gem_put_cell(gp);
-		up(&gp->pm_sem);
+		mutex_unlock(&gp->pm_mutex);
 		return 0;
 	}
 	pci_set_master(gp->pdev);
@@ -2486,7 +2487,7 @@ static int gem_resume(struct pci_dev *pdev)
 
 	netif_poll_enable(dev);
 	
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 
 	return 0;
 }
@@ -2591,7 +2592,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
 		return 0;
 	}
 
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 	spin_lock_irq(&gp->lock);
 	spin_lock(&gp->tx_lock);
 	dev->mtu = new_mtu;
@@ -2602,7 +2603,7 @@ static int gem_change_mtu(struct net_device *dev, int new_mtu)
 	}
 	spin_unlock(&gp->tx_lock);
 	spin_unlock_irq(&gp->lock);
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 
 	return 0;
 }
@@ -2771,10 +2772,10 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	int rc = -EOPNOTSUPP;
 	unsigned long flags;
 
-	/* Hold the PM semaphore while doing ioctl's or we may collide
+	/* Hold the PM mutex while doing ioctl's or we may collide
 	 * with power management.
 	 */
-	down(&gp->pm_sem);
+	mutex_lock(&gp->pm_mutex);
 		
 	spin_lock_irqsave(&gp->lock, flags);
 	gem_get_cell(gp);
@@ -2812,7 +2813,7 @@ static int gem_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	gem_put_cell(gp);
 	spin_unlock_irqrestore(&gp->lock, flags);
 
-	up(&gp->pm_sem);
+	mutex_unlock(&gp->pm_mutex);
 	
 	return rc;
 }
@@ -3033,7 +3034,7 @@ static int __devinit gem_init_one(struct pci_dev *pdev,
 
 	spin_lock_init(&gp->lock);
 	spin_lock_init(&gp->tx_lock);
-	init_MUTEX(&gp->pm_sem);
+	mutex_init(&gp->pm_mutex);
 
 	init_timer(&gp->link_timer);
 	gp->link_timer.function = gem_link_timer;

+ 3 - 3
drivers/net/sungem.h

@@ -980,15 +980,15 @@ struct gem {
 	int			tx_new, tx_old;
 
 	unsigned int has_wol : 1;	/* chip supports wake-on-lan */
-	unsigned int asleep : 1;	/* chip asleep, protected by pm_sem */
+	unsigned int asleep : 1;	/* chip asleep, protected by pm_mutex */
 	unsigned int asleep_wol : 1;	/* was asleep with WOL enabled */
-	unsigned int opened : 1;	/* driver opened, protected by pm_sem */
+	unsigned int opened : 1;	/* driver opened, protected by pm_mutex */
 	unsigned int running : 1;	/* chip running, protected by lock */
 	
 	/* cell enable count, protected by lock */
 	int			cell_enabled;  
 	
-	struct semaphore	pm_sem;
+	struct mutex		pm_mutex;
 
 	u32			msg_enable;
 	u32			status;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 512 - 89
drivers/net/tg3.c


+ 17 - 2
drivers/net/tg3.h

@@ -138,6 +138,7 @@
 #define   ASIC_REV_5752			 0x06
 #define   ASIC_REV_5780			 0x08
 #define   ASIC_REV_5714			 0x09
+#define   ASIC_REV_5787			 0x0b
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -1393,6 +1394,7 @@
 #define GRC_MDI_CTRL			0x00006844
 #define GRC_SEEPROM_DELAY		0x00006848
 /* 0x684c --> 0x6c00 unused */
+#define GRC_FASTBOOT_PC			0x00006894	/* 5752, 5755, 5787 */
 
 /* 0x6c00 --> 0x7000 unused */
 
@@ -1436,6 +1438,13 @@
 #define  FLASH_5752VENDOR_ST_M45PE10	 0x02400000
 #define  FLASH_5752VENDOR_ST_M45PE20	 0x02400002
 #define  FLASH_5752VENDOR_ST_M45PE40	 0x02400001
+#define  FLASH_5755VENDOR_ATMEL_FLASH_1	 0x03400001
+#define  FLASH_5755VENDOR_ATMEL_FLASH_2	 0x03400002
+#define  FLASH_5755VENDOR_ATMEL_FLASH_3	 0x03400000
+#define  FLASH_5787VENDOR_ATMEL_EEPROM_64KHZ	 0x03000003
+#define  FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ	 0x03000002
+#define  FLASH_5787VENDOR_MICRO_EEPROM_64KHZ	 0x03000000
+#define  FLASH_5787VENDOR_MICRO_EEPROM_376KHZ	 0x02000000
 #define  NVRAM_CFG1_5752PAGE_SIZE_MASK	 0x70000000
 #define  FLASH_5752PAGE_SIZE_256	 0x00000000
 #define  FLASH_5752PAGE_SIZE_512	 0x10000000
@@ -2185,7 +2194,7 @@ struct tg3 {
 #define TG3_FLG2_PHY_SERDES		0x00002000
 #define TG3_FLG2_CAPACITIVE_COUPLING	0x00004000
 #define TG3_FLG2_FLASH			0x00008000
-#define TG3_FLG2_HW_TSO			0x00010000
+#define TG3_FLG2_HW_TSO_1		0x00010000
 #define TG3_FLG2_SERDES_PREEMPHASIS	0x00020000
 #define TG3_FLG2_5705_PLUS		0x00040000
 #define TG3_FLG2_5750_PLUS		0x00080000
@@ -2198,6 +2207,9 @@ struct tg3 {
 #define TG3_FLG2_PARALLEL_DETECT	0x01000000
 #define TG3_FLG2_ICH_WORKAROUND		0x02000000
 #define TG3_FLG2_5780_CLASS		0x04000000
+#define TG3_FLG2_HW_TSO_2		0x08000000
+#define TG3_FLG2_HW_TSO			(TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2)
+#define TG3_FLG2_1SHOT_MSI		0x10000000
 
 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3
@@ -2247,6 +2259,7 @@ struct tg3 {
 #define PHY_ID_BCM5752			0x60008100
 #define PHY_ID_BCM5714			0x60008340
 #define PHY_ID_BCM5780			0x60008350
+#define PHY_ID_BCM5787			0xbc050ce0
 #define PHY_ID_BCM8002			0x60010140
 #define PHY_ID_INVALID			0xffffffff
 #define PHY_ID_REV_MASK			0x0000000f
@@ -2258,6 +2271,7 @@ struct tg3 {
 	u32				led_ctrl;
 
 	char				board_part_number[24];
+	char				fw_ver[16];
 	u32				nic_sram_data_cfg;
 	u32				pci_clock_ctrl;
 	struct pci_dev			*pdev_peer;
@@ -2271,7 +2285,8 @@ struct tg3 {
 	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
 	 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
 	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
-	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
+	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM5787 || \
+	 (X) == PHY_ID_BCM8002)
 
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;

+ 1 - 2
drivers/net/wan/sbni.c

@@ -1495,8 +1495,7 @@ module_param(skip_pci_probe, bool, 0);
 MODULE_LICENSE("GPL");
 
 
-int
-init_module( void )
+int __init init_module( void )
 {
 	struct net_device  *dev;
 	int err;

+ 1 - 1
include/asm-sparc/socket.h

@@ -47,7 +47,7 @@
 #define SO_TIMESTAMP		0x001d
 #define SCM_TIMESTAMP		SO_TIMESTAMP
 
-#define SO_PEERSEC		0x100e
+#define SO_PEERSEC		0x001e
 
 /* Security levels - as per NRL IPv6 - don't actually do anything */
 #define SO_SECURITY_AUTHENTICATION		0x5001

+ 82 - 50
include/linux/dccp.h

@@ -18,7 +18,7 @@
  * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
  */
 struct dccp_hdr {
-	__u16	dccph_sport,
+	__be16	dccph_sport,
 		dccph_dport;
 	__u8	dccph_doff;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
@@ -32,18 +32,18 @@ struct dccp_hdr {
 #endif
 	__u16	dccph_checksum;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-	__u32	dccph_x:1,
+	__u8	dccph_x:1,
 		dccph_type:4,
-		dccph_reserved:3,
-		dccph_seq:24;
+		dccph_reserved:3;
 #elif defined(__BIG_ENDIAN_BITFIELD)
-	__u32	dccph_reserved:3,
+	__u8	dccph_reserved:3,
 		dccph_type:4,
-		dccph_x:1,
-		dccph_seq:24;
+		dccph_x:1;
 #else
 #error  "Adjust your <asm/byteorder.h> defines"
 #endif
+	__u8	dccph_seq2;
+	__be16	dccph_seq;
 };
 
 /**
@@ -52,7 +52,7 @@ struct dccp_hdr {
  * @dccph_seq_low - low 24 bits of a 48 bit seq packet
  */
 struct dccp_hdr_ext {
-	__u32	dccph_seq_low;
+	__be32	dccph_seq_low;
 };
 
 /**
@@ -62,7 +62,7 @@ struct dccp_hdr_ext {
  * @dccph_req_options - list of options (must be a multiple of 32 bits
  */
 struct dccp_hdr_request {
-	__u32	dccph_req_service;
+	__be32	dccph_req_service;
 };
 /**
  * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
@@ -71,9 +71,9 @@ struct dccp_hdr_request {
  * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
  */
 struct dccp_hdr_ack_bits {
-	__u32	dccph_reserved1:8,
-		dccph_ack_nr_high:24;
-	__u32	dccph_ack_nr_low;
+	__be16	dccph_reserved1;
+	__be16	dccph_ack_nr_high;
+	__be32	dccph_ack_nr_low;
 };
 /**
  * struct dccp_hdr_response - Conection initiation response header
@@ -85,7 +85,7 @@ struct dccp_hdr_ack_bits {
  */
 struct dccp_hdr_response {
 	struct dccp_hdr_ack_bits	dccph_resp_ack;
-	__u32				dccph_resp_service;
+	__be32				dccph_resp_service;
 };
 
 /**
@@ -154,6 +154,10 @@ enum {
 	DCCPO_MANDATORY = 1,
 	DCCPO_MIN_RESERVED = 3,
 	DCCPO_MAX_RESERVED = 31,
+	DCCPO_CHANGE_L = 32,
+	DCCPO_CONFIRM_L = 33,
+	DCCPO_CHANGE_R = 34,
+	DCCPO_CONFIRM_R = 35,
 	DCCPO_NDP_COUNT = 37,
 	DCCPO_ACK_VECTOR_0 = 38,
 	DCCPO_ACK_VECTOR_1 = 39,
@@ -168,7 +172,9 @@ enum {
 /* DCCP features */
 enum {
 	DCCPF_RESERVED = 0,
+	DCCPF_CCID = 1,
 	DCCPF_SEQUENCE_WINDOW = 3,
+	DCCPF_ACK_RATIO = 5,
 	DCCPF_SEND_ACK_VECTOR = 6,
 	DCCPF_SEND_NDP_COUNT = 7,
 	/* 10-127 reserved */
@@ -176,9 +182,18 @@ enum {
 	DCCPF_MAX_CCID_SPECIFIC = 255,
 };
 
+/* this structure is argument to DCCP_SOCKOPT_CHANGE_X */
+struct dccp_so_feat {
+	__u8 dccpsf_feat;
+	__u8 *dccpsf_val;
+	__u8 dccpsf_len;
+};
+
 /* DCCP socket options */
 #define DCCP_SOCKOPT_PACKET_SIZE	1
 #define DCCP_SOCKOPT_SERVICE		2
+#define DCCP_SOCKOPT_CHANGE_L		3
+#define DCCP_SOCKOPT_CHANGE_R		4
 #define DCCP_SOCKOPT_CCID_RX_INFO	128
 #define DCCP_SOCKOPT_CCID_TX_INFO	192
 
@@ -254,16 +269,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
 static inline __u64 dccp_hdr_seq(const struct sk_buff *skb)
 {
 	const struct dccp_hdr *dh = dccp_hdr(skb);
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-	__u64 seq_nr = ntohl(dh->dccph_seq << 8);
-#elif defined(__BIG_ENDIAN_BITFIELD)
-	__u64 seq_nr = ntohl(dh->dccph_seq);
-#else
-#error  "Adjust your <asm/byteorder.h> defines"
-#endif
+	__u64 seq_nr =  ntohs(dh->dccph_seq);
 
 	if (dh->dccph_x != 0)
 		seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low);
+	else
+		seq_nr += (u32)dh->dccph_seq2 << 16;
 
 	return seq_nr;
 }
@@ -281,13 +292,7 @@ static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *
 static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
 {
 	const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-	return (((u64)ntohl(dhack->dccph_ack_nr_high << 8)) << 32) + ntohl(dhack->dccph_ack_nr_low);
-#elif defined(__BIG_ENDIAN_BITFIELD)
-	return (((u64)ntohl(dhack->dccph_ack_nr_high)) << 32) + ntohl(dhack->dccph_ack_nr_low);
-#else
-#error  "Adjust your <asm/byteorder.h> defines"
-#endif
+	return ((u64)ntohs(dhack->dccph_ack_nr_high) << 32) + ntohl(dhack->dccph_ack_nr_low);
 }
 
 static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
@@ -314,38 +319,60 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
 
 /* initial values for each feature */
 #define DCCPF_INITIAL_SEQUENCE_WINDOW		100
-/* FIXME: for now we're using CCID 3 (TFRC) */
-#define DCCPF_INITIAL_CCID			3
-#define DCCPF_INITIAL_SEND_ACK_VECTOR		0
+#define DCCPF_INITIAL_ACK_RATIO			2
+#define DCCPF_INITIAL_CCID			2
+#define DCCPF_INITIAL_SEND_ACK_VECTOR		1
 /* FIXME: for now we're default to 1 but it should really be 0 */
 #define DCCPF_INITIAL_SEND_NDP_COUNT		1
 
 #define DCCP_NDP_LIMIT 0xFFFFFF
 
 /**
-  * struct dccp_options - option values for a DCCP connection
-  *	@dccpo_sequence_window - Sequence Window Feature (section 7.5.2)
-  *	@dccpo_ccid - Congestion Control Id (CCID) (section 10)
-  *	@dccpo_send_ack_vector - Send Ack Vector Feature (section 11.5)
-  *	@dccpo_send_ndp_count - Send NDP Count Feature (7.7.2)
+  * struct dccp_minisock - Minimal DCCP connection representation
+  *
+  * Will be used to pass the state from dccp_request_sock to dccp_sock.
+  *
+  * @dccpms_sequence_window - Sequence Window Feature (section 7.5.2)
+  * @dccpms_ccid - Congestion Control Id (CCID) (section 10)
+  * @dccpms_send_ack_vector - Send Ack Vector Feature (section 11.5)
+  * @dccpms_send_ndp_count - Send NDP Count Feature (7.7.2)
   */
-struct dccp_options {
-	__u64	dccpo_sequence_window;
-	__u8	dccpo_rx_ccid;
-	__u8	dccpo_tx_ccid;
-	__u8	dccpo_send_ack_vector;
-	__u8	dccpo_send_ndp_count;
+struct dccp_minisock {
+	__u64			dccpms_sequence_window;
+	__u8			dccpms_rx_ccid;
+	__u8			dccpms_tx_ccid;
+	__u8			dccpms_send_ack_vector;
+	__u8			dccpms_send_ndp_count;
+	__u8			dccpms_ack_ratio;
+	struct list_head	dccpms_pending;
+	struct list_head	dccpms_conf;
+};
+
+struct dccp_opt_conf {
+	__u8			*dccpoc_val;
+	__u8			dccpoc_len;
+};
+
+struct dccp_opt_pend {
+	struct list_head	dccpop_node;
+	__u8			dccpop_type;
+	__u8			dccpop_feat;
+	__u8		        *dccpop_val;
+	__u8			dccpop_len;
+	int			dccpop_conf;
+	struct dccp_opt_conf    *dccpop_sc;
 };
 
-extern void __dccp_options_init(struct dccp_options *dccpo);
-extern void dccp_options_init(struct dccp_options *dccpo);
+extern void __dccp_minisock_init(struct dccp_minisock *dmsk);
+extern void dccp_minisock_init(struct dccp_minisock *dmsk);
+
 extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb);
 
 struct dccp_request_sock {
 	struct inet_request_sock dreq_inet_rsk;
 	__u64			 dreq_iss;
 	__u64			 dreq_isr;
-	__u32			 dreq_service;
+	__be32			 dreq_service;
 };
 
 static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
@@ -373,13 +400,13 @@ enum dccp_role {
 
 struct dccp_service_list {
 	__u32	dccpsl_nr;
-	__u32	dccpsl_list[0];
+	__be32	dccpsl_list[0];
 };
 
 #define DCCP_SERVICE_INVALID_VALUE htonl((__u32)-1)
 
 static inline int dccp_list_has_service(const struct dccp_service_list *sl,
-					const u32 service)
+					const __be32 service)
 {
 	if (likely(sl != NULL)) {
 		u32 i = sl->dccpsl_nr;
@@ -425,17 +452,17 @@ struct dccp_sock {
 	__u64				dccps_gss;
 	__u64				dccps_gsr;
 	__u64				dccps_gar;
-	__u32				dccps_service;
+	__be32				dccps_service;
 	struct dccp_service_list	*dccps_service_list;
 	struct timeval			dccps_timestamp_time;
 	__u32				dccps_timestamp_echo;
 	__u32				dccps_packet_size;
+	__u16				dccps_l_ack_ratio;
+	__u16				dccps_r_ack_ratio;
 	unsigned long			dccps_ndp_count;
 	__u32				dccps_mss_cache;
-	struct dccp_options		dccps_options;
+	struct dccp_minisock		dccps_minisock;
 	struct dccp_ackvec		*dccps_hc_rx_ackvec;
-	void				*dccps_hc_rx_ccid_private;
-	void				*dccps_hc_tx_ccid_private;
 	struct ccid			*dccps_hc_rx_ccid;
 	struct ccid			*dccps_hc_tx_ccid;
 	struct dccp_options_received	dccps_options_received;
@@ -450,6 +477,11 @@ static inline struct dccp_sock *dccp_sk(const struct sock *sk)
 	return (struct dccp_sock *)sk;
 }
 
+static inline struct dccp_minisock *dccp_msk(const struct sock *sk)
+{
+	return (struct dccp_minisock *)&dccp_sk(sk)->dccps_minisock;
+}
+
 static inline int dccp_service_not_initialized(const struct sock *sk)
 {
 	return dccp_sk(sk)->dccps_service == DCCP_SERVICE_INVALID_VALUE;

+ 22 - 22
include/linux/dn.h

@@ -71,17 +71,17 @@
 
 struct dn_naddr 
 {
-	unsigned short		a_len;
-	unsigned char a_addr[DN_MAXADDL];
+	__le16		a_len;
+	__u8 a_addr[DN_MAXADDL]; /* Two bytes little endian */
 };
 
 struct sockaddr_dn
 {
-	unsigned short		sdn_family;
-	unsigned char		sdn_flags;
-	unsigned char		sdn_objnum;
-	unsigned short		sdn_objnamel;
-	unsigned char		sdn_objname[DN_MAXOBJL];
+	__u16		sdn_family;
+	__u8		sdn_flags;
+	__u8		sdn_objnum;
+	__le16		sdn_objnamel;
+	__u8		sdn_objname[DN_MAXOBJL];
 	struct   dn_naddr	sdn_add;
 };
 #define sdn_nodeaddrl   sdn_add.a_len   /* Node address length  */
@@ -93,38 +93,38 @@ struct sockaddr_dn
  * DECnet set/get DSO_CONDATA, DSO_DISDATA (optional data) structure
  */
 struct optdata_dn {
-        unsigned short  opt_status;     /* Extended status return */
+        __le16  opt_status;     /* Extended status return */
 #define opt_sts opt_status
-        unsigned short  opt_optl;       /* Length of user data    */
-        unsigned char   opt_data[16];   /* User data              */
+        __le16  opt_optl;       /* Length of user data    */
+        __u8   opt_data[16];   /* User data              */
 };
 
 struct accessdata_dn
 {
-	unsigned char		acc_accl;
-	unsigned char		acc_acc[DN_MAXACCL];
-	unsigned char 		acc_passl;
-	unsigned char		acc_pass[DN_MAXACCL];
-	unsigned char 		acc_userl;
-	unsigned char		acc_user[DN_MAXACCL];
+	__u8		acc_accl;
+	__u8		acc_acc[DN_MAXACCL];
+	__u8 		acc_passl;
+	__u8		acc_pass[DN_MAXACCL];
+	__u8 		acc_userl;
+	__u8		acc_user[DN_MAXACCL];
 };
 
 /*
  * DECnet logical link information structure
  */
 struct linkinfo_dn {
-        unsigned short  idn_segsize;    /* Segment size for link */
-        unsigned char   idn_linkstate;  /* Logical link state    */
+        __le16  idn_segsize;    /* Segment size for link */
+        __u8   idn_linkstate;  /* Logical link state    */
 };
 
 /*
  * Ethernet address format (for DECnet)
  */
 union etheraddress {
-        unsigned char dne_addr[6];             /* Full ethernet address */
+        __u8 dne_addr[6];             /* Full ethernet address */
   struct {
-                unsigned char dne_hiord[4];    /* DECnet HIORD prefix   */
-                unsigned char dne_nodeaddr[2]; /* DECnet node address   */
+                __u8 dne_hiord[4];    /* DECnet HIORD prefix   */
+                __u8 dne_nodeaddr[2]; /* DECnet node address   */
   } dne_remote;
 };
 
@@ -133,7 +133,7 @@ union etheraddress {
  * DECnet physical socket address format
  */
 struct dn_addr {
-        unsigned short dna_family;      /* AF_DECnet               */
+        __le16 dna_family;      /* AF_DECnet               */
         union etheraddress dna_netaddr; /* DECnet ethernet address */
 };
 

+ 9 - 2
include/linux/icmpv6.h

@@ -40,14 +40,16 @@ struct icmp6hdr {
                 struct icmpv6_nd_ra {
 			__u8		hop_limit;
 #if defined(__LITTLE_ENDIAN_BITFIELD)
-			__u8		reserved:6,
+			__u8		reserved:4,
+					router_pref:2,
 					other:1,
 					managed:1;
 
 #elif defined(__BIG_ENDIAN_BITFIELD)
 			__u8		managed:1,
 					other:1,
-					reserved:6;
+					router_pref:2,
+					reserved:4;
 #else
 #error	"Please fix <asm/byteorder.h>"
 #endif
@@ -70,8 +72,13 @@ struct icmp6hdr {
 #define icmp6_addrconf_managed	icmp6_dataun.u_nd_ra.managed
 #define icmp6_addrconf_other	icmp6_dataun.u_nd_ra.other
 #define icmp6_rt_lifetime	icmp6_dataun.u_nd_ra.rt_lifetime
+#define icmp6_router_pref	icmp6_dataun.u_nd_ra.router_pref
 };
 
+#define ICMPV6_ROUTER_PREF_LOW		0x3
+#define ICMPV6_ROUTER_PREF_MEDIUM	0x0
+#define ICMPV6_ROUTER_PREF_HIGH		0x1
+#define ICMPV6_ROUTER_PREF_INVALID	0x2
 
 #define ICMPV6_DEST_UNREACH		1
 #define ICMPV6_PKT_TOOBIG		2

+ 23 - 3
include/linux/if.h

@@ -33,7 +33,7 @@
 #define	IFF_LOOPBACK	0x8		/* is a loopback net		*/
 #define	IFF_POINTOPOINT	0x10		/* interface is has p-p link	*/
 #define	IFF_NOTRAILERS	0x20		/* avoid use of trailers	*/
-#define	IFF_RUNNING	0x40		/* interface running and carrier ok */
+#define	IFF_RUNNING	0x40		/* interface RFC2863 OPER_UP	*/
 #define	IFF_NOARP	0x80		/* no ARP protocol		*/
 #define	IFF_PROMISC	0x100		/* receive all packets		*/
 #define	IFF_ALLMULTI	0x200		/* receive all multicast packets*/
@@ -43,12 +43,16 @@
 
 #define IFF_MULTICAST	0x1000		/* Supports multicast		*/
 
-#define IFF_VOLATILE	(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|IFF_MASTER|IFF_SLAVE|IFF_RUNNING)
-
 #define IFF_PORTSEL	0x2000          /* can set media type		*/
 #define IFF_AUTOMEDIA	0x4000		/* auto media select active	*/
 #define IFF_DYNAMIC	0x8000		/* dialup device with changing addresses*/
 
+#define IFF_LOWER_UP	0x10000		/* driver signals L1 up		*/
+#define IFF_DORMANT	0x20000		/* driver signals dormant	*/
+
+#define IFF_VOLATILE	(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|\
+		IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
+
 /* Private (from user) interface flags (netdevice->priv_flags). */
 #define IFF_802_1Q_VLAN 0x1             /* 802.1Q VLAN device.          */
 #define IFF_EBRIDGE	0x2		/* Ethernet bridging device.	*/
@@ -83,6 +87,22 @@
 #define IF_PROTO_FR_ETH_PVC 0x200B
 #define IF_PROTO_RAW    0x200C          /* RAW Socket                   */
 
+/* RFC 2863 operational status */
+enum {
+	IF_OPER_UNKNOWN,
+	IF_OPER_NOTPRESENT,
+	IF_OPER_DOWN,
+	IF_OPER_LOWERLAYERDOWN,
+	IF_OPER_TESTING,
+	IF_OPER_DORMANT,
+	IF_OPER_UP,
+};
+
+/* link modes */
+enum {
+	IF_LINK_MODE_DEFAULT,
+	IF_LINK_MODE_DORMANT,	/* limit upward transition to dormant */
+};
 
 /*
  *	Device mapping structure. I'd just gone off and designed a 

+ 1 - 0
include/linux/in.h

@@ -72,6 +72,7 @@ struct in_addr {
 #define IP_FREEBIND	15
 #define IP_IPSEC_POLICY	16
 #define IP_XFRM_POLICY	17
+#define IP_PASSSEC	18
 
 /* BSD compatibility */
 #define IP_RECVRETOPTS	IP_RETOPTS

+ 1 - 0
include/linux/inetdevice.h

@@ -25,6 +25,7 @@ struct ipv4_devconf
 	int     arp_filter;
 	int	arp_announce;
 	int	arp_ignore;
+	int	arp_accept;
 	int	medium_id;
 	int	no_xfrm;
 	int	no_policy;

+ 14 - 0
include/linux/ipv6.h

@@ -145,6 +145,15 @@ struct ipv6_devconf {
 	__s32		max_desync_factor;
 #endif
 	__s32		max_addresses;
+	__s32		accept_ra_defrtr;
+	__s32		accept_ra_pinfo;
+#ifdef CONFIG_IPV6_ROUTER_PREF
+	__s32		accept_ra_rtr_pref;
+	__s32		rtr_probe_interval;
+#ifdef CONFIG_IPV6_ROUTE_INFO
+	__s32		accept_ra_rt_info_max_plen;
+#endif
+#endif
 	void		*sysctl;
 };
 
@@ -167,6 +176,11 @@ enum {
 	DEVCONF_MAX_DESYNC_FACTOR,
 	DEVCONF_MAX_ADDRESSES,
 	DEVCONF_FORCE_MLD_VERSION,
+	DEVCONF_ACCEPT_RA_DEFRTR,
+	DEVCONF_ACCEPT_RA_PINFO,
+	DEVCONF_ACCEPT_RA_RTR_PREF,
+	DEVCONF_RTR_PROBE_INTERVAL,
+	DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
 	DEVCONF_MAX
 };
 

+ 10 - 0
include/linux/ipv6_route.h

@@ -23,12 +23,22 @@
 #define RTF_NONEXTHOP	0x00200000	/* route with no nexthop	*/
 #define RTF_EXPIRES	0x00400000
 
+#define RTF_ROUTEINFO	0x00800000	/* route information - RA	*/
+
 #define RTF_CACHE	0x01000000	/* cache entry			*/
 #define RTF_FLOW	0x02000000	/* flow significant route	*/
 #define RTF_POLICY	0x04000000	/* policy route			*/
 
+#define RTF_PREF(pref)	((pref) << 27)
+#define RTF_PREF_MASK	0x18000000
+
 #define RTF_LOCAL	0x80000000
 
+#ifdef __KERNEL__
+#define IPV6_EXTRACT_PREF(flag)	(((flag) & RTF_PREF_MASK) >> 27)
+#define IPV6_DECODE_PREF(pref)	((pref) ^ 2)	/* 1:low,2:med,3:high */
+#endif
+
 struct in6_rtmsg {
 	struct in6_addr		rtmsg_dst;
 	struct in6_addr		rtmsg_src;

+ 1 - 0
include/linux/irda.h

@@ -76,6 +76,7 @@ typedef enum {
 	IRDA_MCP2120_DONGLE      = 9,
 	IRDA_ACT200L_DONGLE      = 10,
 	IRDA_MA600_DONGLE        = 11,
+	IRDA_TOIM3232_DONGLE     = 12,
 } IRDA_DONGLE;
 
 /* Protocol types to be used for SOCK_DGRAM */

+ 24 - 0
include/linux/list.h

@@ -410,6 +410,17 @@ static inline void list_splice_init(struct list_head *list,
 	     prefetch(pos->member.next), &pos->member != (head);	\
 	     pos = list_entry(pos->member.next, typeof(*pos), member))
 
+/**
+ * list_for_each_entry_from -	iterate over list of given type
+ *			continuing from existing point
+ * @pos:	the type * to use as a loop counter.
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_from(pos, head, member) 			\
+	for (; prefetch(pos->member.next), &pos->member != (head);	\
+	     pos = list_entry(pos->member.next, typeof(*pos), member))
+
 /**
  * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
  * @pos:	the type * to use as a loop counter.
@@ -437,6 +448,19 @@ static inline void list_splice_init(struct list_head *list,
 	     &pos->member != (head);						\
 	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
+/**
+ * list_for_each_entry_safe_from - iterate over list of given type
+ *			from existing point safe against removal of list entry
+ * @pos:	the type * to use as a loop counter.
+ * @n:		another type * to use as temporary storage
+ * @head:	the head for your list.
+ * @member:	the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member) 			\
+	for (n = list_entry(pos->member.next, typeof(*pos), member);		\
+	     &pos->member != (head);						\
+	     pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
 /**
  * list_for_each_entry_safe_reverse - iterate backwards over list of given type safe against
  *				      removal of list entry

+ 4 - 0
include/linux/net.h

@@ -149,6 +149,10 @@ struct proto_ops {
 				      int optname, char __user *optval, int optlen);
 	int		(*getsockopt)(struct socket *sock, int level,
 				      int optname, char __user *optval, int __user *optlen);
+	int		(*compat_setsockopt)(struct socket *sock, int level,
+				      int optname, char __user *optval, int optlen);
+	int		(*compat_getsockopt)(struct socket *sock, int level,
+				      int optname, char __user *optval, int __user *optlen);
 	int		(*sendmsg)   (struct kiocb *iocb, struct socket *sock,
 				      struct msghdr *m, size_t total_len);
 	int		(*recvmsg)   (struct kiocb *iocb, struct socket *sock,

+ 37 - 4
include/linux/netdevice.h

@@ -230,7 +230,8 @@ enum netdev_state_t
 	__LINK_STATE_SCHED,
 	__LINK_STATE_NOCARRIER,
 	__LINK_STATE_RX_SCHED,
-	__LINK_STATE_LINKWATCH_PENDING
+	__LINK_STATE_LINKWATCH_PENDING,
+	__LINK_STATE_DORMANT,
 };
 
 
@@ -335,11 +336,14 @@ struct net_device
 	 */
 
 
-	unsigned short		flags;	/* interface flags (a la BSD)	*/
+	unsigned int		flags;	/* interface flags (a la BSD)	*/
 	unsigned short		gflags;
         unsigned short          priv_flags; /* Like 'flags' but invisible to userspace. */
 	unsigned short		padded;	/* How much padding added by alloc_netdev() */
 
+	unsigned char		operstate; /* RFC2863 operstate */
+	unsigned char		link_mode; /* mapping policy to operstate */
+
 	unsigned		mtu;	/* interface MTU value		*/
 	unsigned short		type;	/* interface hardware type	*/
 	unsigned short		hard_header_len;	/* hardware hdr length	*/
@@ -708,12 +712,18 @@ static inline void dev_put(struct net_device *dev)
 	atomic_dec(&dev->refcnt);
 }
 
-#define __dev_put(dev) atomic_dec(&(dev)->refcnt)
-#define dev_hold(dev) atomic_inc(&(dev)->refcnt)
+static inline void dev_hold(struct net_device *dev)
+{
+	atomic_inc(&dev->refcnt);
+}
 
 /* Carrier loss detection, dial on demand. The functions netif_carrier_on
  * and _off may be called from IRQ context, but it is caller
  * who is responsible for serialization of these calls.
+ *
+ * The name carrier is inappropriate, these functions should really be
+ * called netif_lowerlayer_*() because they represent the state of any
+ * kind of lower layer not just hardware media.
  */
 
 extern void linkwatch_fire_event(struct net_device *dev);
@@ -729,6 +739,29 @@ extern void netif_carrier_on(struct net_device *dev);
 
 extern void netif_carrier_off(struct net_device *dev);
 
+static inline void netif_dormant_on(struct net_device *dev)
+{
+	if (!test_and_set_bit(__LINK_STATE_DORMANT, &dev->state))
+		linkwatch_fire_event(dev);
+}
+
+static inline void netif_dormant_off(struct net_device *dev)
+{
+	if (test_and_clear_bit(__LINK_STATE_DORMANT, &dev->state))
+		linkwatch_fire_event(dev);
+}
+
+static inline int netif_dormant(const struct net_device *dev)
+{
+	return test_bit(__LINK_STATE_DORMANT, &dev->state);
+}
+
+
+static inline int netif_oper_up(const struct net_device *dev) {
+	return (dev->operstate == IF_OPER_UP ||
+		dev->operstate == IF_OPER_UNKNOWN /* backward compat */);
+}
+
 /* Hot-plugging. */
 static inline int netif_device_present(struct net_device *dev)
 {

+ 9 - 0
include/linux/netfilter.h

@@ -80,10 +80,14 @@ struct nf_sockopt_ops
 	int set_optmin;
 	int set_optmax;
 	int (*set)(struct sock *sk, int optval, void __user *user, unsigned int len);
+	int (*compat_set)(struct sock *sk, int optval,
+			void __user *user, unsigned int len);
 
 	int get_optmin;
 	int get_optmax;
 	int (*get)(struct sock *sk, int optval, void __user *user, int *len);
+	int (*compat_get)(struct sock *sk, int optval,
+			void __user *user, int *len);
 
 	/* Number of users inside set() or get(). */
 	unsigned int use;
@@ -246,6 +250,11 @@ int nf_setsockopt(struct sock *sk, int pf, int optval, char __user *opt,
 int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt,
 		  int *len);
 
+int compat_nf_setsockopt(struct sock *sk, int pf, int optval,
+		char __user *opt, int len);
+int compat_nf_getsockopt(struct sock *sk, int pf, int optval,
+		char __user *opt, int *len);
+
 /* Packet queuing */
 struct nf_queue_handler {
 	int (*outfn)(struct sk_buff *skb, struct nf_info *info,

+ 1 - 0
include/linux/netfilter/nfnetlink.h

@@ -164,6 +164,7 @@ extern void nfattr_parse(struct nfattr *tb[], int maxattr,
  	__res;								\
 })
 
+extern int nfnetlink_has_listeners(unsigned int group);
 extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, 
 			  int echo);
 extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);

+ 6 - 0
include/linux/netfilter/nfnetlink_log.h

@@ -47,6 +47,8 @@ enum nfulnl_attr_type {
 	NFULA_PAYLOAD,			/* opaque data payload */
 	NFULA_PREFIX,			/* string prefix */
 	NFULA_UID,			/* user id of socket */
+	NFULA_SEQ,			/* instance-local sequence number */
+	NFULA_SEQ_GLOBAL,		/* global sequence number */
 
 	__NFULA_MAX
 };
@@ -77,6 +79,7 @@ enum nfulnl_attr_config {
 	NFULA_CFG_NLBUFSIZ,		/* u_int32_t buffer size */
 	NFULA_CFG_TIMEOUT,		/* u_int32_t in 1/100 s */
 	NFULA_CFG_QTHRESH,		/* u_int32_t */
+	NFULA_CFG_FLAGS,		/* u_int16_t */
 	__NFULA_CFG_MAX
 };
 #define NFULA_CFG_MAX (__NFULA_CFG_MAX -1)
@@ -85,4 +88,7 @@ enum nfulnl_attr_config {
 #define NFULNL_COPY_META	0x01
 #define NFULNL_COPY_PACKET	0x02
 
+#define NFULNL_CFG_F_SEQ	0x0001
+#define NFULNL_CFG_F_SEQ_GLOBAL	0x0002
+
 #endif /* _NFNETLINK_LOG_H */

+ 31 - 6
include/linux/netfilter/x_tables.h

@@ -92,8 +92,6 @@ struct xt_match
 
 	const char name[XT_FUNCTION_MAXNAMELEN-1];
 
-	u_int8_t revision;
-
 	/* Return true or false: return FALSE and set *hotdrop = 1 to
            force immediate packet drop. */
 	/* Arguments changed since 2.6.9, as this must now handle
@@ -102,6 +100,7 @@ struct xt_match
 	int (*match)(const struct sk_buff *skb,
 		     const struct net_device *in,
 		     const struct net_device *out,
+		     const struct xt_match *match,
 		     const void *matchinfo,
 		     int offset,
 		     unsigned int protoff,
@@ -111,15 +110,25 @@ struct xt_match
 	/* Should return true or false. */
 	int (*checkentry)(const char *tablename,
 			  const void *ip,
+			  const struct xt_match *match,
 			  void *matchinfo,
 			  unsigned int matchinfosize,
 			  unsigned int hook_mask);
 
 	/* Called when entry of this type deleted. */
-	void (*destroy)(void *matchinfo, unsigned int matchinfosize);
+	void (*destroy)(const struct xt_match *match, void *matchinfo,
+			unsigned int matchinfosize);
 
 	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
 	struct module *me;
+
+	char *table;
+	unsigned int matchsize;
+	unsigned int hooks;
+	unsigned short proto;
+
+	unsigned short family;
+	u_int8_t revision;
 };
 
 /* Registration hooks for targets. */
@@ -129,8 +138,6 @@ struct xt_target
 
 	const char name[XT_FUNCTION_MAXNAMELEN-1];
 
-	u_int8_t revision;
-
 	/* Returns verdict. Argument order changed since 2.6.9, as this
 	   must now handle non-linear skbs, using skb_copy_bits and
 	   skb_ip_make_writable. */
@@ -138,6 +145,7 @@ struct xt_target
 			       const struct net_device *in,
 			       const struct net_device *out,
 			       unsigned int hooknum,
+			       const struct xt_target *target,
 			       const void *targinfo,
 			       void *userdata);
 
@@ -147,15 +155,25 @@ struct xt_target
 	/* Should return true or false. */
 	int (*checkentry)(const char *tablename,
 			  const void *entry,
+			  const struct xt_target *target,
 			  void *targinfo,
 			  unsigned int targinfosize,
 			  unsigned int hook_mask);
 
 	/* Called when entry of this type deleted. */
-	void (*destroy)(void *targinfo, unsigned int targinfosize);
+	void (*destroy)(const struct xt_target *target, void *targinfo,
+			unsigned int targinfosize);
 
 	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
 	struct module *me;
+
+	char *table;
+	unsigned int targetsize;
+	unsigned int hooks;
+	unsigned short proto;
+
+	unsigned short family;
+	u_int8_t revision;
 };
 
 /* Furniture shopping... */
@@ -207,6 +225,13 @@ extern void xt_unregister_target(int af, struct xt_target *target);
 extern int xt_register_match(int af, struct xt_match *target);
 extern void xt_unregister_match(int af, struct xt_match *target);
 
+extern int xt_check_match(const struct xt_match *match, unsigned short family,
+			  unsigned int size, const char *table, unsigned int hook,
+			  unsigned short proto, int inv_proto);
+extern int xt_check_target(const struct xt_target *target, unsigned short family,
+			   unsigned int size, const char *table, unsigned int hook,
+			   unsigned short proto, int inv_proto);
+
 extern int xt_register_table(struct xt_table *table,
 			     struct xt_table_info *bootstrap,
 			     struct xt_table_info *newinfo);

+ 58 - 0
include/linux/netfilter/xt_policy.h

@@ -0,0 +1,58 @@
+#ifndef _XT_POLICY_H
+#define _XT_POLICY_H
+
+#define XT_POLICY_MAX_ELEM	4
+
+enum xt_policy_flags
+{
+	XT_POLICY_MATCH_IN	= 0x1,
+	XT_POLICY_MATCH_OUT	= 0x2,
+	XT_POLICY_MATCH_NONE	= 0x4,
+	XT_POLICY_MATCH_STRICT	= 0x8,
+};
+
+enum xt_policy_modes
+{
+	XT_POLICY_MODE_TRANSPORT,
+	XT_POLICY_MODE_TUNNEL
+};
+
+struct xt_policy_spec
+{
+	u_int8_t	saddr:1,
+			daddr:1,
+			proto:1,
+			mode:1,
+			spi:1,
+			reqid:1;
+};
+
+union xt_policy_addr
+{
+	struct in_addr	a4;
+	struct in6_addr	a6;
+};
+
+struct xt_policy_elem
+{
+	union xt_policy_addr	saddr;
+	union xt_policy_addr	smask;
+	union xt_policy_addr	daddr;
+	union xt_policy_addr	dmask;
+	u_int32_t		spi;
+	u_int32_t		reqid;
+	u_int8_t		proto;
+	u_int8_t		mode;
+
+	struct xt_policy_spec	match;
+	struct xt_policy_spec	invert;
+};
+
+struct xt_policy_info
+{
+	struct xt_policy_elem pol[XT_POLICY_MAX_ELEM];
+	u_int16_t flags;
+	u_int16_t len;
+};
+
+#endif /* _XT_POLICY_H */

+ 0 - 27
include/linux/netfilter_bridge.h

@@ -47,22 +47,6 @@ enum nf_br_hook_priorities {
 #define BRNF_BRIDGED			0x08
 #define BRNF_NF_BRIDGE_PREROUTING	0x10
 
-static inline
-struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
-{
-	struct nf_bridge_info **nf_bridge = &(skb->nf_bridge);
-
-	if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) {
-		atomic_set(&(*nf_bridge)->use, 1);
-		(*nf_bridge)->mask = 0;
-		(*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL;
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-		(*nf_bridge)->netoutdev = NULL;
-#endif
-	}
-
-	return *nf_bridge;
-}
 
 /* Only used in br_forward.c */
 static inline
@@ -77,17 +61,6 @@ void nf_bridge_maybe_copy_header(struct sk_buff *skb)
 	}
 }
 
-static inline
-void nf_bridge_save_header(struct sk_buff *skb)
-{
-        int header_size = 16;
-
-	if (skb->protocol == __constant_htons(ETH_P_8021Q))
-		header_size = 18;
-
-	memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
-}
-
 /* This is called by the IP fragmenting code and it ensures there is
  * enough room for the encapsulating header (if there is one). */
 static inline

+ 2 - 0
include/linux/netfilter_ipv4/ip_conntrack.h

@@ -29,6 +29,7 @@ union ip_conntrack_expect_proto {
 };
 
 /* Add protocol helper include file here */
+#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
 #include <linux/netfilter_ipv4/ip_conntrack_pptp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_amanda.h>
 #include <linux/netfilter_ipv4/ip_conntrack_ftp.h>
@@ -37,6 +38,7 @@ union ip_conntrack_expect_proto {
 /* per conntrack: application helper private data */
 union ip_conntrack_help {
 	/* insert conntrack helper private data (master) here */
+	struct ip_ct_h323_master ct_h323_info;
 	struct ip_ct_pptp_master ct_pptp_info;
 	struct ip_ct_ftp_master ct_ftp_info;
 	struct ip_ct_irc_master ct_irc_info;

+ 30 - 0
include/linux/netfilter_ipv4/ip_conntrack_h323.h

@@ -0,0 +1,30 @@
+#ifndef _IP_CONNTRACK_H323_H
+#define _IP_CONNTRACK_H323_H
+
+#ifdef __KERNEL__
+
+#define RAS_PORT 1719
+#define Q931_PORT 1720
+#define H323_RTP_CHANNEL_MAX 4	/* Audio, video, FAX and other */
+
+/* This structure exists only once per master */
+struct ip_ct_h323_master {
+
+	/* Original and NATed Q.931 or H.245 signal ports */
+	u_int16_t sig_port[IP_CT_DIR_MAX];
+
+	/* Original and NATed RTP ports */
+	u_int16_t rtp_port[H323_RTP_CHANNEL_MAX][IP_CT_DIR_MAX];
+
+	union {
+		/* RAS connection timeout */
+		u_int32_t timeout;
+
+		/* Next TPKT length (for separate TPKT header and data) */
+		u_int16_t tpkt_len[IP_CT_DIR_MAX];
+	};
+};
+
+#endif
+
+#endif

+ 1 - 1
include/linux/netfilter_ipv4/ip_nat.h

@@ -23,7 +23,7 @@ struct ip_nat_seq {
 	 * modification (if any) */
 	u_int32_t correction_pos;
 	/* sequence number offset before and after last modification */
-	int32_t offset_before, offset_after;
+	int16_t offset_before, offset_after;
 };
 
 /* Single range specification. */

+ 16 - 53
include/linux/netfilter_ipv4/ipt_policy.h

@@ -1,58 +1,21 @@
 #ifndef _IPT_POLICY_H
 #define _IPT_POLICY_H
 
-#define IPT_POLICY_MAX_ELEM	4
-
-enum ipt_policy_flags
-{
-	IPT_POLICY_MATCH_IN	= 0x1,
-	IPT_POLICY_MATCH_OUT	= 0x2,
-	IPT_POLICY_MATCH_NONE	= 0x4,
-	IPT_POLICY_MATCH_STRICT	= 0x8,
-};
-
-enum ipt_policy_modes
-{
-	IPT_POLICY_MODE_TRANSPORT,
-	IPT_POLICY_MODE_TUNNEL
-};
-
-struct ipt_policy_spec
-{
-	u_int8_t	saddr:1,
-			daddr:1,
-			proto:1,
-			mode:1,
-			spi:1,
-			reqid:1;
-};
-
-union ipt_policy_addr
-{
-	struct in_addr	a4;
-	struct in6_addr	a6;
-};
-
-struct ipt_policy_elem
-{
-	union ipt_policy_addr	saddr;
-	union ipt_policy_addr	smask;
-	union ipt_policy_addr	daddr;
-	union ipt_policy_addr	dmask;
-	u_int32_t		spi;
-	u_int32_t		reqid;
-	u_int8_t		proto;
-	u_int8_t		mode;
-
-	struct ipt_policy_spec	match;
-	struct ipt_policy_spec	invert;
-};
-
-struct ipt_policy_info
-{
-	struct ipt_policy_elem pol[IPT_POLICY_MAX_ELEM];
-	u_int16_t flags;
-	u_int16_t len;
-};
+#define IPT_POLICY_MAX_ELEM		XT_POLICY_MAX_ELEM
+
+/* ipt_policy_flags */
+#define IPT_POLICY_MATCH_IN		XT_POLICY_MATCH_IN
+#define IPT_POLICY_MATCH_OUT		XT_POLICY_MATCH_OUT
+#define IPT_POLICY_MATCH_NONE		XT_POLICY_MATCH_NONE
+#define IPT_POLICY_MATCH_STRICT		XT_POLICY_MATCH_STRICT
+
+/* ipt_policy_modes */
+#define IPT_POLICY_MODE_TRANSPORT	XT_POLICY_MODE_TRANSPORT
+#define IPT_POLICY_MODE_TUNNEL		XT_POLICY_MODE_TUNNEL
+
+#define ipt_policy_spec			xt_policy_spec
+#define ipt_policy_addr			xt_policy_addr
+#define ipt_policy_elem			xt_policy_elem
+#define ipt_policy_info			xt_policy_info
 
 #endif /* _IPT_POLICY_H */

+ 16 - 53
include/linux/netfilter_ipv6/ip6t_policy.h

@@ -1,58 +1,21 @@
 #ifndef _IP6T_POLICY_H
 #define _IP6T_POLICY_H
 
-#define IP6T_POLICY_MAX_ELEM	4
-
-enum ip6t_policy_flags
-{
-	IP6T_POLICY_MATCH_IN		= 0x1,
-	IP6T_POLICY_MATCH_OUT		= 0x2,
-	IP6T_POLICY_MATCH_NONE		= 0x4,
-	IP6T_POLICY_MATCH_STRICT	= 0x8,
-};
-
-enum ip6t_policy_modes
-{
-	IP6T_POLICY_MODE_TRANSPORT,
-	IP6T_POLICY_MODE_TUNNEL
-};
-
-struct ip6t_policy_spec
-{
-	u_int8_t	saddr:1,
-			daddr:1,
-			proto:1,
-			mode:1,
-			spi:1,
-			reqid:1;
-};
-
-union ip6t_policy_addr
-{
-	struct in_addr	a4;
-	struct in6_addr	a6;
-};
-
-struct ip6t_policy_elem
-{
-	union ip6t_policy_addr	saddr;
-	union ip6t_policy_addr	smask;
-	union ip6t_policy_addr	daddr;
-	union ip6t_policy_addr	dmask;
-	u_int32_t		spi;
-	u_int32_t		reqid;
-	u_int8_t		proto;
-	u_int8_t		mode;
-
-	struct ip6t_policy_spec	match;
-	struct ip6t_policy_spec	invert;
-};
-
-struct ip6t_policy_info
-{
-	struct ip6t_policy_elem pol[IP6T_POLICY_MAX_ELEM];
-	u_int16_t flags;
-	u_int16_t len;
-};
+#define IP6T_POLICY_MAX_ELEM		XT_POLICY_MAX_ELEM
+
+/* ip6t_policy_flags */
+#define IP6T_POLICY_MATCH_IN		XT_POLICY_MATCH_IN
+#define IP6T_POLICY_MATCH_OUT		XT_POLICY_MATCH_OUT
+#define IP6T_POLICY_MATCH_NONE		XT_POLICY_MATCH_NONE
+#define IP6T_POLICY_MATCH_STRICT	XT_POLICY_MATCH_STRICT
+
+/* ip6t_policy_modes */
+#define IP6T_POLICY_MODE_TRANSPORT	XT_POLICY_MODE_TRANSPORT
+#define IP6T_POLICY_MODE_TUNNEL		XT_POLICY_MODE_TUNNEL
+
+#define ip6t_policy_spec		xt_policy_spec
+#define ip6t_policy_addr		xt_policy_addr
+#define ip6t_policy_elem		xt_policy_elem
+#define ip6t_policy_info		xt_policy_info
 
 #endif /* _IP6T_POLICY_H */

+ 1 - 0
include/linux/netlink.h

@@ -151,6 +151,7 @@ struct netlink_skb_parms
 
 extern struct sock *netlink_kernel_create(int unit, unsigned int groups, void (*input)(struct sock *sk, int len), struct module *module);
 extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
+extern int netlink_has_listeners(struct sock *sk, unsigned int group);
 extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock);
 extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
 			     __u32 group, gfp_t allocation);

+ 6 - 0
include/linux/pci_ids.h

@@ -1857,16 +1857,22 @@
 #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
 #define PCI_DEVICE_ID_TIGON3_5714	0x1668
+#define PCI_DEVICE_ID_TIGON3_5714S	0x1669
 #define PCI_DEVICE_ID_TIGON3_5780	0x166a
 #define PCI_DEVICE_ID_TIGON3_5780S	0x166b
 #define PCI_DEVICE_ID_TIGON3_5705F	0x166e
+#define PCI_DEVICE_ID_TIGON3_5754M	0x1672
 #define PCI_DEVICE_ID_TIGON3_5750	0x1676
 #define PCI_DEVICE_ID_TIGON3_5751	0x1677
 #define PCI_DEVICE_ID_TIGON3_5715	0x1678
+#define PCI_DEVICE_ID_TIGON3_5715S	0x1679
+#define PCI_DEVICE_ID_TIGON3_5754	0x167a
 #define PCI_DEVICE_ID_TIGON3_5750M	0x167c
 #define PCI_DEVICE_ID_TIGON3_5751M	0x167d
 #define PCI_DEVICE_ID_TIGON3_5751F	0x167e
+#define PCI_DEVICE_ID_TIGON3_5787M	0x1693
 #define PCI_DEVICE_ID_TIGON3_5782	0x1696
+#define PCI_DEVICE_ID_TIGON3_5787	0x169b
 #define PCI_DEVICE_ID_TIGON3_5788	0x169c
 #define PCI_DEVICE_ID_TIGON3_5789	0x169d
 #define PCI_DEVICE_ID_TIGON3_5702X	0x16a6

+ 10 - 13
include/linux/rtnetlink.h

@@ -199,6 +199,7 @@ enum
 #define RTPROT_BIRD	12	/* BIRD */
 #define RTPROT_DNROUTED	13	/* DECnet routing daemon */
 #define RTPROT_XORP	14	/* XORP */
+#define RTPROT_NTK	15	/* Netsukuku */
 
 /* rtm_scope
 
@@ -733,6 +734,8 @@ enum
 #define IFLA_MAP IFLA_MAP
 	IFLA_WEIGHT,
 #define IFLA_WEIGHT IFLA_WEIGHT
+	IFLA_OPERSTATE,
+	IFLA_LINKMODE,
 	__IFLA_MAX
 };
 
@@ -905,6 +908,7 @@ struct tcamsg
 #ifdef __KERNEL__
 
 #include <linux/config.h>
+#include <linux/mutex.h>
 
 extern size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size);
 static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
@@ -1036,24 +1040,17 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
 
 extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
 
-extern struct semaphore rtnl_sem;
-
-#define rtnl_shlock()		down(&rtnl_sem)
-#define rtnl_shlock_nowait()	down_trylock(&rtnl_sem)
-
-#define rtnl_shunlock()	do { up(&rtnl_sem); \
-		             if (rtnl && rtnl->sk_receive_queue.qlen) \
-				     rtnl->sk_data_ready(rtnl, 0); \
-		        } while(0)
-
+/* RTNL is used as a global lock for all changes to network configuration  */
 extern void rtnl_lock(void);
-extern int rtnl_lock_interruptible(void);
 extern void rtnl_unlock(void);
+extern int rtnl_trylock(void);
+
 extern void rtnetlink_init(void);
+extern void __rtnl_unlock(void);
 
 #define ASSERT_RTNL() do { \
-	if (unlikely(down_trylock(&rtnl_sem) == 0)) { \
-		up(&rtnl_sem); \
+	if (unlikely(rtnl_trylock())) { \
+		rtnl_unlock(); \
 		printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
 		       __FILE__,  __LINE__); \
 		dump_stack(); \

+ 19 - 6
include/linux/security.h

@@ -1286,7 +1286,8 @@ struct security_operations {
 	int (*socket_setsockopt) (struct socket * sock, int level, int optname);
 	int (*socket_shutdown) (struct socket * sock, int how);
 	int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb);
-	int (*socket_getpeersec) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
+	int (*socket_getpeersec_stream) (struct socket *sock, char __user *optval, int __user *optlen, unsigned len);
+	int (*socket_getpeersec_dgram) (struct sk_buff *skb, char **secdata, u32 *seclen);
 	int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
 	void (*sk_free_security) (struct sock *sk);
 	unsigned int (*sk_getsid) (struct sock *sk, struct flowi *fl, u8 dir);
@@ -2741,10 +2742,16 @@ static inline int security_sock_rcv_skb (struct sock * sk,
 	return security_ops->socket_sock_rcv_skb (sk, skb);
 }
 
-static inline int security_socket_getpeersec(struct socket *sock, char __user *optval,
-					     int __user *optlen, unsigned len)
+static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+						    int __user *optlen, unsigned len)
 {
-	return security_ops->socket_getpeersec(sock, optval, optlen, len);
+	return security_ops->socket_getpeersec_stream(sock, optval, optlen, len);
+}
+
+static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
+						   u32 *seclen)
+{
+	return security_ops->socket_getpeersec_dgram(skb, secdata, seclen);
 }
 
 static inline int security_sk_alloc(struct sock *sk, int family, gfp_t priority)
@@ -2863,8 +2870,14 @@ static inline int security_sock_rcv_skb (struct sock * sk,
 	return 0;
 }
 
-static inline int security_socket_getpeersec(struct socket *sock, char __user *optval,
-					     int __user *optlen, unsigned len)
+static inline int security_socket_getpeersec_stream(struct socket *sock, char __user *optval,
+						    int __user *optlen, unsigned len)
+{
+	return -ENOPROTOOPT;
+}
+
+static inline int security_socket_getpeersec_dgram(struct sk_buff *skb, char **secdata,
+						   u32 *seclen)
 {
 	return -ENOPROTOOPT;
 }

+ 19 - 28
include/linux/skbuff.h

@@ -270,7 +270,6 @@ struct sk_buff {
 
 	void			(*destructor)(struct sk_buff *skb);
 #ifdef CONFIG_NETFILTER
-	__u32			nfmark;
 	struct nf_conntrack	*nfct;
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 	struct sk_buff		*nfct_reasm;
@@ -278,6 +277,7 @@ struct sk_buff {
 #ifdef CONFIG_BRIDGE_NETFILTER
 	struct nf_bridge_info	*nf_bridge;
 #endif
+	__u32			nfmark;
 #endif /* CONFIG_NETFILTER */
 #ifdef CONFIG_NET_SCHED
 	__u16			tc_index;	/* traffic control index */
@@ -304,6 +304,7 @@ struct sk_buff {
 
 #include <asm/system.h>
 
+extern void kfree_skb(struct sk_buff *skb);
 extern void	       __kfree_skb(struct sk_buff *skb);
 extern struct sk_buff *__alloc_skb(unsigned int size,
 				   gfp_t priority, int fclone);
@@ -403,22 +404,6 @@ static inline struct sk_buff *skb_get(struct sk_buff *skb)
  * atomic change.
  */
 
-/**
- *	kfree_skb - free an sk_buff
- *	@skb: buffer to free
- *
- *	Drop a reference to the buffer and free it if the usage count has
- *	hit zero.
- */
-static inline void kfree_skb(struct sk_buff *skb)
-{
-	if (likely(atomic_read(&skb->users) == 1))
-		smp_rmb();
-	else if (likely(!atomic_dec_and_test(&skb->users)))
-		return;
-	__kfree_skb(skb);
-}
-
 /**
  *	skb_cloned - is the buffer a clone
  *	@skb: buffer to check
@@ -1174,12 +1159,14 @@ static inline int skb_linearize(struct sk_buff *skb, gfp_t gfp)
  */
 
 static inline void skb_postpull_rcsum(struct sk_buff *skb,
-					 const void *start, int len)
+				      const void *start, unsigned int len)
 {
 	if (skb->ip_summed == CHECKSUM_HW)
 		skb->csum = csum_sub(skb->csum, csum_partial(start, len, 0));
 }
 
+unsigned char *skb_pull_rcsum(struct sk_buff *skb, unsigned int len);
+
 /**
  *	pskb_trim_rcsum - trim received skb and update checksum
  *	@skb: buffer to trim
@@ -1351,16 +1338,6 @@ static inline void nf_conntrack_put_reasm(struct sk_buff *skb)
 		kfree_skb(skb);
 }
 #endif
-static inline void nf_reset(struct sk_buff *skb)
-{
-	nf_conntrack_put(skb->nfct);
-	skb->nfct = NULL;
-#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
-	nf_conntrack_put_reasm(skb->nfct_reasm);
-	skb->nfct_reasm = NULL;
-#endif
-}
-
 #ifdef CONFIG_BRIDGE_NETFILTER
 static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge)
 {
@@ -1373,6 +1350,20 @@ static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge)
 		atomic_inc(&nf_bridge->use);
 }
 #endif /* CONFIG_BRIDGE_NETFILTER */
+static inline void nf_reset(struct sk_buff *skb)
+{
+	nf_conntrack_put(skb->nfct);
+	skb->nfct = NULL;
+#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
+	nf_conntrack_put_reasm(skb->nfct_reasm);
+	skb->nfct_reasm = NULL;
+#endif
+#ifdef CONFIG_BRIDGE_NETFILTER
+	nf_bridge_put(skb->nf_bridge);
+	skb->nf_bridge = NULL;
+#endif
+}
+
 #else /* CONFIG_NETFILTER */
 static inline void nf_reset(struct sk_buff *skb) {}
 #endif /* CONFIG_NETFILTER */

+ 1 - 0
include/linux/socket.h

@@ -150,6 +150,7 @@ __KINLINE struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__
 
 #define	SCM_RIGHTS	0x01		/* rw: access rights (array of int) */
 #define SCM_CREDENTIALS 0x02		/* rw: struct ucred		*/
+#define SCM_SECURITY	0x03		/* rw: security label		*/
 
 struct ucred {
 	__u32	pid;

+ 1 - 1
include/linux/sunrpc/svcsock.h

@@ -36,7 +36,7 @@ struct svc_sock {
 
 	struct list_head	sk_deferred;	/* deferred requests that need to
 						 * be revisted */
-	struct semaphore        sk_sem;		/* to serialize sending data */
+	struct mutex		sk_mutex;	/* to serialize sending data */
 
 	int			(*sk_recvfrom)(struct svc_rqst *rqstp);
 	int			(*sk_sendto)(struct svc_rqst *rqstp);

+ 27 - 0
include/linux/sysctl.h

@@ -211,6 +211,7 @@ enum
 	NET_SCTP=17,
 	NET_LLC=18,
 	NET_NETFILTER=19,
+	NET_DCCP=20,
 };
 
 /* /proc/sys/kernel/random */
@@ -261,6 +262,8 @@ enum
 	NET_CORE_DEV_WEIGHT=17,
 	NET_CORE_SOMAXCONN=18,
 	NET_CORE_BUDGET=19,
+	NET_CORE_AEVENT_ETIME=20,
+	NET_CORE_AEVENT_RSEQTH=21,
 };
 
 /* /proc/sys/net/ethernet */
@@ -397,6 +400,9 @@ enum
 	NET_TCP_CONG_CONTROL=110,
 	NET_TCP_ABC=111,
 	NET_IPV4_IPFRAG_MAX_DIST=112,
+ 	NET_TCP_MTU_PROBING=113,
+	NET_TCP_BASE_MSS=114,
+	NET_IPV4_TCP_WORKAROUND_SIGNED_WINDOWS=115,
 };
 
 enum {
@@ -451,6 +457,7 @@ enum
 	NET_IPV4_CONF_ARP_ANNOUNCE=18,
 	NET_IPV4_CONF_ARP_IGNORE=19,
 	NET_IPV4_CONF_PROMOTE_SECONDARIES=20,
+	NET_IPV4_CONF_ARP_ACCEPT=21,
 	__NET_IPV4_CONF_MAX
 };
 
@@ -531,6 +538,11 @@ enum {
 	NET_IPV6_MAX_DESYNC_FACTOR=15,
 	NET_IPV6_MAX_ADDRESSES=16,
 	NET_IPV6_FORCE_MLD_VERSION=17,
+	NET_IPV6_ACCEPT_RA_DEFRTR=18,
+	NET_IPV6_ACCEPT_RA_PINFO=19,
+	NET_IPV6_ACCEPT_RA_RTR_PREF=20,
+	NET_IPV6_RTR_PROBE_INTERVAL=21,
+	NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
 	__NET_IPV6_MAX
 };
 
@@ -562,6 +574,21 @@ enum {
 	__NET_NEIGH_MAX
 };
 
+/* /proc/sys/net/dccp */
+enum {
+	NET_DCCP_DEFAULT=1,
+};
+
+/* /proc/sys/net/dccp/default */
+enum {
+	NET_DCCP_DEFAULT_SEQ_WINDOW  = 1,
+	NET_DCCP_DEFAULT_RX_CCID     = 2,
+	NET_DCCP_DEFAULT_TX_CCID     = 3,
+	NET_DCCP_DEFAULT_ACK_RATIO   = 4,
+	NET_DCCP_DEFAULT_SEND_ACKVEC = 5,
+	NET_DCCP_DEFAULT_SEND_NDP    = 6,
+};
+
 /* /proc/sys/net/ipx */
 enum {
 	NET_IPX_PPROP_BROADCASTING=1,

+ 6 - 0
include/linux/tcp.h

@@ -343,6 +343,12 @@ struct tcp_sock {
 		__u32	seq;
 		__u32	time;
 	} rcvq_space;
+
+/* TCP-specific MTU probe information. */
+	struct {
+		__u32		  probe_seq_start;
+		__u32		  probe_seq_end;
+	} mtu_probe;
 };
 
 static inline struct tcp_sock *tcp_sk(const struct sock *sk)

+ 30 - 0
include/linux/xfrm.h

@@ -156,6 +156,10 @@ enum {
 	XFRM_MSG_FLUSHPOLICY,
 #define XFRM_MSG_FLUSHPOLICY XFRM_MSG_FLUSHPOLICY
 
+	XFRM_MSG_NEWAE,
+#define XFRM_MSG_NEWAE XFRM_MSG_NEWAE
+	XFRM_MSG_GETAE,
+#define XFRM_MSG_GETAE XFRM_MSG_GETAE
 	__XFRM_MSG_MAX
 };
 #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1)
@@ -194,6 +198,21 @@ struct xfrm_encap_tmpl {
 	xfrm_address_t	encap_oa;
 };
 
+/* AEVENT flags  */
+enum xfrm_ae_ftype_t {
+	XFRM_AE_UNSPEC,
+	XFRM_AE_RTHR=1,	/* replay threshold*/
+	XFRM_AE_RVAL=2, /* replay value */
+	XFRM_AE_LVAL=4, /* lifetime value */
+	XFRM_AE_ETHR=8, /* expiry timer threshold */
+	XFRM_AE_CR=16, /* Event cause is replay update */
+	XFRM_AE_CE=32, /* Event cause is timer expiry */
+	XFRM_AE_CU=64, /* Event cause is policy update */
+	__XFRM_AE_MAX
+
+#define XFRM_AE_MAX (__XFRM_AE_MAX - 1)
+};
+
 /* Netlink message attributes.  */
 enum xfrm_attr_type_t {
 	XFRMA_UNSPEC,
@@ -205,6 +224,10 @@ enum xfrm_attr_type_t {
 	XFRMA_SA,
 	XFRMA_POLICY,
 	XFRMA_SEC_CTX,		/* struct xfrm_sec_ctx */
+	XFRMA_LTIME_VAL,
+	XFRMA_REPLAY_VAL,
+	XFRMA_REPLAY_THRESH,
+	XFRMA_ETIMER_THRESH,
 	__XFRMA_MAX
 
 #define XFRMA_MAX (__XFRMA_MAX - 1)
@@ -235,6 +258,11 @@ struct xfrm_usersa_id {
 	__u8				proto;
 };
 
+struct xfrm_aevent_id {
+	struct xfrm_usersa_id		sa_id;
+	__u32				flags;
+};
+
 struct xfrm_userspi_info {
 	struct xfrm_usersa_info		info;
 	__u32				min;
@@ -306,6 +334,8 @@ enum xfrm_nlgroups {
 #define XFRMNLGRP_SA		XFRMNLGRP_SA
 	XFRMNLGRP_POLICY,
 #define XFRMNLGRP_POLICY	XFRMNLGRP_POLICY
+	XFRMNLGRP_AEVENTS,
+#define XFRMNLGRP_AEVENTS	XFRMNLGRP_AEVENTS
 	__XFRMNLGRP_MAX
 };
 #define XFRMNLGRP_MAX	(__XFRMNLGRP_MAX - 1)

+ 2 - 1
include/net/af_unix.h

@@ -4,6 +4,7 @@
 #include <linux/config.h>
 #include <linux/socket.h>
 #include <linux/un.h>
+#include <linux/mutex.h>
 #include <net/sock.h>
 
 extern void unix_inflight(struct file *fp);
@@ -71,7 +72,7 @@ struct unix_sock {
         struct unix_address     *addr;
         struct dentry		*dentry;
         struct vfsmount		*mnt;
-        struct semaphore        readsem;
+	struct mutex		readlock;
         struct sock		*peer;
         struct sock		*other;
         struct sock		*gc_tree;

+ 52 - 53
include/net/dn.h

@@ -6,10 +6,8 @@
 #include <net/tcp.h>
 #include <asm/byteorder.h>
 
-typedef unsigned short dn_address;
-
-#define dn_ntohs(x) le16_to_cpu((unsigned short)(x))
-#define dn_htons(x) cpu_to_le16((unsigned short)(x))
+#define dn_ntohs(x) le16_to_cpu(x)
+#define dn_htons(x) cpu_to_le16(x)
 
 struct dn_scp                                   /* Session Control Port */
 {
@@ -31,36 +29,36 @@ struct dn_scp                                   /* Session Control Port */
 #define DN_CL    15                     /* Closed               */
 #define DN_CN    16                     /* Closed Notification  */
 
-        unsigned short          addrloc;
-        unsigned short          addrrem;
-        unsigned short          numdat;
-        unsigned short          numoth;
-        unsigned short          numoth_rcv;
-        unsigned short          numdat_rcv;
-        unsigned short          ackxmt_dat;
-        unsigned short          ackxmt_oth;
-        unsigned short          ackrcv_dat;
-        unsigned short          ackrcv_oth;
-        unsigned char           flowrem_sw;
-	unsigned char		flowloc_sw;
+        __le16          addrloc;
+        __le16          addrrem;
+        __u16          numdat;
+        __u16          numoth;
+        __u16          numoth_rcv;
+        __u16          numdat_rcv;
+        __u16          ackxmt_dat;
+        __u16          ackxmt_oth;
+        __u16          ackrcv_dat;
+        __u16          ackrcv_oth;
+        __u8           flowrem_sw;
+	__u8           flowloc_sw;
 #define DN_SEND         2
 #define DN_DONTSEND     1
 #define DN_NOCHANGE     0
-	unsigned short		flowrem_dat;
-	unsigned short		flowrem_oth;
-	unsigned short		flowloc_dat;
-	unsigned short		flowloc_oth;
-	unsigned char		services_rem;
-	unsigned char		services_loc;
-	unsigned char		info_rem;
-	unsigned char		info_loc;
-
-	unsigned short		segsize_rem;
-	unsigned short		segsize_loc;
-
-	unsigned char		nonagle;
-	unsigned char		multi_ireq;
-	unsigned char		accept_mode;
+	__u16		flowrem_dat;
+	__u16		flowrem_oth;
+	__u16		flowloc_dat;
+	__u16		flowloc_oth;
+	__u8		services_rem;
+	__u8		services_loc;
+	__u8		info_rem;
+	__u8		info_loc;
+
+	__u16		segsize_rem;
+	__u16		segsize_loc;
+
+	__u8		nonagle;
+	__u8		multi_ireq;
+	__u8		accept_mode;
 	unsigned long		seg_total; /* Running total of current segment */
 
 	struct optdata_dn     conndata_in;
@@ -160,40 +158,41 @@ static inline struct dn_scp *DN_SK(struct sock *sk)
  */
 #define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb)
 struct dn_skb_cb {
-	unsigned short dst;
-	unsigned short src;
-	unsigned short hops;
-	unsigned short dst_port;
-	unsigned short src_port;
-	unsigned char services;
-	unsigned char info;
-	unsigned char rt_flags;
-	unsigned char nsp_flags;
-	unsigned short segsize;
-	unsigned short segnum;
-	unsigned short xmit_count;
+	__le16 dst;
+	__le16 src;
+	__u16 hops;
+	__le16 dst_port;
+	__le16 src_port;
+	__u8 services;
+	__u8 info;
+	__u8 rt_flags;
+	__u8 nsp_flags;
+	__u16 segsize;
+	__u16 segnum;
+	__u16 xmit_count;
 	unsigned long stamp;
 	int iif;
 };
 
-static inline dn_address dn_eth2dn(unsigned char *ethaddr)
+static inline __le16 dn_eth2dn(unsigned char *ethaddr)
 {
-	return ethaddr[4] | (ethaddr[5] << 8);
+	return dn_htons(ethaddr[4] | (ethaddr[5] << 8));
 }
 
-static inline dn_address dn_saddr2dn(struct sockaddr_dn *saddr)
+static inline __le16 dn_saddr2dn(struct sockaddr_dn *saddr)
 {
-	return *(dn_address *)saddr->sdn_nodeaddr;
+	return *(__le16 *)saddr->sdn_nodeaddr;
 }
 
-static inline void dn_dn2eth(unsigned char *ethaddr, dn_address addr)
+static inline void dn_dn2eth(unsigned char *ethaddr, __le16 addr)
 {
+	__u16 a = dn_ntohs(addr);
 	ethaddr[0] = 0xAA;
 	ethaddr[1] = 0x00;
 	ethaddr[2] = 0x04;
 	ethaddr[3] = 0x00;
-	ethaddr[4] = (unsigned char)(addr & 0xff);
-	ethaddr[5] = (unsigned char)(addr >> 8);
+	ethaddr[4] = (__u8)(a & 0xff);
+	ethaddr[5] = (__u8)(a >> 8);
 }
 
 static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp)
@@ -202,7 +201,7 @@ static inline void dn_sk_ports_copy(struct flowi *fl, struct dn_scp *scp)
 	fl->uli_u.dnports.dport = scp->addrrem;
 	fl->uli_u.dnports.objnum = scp->addr.sdn_objnum;
 	if (fl->uli_u.dnports.objnum == 0) {
-		fl->uli_u.dnports.objnamel = scp->addr.sdn_objnamel;
+		fl->uli_u.dnports.objnamel = (__u8)dn_ntohs(scp->addr.sdn_objnamel);
 		memcpy(fl->uli_u.dnports.objname, scp->addr.sdn_objname, 16);
 	}
 }
@@ -217,7 +216,7 @@ extern unsigned dn_mss_from_pmtu(struct net_device *dev, int mtu);
 extern struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr);
 extern struct sock *dn_find_by_skb(struct sk_buff *skb);
 #define DN_ASCBUF_LEN 9
-extern char *dn_addr2asc(dn_address, char *);
+extern char *dn_addr2asc(__u16, char *);
 extern int dn_destroy_timer(struct sock *sk);
 
 extern int dn_sockaddr2username(struct sockaddr_dn *addr, unsigned char *buf, unsigned char type);
@@ -226,7 +225,7 @@ extern int dn_username2sockaddr(unsigned char *data, int len, struct sockaddr_dn
 extern void dn_start_slow_timer(struct sock *sk);
 extern void dn_stop_slow_timer(struct sock *sk);
 
-extern dn_address decnet_address;
+extern __le16 decnet_address;
 extern int decnet_debug_level;
 extern int decnet_time_wait;
 extern int decnet_dn_count;

+ 44 - 44
include/net/dn_dev.h

@@ -7,11 +7,11 @@ struct dn_dev;
 struct dn_ifaddr {
 	struct dn_ifaddr *ifa_next;
 	struct dn_dev    *ifa_dev;
-	dn_address       ifa_local;
-	dn_address       ifa_address;
-	unsigned char    ifa_flags;
-	unsigned char    ifa_scope;
-	char             ifa_label[IFNAMSIZ];
+	__le16            ifa_local;
+	__le16            ifa_address;
+	__u8              ifa_flags;
+	__u8              ifa_scope;
+	char              ifa_label[IFNAMSIZ];
 };
 
 #define DN_DEV_S_RU  0 /* Run - working normally   */
@@ -91,7 +91,7 @@ struct dn_dev {
 	struct timer_list timer;
 	unsigned long t3;
 	struct neigh_parms *neigh_parms;
-	unsigned char addr[ETH_ALEN];
+	__u8 addr[ETH_ALEN];
 	struct neighbour *router; /* Default router on circuit */
 	struct neighbour *peer;   /* Peer on pointopoint links */
 	unsigned long uptime;     /* Time device went up in jiffies */
@@ -99,56 +99,56 @@ struct dn_dev {
 
 struct dn_short_packet
 {
-	unsigned char   msgflg;
-	unsigned short  dstnode;
-	unsigned short  srcnode;
-	unsigned char   forward;
+	__u8    msgflg;
+	__le16 dstnode;
+	__le16 srcnode;
+	__u8   forward;
 } __attribute__((packed));
 
 struct dn_long_packet
 {
-	unsigned char   msgflg;
-	unsigned char   d_area;
-	unsigned char   d_subarea;
-	unsigned char   d_id[6];
-	unsigned char   s_area;
-	unsigned char   s_subarea;
-	unsigned char   s_id[6];
-	unsigned char   nl2;
-	unsigned char   visit_ct;
-	unsigned char   s_class;
-	unsigned char   pt;
+	__u8   msgflg;
+	__u8   d_area;
+	__u8   d_subarea;
+	__u8   d_id[6];
+	__u8   s_area;
+	__u8   s_subarea;
+	__u8   s_id[6];
+	__u8   nl2;
+	__u8   visit_ct;
+	__u8   s_class;
+	__u8   pt;
 } __attribute__((packed));
 
 /*------------------------- DRP - Routing messages ---------------------*/
 
 struct endnode_hello_message
 {
-	unsigned char   msgflg;
-	unsigned char   tiver[3];
-	unsigned char   id[6];
-	unsigned char   iinfo;
-	unsigned short  blksize;
-	unsigned char   area;
-	unsigned char   seed[8];
-	unsigned char   neighbor[6];
-	unsigned short  timer;
-	unsigned char   mpd;
-	unsigned char   datalen;
-	unsigned char   data[2];
+	__u8   msgflg;
+	__u8   tiver[3];
+	__u8   id[6];
+	__u8   iinfo;
+	__le16 blksize;
+	__u8   area;
+	__u8   seed[8];
+	__u8   neighbor[6];
+	__le16 timer;
+	__u8   mpd;
+	__u8   datalen;
+	__u8   data[2];
 } __attribute__((packed));
 
 struct rtnode_hello_message
 {
-	unsigned char   msgflg;
-	unsigned char   tiver[3];
-	unsigned char   id[6];
-	unsigned char   iinfo;
-	unsigned short  blksize;
-	unsigned char   priority;
-	unsigned char   area;
-	unsigned short  timer;
-	unsigned char   mpd;
+	__u8   msgflg;
+	__u8   tiver[3];
+	__u8   id[6];
+	__u8   iinfo;
+	__le16  blksize;
+	__u8   priority;
+	__u8   area;
+	__le16  timer;
+	__u8   mpd;
 } __attribute__((packed));
 
 
@@ -169,12 +169,12 @@ extern void dn_dev_down(struct net_device *);
 
 extern int dn_dev_set_default(struct net_device *dev, int force);
 extern struct net_device *dn_dev_get_default(void);
-extern int dn_dev_bind_default(dn_address *addr);
+extern int dn_dev_bind_default(__le16 *addr);
 
 extern int register_dnaddr_notifier(struct notifier_block *nb);
 extern int unregister_dnaddr_notifier(struct notifier_block *nb);
 
-static inline int dn_dev_islocal(struct net_device *dev, dn_address addr)
+static inline int dn_dev_islocal(struct net_device *dev, __le16 addr)
 {
 	struct dn_dev *dn_db = dev->dn_ptr;
 	struct dn_ifaddr *ifa;

+ 11 - 11
include/net/dn_fib.h

@@ -37,7 +37,7 @@ struct dn_fib_nh {
 	int			nh_weight;
 	int			nh_power;
 	int			nh_oif;
-	u32			nh_gw;
+	__le16			nh_gw;
 };
 
 struct dn_fib_info {
@@ -48,7 +48,7 @@ struct dn_fib_info {
 	int			fib_dead;
 	unsigned		fib_flags;
 	int			fib_protocol;
-	dn_address		fib_prefsrc;
+	__le16			fib_prefsrc;
 	__u32			fib_priority;
 	__u32			fib_metrics[RTAX_MAX];
 #define dn_fib_mtu  fib_metrics[RTAX_MTU-1]
@@ -71,15 +71,15 @@ struct dn_fib_info {
 #define DN_FIB_RES_OIF(res)	(DN_FIB_RES_NH(res).nh_oif)
 
 typedef struct {
-	u16	datum;
+	__le16	datum;
 } dn_fib_key_t;
 
 typedef struct {
-	u16	datum;
+	__le16	datum;
 } dn_fib_hash_t;
 
 typedef struct {
-	u16	datum;
+	__u16	datum;
 } dn_fib_idx_t;
 
 struct dn_fib_node {
@@ -126,11 +126,11 @@ extern int dn_fib_semantic_match(int type, struct dn_fib_info *fi,
 			const struct flowi *fl,
 			struct dn_fib_res *res);
 extern void dn_fib_release_info(struct dn_fib_info *fi);
-extern u16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type);
+extern __le16 dn_fib_get_attr16(struct rtattr *attr, int attrlen, int type);
 extern void dn_fib_flush(void);
 extern void dn_fib_select_multipath(const struct flowi *fl,
 					struct dn_fib_res *res);
-extern int dn_fib_sync_down(dn_address local, struct net_device *dev, 
+extern int dn_fib_sync_down(__le16 local, struct net_device *dev,
 				int force);
 extern int dn_fib_sync_up(struct net_device *dev);
 
@@ -148,8 +148,8 @@ extern void dn_fib_table_cleanup(void);
 extern void dn_fib_rules_init(void);
 extern void dn_fib_rules_cleanup(void);
 extern void dn_fib_rule_put(struct dn_fib_rule *);
-extern __u16 dn_fib_rules_policy(__u16 saddr, struct dn_fib_res *res, unsigned *flags);
-extern unsigned dnet_addr_type(__u16 addr);
+extern __le16 dn_fib_rules_policy(__le16 saddr, struct dn_fib_res *res, unsigned *flags);
+extern unsigned dnet_addr_type(__le16 addr);
 extern int dn_fib_lookup(const struct flowi *fl, struct dn_fib_res *res);
 
 /*
@@ -194,10 +194,10 @@ extern struct dn_fib_table *dn_fib_tables[];
 
 #endif /* CONFIG_DECNET_ROUTER */
 
-static inline u16 dnet_make_mask(int n)
+static inline __le16 dnet_make_mask(int n)
 {
         if (n)
-                return htons(~((1<<(16-n))-1));
+                return dn_htons(~((1<<(16-n))-1));
         return 0;
 }
 

+ 2 - 2
include/net/dn_neigh.h

@@ -7,13 +7,13 @@
  */
 struct dn_neigh {
         struct neighbour n;
-	dn_address addr;
+	__le16 addr;
         unsigned long flags;
 #define DN_NDFLAG_R1    0x0001 /* Router L1      */
 #define DN_NDFLAG_R2    0x0002 /* Router L2      */
 #define DN_NDFLAG_P3    0x0004 /* Phase III Node */
         unsigned long blksize;
-	unsigned char priority;
+	__u8 priority;
 };
 
 extern void dn_neigh_init(void);

+ 36 - 36
include/net/dn_nsp.h

@@ -72,77 +72,77 @@ extern struct sk_buff *dn_alloc_send_skb(struct sock *sk, size_t *size, int nobl
 
 struct nsp_data_seg_msg
 {
-	unsigned char   msgflg;
-	unsigned short  dstaddr;
-	unsigned short  srcaddr;
+	__u8   msgflg;
+	__le16 dstaddr;
+	__le16 srcaddr;
 } __attribute__((packed));
 
 struct nsp_data_opt_msg
 {
-	unsigned short  acknum;
-	unsigned short  segnum;
-	unsigned short  lsflgs;
+	__le16 acknum;
+	__le16 segnum;
+	__le16 lsflgs;
 } __attribute__((packed));
 
 struct nsp_data_opt_msg1
 {
-	unsigned short  acknum;
-	unsigned short  segnum;
+	__le16 acknum;
+	__le16 segnum;
 } __attribute__((packed));
 
 
 /* Acknowledgment Message (data/other data)                             */
 struct nsp_data_ack_msg
 {
-	unsigned char   msgflg;
-	unsigned short  dstaddr;
-	unsigned short  srcaddr;
-	unsigned short  acknum;
+	__u8   msgflg;
+	__le16 dstaddr;
+	__le16 srcaddr;
+	__le16 acknum;
 } __attribute__((packed));
 
 /* Connect Acknowledgment Message */
 struct  nsp_conn_ack_msg
 {
-	unsigned char   msgflg;
-	unsigned short  dstaddr;
+	__u8 msgflg;
+	__le16 dstaddr;
 } __attribute__((packed));
 
 
 /* Connect Initiate/Retransmit Initiate/Connect Confirm */
 struct  nsp_conn_init_msg
 {
-	unsigned char   msgflg;
+	__u8   msgflg;
 #define NSP_CI      0x18            /* Connect Initiate     */
 #define NSP_RCI     0x68            /* Retrans. Conn Init   */
-	unsigned short  dstaddr;
-	unsigned short  srcaddr;
-	unsigned char   services;
+	__le16 dstaddr;
+	__le16 srcaddr;
+	__u8   services;
 #define NSP_FC_NONE   0x00            /* Flow Control None    */
 #define NSP_FC_SRC    0x04            /* Seg Req. Count       */
 #define NSP_FC_SCMC   0x08            /* Sess. Control Mess   */
 #define NSP_FC_MASK   0x0c            /* FC type mask         */
-	unsigned char   info;
-	unsigned short  segsize;
+	__u8   info;
+	__le16 segsize;
 } __attribute__((packed));
 
 /* Disconnect Initiate/Disconnect Confirm */
 struct  nsp_disconn_init_msg
 {
-	unsigned char   msgflg;
-	unsigned short  dstaddr;
-	unsigned short  srcaddr;
-	unsigned short  reason;
+	__u8   msgflg;
+	__le16 dstaddr;
+	__le16 srcaddr;
+	__le16 reason;
 } __attribute__((packed));
 
 
 
 struct  srcobj_fmt
 {
-	char            format;
-	unsigned char   task;
-	unsigned short  grpcode;
-	unsigned short  usrcode;
-	char            dlen;
+	__u8   format;
+	__u8   task;
+	__le16 grpcode;
+	__le16 usrcode;
+	__u8   dlen;
 } __attribute__((packed));
 
 /*
@@ -150,7 +150,7 @@ struct  srcobj_fmt
  * numbers used in NSP. Similar in operation to the functions
  * of the same name in TCP.
  */
-static __inline__ int dn_before(unsigned short seq1, unsigned short seq2)
+static __inline__ int dn_before(__u16 seq1, __u16 seq2)
 {
         seq1 &= 0x0fff;
         seq2 &= 0x0fff;
@@ -159,7 +159,7 @@ static __inline__ int dn_before(unsigned short seq1, unsigned short seq2)
 }
 
 
-static __inline__ int dn_after(unsigned short seq1, unsigned short seq2)
+static __inline__ int dn_after(__u16 seq1, __u16 seq2)
 {
         seq1 &= 0x0fff;
         seq2 &= 0x0fff;
@@ -167,23 +167,23 @@ static __inline__ int dn_after(unsigned short seq1, unsigned short seq2)
         return (int)((seq2 - seq1) & 0x0fff) > 2048;
 }
 
-static __inline__ int dn_equal(unsigned short seq1, unsigned short seq2)
+static __inline__ int dn_equal(__u16 seq1, __u16 seq2)
 {
         return ((seq1 ^ seq2) & 0x0fff) == 0;
 }
 
-static __inline__ int dn_before_or_equal(unsigned short seq1, unsigned short seq2)
+static __inline__ int dn_before_or_equal(__u16 seq1, __u16 seq2)
 {
 	return (dn_before(seq1, seq2) || dn_equal(seq1, seq2));
 }
 
-static __inline__ void seq_add(unsigned short *seq, unsigned short off)
+static __inline__ void seq_add(__u16 *seq, __u16 off)
 {
         (*seq) += off;
         (*seq) &= 0x0fff;
 }
 
-static __inline__ int seq_next(unsigned short seq1, unsigned short seq2)
+static __inline__ int seq_next(__u16 seq1, __u16 seq2)
 {
 	return dn_equal(seq1 + 1, seq2);
 }
@@ -191,7 +191,7 @@ static __inline__ int seq_next(unsigned short seq1, unsigned short seq2)
 /*
  * Can we delay the ack ?
  */
-static __inline__ int sendack(unsigned short seq)
+static __inline__ int sendack(__u16 seq)
 {
         return (int)((seq & 0x1000) ? 0 : 1);
 }

+ 6 - 6
include/net/dn_route.h

@@ -71,12 +71,12 @@ struct dn_route {
 		struct dn_route *rt_next;
 	} u;
 
-	__u16 rt_saddr;
-	__u16 rt_daddr;
-	__u16 rt_gateway;
-	__u16 rt_local_src;	/* Source used for forwarding packets */
-	__u16 rt_src_map;
-	__u16 rt_dst_map;
+	__le16 rt_saddr;
+	__le16 rt_daddr;
+	__le16 rt_gateway;
+	__le16 rt_local_src;	/* Source used for forwarding packets */
+	__le16 rt_src_map;
+	__le16 rt_dst_map;
 
 	unsigned rt_flags;
 	unsigned rt_type;

+ 4 - 4
include/net/flow.h

@@ -30,8 +30,8 @@ struct flowi {
 		} ip6_u;
 
 		struct {
-			__u16			daddr;
-			__u16			saddr;
+			__le16			daddr;
+			__le16			saddr;
 			__u32			fwmark;
 			__u8			scope;
 		} dn_u;
@@ -64,8 +64,8 @@ struct flowi {
 		} icmpt;
 
 		struct {
-			__u16	sport;
-			__u16	dport;
+			__le16	sport;
+			__le16	dport;
 			__u8	objnum;
 			__u8	objnamel; /* Not 16 bits since max val is 16 */
 			__u8	objname[16]; /* Not zero terminated */

+ 0 - 3
include/net/if_inet6.h

@@ -180,11 +180,8 @@ struct inet6_dev
 
 #ifdef CONFIG_IPV6_PRIVACY
 	u8			rndid[8];
-	u8			entropy[8];
 	struct timer_list	regen_timer;
 	struct inet6_ifaddr	*tempaddr_list;
-	__u8			work_eui64[8];
-	__u8			work_digest[16];
 #endif
 
 	struct neigh_parms	*nd_parms;

+ 26 - 0
include/net/inet_connection_sock.h

@@ -50,6 +50,12 @@ struct inet_connection_sock_af_ops {
 				  char __user *optval, int optlen);
 	int	    (*getsockopt)(struct sock *sk, int level, int optname, 
 				  char __user *optval, int __user *optlen);
+	int	    (*compat_setsockopt)(struct sock *sk,
+				int level, int optname,
+				char __user *optval, int optlen);
+	int	    (*compat_getsockopt)(struct sock *sk,
+				int level, int optname,
+				char __user *optval, int __user *optlen);
 	void	    (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
 	int sockaddr_len;
 };
@@ -72,6 +78,7 @@ struct inet_connection_sock_af_ops {
  * @icsk_probes_out:	   unanswered 0 window probes
  * @icsk_ext_hdr_len:	   Network protocol overhead (IP/IPv6 options)
  * @icsk_ack:		   Delayed ACK control data
+ * @icsk_mtup;		   MTU probing control data
  */
 struct inet_connection_sock {
 	/* inet_sock has to be the first member! */
@@ -104,6 +111,16 @@ struct inet_connection_sock {
 		__u16		  last_seg_size; /* Size of last incoming segment	   */
 		__u16		  rcv_mss;	 /* MSS used for delayed ACK decisions	   */ 
 	} icsk_ack;
+	struct {
+		int		  enabled;
+
+		/* Range of MTUs to search */
+		int		  search_high;
+		int		  search_low;
+
+		/* Information on the current probe. */
+		int		  probe_size;
+	} icsk_mtup;
 	u32			  icsk_ca_priv[16];
 #define ICSK_CA_PRIV_SIZE	(16 * sizeof(u32))
 };
@@ -310,4 +327,13 @@ extern void inet_csk_listen_stop(struct sock *sk);
 
 extern void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr);
 
+extern int inet_csk_ctl_sock_create(struct socket **sock,
+				    unsigned short family,
+				    unsigned short type,
+				    unsigned char protocol);
+
+extern int inet_csk_compat_getsockopt(struct sock *sk, int level, int optname,
+				      char __user *optval, int __user *optlen);
+extern int inet_csk_compat_setsockopt(struct sock *sk, int level, int optname,
+				      char __user *optval, int optlen);
 #endif /* _INET_CONNECTION_SOCK_H */

+ 4 - 0
include/net/ip.h

@@ -356,6 +356,10 @@ extern void	ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb);
 extern int	ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc);
 extern int	ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval, int optlen);
 extern int	ip_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen);
+extern int	compat_ip_setsockopt(struct sock *sk, int level,
+			int optname, char __user *optval, int optlen);
+extern int	compat_ip_getsockopt(struct sock *sk, int level,
+			int optname, char __user *optval, int __user *optlen);
 extern int	ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *));
 
 extern int 	ip_recv_error(struct sock *sk, struct msghdr *msg, int len);

+ 22 - 2
include/net/ip6_route.h

@@ -7,6 +7,23 @@
 #define IP6_RT_PRIO_KERN	512
 #define IP6_RT_FLOW_MASK	0x00ff
 
+struct route_info {
+	__u8			type;
+	__u8			length;
+	__u8			prefix_len;
+#if defined(__BIG_ENDIAN_BITFIELD)
+	__u8			reserved_h:3,
+				route_pref:2,
+				reserved_l:3;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+	__u8			reserved_l:3,
+				route_pref:2,
+				reserved_h:3;
+#endif
+	__u32			lifetime;
+	__u8			prefix[0];	/* 0,8 or 16 */
+};
+
 #ifdef __KERNEL__
 
 #include <net/flow.h>
@@ -87,11 +104,14 @@ extern struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
 extern struct rt6_info *	rt6_get_dflt_router(struct in6_addr *addr,
 						    struct net_device *dev);
 extern struct rt6_info *	rt6_add_dflt_router(struct in6_addr *gwaddr,
-						    struct net_device *dev);
+						    struct net_device *dev,
+						    unsigned int pref);
 
 extern void			rt6_purge_dflt_routers(void);
 
-extern void			rt6_reset_dflt_pointer(struct rt6_info *rt);
+extern int			rt6_route_rcv(struct net_device *dev,
+					      u8 *opt, int len,
+					      struct in6_addr *gwaddr);
 
 extern void			rt6_redirect(struct in6_addr *dest,
 					     struct in6_addr *saddr,

+ 22 - 0
include/net/ipv6.h

@@ -282,6 +282,18 @@ static inline int ipv6_addr_cmp(const struct in6_addr *a1, const struct in6_addr
 	return memcmp((const void *) a1, (const void *) a2, sizeof(struct in6_addr));
 }
 
+static inline int
+ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
+		     const struct in6_addr *a2)
+{
+	unsigned int i;
+
+	for (i = 0; i < 4; i++)
+		if ((a1->s6_addr32[i] ^ a2->s6_addr32[i]) & m->s6_addr32[i])
+			return 1;
+	return 0;
+}
+
 static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
 {
 	memcpy((void *) a1, (const void *) a2, sizeof(struct in6_addr));
@@ -508,6 +520,16 @@ extern int			ipv6_getsockopt(struct sock *sk, int level,
 						int optname,
 						char __user *optval, 
 						int __user *optlen);
+extern int			compat_ipv6_setsockopt(struct sock *sk,
+						int level,
+						int optname,
+						char __user *optval,
+						int optlen);
+extern int			compat_ipv6_getsockopt(struct sock *sk,
+						int level,
+						int optname,
+						char __user *optval,
+						int __user *optlen);
 
 extern void			ipv6_packet_init(void);
 

+ 1 - 1
include/net/llc.h

@@ -71,7 +71,7 @@ extern int llc_rcv(struct sk_buff *skb, struct net_device *dev,
 		   struct packet_type *pt, struct net_device *orig_dev);
 
 extern int llc_mac_hdr_init(struct sk_buff *skb,
-			    unsigned char *sa, unsigned char *da);
+			    const unsigned char *sa, const unsigned char *da);
 
 extern void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
 						   struct sk_buff *skb));

+ 2 - 0
include/net/ndisc.h

@@ -22,6 +22,8 @@ enum {
 	ND_OPT_PREFIX_INFO = 3,		/* RFC2461 */
 	ND_OPT_REDIRECT_HDR = 4,	/* RFC2461 */
 	ND_OPT_MTU = 5,			/* RFC2461 */
+	__ND_OPT_ARRAY_MAX,
+	ND_OPT_ROUTE_INFO = 24,		/* RFC4191 */
 	__ND_OPT_MAX
 };
 

+ 1 - 1
include/net/neighbour.h

@@ -68,6 +68,7 @@ struct neigh_parms
 	struct net_device *dev;
 	struct neigh_parms *next;
 	int	(*neigh_setup)(struct neighbour *);
+	void	(*neigh_destructor)(struct neighbour *);
 	struct neigh_table *tbl;
 
 	void	*sysctl_table;
@@ -145,7 +146,6 @@ struct neighbour
 struct neigh_ops
 {
 	int			family;
-	void			(*destructor)(struct neighbour *);
 	void			(*solicit)(struct neighbour *, struct sk_buff*);
 	void			(*error_report)(struct neighbour *, struct sk_buff*);
 	int			(*output)(struct sk_buff*);

+ 34 - 22
include/net/netfilter/nf_conntrack.h

@@ -67,6 +67,18 @@ do {									\
 
 struct nf_conntrack_helper;
 
+/* nf_conn feature for connections that have a helper */
+struct nf_conn_help {
+	/* Helper. if any */
+	struct nf_conntrack_helper *helper;
+
+	union nf_conntrack_help help;
+
+	/* Current number of expected connections */
+	unsigned int expecting;
+};
+
+
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 struct nf_conn
 {
@@ -81,6 +93,9 @@ struct nf_conn
 	/* Have we seen traffic both ways yet? (bitset) */
 	unsigned long status;
 
+	/* If we were expected by an expectation, this will be it */
+	struct nf_conn *master;
+
 	/* Timer function; drops refcnt when it goes off. */
 	struct timer_list timeout;
 
@@ -88,38 +103,22 @@ struct nf_conn
 	/* Accounting Information (same cache line as other written members) */
 	struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
 #endif
-	/* If we were expected by an expectation, this will be it */
-	struct nf_conn *master;
-	
-	/* Current number of expected connections */
-	unsigned int expecting;
 
 	/* Unique ID that identifies this conntrack*/
 	unsigned int id;
 
-	/* Helper. if any */
-	struct nf_conntrack_helper *helper;
-
 	/* features - nat, helper, ... used by allocating system */
 	u_int32_t features;
 
-	/* Storage reserved for other modules: */
-
-	union nf_conntrack_proto proto;
-
 #if defined(CONFIG_NF_CONNTRACK_MARK)
 	u_int32_t mark;
 #endif
 
-	/* These members are dynamically allocated. */
-
-	union nf_conntrack_help *help;
+	/* Storage reserved for other modules: */
+	union nf_conntrack_proto proto;
 
-	/* Layer 3 dependent members. (ex: NAT) */
-	union {
-		struct nf_conntrack_ipv4 *ipv4;
-	} l3proto;
-	void *data[0];
+	/* features dynamically at the end: helper, nat (both optional) */
+	char data[0];
 };
 
 struct nf_conntrack_expect
@@ -373,10 +372,23 @@ nf_conntrack_expect_event(enum ip_conntrack_expect_events event,
 #define NF_CT_F_NUM	4
 
 extern int
-nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size,
-			    int (*init_conntrack)(struct nf_conn *, u_int32_t));
+nf_conntrack_register_cache(u_int32_t features, const char *name, size_t size);
 extern void
 nf_conntrack_unregister_cache(u_int32_t features);
 
+/* valid combinations:
+ * basic: nf_conn, nf_conn .. nf_conn_help
+ * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help
+ */
+static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
+{
+	unsigned int offset = sizeof(struct nf_conn);
+
+	if (!(ct->features & NF_CT_F_HELP))
+		return NULL;
+
+	return (struct nf_conn_help *) ((void *)ct + offset);
+}
+
 #endif /* __KERNEL__ */
 #endif /* _NF_CONNTRACK_H */

+ 6 - 4
include/net/scm.h

@@ -37,10 +37,12 @@ static __inline__ void scm_destroy(struct scm_cookie *scm)
 static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
 			       struct scm_cookie *scm)
 {
-	memset(scm, 0, sizeof(*scm));
-	scm->creds.uid = current->uid;
-	scm->creds.gid = current->gid;
-	scm->creds.pid = current->tgid;
+	struct task_struct *p = current;
+	scm->creds.uid = p->uid;
+	scm->creds.gid = p->gid;
+	scm->creds.pid = p->tgid;
+	scm->fp = NULL;
+	scm->seq = 0;
 	if (msg->msg_controllen <= 0)
 		return 0;
 	return __scm_send(sock, msg, scm);

+ 10 - 0
include/net/sctp/structs.h

@@ -514,6 +514,16 @@ struct sctp_af {
 					 int optname,
 					 char __user *optval,
 					 int __user *optlen);
+	int		(*compat_setsockopt)	(struct sock *sk,
+					 int level,
+					 int optname,
+					 char __user *optval,
+					 int optlen);
+	int		(*compat_getsockopt)	(struct sock *sk,
+					 int level,
+					 int optname,
+					 char __user *optval,
+					 int __user *optlen);
 	struct dst_entry *(*get_dst)	(struct sctp_association *asoc,
 					 union sctp_addr *daddr,
 					 union sctp_addr *saddr);

+ 12 - 0
include/net/sock.h

@@ -520,6 +520,14 @@ struct proto {
 	int			(*getsockopt)(struct sock *sk, int level, 
 					int optname, char __user *optval, 
 					int __user *option);  	 
+	int			(*compat_setsockopt)(struct sock *sk,
+					int level,
+					int optname, char __user *optval,
+					int optlen);
+	int			(*compat_getsockopt)(struct sock *sk,
+					int level,
+					int optname, char __user *optval,
+					int __user *option);
 	int			(*sendmsg)(struct kiocb *iocb, struct sock *sk,
 					   struct msghdr *msg, size_t len);
 	int			(*recvmsg)(struct kiocb *iocb, struct sock *sk,
@@ -816,6 +824,10 @@ extern int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
 			       struct msghdr *msg, size_t size, int flags);
 extern int sock_common_setsockopt(struct socket *sock, int level, int optname,
 				  char __user *optval, int optlen);
+extern int compat_sock_common_getsockopt(struct socket *sock, int level,
+		int optname, char __user *optval, int __user *optlen);
+extern int compat_sock_common_setsockopt(struct socket *sock, int level,
+		int optname, char __user *optval, int optlen);
 
 extern void sk_common_release(struct sock *sk);
 

+ 16 - 0
include/net/tcp.h

@@ -60,6 +60,9 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);
 /* Minimal RCV_MSS. */
 #define TCP_MIN_RCVMSS		536U
 
+/* The least MTU to use for probing */
+#define TCP_BASE_MSS		512
+
 /* After receiving this amount of duplicate ACKs fast retransmit starts. */
 #define TCP_FASTRETRANS_THRESH 3
 
@@ -219,6 +222,9 @@ extern int sysctl_tcp_nometrics_save;
 extern int sysctl_tcp_moderate_rcvbuf;
 extern int sysctl_tcp_tso_win_divisor;
 extern int sysctl_tcp_abc;
+extern int sysctl_tcp_mtu_probing;
+extern int sysctl_tcp_base_mss;
+extern int sysctl_tcp_workaround_signed_windows;
 
 extern atomic_t tcp_memory_allocated;
 extern atomic_t tcp_sockets_allocated;
@@ -347,6 +353,12 @@ extern int			tcp_getsockopt(struct sock *sk, int level,
 extern int			tcp_setsockopt(struct sock *sk, int level, 
 					       int optname, char __user *optval, 
 					       int optlen);
+extern int			compat_tcp_getsockopt(struct sock *sk,
+					int level, int optname,
+					char __user *optval, int __user *optlen);
+extern int			compat_tcp_setsockopt(struct sock *sk,
+					int level, int optname,
+					char __user *optval, int optlen);
 extern void			tcp_set_keepalive(struct sock *sk, int val);
 extern int			tcp_recvmsg(struct kiocb *iocb, struct sock *sk,
 					    struct msghdr *msg,
@@ -447,6 +459,10 @@ extern int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 
 extern void tcp_initialize_rcv_mss(struct sock *sk);
 
+extern int tcp_mtu_to_mss(struct sock *sk, int pmtu);
+extern int tcp_mss_to_mtu(struct sock *sk, int mss);
+extern void tcp_mtup_init(struct sock *sk);
+
 static inline void __tcp_fast_path_on(struct tcp_sock *tp, u32 snd_wnd)
 {
 	tp->pred_flags = htonl((tp->tcp_header_len << 26) |

+ 58 - 4
include/net/xfrm.h

@@ -11,6 +11,7 @@
 #include <linux/crypto.h>
 #include <linux/pfkeyv2.h>
 #include <linux/in6.h>
+#include <linux/mutex.h>
 
 #include <net/sock.h>
 #include <net/dst.h>
@@ -20,7 +21,11 @@
 
 #define XFRM_ALIGN8(len)	(((len) + 7) & ~7)
 
-extern struct semaphore xfrm_cfg_sem;
+extern struct sock *xfrm_nl;
+extern u32 sysctl_xfrm_aevent_etime;
+extern u32 sysctl_xfrm_aevent_rseqth;
+
+extern struct mutex xfrm_cfg_mutex;
 
 /* Organization of SPD aka "XFRM rules"
    ------------------------------------
@@ -135,6 +140,16 @@ struct xfrm_state
 	/* State for replay detection */
 	struct xfrm_replay_state replay;
 
+	/* Replay detection state at the time we sent the last notification */
+	struct xfrm_replay_state preplay;
+
+	/* Replay detection notification settings */
+	u32			replay_maxage;
+	u32			replay_maxdiff;
+
+	/* Replay detection notification timer */
+	struct timer_list	rtimer;
+
 	/* Statistics */
 	struct xfrm_stats	stats;
 
@@ -169,6 +184,7 @@ struct km_event
 		u32 hard;
 		u32 proto;
 		u32 byid;
+		u32 aevent;
 	} data;
 
 	u32	seq;
@@ -199,10 +215,13 @@ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
 extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c);
 extern void km_state_notify(struct xfrm_state *x, struct km_event *c);
-
 #define XFRM_ACQ_EXPIRES	30
 
 struct xfrm_tmpl;
+extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol);
+extern void km_state_expired(struct xfrm_state *x, int hard, u32 pid);
+extern int __xfrm_state_delete(struct xfrm_state *x);
+
 struct xfrm_state_afinfo {
 	unsigned short		family;
 	rwlock_t		lock;
@@ -305,7 +324,21 @@ struct xfrm_policy
 	struct xfrm_tmpl       	xfrm_vec[XFRM_MAX_DEPTH];
 };
 
-#define XFRM_KM_TIMEOUT		30
+#define XFRM_KM_TIMEOUT                30
+/* which seqno */
+#define XFRM_REPLAY_SEQ		1
+#define XFRM_REPLAY_OSEQ	2
+#define XFRM_REPLAY_SEQ_MASK	3
+/* what happened */
+#define XFRM_REPLAY_UPDATE	XFRM_AE_CR
+#define XFRM_REPLAY_TIMEOUT	XFRM_AE_CE
+
+/* default aevent timeout in units of 100ms */
+#define XFRM_AE_ETIME			10
+/* Async Event timer multiplier */
+#define XFRM_AE_ETH_M			10
+/* default seq threshold size */
+#define XFRM_AE_SEQT_SIZE		2
 
 struct xfrm_mgr
 {
@@ -865,6 +898,7 @@ extern int xfrm_state_delete(struct xfrm_state *x);
 extern void xfrm_state_flush(u8 proto);
 extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);
 extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);
+extern void xfrm_replay_notify(struct xfrm_state *x, int event);
 extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);
 extern int xfrm_init_state(struct xfrm_state *x);
@@ -924,7 +958,7 @@ extern void xfrm_init_pmtu(struct dst_entry *dst);
 
 extern wait_queue_head_t km_waitq;
 extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);
-extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard);
+extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid);
 
 extern void xfrm_input_init(void);
 extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);
@@ -965,4 +999,24 @@ static inline int xfrm_policy_id2dir(u32 index)
 	return index & 7;
 }
 
+static inline int xfrm_aevent_is_on(void)
+{
+	struct sock *nlsk;
+	int ret = 0;
+
+	rcu_read_lock();
+	nlsk = rcu_dereference(xfrm_nl);
+	if (nlsk)
+		ret = netlink_has_listeners(nlsk, XFRMNLGRP_AEVENTS);
+	rcu_read_unlock();
+	return ret;
+}
+
+static inline void xfrm_aevent_doreplay(struct xfrm_state *x)
+{
+	if (xfrm_aevent_is_on())
+		xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
+}
+
+
 #endif	/* _NET_XFRM_H */

+ 1 - 3
net/802/psnap.c

@@ -59,10 +59,8 @@ static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
 	proto = find_snap_client(skb->h.raw);
 	if (proto) {
 		/* Pass the frame on. */
-		u8 *hdr = skb->data;
 		skb->h.raw  += 5;
-		skb_pull(skb, 5);
-		skb_postpull_rcsum(skb, hdr, 5);
+		skb_pull_rcsum(skb, 5);
 		rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
 	} else {
 		skb->sk = NULL;

+ 27 - 16
net/8021q/vlan.c

@@ -69,7 +69,7 @@ static struct packet_type vlan_packet_type = {
 
 /* Bits of netdev state that are propagated from real device to virtual */
 #define VLAN_LINK_STATE_MASK \
-	((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER))
+	((1<<__LINK_STATE_PRESENT)|(1<<__LINK_STATE_NOCARRIER)|(1<<__LINK_STATE_DORMANT))
 
 /* End of global variables definitions. */
 
@@ -344,6 +344,26 @@ static void vlan_setup(struct net_device *new_dev)
 	new_dev->do_ioctl = vlan_dev_ioctl;
 }
 
+static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
+{
+	/* Have to respect userspace enforced dormant state
+	 * of real device, also must allow supplicant running
+	 * on VLAN device
+	 */
+	if (dev->operstate == IF_OPER_DORMANT)
+		netif_dormant_on(vlandev);
+	else
+		netif_dormant_off(vlandev);
+
+	if (netif_carrier_ok(dev)) {
+		if (!netif_carrier_ok(vlandev))
+			netif_carrier_on(vlandev);
+	} else {
+		if (netif_carrier_ok(vlandev))
+			netif_carrier_off(vlandev);
+	}
+}
+
 /*  Attach a VLAN device to a mac address (ie Ethernet Card).
  *  Returns the device that was created, or NULL if there was
  *  an error of some kind.
@@ -450,7 +470,7 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
 	new_dev->flags = real_dev->flags;
 	new_dev->flags &= ~IFF_UP;
 
-	new_dev->state = real_dev->state & VLAN_LINK_STATE_MASK;
+	new_dev->state = real_dev->state & ~(1<<__LINK_STATE_START);
 
 	/* need 4 bytes for extra VLAN header info,
 	 * hope the underlying device can handle it.
@@ -498,6 +518,10 @@ static struct net_device *register_vlan_device(const char *eth_IF_name,
 	if (register_netdevice(new_dev))
 		goto out_free_newdev;
 
+	new_dev->iflink = real_dev->ifindex;
+	vlan_transfer_operstate(real_dev, new_dev);
+	linkwatch_fire_event(new_dev); /* _MUST_ call rfc2863_policy() */
+
 	/* So, got the sucker initialized, now lets place
 	 * it into our local structure.
 	 */
@@ -573,25 +597,12 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
 	switch (event) {
 	case NETDEV_CHANGE:
 		/* Propagate real device state to vlan devices */
-		flgs = dev->state & VLAN_LINK_STATE_MASK;
 		for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
 			vlandev = grp->vlan_devices[i];
 			if (!vlandev)
 				continue;
 
-			if (netif_carrier_ok(dev)) {
-				if (!netif_carrier_ok(vlandev))
-					netif_carrier_on(vlandev);
-			} else {
-				if (netif_carrier_ok(vlandev))
-					netif_carrier_off(vlandev);
-			}
-
-			if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) {
-				vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) 
-					| flgs;
-				netdev_state_change(vlandev);
-			}
+			vlan_transfer_operstate(dev, vlandev);
 		}
 		break;
 

+ 2 - 4
net/8021q/vlan_dev.c

@@ -163,10 +163,8 @@ int vlan_skb_recv(struct sk_buff *skb, struct net_device *dev,
 	stats->rx_packets++;
 	stats->rx_bytes += skb->len;
 
-	skb_pull(skb, VLAN_HLEN); /* take off the VLAN header (4 bytes currently) */
-
-	/* Need to correct hardware checksum */
-	skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+	/* Take off the VLAN header (4 bytes currently) */
+	skb_pull_rcsum(skb, VLAN_HLEN);
 
 	/* Ok, lets check to make sure the device (dev) we
 	 * came in on is what this VLAN is attached to.

+ 1 - 1
net/atm/clip.c

@@ -289,7 +289,6 @@ static void clip_neigh_error(struct neighbour *neigh,struct sk_buff *skb)
 
 static struct neigh_ops clip_neigh_ops = {
 	.family =		AF_INET,
-	.destructor =		clip_neigh_destroy,
 	.solicit =		clip_neigh_solicit,
 	.error_report =		clip_neigh_error,
 	.output =		dev_queue_xmit,
@@ -347,6 +346,7 @@ static struct neigh_table clip_tbl = {
 	/* parameters are copied from ARP ... */
 	.parms = {
 		.tbl 			= &clip_tbl,
+		.neigh_destructor	= clip_neigh_destroy,
 		.base_reachable_time 	= 30 * HZ,
 		.retrans_time 		= 1 * HZ,
 		.gc_staletime 		= 60 * HZ,

+ 2 - 2
net/atm/common.c

@@ -451,12 +451,12 @@ int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
 		dev = try_then_request_module(atm_dev_lookup(itf), "atm-device-%d", itf);
 	} else {
 		dev = NULL;
-		down(&atm_dev_mutex);
+		mutex_lock(&atm_dev_mutex);
 		if (!list_empty(&atm_devs)) {
 			dev = list_entry(atm_devs.next, struct atm_dev, dev_list);
 			atm_dev_hold(dev);
 		}
-		up(&atm_dev_mutex);
+		mutex_unlock(&atm_dev_mutex);
 	}
 	if (!dev)
 		return -ENODEV;

+ 8 - 7
net/atm/ioctl.c

@@ -18,6 +18,7 @@
 #include <linux/atmmpc.h>
 #include <net/atmclip.h>
 #include <linux/atmlec.h>
+#include <linux/mutex.h>
 #include <asm/ioctls.h>
 
 #include "resources.h"
@@ -25,22 +26,22 @@
 #include "common.h"
 
 
-static DECLARE_MUTEX(ioctl_mutex);
+static DEFINE_MUTEX(ioctl_mutex);
 static LIST_HEAD(ioctl_list);
 
 
 void register_atm_ioctl(struct atm_ioctl *ioctl)
 {
-	down(&ioctl_mutex);
+	mutex_lock(&ioctl_mutex);
 	list_add_tail(&ioctl->list, &ioctl_list);
-	up(&ioctl_mutex);
+	mutex_unlock(&ioctl_mutex);
 }
 
 void deregister_atm_ioctl(struct atm_ioctl *ioctl)
 {
-	down(&ioctl_mutex);
+	mutex_lock(&ioctl_mutex);
 	list_del(&ioctl->list);
-	up(&ioctl_mutex);
+	mutex_unlock(&ioctl_mutex);
 }
 
 EXPORT_SYMBOL(register_atm_ioctl);
@@ -137,7 +138,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 
 	error = -ENOIOCTLCMD;
 
-	down(&ioctl_mutex);
+	mutex_lock(&ioctl_mutex);
 	list_for_each(pos, &ioctl_list) {
 		struct atm_ioctl * ic = list_entry(pos, struct atm_ioctl, list);
 		if (try_module_get(ic->owner)) {
@@ -147,7 +148,7 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 				break;
 		}
 	}
-	up(&ioctl_mutex);
+	mutex_unlock(&ioctl_mutex);
 
 	if (error != -ENOIOCTLCMD)
 		goto done;

+ 17 - 15
net/atm/resources.c

@@ -18,6 +18,8 @@
 #include <linux/bitops.h>
 #include <linux/capability.h>
 #include <linux/delay.h>
+#include <linux/mutex.h>
+
 #include <net/sock.h>	 /* for struct sock */
 
 #include "common.h"
@@ -26,7 +28,7 @@
 
 
 LIST_HEAD(atm_devs);
-DECLARE_MUTEX(atm_dev_mutex);
+DEFINE_MUTEX(atm_dev_mutex);
 
 static struct atm_dev *__alloc_atm_dev(const char *type)
 {
@@ -65,9 +67,9 @@ struct atm_dev *atm_dev_lookup(int number)
 {
 	struct atm_dev *dev;
 
-	down(&atm_dev_mutex);
+	mutex_lock(&atm_dev_mutex);
 	dev = __atm_dev_lookup(number);
-	up(&atm_dev_mutex);
+	mutex_unlock(&atm_dev_mutex);
 	return dev;
 }
 
@@ -83,11 +85,11 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
 		    type);
 		return NULL;
 	}
-	down(&atm_dev_mutex);
+	mutex_lock(&atm_dev_mutex);
 	if (number != -1) {
 		if ((inuse = __atm_dev_lookup(number))) {
 			atm_dev_put(inuse);
-			up(&atm_dev_mutex);
+			mutex_unlock(&atm_dev_mutex);
 			kfree(dev);
 			return NULL;
 		}
@@ -112,12 +114,12 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops,
 		printk(KERN_ERR "atm_dev_register: "
 		       "atm_proc_dev_register failed for dev %s\n",
 		       type);
-		up(&atm_dev_mutex);
+		mutex_unlock(&atm_dev_mutex);
 		kfree(dev);
 		return NULL;
 	}
 	list_add_tail(&dev->dev_list, &atm_devs);
-	up(&atm_dev_mutex);
+	mutex_unlock(&atm_dev_mutex);
 
 	return dev;
 }
@@ -133,9 +135,9 @@ void atm_dev_deregister(struct atm_dev *dev)
 	 * with same number can appear, such we need deregister proc, 
 	 * release async all vccs and remove them from vccs list too
 	 */
-	down(&atm_dev_mutex);
+	mutex_lock(&atm_dev_mutex);
 	list_del(&dev->dev_list);
-	up(&atm_dev_mutex);
+	mutex_unlock(&atm_dev_mutex);
 
 	atm_dev_release_vccs(dev);
 	atm_proc_dev_deregister(dev);
@@ -196,16 +198,16 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
 				return -EFAULT;
 			if (get_user(len, &iobuf->length))
 				return -EFAULT;
-			down(&atm_dev_mutex);
+			mutex_lock(&atm_dev_mutex);
 			list_for_each(p, &atm_devs)
 				size += sizeof(int);
 			if (size > len) {
-				up(&atm_dev_mutex);
+				mutex_unlock(&atm_dev_mutex);
 				return -E2BIG;
 			}
 			tmp_buf = kmalloc(size, GFP_ATOMIC);
 			if (!tmp_buf) {
-				up(&atm_dev_mutex);
+				mutex_unlock(&atm_dev_mutex);
 				return -ENOMEM;
 			}
 			tmp_p = tmp_buf;
@@ -213,7 +215,7 @@ int atm_dev_ioctl(unsigned int cmd, void __user *arg)
 				dev = list_entry(p, struct atm_dev, dev_list);
 				*tmp_p++ = dev->number;
 			}
-			up(&atm_dev_mutex);
+			mutex_unlock(&atm_dev_mutex);
 		        error = ((copy_to_user(buf, tmp_buf, size)) ||
 					put_user(size, &iobuf->length))
 						? -EFAULT : 0;
@@ -400,13 +402,13 @@ static __inline__ void *dev_get_idx(loff_t left)
 
 void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
 {
- 	down(&atm_dev_mutex);
+ 	mutex_lock(&atm_dev_mutex);
 	return *pos ? dev_get_idx(*pos) : (void *) 1;
 }
 
 void atm_dev_seq_stop(struct seq_file *seq, void *v)
 {
- 	up(&atm_dev_mutex);
+ 	mutex_unlock(&atm_dev_mutex);
 }
  
 void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)

+ 2 - 1
net/atm/resources.h

@@ -8,10 +8,11 @@
 
 #include <linux/config.h>
 #include <linux/atmdev.h>
+#include <linux/mutex.h>
 
 
 extern struct list_head atm_devs;
-extern struct semaphore atm_dev_mutex;
+extern struct mutex atm_dev_mutex;
 
 int atm_dev_ioctl(unsigned int cmd, void __user *arg);
 

+ 5 - 3
net/bluetooth/rfcomm/core.c

@@ -37,6 +37,8 @@
 #include <linux/wait.h>
 #include <linux/device.h>
 #include <linux/net.h>
+#include <linux/mutex.h>
+
 #include <net/sock.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
@@ -57,9 +59,9 @@ static unsigned int l2cap_mtu = RFCOMM_MAX_L2CAP_MTU;
 
 static struct task_struct *rfcomm_thread;
 
-static DECLARE_MUTEX(rfcomm_sem);
-#define rfcomm_lock()	down(&rfcomm_sem);
-#define rfcomm_unlock()	up(&rfcomm_sem);
+static DEFINE_MUTEX(rfcomm_mutex);
+#define rfcomm_lock()	mutex_lock(&rfcomm_mutex)
+#define rfcomm_unlock()	mutex_unlock(&rfcomm_mutex)
 
 static unsigned long rfcomm_event;
 

+ 1 - 0
net/bridge/Kconfig

@@ -4,6 +4,7 @@
 
 config BRIDGE
 	tristate "802.1d Ethernet Bridging"
+	select LLC
 	---help---
 	  If you say Y here, then your Linux box will be able to act as an
 	  Ethernet bridge, which means that the different Ethernet segments it

+ 12 - 0
net/bridge/br.c

@@ -19,13 +19,23 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/init.h>
+#include <linux/llc.h>
+#include <net/llc.h>
 
 #include "br_private.h"
 
 int (*br_should_route_hook) (struct sk_buff **pskb) = NULL;
 
+static struct llc_sap *br_stp_sap;
+
 static int __init br_init(void)
 {
+	br_stp_sap = llc_sap_open(LLC_SAP_BSPAN, br_stp_rcv);
+	if (!br_stp_sap) {
+		printk(KERN_ERR "bridge: can't register sap for STP\n");
+		return -EBUSY;
+	}
+
 	br_fdb_init();
 
 #ifdef CONFIG_BRIDGE_NETFILTER
@@ -45,6 +55,8 @@ static int __init br_init(void)
 
 static void __exit br_deinit(void)
 {
+	llc_sap_close(br_stp_sap);
+
 #ifdef CONFIG_BRIDGE_NETFILTER
 	br_netfilter_fini();
 #endif

+ 1 - 2
net/bridge/br_device.c

@@ -27,6 +27,7 @@ static struct net_device_stats *br_dev_get_stats(struct net_device *dev)
 	return &br->statistics;
 }
 
+/* net device transmit always called with no BH (preempt_disabled) */
 int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct net_bridge *br = netdev_priv(dev);
@@ -39,7 +40,6 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb->mac.raw = skb->data;
 	skb_pull(skb, ETH_HLEN);
 
-	rcu_read_lock();
 	if (dest[0] & 1) 
 		br_flood_deliver(br, skb, 0);
 	else if ((dst = __br_fdb_get(br, dest)) != NULL)
@@ -47,7 +47,6 @@ int br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
 	else
 		br_flood_deliver(br, skb, 0);
 
-	rcu_read_unlock();
 	return 0;
 }
 

+ 2 - 4
net/bridge/br_fdb.c

@@ -341,7 +341,6 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
 	if (hold_time(br) == 0)
 		return;
 
-	rcu_read_lock();
 	fdb = fdb_find(head, addr);
 	if (likely(fdb)) {
 		/* attempt to update an entry for a local interface */
@@ -356,13 +355,12 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
 			fdb->ageing_timer = jiffies;
 		}
 	} else {
-		spin_lock_bh(&br->hash_lock);
+		spin_lock(&br->hash_lock);
 		if (!fdb_find(head, addr))
 			fdb_create(head, source, addr, 0);
 		/* else  we lose race and someone else inserts
 		 * it first, don't bother updating
 		 */
-		spin_unlock_bh(&br->hash_lock);
+		spin_unlock(&br->hash_lock);
 	}
-	rcu_read_unlock();
 }

+ 4 - 5
net/bridge/br_if.c

@@ -210,7 +210,8 @@ static struct net_device *new_bridge_dev(const char *name)
 
 	br->bridge_id.prio[0] = 0x80;
 	br->bridge_id.prio[1] = 0x00;
-	memset(br->bridge_id.addr, 0, ETH_ALEN);
+
+	memcpy(br->group_addr, br_group_address, ETH_ALEN);
 
 	br->feature_mask = dev->features;
 	br->stp_enabled = 0;
@@ -237,12 +238,11 @@ static int find_portno(struct net_bridge *br)
 	struct net_bridge_port *p;
 	unsigned long *inuse;
 
-	inuse = kmalloc(BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long),
+	inuse = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long),
 			GFP_KERNEL);
 	if (!inuse)
 		return -ENOMEM;
 
-	memset(inuse, 0, BITS_TO_LONGS(BR_MAX_PORTS)*sizeof(unsigned long));
 	set_bit(0, inuse);	/* zero is reserved */
 	list_for_each_entry(p, &br->port_list, list) {
 		set_bit(p->port_no, inuse);
@@ -264,11 +264,10 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
 	if (index < 0)
 		return ERR_PTR(index);
 
-	p = kmalloc(sizeof(*p), GFP_KERNEL);
+	p = kzalloc(sizeof(*p), GFP_KERNEL);
 	if (p == NULL)
 		return ERR_PTR(-ENOMEM);
 
-	memset(p, 0, sizeof(*p));
 	p->br = br;
 	dev_hold(dev);
 	p->dev = dev;

+ 26 - 17
net/bridge/br_input.c

@@ -19,13 +19,8 @@
 #include <linux/netfilter_bridge.h>
 #include "br_private.h"
 
-const unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
-
-static int br_pass_frame_up_finish(struct sk_buff *skb)
-{
-	netif_receive_skb(skb);
-	return 0;
-}
+/* Bridge group multicast address 802.1d (pg 51). */
+const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
 
 static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
 {
@@ -38,7 +33,7 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
 	skb->dev = br->dev;
 
 	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
-			br_pass_frame_up_finish);
+		netif_receive_skb);
 }
 
 /* note: already called with rcu_read_lock (preempt_disabled) */
@@ -100,6 +95,25 @@ drop:
 	goto out;
 }
 
+/* note: already called with rcu_read_lock (preempt_disabled) */
+static int br_handle_local_finish(struct sk_buff *skb)
+{
+	struct net_bridge_port *p = rcu_dereference(skb->dev->br_port);
+
+	if (p && p->state != BR_STATE_DISABLED)
+		br_fdb_update(p->br, p, eth_hdr(skb)->h_source);
+
+	return 0;	 /* process further */
+}
+
+/* Does address match the link local multicast address.
+ * 01:80:c2:00:00:0X
+ */
+static inline int is_link_local(const unsigned char *dest)
+{
+	return memcmp(dest, br_group_address, 5) == 0 && (dest[5] & 0xf0) == 0;
+}
+
 /*
  * Called via br_handle_frame_hook.
  * Return 0 if *pskb should be processed furthur
@@ -117,15 +131,10 @@ int br_handle_frame(struct net_bridge_port *p, struct sk_buff **pskb)
 	if (!is_valid_ether_addr(eth_hdr(skb)->h_source))
 		goto err;
 
-	if (p->br->stp_enabled &&
-	    !memcmp(dest, bridge_ula, 5) &&
-	    !(dest[5] & 0xF0)) {
-		if (!dest[5]) {
-			NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev, 
-				NULL, br_stp_handle_bpdu);
-			return 1;
-		}
-		goto err;
+	if (unlikely(is_link_local(dest))) {
+		skb->pkt_type = PACKET_HOST;
+		return NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
+			       NULL, br_handle_local_finish) != 0;
 	}
 
 	if (p->state == BR_STATE_FORWARDING || p->state == BR_STATE_LEARNING) {

+ 126 - 99
net/bridge/br_netfilter.c

@@ -61,15 +61,25 @@ static int brnf_filter_vlan_tagged = 1;
 #define brnf_filter_vlan_tagged 1
 #endif
 
-#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) &&    \
-	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP) &&  \
-	brnf_filter_vlan_tagged)
-#define IS_VLAN_IPV6 (skb->protocol == __constant_htons(ETH_P_8021Q) &&    \
-	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IPV6) &&  \
-	brnf_filter_vlan_tagged)
-#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) &&   \
-	hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP) && \
-	brnf_filter_vlan_tagged)
+static __be16 inline vlan_proto(const struct sk_buff *skb)
+{
+	return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+}
+
+#define IS_VLAN_IP(skb) \
+	(skb->protocol == htons(ETH_P_8021Q) && \
+ 	 vlan_proto(skb) == htons(ETH_P_IP) && 	\
+	 brnf_filter_vlan_tagged)
+
+#define IS_VLAN_IPV6(skb) \
+	(skb->protocol == htons(ETH_P_8021Q) && \
+	 vlan_proto(skb) == htons(ETH_P_IPV6) &&\
+	 brnf_filter_vlan_tagged)
+
+#define IS_VLAN_ARP(skb) \
+	(skb->protocol == htons(ETH_P_8021Q) &&	\
+	 vlan_proto(skb) == htons(ETH_P_ARP) &&	\
+	 brnf_filter_vlan_tagged)
 
 /* We need these fake structures to make netfilter happy --
  * lots of places assume that skb->dst != NULL, which isn't
@@ -103,6 +113,25 @@ static inline struct net_device *bridge_parent(const struct net_device *dev)
 	return port ? port->br->dev : NULL;
 }
 
+static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
+{
+	skb->nf_bridge = kzalloc(sizeof(struct nf_bridge_info), GFP_ATOMIC);
+	if (likely(skb->nf_bridge))
+		atomic_set(&(skb->nf_bridge->use), 1);
+
+	return skb->nf_bridge;
+}
+
+static inline void nf_bridge_save_header(struct sk_buff *skb)
+{
+        int header_size = 16;
+
+	if (skb->protocol == htons(ETH_P_8021Q))
+		header_size = 18;
+
+	memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
+}
+
 /* PF_BRIDGE/PRE_ROUTING *********************************************/
 /* Undo the changes made for ip6tables PREROUTING and continue the
  * bridge PRE_ROUTING hook. */
@@ -120,7 +149,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
 	dst_hold(skb->dst);
 
 	skb->dev = nf_bridge->physindev;
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
@@ -136,7 +165,7 @@ static void __br_dnat_complain(void)
 
 	if (jiffies - last_complaint >= 5 * HZ) {
 		printk(KERN_WARNING "Performing cross-bridge DNAT requires IP "
-			"forwarding to be enabled\n");
+		       "forwarding to be enabled\n");
 		last_complaint = jiffies;
 	}
 }
@@ -196,7 +225,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 	if (!skb->dev)
 		kfree_skb(skb);
 	else {
-		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		if (skb->protocol == htons(ETH_P_8021Q)) {
 			skb_pull(skb, VLAN_HLEN);
 			skb->nh.raw += VLAN_HLEN;
 		}
@@ -218,12 +247,17 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
 	nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
 
 	if (dnat_took_place(skb)) {
-		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
-		    dev)) {
+		if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) {
 			struct rtable *rt;
-			struct flowi fl = { .nl_u = 
-			{ .ip4_u = { .daddr = iph->daddr, .saddr = 0 ,
-				     .tos = RT_TOS(iph->tos)} }, .proto = 0};
+			struct flowi fl = {
+				.nl_u = {
+					.ip4_u = {
+						 .daddr = iph->daddr,
+						 .saddr = 0,
+						 .tos = RT_TOS(iph->tos) },
+				},
+				.proto = 0,
+			};
 
 			if (!ip_route_output_key(&rt, &fl)) {
 				/* - Bridged-and-DNAT'ed traffic doesn't
@@ -247,7 +281,7 @@ bridged_dnat:
 				nf_bridge->mask |= BRNF_BRIDGED_DNAT;
 				skb->dev = nf_bridge->physindev;
 				if (skb->protocol ==
-				    __constant_htons(ETH_P_8021Q)) {
+				    htons(ETH_P_8021Q)) {
 					skb_push(skb, VLAN_HLEN);
 					skb->nh.raw -= VLAN_HLEN;
 				}
@@ -257,8 +291,7 @@ bridged_dnat:
 					       1);
 				return 0;
 			}
-			memcpy(eth_hdr(skb)->h_dest, dev->dev_addr,
-			       ETH_ALEN);
+			memcpy(eth_hdr(skb)->h_dest, dev->dev_addr, ETH_ALEN);
 			skb->pkt_type = PACKET_HOST;
 		}
 	} else {
@@ -267,7 +300,7 @@ bridged_dnat:
 	}
 
 	skb->dev = nf_bridge->physindev;
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
@@ -297,10 +330,10 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
 /* We only check the length. A bridge shouldn't do any hop-by-hop stuff anyway */
 static int check_hbh_len(struct sk_buff *skb)
 {
-	unsigned char *raw = (u8*)(skb->nh.ipv6h+1);
+	unsigned char *raw = (u8 *) (skb->nh.ipv6h + 1);
 	u32 pkt_len;
 	int off = raw - skb->nh.raw;
-	int len = (raw[1]+1)<<3;
+	int len = (raw[1] + 1) << 3;
 
 	if ((raw + len) - skb->data > skb_headlen(skb))
 		goto bad;
@@ -309,7 +342,7 @@ static int check_hbh_len(struct sk_buff *skb)
 	len -= 2;
 
 	while (len > 0) {
-		int optlen = skb->nh.raw[off+1]+2;
+		int optlen = skb->nh.raw[off + 1] + 2;
 
 		switch (skb->nh.raw[off]) {
 		case IPV6_TLV_PAD0:
@@ -320,16 +353,16 @@ static int check_hbh_len(struct sk_buff *skb)
 			break;
 
 		case IPV6_TLV_JUMBO:
-			if (skb->nh.raw[off+1] != 4 || (off&3) != 2)
+			if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2)
 				goto bad;
-			pkt_len = ntohl(*(u32*)(skb->nh.raw+off+2));
+			pkt_len = ntohl(*(u32 *) (skb->nh.raw + off + 2));
 			if (pkt_len <= IPV6_MAXPLEN ||
 			    skb->nh.ipv6h->payload_len)
 				goto bad;
 			if (pkt_len > skb->len - sizeof(struct ipv6hdr))
 				goto bad;
 			if (pskb_trim_rcsum(skb,
-			    pkt_len+sizeof(struct ipv6hdr)))
+					    pkt_len + sizeof(struct ipv6hdr)))
 				goto bad;
 			break;
 		default:
@@ -350,12 +383,13 @@ bad:
 /* Replicate the checks that IPv6 does on packet reception and pass the packet
  * to ip6tables, which doesn't support NAT, so things are fairly simple. */
 static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
-   struct sk_buff *skb, const struct net_device *in,
-   const struct net_device *out, int (*okfn)(struct sk_buff *))
+					   struct sk_buff *skb,
+					   const struct net_device *in,
+					   const struct net_device *out,
+					   int (*okfn)(struct sk_buff *))
 {
 	struct ipv6hdr *hdr;
 	u32 pkt_len;
-	struct nf_bridge_info *nf_bridge;
 
 	if (skb->len < sizeof(struct ipv6hdr))
 		goto inhdr_error;
@@ -381,10 +415,10 @@ static unsigned int br_nf_pre_routing_ipv6(unsigned int hook,
 		}
 	}
 	if (hdr->nexthdr == NEXTHDR_HOP && check_hbh_len(skb))
-			goto inhdr_error;
+		goto inhdr_error;
 
- 	nf_bridge_put(skb->nf_bridge);
-	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
+	nf_bridge_put(skb->nf_bridge);
+	if (!nf_bridge_alloc(skb))
 		return NF_DROP;
 	if (!setup_pre_routing(skb))
 		return NF_DROP;
@@ -412,10 +446,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 	struct iphdr *iph;
 	__u32 len;
 	struct sk_buff *skb = *pskb;
-	struct nf_bridge_info *nf_bridge;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(*pskb);
 
-	if (skb->protocol == __constant_htons(ETH_P_IPV6) || IS_VLAN_IPV6) {
+	if (skb->protocol == htons(ETH_P_IPV6) || IS_VLAN_IPV6(skb)) {
 #ifdef CONFIG_SYSCTL
 		if (!brnf_call_ip6tables)
 			return NF_ACCEPT;
@@ -423,10 +455,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 		if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
 			goto out;
 
-		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
-			u8 *vhdr = skb->data;
-			skb_pull(skb, VLAN_HLEN);
-			skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+		if (skb->protocol == htons(ETH_P_8021Q)) {
+			skb_pull_rcsum(skb, VLAN_HLEN);
 			skb->nh.raw += VLAN_HLEN;
 		}
 		return br_nf_pre_routing_ipv6(hook, skb, in, out, okfn);
@@ -436,16 +466,14 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 		return NF_ACCEPT;
 #endif
 
-	if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP)
+	if (skb->protocol != htons(ETH_P_IP) && !IS_VLAN_IP(skb))
 		return NF_ACCEPT;
 
 	if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL)
 		goto out;
 
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
-		u8 *vhdr = skb->data;
-		skb_pull(skb, VLAN_HLEN);
-		skb_postpull_rcsum(skb, vhdr, VLAN_HLEN);
+	if (skb->protocol == htons(ETH_P_8021Q)) {
+		skb_pull_rcsum(skb, VLAN_HLEN);
 		skb->nh.raw += VLAN_HLEN;
 	}
 
@@ -456,15 +484,15 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 	if (iph->ihl < 5 || iph->version != 4)
 		goto inhdr_error;
 
-	if (!pskb_may_pull(skb, 4*iph->ihl))
+	if (!pskb_may_pull(skb, 4 * iph->ihl))
 		goto inhdr_error;
 
 	iph = skb->nh.iph;
-	if (ip_fast_csum((__u8 *)iph, iph->ihl) != 0)
+	if (ip_fast_csum((__u8 *) iph, iph->ihl) != 0)
 		goto inhdr_error;
 
 	len = ntohs(iph->tot_len);
-	if (skb->len < len || len < 4*iph->ihl)
+	if (skb->len < len || len < 4 * iph->ihl)
 		goto inhdr_error;
 
 	if (skb->len > len) {
@@ -473,8 +501,8 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 			skb->ip_summed = CHECKSUM_NONE;
 	}
 
- 	nf_bridge_put(skb->nf_bridge);
-	if ((nf_bridge = nf_bridge_alloc(skb)) == NULL)
+	nf_bridge_put(skb->nf_bridge);
+	if (!nf_bridge_alloc(skb))
 		return NF_DROP;
 	if (!setup_pre_routing(skb))
 		return NF_DROP;
@@ -486,7 +514,7 @@ static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb,
 	return NF_STOLEN;
 
 inhdr_error:
-//	IP_INC_STATS_BH(IpInHdrErrors);
+//      IP_INC_STATS_BH(IpInHdrErrors);
 out:
 	return NF_DROP;
 }
@@ -500,8 +528,9 @@ out:
  * register an IPv4 PRE_ROUTING 'sabotage' hook that will
  * prevent this from happening. */
 static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				   const struct net_device *in,
+				   const struct net_device *out,
+				   int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *skb = *pskb;
 
@@ -513,15 +542,13 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb,
 	return NF_ACCEPT;
 }
 
-
 /* PF_BRIDGE/FORWARD *************************************************/
 static int br_nf_forward_finish(struct sk_buff *skb)
 {
 	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
 	struct net_device *in;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 
-	if (skb->protocol != __constant_htons(ETH_P_ARP) && !IS_VLAN_ARP) {
+	if (skb->protocol != htons(ETH_P_ARP) && !IS_VLAN_ARP(skb)) {
 		in = nf_bridge->physindev;
 		if (nf_bridge->mask & BRNF_PKT_TYPE) {
 			skb->pkt_type = PACKET_OTHERHOST;
@@ -530,12 +557,12 @@ static int br_nf_forward_finish(struct sk_buff *skb)
 	} else {
 		in = *((struct net_device **)(skb->cb));
 	}
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in,
-			skb->dev, br_forward_finish, 1);
+		       skb->dev, br_forward_finish, 1);
 	return 0;
 }
 
@@ -545,12 +572,12 @@ static int br_nf_forward_finish(struct sk_buff *skb)
  * because of the physdev module. For ARP, indev and outdev are the
  * bridge ports. */
 static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				     const struct net_device *in,
+				     const struct net_device *out,
+				     int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *skb = *pskb;
 	struct nf_bridge_info *nf_bridge;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 	struct net_device *parent;
 	int pf;
 
@@ -561,12 +588,12 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
 	if (!parent)
 		return NF_DROP;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
 
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_pull(*pskb, VLAN_HLEN);
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
@@ -588,11 +615,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb,
 }
 
 static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *skb = *pskb;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 	struct net_device **d = (struct net_device **)(skb->cb);
 
 #ifdef CONFIG_SYSCTL
@@ -600,15 +627,15 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
 		return NF_ACCEPT;
 #endif
 
-	if (skb->protocol != __constant_htons(ETH_P_ARP)) {
-		if (!IS_VLAN_ARP)
+	if (skb->protocol != htons(ETH_P_ARP)) {
+		if (!IS_VLAN_ARP(skb))
 			return NF_ACCEPT;
 		skb_pull(*pskb, VLAN_HLEN);
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
 
 	if (skb->nh.arph->ar_pln != 4) {
-		if (IS_VLAN_ARP) {
+		if (IS_VLAN_ARP(skb)) {
 			skb_push(*pskb, VLAN_HLEN);
 			(*pskb)->nh.raw -= VLAN_HLEN;
 		}
@@ -621,17 +648,16 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
 	return NF_STOLEN;
 }
 
-
 /* PF_BRIDGE/LOCAL_OUT ***********************************************/
 static int br_nf_local_out_finish(struct sk_buff *skb)
 {
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_push(skb, VLAN_HLEN);
 		skb->nh.raw -= VLAN_HLEN;
 	}
 
 	NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
-			br_forward_finish, NF_BR_PRI_FIRST + 1);
+		       br_forward_finish, NF_BR_PRI_FIRST + 1);
 
 	return 0;
 }
@@ -657,19 +683,19 @@ static int br_nf_local_out_finish(struct sk_buff *skb)
  * even routed packets that didn't arrive on a bridge interface have their
  * nf_bridge->physindev set. */
 static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				    const struct net_device *in,
+				    const struct net_device *out,
+				    int (*okfn)(struct sk_buff *))
 {
 	struct net_device *realindev, *realoutdev;
 	struct sk_buff *skb = *pskb;
 	struct nf_bridge_info *nf_bridge;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 	int pf;
 
 	if (!skb->nf_bridge)
 		return NF_ACCEPT;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
@@ -695,7 +721,7 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
 			skb->pkt_type = PACKET_OTHERHOST;
 			nf_bridge->mask ^= BRNF_PKT_TYPE;
 		}
-		if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+		if (skb->protocol == htons(ETH_P_8021Q)) {
 			skb_push(skb, VLAN_HLEN);
 			skb->nh.raw -= VLAN_HLEN;
 		}
@@ -713,14 +739,14 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
 	if (nf_bridge->netoutdev)
 		realoutdev = nf_bridge->netoutdev;
 #endif
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_pull(skb, VLAN_HLEN);
 		(*pskb)->nh.raw += VLAN_HLEN;
 	}
 	/* IP forwarded traffic has a physindev, locally
 	 * generated traffic hasn't. */
 	if (realindev != NULL) {
-		if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT) ) {
+		if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) {
 			struct net_device *parent = bridge_parent(realindev);
 			if (parent)
 				realindev = parent;
@@ -742,12 +768,12 @@ out:
 
 /* PF_BRIDGE/POST_ROUTING ********************************************/
 static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				       const struct net_device *in,
+				       const struct net_device *out,
+				       int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *skb = *pskb;
 	struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge;
-	struct vlan_ethhdr *hdr = vlan_eth_hdr(skb);
 	struct net_device *realoutdev = bridge_parent(skb->dev);
 	int pf;
 
@@ -756,7 +782,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 	 * keep the check just to be sure... */
 	if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) {
 		printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: "
-				 "bad mac.raw pointer.");
+		       "bad mac.raw pointer.");
 		goto print_error;
 	}
 #endif
@@ -767,7 +793,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 	if (!realoutdev)
 		return NF_DROP;
 
-	if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP)
+	if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
 		pf = PF_INET;
 	else
 		pf = PF_INET6;
@@ -786,7 +812,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 		nf_bridge->mask |= BRNF_PKT_TYPE;
 	}
 
-	if (skb->protocol == __constant_htons(ETH_P_8021Q)) {
+	if (skb->protocol == htons(ETH_P_8021Q)) {
 		skb_pull(skb, VLAN_HLEN);
 		skb->nh.raw += VLAN_HLEN;
 	}
@@ -798,7 +824,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb,
 		realoutdev = nf_bridge->netoutdev;
 #endif
 	NF_HOOK(pf, NF_IP_POST_ROUTING, skb, NULL, realoutdev,
-	        br_dev_queue_push_xmit);
+		br_dev_queue_push_xmit);
 
 	return NF_STOLEN;
 
@@ -810,18 +836,18 @@ print_error:
 			printk("[%s]", realoutdev->name);
 	}
 	printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw,
-					      skb->data);
+	       skb->data);
 	return NF_ACCEPT;
 #endif
 }
 
-
 /* IP/SABOTAGE *****************************************************/
 /* Don't hand locally destined packets to PF_INET(6)/PRE_ROUTING
  * for the second time. */
 static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				   const struct net_device *in,
+				   const struct net_device *out,
+				   int (*okfn)(struct sk_buff *))
 {
 	if ((*pskb)->nf_bridge &&
 	    !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
@@ -835,18 +861,18 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
  * and PF_INET(6)/POST_ROUTING until we have done the forwarding
  * decision in the bridge code and have determined nf_bridge->physoutdev. */
 static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
-   const struct net_device *in, const struct net_device *out,
-   int (*okfn)(struct sk_buff *))
+				    const struct net_device *in,
+				    const struct net_device *out,
+				    int (*okfn)(struct sk_buff *))
 {
 	struct sk_buff *skb = *pskb;
 
 	if ((out->hard_start_xmit == br_dev_xmit &&
-	    okfn != br_nf_forward_finish &&
-	    okfn != br_nf_local_out_finish &&
-	    okfn != br_dev_queue_push_xmit)
+	     okfn != br_nf_forward_finish &&
+	     okfn != br_nf_local_out_finish && okfn != br_dev_queue_push_xmit)
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 	    || ((out->priv_flags & IFF_802_1Q_VLAN) &&
-	    VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
+		VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
 #endif
 	    ) {
 		struct nf_bridge_info *nf_bridge;
@@ -971,8 +997,8 @@ static struct nf_hook_ops br_nf_ops[] = {
 
 #ifdef CONFIG_SYSCTL
 static
-int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp,
-			void __user *buffer, size_t *lenp, loff_t *ppos)
+int brnf_sysctl_call_tables(ctl_table * ctl, int write, struct file *filp,
+			    void __user * buffer, size_t * lenp, loff_t * ppos)
 {
 	int ret;
 
@@ -1059,7 +1085,8 @@ int br_netfilter_init(void)
 #ifdef CONFIG_SYSCTL
 	brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0);
 	if (brnf_sysctl_header == NULL) {
-		printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n");
+		printk(KERN_WARNING
+		       "br_netfilter: can't register to sysctl.\n");
 		for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++)
 			nf_unregister_hook(&br_nf_ops[i]);
 		return -EFAULT;

Vissa filer visades inte eftersom för många filer har ändrats