Netdev List
 help / color / mirror / Atom feed
* Re: masquerading failure for at least icmp and tcp+sack on amd64
From: David S. Miller @ 2005-09-14  3:41 UTC (permalink / raw)
  To: kaber; +Cc: akpm, netdev, netfilter-devel, schmorp, shemminger
In-Reply-To: <43277943.8050700@trash.net>

From: Patrick McHardy <kaber@trash.net>
Date: Wed, 14 Sep 2005 03:13:39 +0200

> David S. Miller wrote:
> > I personally think netfilter should do so.
> 
> I agree. One thing I've planned for some silent moment is
> to clean up the entire netfilter checksumming code (there's
> lots of small duplicated chunks). Probably at least some
> of it will also be applicable for the remaining stack.

There is another thing I thought about today, and that is
to automatically handle this CHECKSUM_HW stuff when the
skb->data area is COW'd via pskb_expand_head() or similar.

I don't know how well that would work, but if it did then
we could consolidate all of this stuff into one spot which
is always nice.

^ permalink raw reply

* [PATCH 2.6.13] IPv4/IPv6: USO Scatter-gather approac
From: ravinandan.arakali @ 2005-09-14  6:55 UTC (permalink / raw)
  To: jgarzik, netdev
  Cc: raghavendra.koushik, ravinandan.arakali, leonid.grossman,
	rapuru.sriram, ananda.raju

Hi,
Attached below is kernel patch with UPD large send offload which address the 
sendfile() syscall also. This patch uses scatter-gather support of skb to 
generate large UDP datagram. 

Below is a "how-to" on changes required in network drivers to use the USO 
interface.


UDP Large Send Offload (USO) Interface:
--------------------------------------
USO is a feature wherein the Linux kernel network stack will offload the IP 
fragmentation functionality of large UDP datagram to hardware. This will reduce
the overhead of stack in fragmenting the large UDP datagram to MTU sized packets

1) Drivers indicate their capability of USO using
dev->features |= NETIF_F_USO | NETIF_F_HW_CSUM | NETIF_F_SG

NETIF_F_HW_CSUM is required for USO over ipv6.

2) USO packet will be submitted for transmission using driver xmit routine. 
USO packet will have a non-zero value for

"skb_shinfo(skb)->uso_size"

skb_shinfo(skb)->uso_size will indicate the length of data part in each IP 
fragment going out of the adapter after IP fragmentation by hardware.

skb->data will contain MAC/IP/UDP header and skb_shinfo(skb)->frags[]
contains the data payload. The skb->ip_summed will be set to CHECKSUM_HW 
indicating that hardware has to do checksum calculation. Hardware should 
compute the UDP checksum of complete datagram and also ip header checksum of 
each fragmented IP packet.

For IPV6 the USO provides the fragment identification-id in 
skb_shinfo(skb)->ip6_frag_id. The adapter should use this ID for generating
IPv6 fragments.

Signed-off-by: Ananda Raju <ananda.raju@neterion.com>
---
diff -uNr linux-2.6.13/include/linux/ethtool.h linux-2.6.13_uso/include/linux/ethtool.h
--- linux-2.6.13/include/linux/ethtool.h	2005-09-07 06:36:15.000000000 -0700
+++ linux-2.6.13_uso/include/linux/ethtool.h	2005-09-07 06:32:29.000000000 -0700
@@ -261,6 +261,8 @@
 int ethtool_op_set_sg(struct net_device *dev, u32 data);
 u32 ethtool_op_get_tso(struct net_device *dev);
 int ethtool_op_set_tso(struct net_device *dev, u32 data);
+u32 ethtool_op_get_uso(struct net_device *dev);
+int ethtool_op_set_uso(struct net_device *dev, u32 data);
 
 /**
  * &ethtool_ops - Alter and report network device settings
@@ -290,6 +292,8 @@
  * set_sg: Turn scatter-gather on or off
  * get_tso: Report whether TCP segmentation offload is enabled
  * set_tso: Turn TCP segmentation offload on or off
+ * get_uso: Report whether UDP large send offload is enabled
+ * set_uso: Turn UDP large send offload on or off
  * self_test: Run specified self-tests
  * get_strings: Return a set of strings that describe the requested objects 
  * phys_id: Identify the device
@@ -354,6 +358,8 @@
 	void	(*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
 	int	(*begin)(struct net_device *);
 	void	(*complete)(struct net_device *);
+	u32     (*get_uso)(struct net_device *);
+	int     (*set_uso)(struct net_device *, u32);
 };
 
 /* CMDs currently supported */
@@ -389,6 +395,8 @@
 #define ETHTOOL_GSTATS		0x0000001d /* get NIC-specific statistics */
 #define ETHTOOL_GTSO		0x0000001e /* Get TSO enable (ethtool_value) */
 #define ETHTOOL_STSO		0x0000001f /* Set TSO enable (ethtool_value) */
+#define ETHTOOL_GUSO           0x00000020 /* Get USO enable (ethtool_value) */
+#define ETHTOOL_SUSO           0x00000021 /* Set USO enable (ethtool_value) */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
diff -uNr linux-2.6.13/include/linux/netdevice.h linux-2.6.13_uso/include/linux/netdevice.h
--- linux-2.6.13/include/linux/netdevice.h	2005-09-07 04:20:51.000000000 -0700
+++ linux-2.6.13_uso/include/linux/netdevice.h	2005-09-07 04:22:51.000000000 -0700
@@ -408,6 +408,7 @@
 #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
 #define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
 #define NETIF_F_LLTX		4096	/* LockLess TX */
+#define NETIF_F_USO             8192    /* Can offload UDP Large Send*/
 
 	/* Called after device is detached from network. */
 	void			(*uninit)(struct net_device *dev);
diff -uNr linux-2.6.13/include/linux/skbuff.h linux-2.6.13_uso/include/linux/skbuff.h
--- linux-2.6.13/include/linux/skbuff.h	2005-09-07 04:20:56.000000000 -0700
+++ linux-2.6.13_uso/include/linux/skbuff.h	2005-09-07 04:22:58.000000000 -0700
@@ -137,6 +137,8 @@
 	unsigned int	nr_frags;
 	unsigned short	tso_size;
 	unsigned short	tso_segs;
+	unsigned short  uso_size;
+	unsigned int    ip6_frag_id;
 	struct sk_buff	*frag_list;
 	skb_frag_t	frags[MAX_SKB_FRAGS];
 };
@@ -327,6 +329,11 @@
 extern void	      skb_under_panic(struct sk_buff *skb, int len,
 				      void *here);
 
+extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+			int getfrag(void *from, char *to, int offset,
+			int len,int odd, struct sk_buff *skb),
+			void *from, int length);
+
 struct skb_seq_state
 {
 	__u32		lower_offset;
diff -uNr linux-2.6.13/net/core/dev.c linux-2.6.13_uso/net/core/dev.c
--- linux-2.6.13/net/core/dev.c	2005-09-07 06:36:25.000000000 -0700
+++ linux-2.6.13_uso/net/core/dev.c	2005-09-07 06:32:02.000000000 -0700
@@ -2706,6 +2706,25 @@
 		       dev->name);
 		dev->features &= ~NETIF_F_TSO;
 	}
+	/* TSO requires that SG is present as well. */
+	if ((dev->features & NETIF_F_TSO) &&
+	    !(dev->features & NETIF_F_SG)) {
+		printk("%s: Dropping NETIF_F_TSO since no SG feature.\n",
+		       dev->name);
+		dev->features &= ~NETIF_F_TSO;
+	}
+	if (dev->features & NETIF_F_USO) {
+		if (!(dev->features & NETIF_F_HW_CSUM)) {
+			printk("%s: Dropping NETIF_F_USO since no ", dev->name);
+			printk("NETIF_F_HW_CSUM feature.\n");
+			dev->features &= ~NETIF_F_USO;
+		}
+		if (!(dev->features & NETIF_F_SG)) {
+			printk("%s: Dropping NETIF_F_USO since no ", dev->name);
+			printk("NETIF_F_SG feature.\n");
+			dev->features &= ~NETIF_F_USO;
+		}
+	}
 
 	/*
 	 *	nil rebuild_header routine,
diff -uNr linux-2.6.13/net/core/ethtool.c linux-2.6.13_uso/net/core/ethtool.c
--- linux-2.6.13/net/core/ethtool.c	2005-09-07 06:36:34.000000000 -0700
+++ linux-2.6.13_uso/net/core/ethtool.c	2005-09-07 06:32:15.000000000 -0700
@@ -81,6 +81,20 @@
 	return 0;
 }
 
+u32 ethtool_op_get_uso(struct net_device *dev)
+{
+	return (dev->features & NETIF_F_USO) != 0;
+}
+
+int ethtool_op_set_uso(struct net_device *dev, u32 data)
+{
+	if (data)
+		dev->features |= NETIF_F_USO;
+	else
+		dev->features &= ~NETIF_F_USO;
+	return 0;
+}
+
 /* Handlers for each ethtool command */
 
 static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
@@ -469,6 +483,9 @@
 		err = dev->ethtool_ops->set_tso(dev, 0);
 		if (err)
 			return err;
+		err = dev->ethtool_ops->set_uso(dev, 0);
+		if (err)
+			return err;
 	}
 
 	return dev->ethtool_ops->set_sg(dev, data);
@@ -557,6 +574,32 @@
 	return dev->ethtool_ops->set_tso(dev, edata.data);
 }
 
+static int ethtool_get_uso(struct net_device *dev, char __user *useraddr)
+{
+	struct ethtool_value edata = { ETHTOOL_GTSO };
+
+	if (!dev->ethtool_ops->get_uso)
+		return -EOPNOTSUPP;
+	edata.data = dev->ethtool_ops->get_uso(dev);
+	if (copy_to_user(useraddr, &edata, sizeof(edata)))
+		 return -EFAULT;
+	return 0;
+}
+static int ethtool_set_uso(struct net_device *dev, char __user *useraddr)
+{
+	struct ethtool_value edata;
+
+	if (!dev->ethtool_ops->set_uso)
+		return -EOPNOTSUPP;
+	if (copy_from_user(&edata, useraddr, sizeof(edata)))
+		return -EFAULT;
+	if (edata.data && !(dev->features & NETIF_F_SG))
+		return -EINVAL;
+	if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
+		return -EINVAL;
+	return dev->ethtool_ops->set_uso(dev, edata.data);
+}
+
 static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_test test;
@@ -806,6 +849,12 @@
 	case ETHTOOL_GSTATS:
 		rc = ethtool_get_stats(dev, useraddr);
 		break;
+	case ETHTOOL_GUSO:
+		rc = ethtool_get_uso(dev, useraddr);
+		break;
+	case ETHTOOL_SUSO:
+		rc = ethtool_set_uso(dev, useraddr);
+		break;
 	default:
 		rc =  -EOPNOTSUPP;
 	}
@@ -833,3 +882,5 @@
 EXPORT_SYMBOL(ethtool_op_set_tso);
 EXPORT_SYMBOL(ethtool_op_set_tx_csum);
 EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
+EXPORT_SYMBOL(ethtool_op_set_uso);
+EXPORT_SYMBOL(ethtool_op_get_uso);
diff -uNr linux-2.6.13/net/core/skbuff.c linux-2.6.13_uso/net/core/skbuff.c
--- linux-2.6.13/net/core/skbuff.c	2005-09-07 04:21:30.000000000 -0700
+++ linux-2.6.13_uso/net/core/skbuff.c	2005-09-07 06:38:57.000000000 -0700
@@ -159,6 +159,8 @@
 	skb_shinfo(skb)->tso_size = 0;
 	skb_shinfo(skb)->tso_segs = 0;
 	skb_shinfo(skb)->frag_list = NULL;
+	skb_shinfo(skb)->uso_size = 0;
+	skb_shinfo(skb)->ip6_frag_id = 0;
 out:
 	return skb;
 nodata:
@@ -1654,6 +1656,64 @@
 	return textsearch_find(config, state);
 }
 
+/*
+ * skb_append_datato_frags - append the user data to a skb,
+ * sk - sock  structure which contains skbs for transmission
+ * getfrag - The function to be called to get the data from the user.
+ * from - pointer to user message iov
+ * length -  length of the iov message
+ *
+ * This procedure will allocate a skb enough to hold protocol headers and
+ * append the user data in the fragment part of the skb and add the skb to
+ * socket write queue
+ */
+int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+			int getfrag(void *from, char *to, int offset, 
+				    int len,int odd, struct sk_buff *skb),
+			void *from, int length)
+{
+	int frg_cnt = 0;
+	skb_frag_t *frag = NULL;
+	struct page *page = NULL;
+	int copy, left;
+	int offset = 0;
+	do {
+		frg_cnt = skb_shinfo(skb)->nr_frags;
+		if (frg_cnt >= MAX_SKB_FRAGS) {
+			kfree_skb(skb);
+			return -EFAULT;
+		}
+		page = alloc_pages(sk->sk_allocation, 0);
+		if (page == NULL) {
+			kfree_skb(skb);
+			return -ENOMEM;
+		}
+		sk->sk_sndmsg_page = page;
+		sk->sk_sndmsg_off = 0;
+		skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
+		frg_cnt = skb_shinfo(skb)->nr_frags;
+		atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
+		skb->truesize += PAGE_SIZE;
+		frag = &skb_shinfo(skb)->frags[frg_cnt - 1];
+		left = PAGE_SIZE - frag->page_offset;
+		copy = (length > left)? left : length;
+		if (getfrag(from, page_address(frag->page) +
+			    frag->page_offset+frag->size,
+			    offset, copy, 0, skb) < 0) {
+			kfree_skb(skb);
+			return -EFAULT;
+		}
+		sk->sk_sndmsg_off += copy;
+		frag->size += copy;
+		skb->len += copy;
+		skb->data_len += copy;
+		offset += copy;
+		length -= copy;
+		page = NULL;
+	} while (length > 0);
+	return 0;
+}
+
 void __init skb_init(void)
 {
 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1696,3 +1756,4 @@
 EXPORT_SYMBOL(skb_seq_read);
 EXPORT_SYMBOL(skb_abort_seq_read);
 EXPORT_SYMBOL(skb_find_text);
+EXPORT_SYMBOL(skb_append_datato_frags);
diff -uNr linux-2.6.13/net/ipv4/ip_output.c linux-2.6.13_uso/net/ipv4/ip_output.c
--- linux-2.6.13/net/ipv4/ip_output.c	2005-09-07 04:21:46.000000000 -0700
+++ linux-2.6.13_uso/net/ipv4/ip_output.c	2005-09-13 07:12:05.000000000 -0700
@@ -280,7 +280,8 @@
 {
 	IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
 
-	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size)
+	if (skb->len > dst_mtu(skb->dst) &&
+		!(skb_shinfo(skb)->uso_size || skb_shinfo(skb)->tso_size))
 		return ip_fragment(skb, ip_finish_output);
 	else
 		return ip_finish_output(skb);
@@ -781,6 +782,46 @@
 		csummode = CHECKSUM_HW;
 
 	inet->cork.length += length;
+	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+			(rt->u.dst.dev->features & NETIF_F_USO)) {
+		/* There is support for UDP large send offload by network
+		 * device, so create one single skb packet containing complete
+		 * udp datagram
+		 */
+		if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+			skb = sock_alloc_send_skb(sk,
+				hh_len + fragheaderlen + transhdrlen + 20,
+				(flags & MSG_DONTWAIT), &err);
+			if (skb == NULL) 
+				goto error;
+			/* reserve space for Hardware header */
+			skb_reserve(skb, hh_len);
+			/* create space for UDP/IP header */
+			skb_put(skb,fragheaderlen + transhdrlen);
+			/* initialize network header pointer */
+			skb->nh.raw = skb->data;
+			/* initialize protocol header pointer */
+			skb->h.raw = skb->data + fragheaderlen;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = 0;
+			sk->sk_sndmsg_off = 0;
+		}
+		err = skb_append_datato_frags(sk,skb, getfrag, from,
+				       (length - transhdrlen));
+		if (!err) {
+			/* specify the length of each IP datagram fragment*/
+			skb_shinfo(skb)->uso_size = (mtu - fragheaderlen);
+			__skb_queue_tail(&sk->sk_write_queue, skb);
+			return 0;
+		} else {
+			/* There is not enough support do UPD LSO,
+			 * so follow normal path
+			 */
+			kfree_skb(skb);
+			goto error;
+		}
+	}
+
 
 	/* So, what's going on in the loop below?
 	 *
@@ -1012,14 +1053,23 @@
 		return -EINVAL;
 
 	inet->cork.length += size;
+	if ((sk->sk_protocol == IPPROTO_UDP) &&
+	    (rt->u.dst.dev->features & NETIF_F_USO))
+		skb_shinfo(skb)->uso_size = (mtu - fragheaderlen);
+
 
 	while (size > 0) {
 		int i;
 
-		/* Check if the remaining data fits into current packet. */
-		len = mtu - skb->len;
-		if (len < size)
-			len = maxfraglen - skb->len;
+		if (skb_shinfo(skb)->uso_size) {
+			len = size;
+		} else {
+
+			/* Check if the remaining data fits into current packet. */
+			len = mtu - skb->len;
+			if (len < size)
+				len = maxfraglen - skb->len;
+		}
 		if (len <= 0) {
 			struct sk_buff *skb_prev;
 			char *data;
diff -uNr linux-2.6.13/net/ipv6/ip6_output.c linux-2.6.13_uso/net/ipv6/ip6_output.c
--- linux-2.6.13/net/ipv6/ip6_output.c	2005-09-07 04:21:57.000000000 -0700
+++ linux-2.6.13_uso/net/ipv6/ip6_output.c	2005-09-13 07:11:10.000000000 -0700
@@ -147,7 +147,8 @@
 
 int ip6_output(struct sk_buff *skb)
 {
-	if (skb->len > dst_mtu(skb->dst) || dst_allfrag(skb->dst))
+	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->uso_size) ||
+				dst_allfrag(skb->dst))
 		return ip6_fragment(skb, ip6_output2);
 	else
 		return ip6_output2(skb);
@@ -893,6 +894,50 @@
 	 */
 
 	inet->cork.length += length;
+	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+	    (rt->u.dst.dev->features & NETIF_F_USO)) {
+		/* There is support for UDP large send offload by network
+		 * device, so create one single skb packet containing complete
+		 * udp datagram
+		 */
+		if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+			skb = sock_alloc_send_skb(sk,
+				hh_len + fragheaderlen + transhdrlen + 20,
+				(flags & MSG_DONTWAIT), &err);
+			if (skb == NULL)
+				goto error;
+			/* reserve space for Hardware header */
+			skb_reserve(skb, hh_len);
+			/* create space for UDP/IP header */
+			skb_put(skb,fragheaderlen + transhdrlen);
+			/* initialize network header pointer */
+			skb->nh.raw = skb->data;
+			/* initialize protocol header pointer */
+			skb->h.raw = skb->data + fragheaderlen;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = 0;
+			sk->sk_sndmsg_off = 0;
+		}
+		err = skb_append_datato_frags(sk,skb, getfrag, from,
+					      (length - transhdrlen));
+		if (!err) {
+			struct frag_hdr fhdr;
+
+			/* specify the length of each IP datagram fragment*/
+			skb_shinfo(skb)->uso_size = (mtu - fragheaderlen) - 
+							sizeof(struct frag_hdr);
+			ipv6_select_ident(skb, &fhdr);
+			skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
+			__skb_queue_tail(&sk->sk_write_queue, skb);
+			return 0;
+		} else {
+			/* There is not enough support do UPD LSO,
+			 * so follow normal path
+			 */
+			kfree_skb(skb);
+			goto error;
+		}
+	}
 
 	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
 		goto alloc_new_skb;

^ permalink raw reply

* [PATCH 2.6.13] IPv4/IPv6: USO Scatter-gather approac
From: ananda.raju @ 2005-09-14  6:56 UTC (permalink / raw)
  To: jgarzik, netdev
  Cc: raghavendra.koushik, ravinandan.arakali, leonid.grossman,
	rapuru.sriram, ananda.raju

Hi,
Attached below is kernel patch with UPD large send offload which address the 
sendfile() syscall also. This patch uses scatter-gather support of skb to 
generate large UDP datagram. 

Below is a "how-to" on changes required in network drivers to use the USO 
interface.


UDP Large Send Offload (USO) Interface:
--------------------------------------
USO is a feature wherein the Linux kernel network stack will offload the IP 
fragmentation functionality of large UDP datagram to hardware. This will reduce
the overhead of stack in fragmenting the large UDP datagram to MTU sized packets

1) Drivers indicate their capability of USO using
dev->features |= NETIF_F_USO | NETIF_F_HW_CSUM | NETIF_F_SG

NETIF_F_HW_CSUM is required for USO over ipv6.

2) USO packet will be submitted for transmission using driver xmit routine. 
USO packet will have a non-zero value for

"skb_shinfo(skb)->uso_size"

skb_shinfo(skb)->uso_size will indicate the length of data part in each IP 
fragment going out of the adapter after IP fragmentation by hardware.

skb->data will contain MAC/IP/UDP header and skb_shinfo(skb)->frags[]
contains the data payload. The skb->ip_summed will be set to CHECKSUM_HW 
indicating that hardware has to do checksum calculation. Hardware should 
compute the UDP checksum of complete datagram and also ip header checksum of 
each fragmented IP packet.

For IPV6 the USO provides the fragment identification-id in 
skb_shinfo(skb)->ip6_frag_id. The adapter should use this ID for generating
IPv6 fragments.

Signed-off-by: Ananda Raju <ananda.raju@neterion.com>
---
diff -uNr linux-2.6.13/include/linux/ethtool.h linux-2.6.13_uso/include/linux/ethtool.h
--- linux-2.6.13/include/linux/ethtool.h	2005-09-07 06:36:15.000000000 -0700
+++ linux-2.6.13_uso/include/linux/ethtool.h	2005-09-07 06:32:29.000000000 -0700
@@ -261,6 +261,8 @@
 int ethtool_op_set_sg(struct net_device *dev, u32 data);
 u32 ethtool_op_get_tso(struct net_device *dev);
 int ethtool_op_set_tso(struct net_device *dev, u32 data);
+u32 ethtool_op_get_uso(struct net_device *dev);
+int ethtool_op_set_uso(struct net_device *dev, u32 data);
 
 /**
  * &ethtool_ops - Alter and report network device settings
@@ -290,6 +292,8 @@
  * set_sg: Turn scatter-gather on or off
  * get_tso: Report whether TCP segmentation offload is enabled
  * set_tso: Turn TCP segmentation offload on or off
+ * get_uso: Report whether UDP large send offload is enabled
+ * set_uso: Turn UDP large send offload on or off
  * self_test: Run specified self-tests
  * get_strings: Return a set of strings that describe the requested objects 
  * phys_id: Identify the device
@@ -354,6 +358,8 @@
 	void	(*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
 	int	(*begin)(struct net_device *);
 	void	(*complete)(struct net_device *);
+	u32     (*get_uso)(struct net_device *);
+	int     (*set_uso)(struct net_device *, u32);
 };
 
 /* CMDs currently supported */
@@ -389,6 +395,8 @@
 #define ETHTOOL_GSTATS		0x0000001d /* get NIC-specific statistics */
 #define ETHTOOL_GTSO		0x0000001e /* Get TSO enable (ethtool_value) */
 #define ETHTOOL_STSO		0x0000001f /* Set TSO enable (ethtool_value) */
+#define ETHTOOL_GUSO           0x00000020 /* Get USO enable (ethtool_value) */
+#define ETHTOOL_SUSO           0x00000021 /* Set USO enable (ethtool_value) */
 
 /* compatibility with older code */
 #define SPARC_ETH_GSET		ETHTOOL_GSET
diff -uNr linux-2.6.13/include/linux/netdevice.h linux-2.6.13_uso/include/linux/netdevice.h
--- linux-2.6.13/include/linux/netdevice.h	2005-09-07 04:20:51.000000000 -0700
+++ linux-2.6.13_uso/include/linux/netdevice.h	2005-09-07 04:22:51.000000000 -0700
@@ -408,6 +408,7 @@
 #define NETIF_F_VLAN_CHALLENGED	1024	/* Device cannot handle VLAN packets */
 #define NETIF_F_TSO		2048	/* Can offload TCP/IP segmentation */
 #define NETIF_F_LLTX		4096	/* LockLess TX */
+#define NETIF_F_USO             8192    /* Can offload UDP Large Send*/
 
 	/* Called after device is detached from network. */
 	void			(*uninit)(struct net_device *dev);
diff -uNr linux-2.6.13/include/linux/skbuff.h linux-2.6.13_uso/include/linux/skbuff.h
--- linux-2.6.13/include/linux/skbuff.h	2005-09-07 04:20:56.000000000 -0700
+++ linux-2.6.13_uso/include/linux/skbuff.h	2005-09-07 04:22:58.000000000 -0700
@@ -137,6 +137,8 @@
 	unsigned int	nr_frags;
 	unsigned short	tso_size;
 	unsigned short	tso_segs;
+	unsigned short  uso_size;
+	unsigned int    ip6_frag_id;
 	struct sk_buff	*frag_list;
 	skb_frag_t	frags[MAX_SKB_FRAGS];
 };
@@ -327,6 +329,11 @@
 extern void	      skb_under_panic(struct sk_buff *skb, int len,
 				      void *here);
 
+extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+			int getfrag(void *from, char *to, int offset,
+			int len,int odd, struct sk_buff *skb),
+			void *from, int length);
+
 struct skb_seq_state
 {
 	__u32		lower_offset;
diff -uNr linux-2.6.13/net/core/dev.c linux-2.6.13_uso/net/core/dev.c
--- linux-2.6.13/net/core/dev.c	2005-09-07 06:36:25.000000000 -0700
+++ linux-2.6.13_uso/net/core/dev.c	2005-09-07 06:32:02.000000000 -0700
@@ -2706,6 +2706,25 @@
 		       dev->name);
 		dev->features &= ~NETIF_F_TSO;
 	}
+	/* TSO requires that SG is present as well. */
+	if ((dev->features & NETIF_F_TSO) &&
+	    !(dev->features & NETIF_F_SG)) {
+		printk("%s: Dropping NETIF_F_TSO since no SG feature.\n",
+		       dev->name);
+		dev->features &= ~NETIF_F_TSO;
+	}
+	if (dev->features & NETIF_F_USO) {
+		if (!(dev->features & NETIF_F_HW_CSUM)) {
+			printk("%s: Dropping NETIF_F_USO since no ", dev->name);
+			printk("NETIF_F_HW_CSUM feature.\n");
+			dev->features &= ~NETIF_F_USO;
+		}
+		if (!(dev->features & NETIF_F_SG)) {
+			printk("%s: Dropping NETIF_F_USO since no ", dev->name);
+			printk("NETIF_F_SG feature.\n");
+			dev->features &= ~NETIF_F_USO;
+		}
+	}
 
 	/*
 	 *	nil rebuild_header routine,
diff -uNr linux-2.6.13/net/core/ethtool.c linux-2.6.13_uso/net/core/ethtool.c
--- linux-2.6.13/net/core/ethtool.c	2005-09-07 06:36:34.000000000 -0700
+++ linux-2.6.13_uso/net/core/ethtool.c	2005-09-07 06:32:15.000000000 -0700
@@ -81,6 +81,20 @@
 	return 0;
 }
 
+u32 ethtool_op_get_uso(struct net_device *dev)
+{
+	return (dev->features & NETIF_F_USO) != 0;
+}
+
+int ethtool_op_set_uso(struct net_device *dev, u32 data)
+{
+	if (data)
+		dev->features |= NETIF_F_USO;
+	else
+		dev->features &= ~NETIF_F_USO;
+	return 0;
+}
+
 /* Handlers for each ethtool command */
 
 static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
@@ -469,6 +483,9 @@
 		err = dev->ethtool_ops->set_tso(dev, 0);
 		if (err)
 			return err;
+		err = dev->ethtool_ops->set_uso(dev, 0);
+		if (err)
+			return err;
 	}
 
 	return dev->ethtool_ops->set_sg(dev, data);
@@ -557,6 +574,32 @@
 	return dev->ethtool_ops->set_tso(dev, edata.data);
 }
 
+static int ethtool_get_uso(struct net_device *dev, char __user *useraddr)
+{
+	struct ethtool_value edata = { ETHTOOL_GTSO };
+
+	if (!dev->ethtool_ops->get_uso)
+		return -EOPNOTSUPP;
+	edata.data = dev->ethtool_ops->get_uso(dev);
+	if (copy_to_user(useraddr, &edata, sizeof(edata)))
+		 return -EFAULT;
+	return 0;
+}
+static int ethtool_set_uso(struct net_device *dev, char __user *useraddr)
+{
+	struct ethtool_value edata;
+
+	if (!dev->ethtool_ops->set_uso)
+		return -EOPNOTSUPP;
+	if (copy_from_user(&edata, useraddr, sizeof(edata)))
+		return -EFAULT;
+	if (edata.data && !(dev->features & NETIF_F_SG))
+		return -EINVAL;
+	if (edata.data && !(dev->features & NETIF_F_HW_CSUM))
+		return -EINVAL;
+	return dev->ethtool_ops->set_uso(dev, edata.data);
+}
+
 static int ethtool_self_test(struct net_device *dev, char __user *useraddr)
 {
 	struct ethtool_test test;
@@ -806,6 +849,12 @@
 	case ETHTOOL_GSTATS:
 		rc = ethtool_get_stats(dev, useraddr);
 		break;
+	case ETHTOOL_GUSO:
+		rc = ethtool_get_uso(dev, useraddr);
+		break;
+	case ETHTOOL_SUSO:
+		rc = ethtool_set_uso(dev, useraddr);
+		break;
 	default:
 		rc =  -EOPNOTSUPP;
 	}
@@ -833,3 +882,5 @@
 EXPORT_SYMBOL(ethtool_op_set_tso);
 EXPORT_SYMBOL(ethtool_op_set_tx_csum);
 EXPORT_SYMBOL(ethtool_op_set_tx_hw_csum);
+EXPORT_SYMBOL(ethtool_op_set_uso);
+EXPORT_SYMBOL(ethtool_op_get_uso);
diff -uNr linux-2.6.13/net/core/skbuff.c linux-2.6.13_uso/net/core/skbuff.c
--- linux-2.6.13/net/core/skbuff.c	2005-09-07 04:21:30.000000000 -0700
+++ linux-2.6.13_uso/net/core/skbuff.c	2005-09-07 06:38:57.000000000 -0700
@@ -159,6 +159,8 @@
 	skb_shinfo(skb)->tso_size = 0;
 	skb_shinfo(skb)->tso_segs = 0;
 	skb_shinfo(skb)->frag_list = NULL;
+	skb_shinfo(skb)->uso_size = 0;
+	skb_shinfo(skb)->ip6_frag_id = 0;
 out:
 	return skb;
 nodata:
@@ -1654,6 +1656,64 @@
 	return textsearch_find(config, state);
 }
 
+/*
+ * skb_append_datato_frags - append the user data to a skb,
+ * sk - sock  structure which contains skbs for transmission
+ * getfrag - The function to be called to get the data from the user.
+ * from - pointer to user message iov
+ * length -  length of the iov message
+ *
+ * This procedure will allocate a skb enough to hold protocol headers and
+ * append the user data in the fragment part of the skb and add the skb to
+ * socket write queue
+ */
+int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
+			int getfrag(void *from, char *to, int offset, 
+				    int len,int odd, struct sk_buff *skb),
+			void *from, int length)
+{
+	int frg_cnt = 0;
+	skb_frag_t *frag = NULL;
+	struct page *page = NULL;
+	int copy, left;
+	int offset = 0;
+	do {
+		frg_cnt = skb_shinfo(skb)->nr_frags;
+		if (frg_cnt >= MAX_SKB_FRAGS) {
+			kfree_skb(skb);
+			return -EFAULT;
+		}
+		page = alloc_pages(sk->sk_allocation, 0);
+		if (page == NULL) {
+			kfree_skb(skb);
+			return -ENOMEM;
+		}
+		sk->sk_sndmsg_page = page;
+		sk->sk_sndmsg_off = 0;
+		skb_fill_page_desc(skb, frg_cnt, page, 0, 0);
+		frg_cnt = skb_shinfo(skb)->nr_frags;
+		atomic_add(PAGE_SIZE, &sk->sk_wmem_alloc);
+		skb->truesize += PAGE_SIZE;
+		frag = &skb_shinfo(skb)->frags[frg_cnt - 1];
+		left = PAGE_SIZE - frag->page_offset;
+		copy = (length > left)? left : length;
+		if (getfrag(from, page_address(frag->page) +
+			    frag->page_offset+frag->size,
+			    offset, copy, 0, skb) < 0) {
+			kfree_skb(skb);
+			return -EFAULT;
+		}
+		sk->sk_sndmsg_off += copy;
+		frag->size += copy;
+		skb->len += copy;
+		skb->data_len += copy;
+		offset += copy;
+		length -= copy;
+		page = NULL;
+	} while (length > 0);
+	return 0;
+}
+
 void __init skb_init(void)
 {
 	skbuff_head_cache = kmem_cache_create("skbuff_head_cache",
@@ -1696,3 +1756,4 @@
 EXPORT_SYMBOL(skb_seq_read);
 EXPORT_SYMBOL(skb_abort_seq_read);
 EXPORT_SYMBOL(skb_find_text);
+EXPORT_SYMBOL(skb_append_datato_frags);
diff -uNr linux-2.6.13/net/ipv4/ip_output.c linux-2.6.13_uso/net/ipv4/ip_output.c
--- linux-2.6.13/net/ipv4/ip_output.c	2005-09-07 04:21:46.000000000 -0700
+++ linux-2.6.13_uso/net/ipv4/ip_output.c	2005-09-13 07:12:05.000000000 -0700
@@ -280,7 +280,8 @@
 {
 	IP_INC_STATS(IPSTATS_MIB_OUTREQUESTS);
 
-	if (skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->tso_size)
+	if (skb->len > dst_mtu(skb->dst) &&
+		!(skb_shinfo(skb)->uso_size || skb_shinfo(skb)->tso_size))
 		return ip_fragment(skb, ip_finish_output);
 	else
 		return ip_finish_output(skb);
@@ -781,6 +782,46 @@
 		csummode = CHECKSUM_HW;
 
 	inet->cork.length += length;
+	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+			(rt->u.dst.dev->features & NETIF_F_USO)) {
+		/* There is support for UDP large send offload by network
+		 * device, so create one single skb packet containing complete
+		 * udp datagram
+		 */
+		if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+			skb = sock_alloc_send_skb(sk,
+				hh_len + fragheaderlen + transhdrlen + 20,
+				(flags & MSG_DONTWAIT), &err);
+			if (skb == NULL) 
+				goto error;
+			/* reserve space for Hardware header */
+			skb_reserve(skb, hh_len);
+			/* create space for UDP/IP header */
+			skb_put(skb,fragheaderlen + transhdrlen);
+			/* initialize network header pointer */
+			skb->nh.raw = skb->data;
+			/* initialize protocol header pointer */
+			skb->h.raw = skb->data + fragheaderlen;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = 0;
+			sk->sk_sndmsg_off = 0;
+		}
+		err = skb_append_datato_frags(sk,skb, getfrag, from,
+				       (length - transhdrlen));
+		if (!err) {
+			/* specify the length of each IP datagram fragment*/
+			skb_shinfo(skb)->uso_size = (mtu - fragheaderlen);
+			__skb_queue_tail(&sk->sk_write_queue, skb);
+			return 0;
+		} else {
+			/* There is not enough support do UPD LSO,
+			 * so follow normal path
+			 */
+			kfree_skb(skb);
+			goto error;
+		}
+	}
+
 
 	/* So, what's going on in the loop below?
 	 *
@@ -1012,14 +1053,23 @@
 		return -EINVAL;
 
 	inet->cork.length += size;
+	if ((sk->sk_protocol == IPPROTO_UDP) &&
+	    (rt->u.dst.dev->features & NETIF_F_USO))
+		skb_shinfo(skb)->uso_size = (mtu - fragheaderlen);
+
 
 	while (size > 0) {
 		int i;
 
-		/* Check if the remaining data fits into current packet. */
-		len = mtu - skb->len;
-		if (len < size)
-			len = maxfraglen - skb->len;
+		if (skb_shinfo(skb)->uso_size) {
+			len = size;
+		} else {
+
+			/* Check if the remaining data fits into current packet. */
+			len = mtu - skb->len;
+			if (len < size)
+				len = maxfraglen - skb->len;
+		}
 		if (len <= 0) {
 			struct sk_buff *skb_prev;
 			char *data;
diff -uNr linux-2.6.13/net/ipv6/ip6_output.c linux-2.6.13_uso/net/ipv6/ip6_output.c
--- linux-2.6.13/net/ipv6/ip6_output.c	2005-09-07 04:21:57.000000000 -0700
+++ linux-2.6.13_uso/net/ipv6/ip6_output.c	2005-09-13 07:11:10.000000000 -0700
@@ -147,7 +147,8 @@
 
 int ip6_output(struct sk_buff *skb)
 {
-	if (skb->len > dst_mtu(skb->dst) || dst_allfrag(skb->dst))
+	if ((skb->len > dst_mtu(skb->dst) && !skb_shinfo(skb)->uso_size) ||
+				dst_allfrag(skb->dst))
 		return ip6_fragment(skb, ip6_output2);
 	else
 		return ip6_output2(skb);
@@ -893,6 +894,50 @@
 	 */
 
 	inet->cork.length += length;
+	if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) &&
+	    (rt->u.dst.dev->features & NETIF_F_USO)) {
+		/* There is support for UDP large send offload by network
+		 * device, so create one single skb packet containing complete
+		 * udp datagram
+		 */
+		if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
+			skb = sock_alloc_send_skb(sk,
+				hh_len + fragheaderlen + transhdrlen + 20,
+				(flags & MSG_DONTWAIT), &err);
+			if (skb == NULL)
+				goto error;
+			/* reserve space for Hardware header */
+			skb_reserve(skb, hh_len);
+			/* create space for UDP/IP header */
+			skb_put(skb,fragheaderlen + transhdrlen);
+			/* initialize network header pointer */
+			skb->nh.raw = skb->data;
+			/* initialize protocol header pointer */
+			skb->h.raw = skb->data + fragheaderlen;
+			skb->ip_summed = CHECKSUM_HW;
+			skb->csum = 0;
+			sk->sk_sndmsg_off = 0;
+		}
+		err = skb_append_datato_frags(sk,skb, getfrag, from,
+					      (length - transhdrlen));
+		if (!err) {
+			struct frag_hdr fhdr;
+
+			/* specify the length of each IP datagram fragment*/
+			skb_shinfo(skb)->uso_size = (mtu - fragheaderlen) - 
+							sizeof(struct frag_hdr);
+			ipv6_select_ident(skb, &fhdr);
+			skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
+			__skb_queue_tail(&sk->sk_write_queue, skb);
+			return 0;
+		} else {
+			/* There is not enough support do UPD LSO,
+			 * so follow normal path
+			 */
+			kfree_skb(skb);
+			goto error;
+		}
+	}
 
 	if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL)
 		goto alloc_new_skb;

^ permalink raw reply

* Re: [patch 9/11] net: dst_entry.refcount, use, lastuse to use alloc_percpu
From: Rusty Russell @ 2005-09-14  7:21 UTC (permalink / raw)
  To: David S. Miller
  Cc: kiran, akpm, linux-kernel, dipankar, bharata, shai, netdev
In-Reply-To: <20050913.162748.86496945.davem@davemloft.net>

On Tue, 2005-09-13 at 16:27 -0700, David S. Miller wrote:
> From: Ravikiran G Thirumalai <kiran@scalex86.org>
> Date: Tue, 13 Sep 2005 16:17:17 -0700
> 
> > But even 1 Million dst cache entries would be 16+4 MB additional for
> > a 4 cpu box....is that too much?
> 
> Absolutely.
> 
> Per-cpu counters are great for things like single instance
> statistics et al.  But once you start doing them per-object
> that's out of control bloat as far as I'm concerned.

This is why my original per-cpu allocator patch was damn slow, and
GFP_KERNEL only.  I wasn't convinced that high-churn objects are a good
fit for spreading across cpus.

I thought that net devices and modules (which uses a primitive
hard-coded "bigref" currently) were a fair uses for bigrefs, though I'd
like to see some stats.

Cheers,
Rusty.
-- 
A bad analogy is like a leaky screwdriver -- Richard Braakman

^ permalink raw reply

* Re: Route cache performance
From: Robert Olsson @ 2005-09-14  8:04 UTC (permalink / raw)
  To: Simon Kirby; +Cc: Alexey Kuznetsov, Robert Olsson, Eric Dumazet, netdev
In-Reply-To: <20050913221448.GD15704@netnation.com>


Simon Kirby writes:


 > Sender: 367 Mbps, 717883 pps valid src/dst, 64 byte (Ethernet) packets
 > 
 > 2.4.27-rc1: 297 Mbps forwarded (w/idle time?!)
 > 2.4.31: 296 Mbps forwarded (w/idle time?!)
 > 2.6.13-rc6: 173 Mbps forwarded

 > Time permitting, I'd also like to run some profiles.  It's interesting
 > to note that 2.6 is slower at forwarding even straight duplicate small
 > packets.  We should definitely get to the bottom of that.

 Yes. This is single flow? Strange.

 Run a fixed size shot 10Mpkts pkts or so for both 2.4 and 2.6 and save 
 /proc/interrupts, proc/net/softnetstat, netstat -i, tc -s qdisc to start with.
 
 A profile on 2.6 could solve the confusion.

 Cheers.
						--ro

 

^ permalink raw reply

* Re: [PATCH 2.6.13] pcnet32: set min ring size to 4
From: Jeff Garzik @ 2005-09-14 12:28 UTC (permalink / raw)
  To: Hubert WS Lin; +Cc: netdev, linux-kernel, fubar, donf, jklewis
In-Reply-To: <4325298D.1010600@tw.ibm.com>

Hubert WS Lin wrote:
> Hi,
> 
> Don Fry reminded me that the pcnet32_loopback_test() asssumes the ring 
> size is no less than 4. The minimum ring size was changed to 4 in 
> pcnet32_set_ringparam() to allow the loopback test to work unchanged.
> 
> Changelog:
> - Set minimum ring size to 4 to allow loopback test to work unchanged
> - Moved variable init_block to first field in struct pcnet32_private
> 
> Signed-off-by: Hubert WS Lin <wslin@tw.ibm.com>

Patch OK, but:

Applying 'pcnet32: set min ring size to 4'

error: patch failed: drivers/net/pcnet32.c:22
error: drivers/net/pcnet32.c: patch does not apply


Please resend, without MIME attachments.

	Jeff

^ permalink raw reply

* Re: [PATCH 1/3] orinoco: WE-18 support
From: Jeff Garzik @ 2005-09-14 12:31 UTC (permalink / raw)
  To: Pavel Roskin
  Cc: Orinoco Development List, netdev-u79uwXL29TY76Z2rM5mHXA,
	Jean Tourrilhes
In-Reply-To: <1126305782.16679.5.camel@dv>

Pavel Roskin wrote:
> Author: Jean Tourrilhes <jt-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
> 
> Use new Wireless Extension API for wireless stats.

Applied patch #1, the rest failed:


[jgarzik@pretzel netdev-2.6]$ applymbox /g/tmp/mbox ~/info/signoff.txt

Applying 'orinoco: WE-18 support'

Wrote tree 2713fbd5e71f7a7dbe94634a1bc4eb81a1ed8af5
Committed: 343c686c04eec556645f251f7d6c9b3d7335dae0

Applying 'orinoco: Update PCMCIA ID's'

error: patch failed: drivers/net/wireless/orinoco_cs.c:601
error: drivers/net/wireless/orinoco_cs.c: patch does not apply



-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl

^ permalink raw reply

* Re: [PATCH 1/2] New PowerPC 4xx on-chip ethernet controller driver
From: Jeff Garzik @ 2005-09-14 12:45 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: netdev, linuxppc-embedded
In-Reply-To: <20050831050048.GB17017@gate.ebshome.net>

Eugene Surovegin wrote:
> Remove old PPC4xx EMAC driver
> 
> Signed-off-by: Eugene Surovegin <ebs@ebshome.net>

Please post a diff, along with a description of the changes.

One huge patch to "remove emac driver" and another huge patch to "add 
emac driver" is quite silly.

	Jeff

^ permalink raw reply

* [git patches] net driver fixes
From: Jeff Garzik @ 2005-09-14 13:14 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please pull from 'upstream-fixes' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to obtain the following fixes:


 drivers/net/Kconfig            |    2 
 drivers/net/e100.c             |    4 -
 drivers/net/e1000/e1000_main.c |    1 
 drivers/net/ixgb/ixgb_main.c   |    2 
 drivers/net/s2io.c             |    9 ++-
 drivers/net/sk98lin/skge.c     |   12 ++---
 drivers/net/skge.c             |   98 ++++++++++++++++++++++-------------------
 drivers/net/skge.h             |    2 
 drivers/net/tulip/xircom_cb.c  |    2 
 drivers/net/wireless/airo.c    |    5 +-
 drivers/s390/net/ctcmain.c     |   41 +++++++++--------
 11 files changed, 94 insertions(+), 84 deletions(-)



Andrew Morton:
  s2io warning fixes

Frank Pavlic:
  s390: ctc driver fixes

John W. Linville:
  e1000: correct rx_dropped counting
  e100: correct rx_dropped and add rx_missed_errors
  ixgb: correct rx_dropped counting

Keith Owens:
  Correct xircom_cb use of CONFIG_NET_POLL_CONTROLLER

matthieu castet:
  airo : fix channel number in scan

Stephen Hemminger:
  sk98lin: remove PCI id info for cards for conflicting devices
  skge: gmac register access errors in dual port



diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1951,7 +1951,7 @@ config SKGE
 	---help---
 	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
 	  and related Gigabit Ethernet adapters. It is a new smaller driver
-	  driver with better performance and more complete ethtool support.
+	  with better performance and more complete ethtool support.
 
 	  It does not support the link failover and network management 
 	  features that "portable" vendor supplied sk98lin driver does.
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1387,13 +1387,13 @@ static void e100_update_stats(struct nic
 		ns->collisions += nic->tx_collisions;
 		ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
 			le32_to_cpu(s->tx_lost_crs);
-		ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
 		ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
 			nic->rx_over_length_errors;
 		ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
 		ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
 		ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
 		ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
+		ns->rx_missed_errors += le32_to_cpu(s->rx_resource_errors);
 		ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
 			le32_to_cpu(s->rx_alignment_errors) +
 			le32_to_cpu(s->rx_short_frame_errors) +
@@ -1727,12 +1727,10 @@ static inline int e100_rx_indicate(struc
 
 	if(unlikely(!(rfd_status & cb_ok))) {
 		/* Don't indicate if hardware indicates errors */
-		nic->net_stats.rx_dropped++;
 		dev_kfree_skb_any(skb);
 	} else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
 		/* Don't indicate oversized frames */
 		nic->rx_over_length_errors++;
-		nic->net_stats.rx_dropped++;
 		dev_kfree_skb_any(skb);
 	} else {
 		nic->net_stats.rx_packets++;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2544,7 +2544,6 @@ e1000_update_stats(struct e1000_adapter 
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.rlec + adapter->stats.mpc + 
 		adapter->stats.cexterr;
-	adapter->net_stats.rx_dropped = adapter->stats.mpc;
 	adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
 	adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1616,8 +1616,6 @@ ixgb_update_stats(struct ixgb_adapter *a
 	    adapter->stats.icbc +
 	    adapter->stats.ecbc + adapter->stats.mpc;
 
-	adapter->net_stats.rx_dropped = adapter->stats.mpc;
-
 	/* see above
 	 * adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	 */
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -428,7 +428,7 @@ static int init_shared_mem(struct s2io_n
 				DBG_PRINT(INIT_DBG, 
 				"%s: Zero DMA address for TxDL. ", dev->name);
 				DBG_PRINT(INIT_DBG, 
-				"Virtual address %llx\n", (u64)tmp_v);
+				"Virtual address %p\n", tmp_v);
 				tmp_v = pci_alloc_consistent(nic->pdev,
 						     PAGE_SIZE, &tmp_p);
 				if (!tmp_v) {
@@ -657,9 +657,10 @@ static void free_shared_mem(struct s2io_
 					    mac_control->zerodma_virt_addr,
 					    (dma_addr_t)0);
 			DBG_PRINT(INIT_DBG, 
-			"%s: Freeing TxDL with zero DMA addr. ", dev->name);
-			DBG_PRINT(INIT_DBG, "Virtual address %llx\n",
-			(u64)(mac_control->zerodma_virt_addr));
+			  	"%s: Freeing TxDL with zero DMA addr. ",
+				dev->name);
+			DBG_PRINT(INIT_DBG, "Virtual address %p\n",
+				mac_control->zerodma_virt_addr);
 		}
 		kfree(mac_control->fifos[i].list_info);
 	}
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -5216,17 +5216,15 @@ static struct pci_device_id skge_pci_tbl
 	{ PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+/* DLink card does not have valid VPD so this driver gags
+ *	{ PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ */
 	{ PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#if 0	/* don't handle Yukon2 cards at the moment -- mlindner@syskonnect.de */
-	{ PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-#endif
 	{ PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
 	{ PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
-	{ 0, }
+	{ 0 }
 };
 
 MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -42,7 +42,7 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"0.9"
+#define DRV_VERSION		"1.0"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
@@ -669,7 +669,7 @@ static void skge_led(struct skge_port *s
 				     PHY_M_LED_BLINK_RT(BLINK_84MS) |
 				     PHY_M_LEDC_TX_CTRL |
 				     PHY_M_LEDC_DP_CTRL);
-		
+
 			gm_phy_write(hw, port, PHY_MARV_LED_OVER,
 				     PHY_M_LED_MO_RX(MO_LED_OFF) |
 				     (skge->speed == SPEED_100 ?
@@ -876,7 +876,7 @@ static int skge_rx_fill(struct skge_port
 
 static void skge_link_up(struct skge_port *skge)
 {
-	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), 
+	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
 		    LED_BLK_OFF|LED_SYNC_OFF|LED_ON);
 
 	netif_carrier_on(skge->netdev);
@@ -987,6 +987,8 @@ static void genesis_reset(struct skge_hw
 {
 	const u8 zero[8]  = { 0 };
 
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+
 	/* reset the statistics module */
 	xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
 	xm_write16(hw, port, XM_IMSK, 0xffff);	/* disable XMAC IRQs */
@@ -1021,8 +1023,6 @@ static void bcom_check_link(struct skge_
 	(void) xm_phy_read(hw, port, PHY_BCOM_STAT);
 	status = xm_phy_read(hw, port, PHY_BCOM_STAT);
 
-	pr_debug("bcom_check_link status=0x%x\n", status);
-
 	if ((status & PHY_ST_LSYNC) == 0) {
 		u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
 		cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
@@ -1106,8 +1106,6 @@ static void bcom_phy_init(struct skge_po
 		{ 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
 	};
 
-	pr_debug("bcom_phy_init\n");
-
 	/* read Id from external PHY (all have the same address) */
 	id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
 
@@ -1340,6 +1338,8 @@ static void genesis_stop(struct skge_por
 	int port = skge->port;
 	u32 reg;
 
+	genesis_reset(hw, port);
+
 	/* Clear Tx packet arbiter timeout IRQ */
 	skge_write16(hw, B3_PA_CTRL,
 		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
@@ -1465,7 +1465,6 @@ static void genesis_link_up(struct skge_
 	u16 cmd;
 	u32 mode, msk;
 
-	pr_debug("genesis_link_up\n");
 	cmd = xm_read16(hw, port, XM_MMU_CMD);
 
 	/*
@@ -1578,7 +1577,6 @@ static void yukon_init(struct skge_hw *h
 	struct skge_port *skge = netdev_priv(hw->dev[port]);
 	u16 ctrl, ct1000, adv;
 
-	pr_debug("yukon_init\n");
 	if (skge->autoneg == AUTONEG_ENABLE) {
 		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
@@ -1677,9 +1675,11 @@ static void yukon_mac_init(struct skge_h
 
 	/* WA code for COMA mode -- set PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
-		skge_write32(hw, B2_GP_IO,
-			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		reg = skge_read32(hw, B2_GP_IO);
+		reg |= GP_DIR_9 | GP_IO_9;
+		skge_write32(hw, B2_GP_IO, reg);
+	}
 
 	/* hard reset */
 	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
@@ -1687,10 +1687,12 @@ static void yukon_mac_init(struct skge_h
 
 	/* WA code for COMA mode -- clear PHY reset */
 	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3)
-		skge_write32(hw, B2_GP_IO,
-			     (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
-			     & ~GP_IO_9);
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		reg = skge_read32(hw, B2_GP_IO);
+		reg |= GP_DIR_9;
+		reg &= ~GP_IO_9;
+		skge_write32(hw, B2_GP_IO, reg);
+	}
 
 	/* Set hardware config mode */
 	reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
@@ -1729,7 +1731,7 @@ static void yukon_mac_init(struct skge_h
 	}
 
 	gma_write16(hw, port, GM_GP_CTRL, reg);
-	skge_read16(hw, GMAC_IRQ_SRC);
+	skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
 
 	yukon_init(hw, port);
 
@@ -1801,20 +1803,26 @@ static void yukon_stop(struct skge_port 
 	struct skge_hw *hw = skge->hw;
 	int port = skge->port;
 
-	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
-		skge_write32(hw, B2_GP_IO,
-			     skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
-	}
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
+	yukon_reset(hw, port);
 
 	gma_write16(hw, port, GM_GP_CTRL,
 			 gma_read16(hw, port, GM_GP_CTRL)
 			 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
 	gma_read16(hw, port, GM_GP_CTRL);
 
+	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
+	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
+		u32 io = skge_read32(hw, B2_GP_IO);
+
+		io |= GP_DIR_9 | GP_IO_9;
+		skge_write32(hw, B2_GP_IO, io);
+		skge_read32(hw, B2_GP_IO);
+	}
+
 	/* set GPHY Control reset */
-	skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
-	skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
+	skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
+	skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
 }
 
 static void yukon_get_stats(struct skge_port *skge, u64 *data)
@@ -1873,10 +1881,8 @@ static void yukon_link_up(struct skge_po
 	int port = skge->port;
 	u16 reg;
 
-	pr_debug("yukon_link_up\n");
-
 	/* Enable Transmit FIFO Underrun */
-	skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
+	skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
 
 	reg = gma_read16(hw, port, GM_GP_CTRL);
 	if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
@@ -1896,7 +1902,6 @@ static void yukon_link_down(struct skge_
 	int port = skge->port;
 	u16 ctrl;
 
-	pr_debug("yukon_link_down\n");
 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
 
 	ctrl = gma_read16(hw, port, GM_GP_CTRL);
@@ -2112,7 +2117,6 @@ static int skge_up(struct net_device *de
 	skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F);
 	skge_led(skge, LED_MODE_ON);
 
-	pr_debug("skge_up completed\n");
 	return 0;
 
  free_rx_ring:
@@ -2135,15 +2139,20 @@ static int skge_down(struct net_device *
 
 	netif_stop_queue(dev);
 
+	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
+	if (hw->chip_id == CHIP_ID_GENESIS)
+		genesis_stop(skge);
+	else
+		yukon_stop(skge);
+
+	hw->intr_mask &= ~portirqmask[skge->port];
+	skge_write32(hw, B0_IMSK, hw->intr_mask);
+
 	/* Stop transmitter */
 	skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
 	skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
 		     RB_RST_SET|RB_DIS_OP_MD);
 
-	if (hw->chip_id == CHIP_ID_GENESIS)
-		genesis_stop(skge);
-	else
-		yukon_stop(skge);
 
 	/* Disable Force Sync bit and Enable Alloc bit */
 	skge_write8(hw, SK_REG(port, TXA_CTRL),
@@ -2367,8 +2376,6 @@ static void genesis_set_multicast(struct
 	u32 mode;
 	u8 filter[8];
 
-	pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count);
-
 	mode = xm_read32(hw, port, XM_MODE);
 	mode |= XM_MD_ENA_HASH;
 	if (dev->flags & IFF_PROMISC)
@@ -2530,8 +2537,6 @@ static int skge_poll(struct net_device *
 	unsigned int to_do = min(dev->quota, *budget);
 	unsigned int work_done = 0;
 
-	pr_debug("skge_poll\n");
-
 	for (e = ring->to_clean; work_done < to_do; e = e->next) {
 		struct skge_rx_desc *rd = e->desc;
 		struct sk_buff *skb;
@@ -2672,9 +2677,9 @@ static void skge_error_irq(struct skge_h
 	if (hw->chip_id == CHIP_ID_GENESIS) {
 		/* clear xmac errors */
 		if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
-			skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
+			skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT);
 		if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
-			skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
+			skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT);
 	} else {
 		/* Timestamp (unused) overflow */
 		if (hwstatus & IS_IRQ_TIST_OV)
@@ -3000,9 +3005,6 @@ static int skge_reset(struct skge_hw *hw
 
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
-	if (hw->chip_id != CHIP_ID_GENESIS)
-		skge_write8(hw, GMAC_IRQ_MSK, 0);
-
 	spin_lock_bh(&hw->phy_lock);
 	for (i = 0; i < hw->ports; i++) {
 		if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3230,6 +3232,11 @@ static void __devexit skge_remove(struct
 	dev0 = hw->dev[0];
 	unregister_netdev(dev0);
 
+	skge_write32(hw, B0_IMSK, 0);
+	skge_write16(hw, B0_LED, LED_STAT_OFF);
+	skge_pci_clear(hw);
+	skge_write8(hw, B0_CTST, CS_RST_SET);
+
 	tasklet_kill(&hw->ext_tasklet);
 
 	free_irq(pdev->irq, hw);
@@ -3238,7 +3245,7 @@ static void __devexit skge_remove(struct
 	if (dev1)
 		free_netdev(dev1);
 	free_netdev(dev0);
-	skge_write16(hw, B0_LED, LED_STAT_OFF);
+
 	iounmap(hw->regs);
 	kfree(hw);
 	pci_set_drvdata(pdev, NULL);
@@ -3257,7 +3264,10 @@ static int skge_suspend(struct pci_dev *
 			struct skge_port *skge = netdev_priv(dev);
 			if (netif_running(dev)) {
 				netif_carrier_off(dev);
-				skge_down(dev);
+				if (skge->wol)
+					netif_stop_queue(dev);
+				else
+					skge_down(dev);
 			}
 			netif_device_detach(dev);
 			wol |= skge->wol;
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -2008,7 +2008,7 @@ enum {
 	GM_IS_RX_FF_OR	= 1<<1,	/* Receive FIFO Overrun */
 	GM_IS_RX_COMPL	= 1<<0,	/* Frame Reception Complete */
 
-#define GMAC_DEF_MSK	(GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | GM_IS_TX_FF_UR)
+#define GMAC_DEF_MSK	(GM_IS_RX_FF_OR | GM_IS_TX_FF_UR)
 
 /*	GMAC_LINK_CTRL	16 bit	GMAC Link Control Reg (YUKON only) */
 						/* Bits 15.. 2:	reserved */
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -117,7 +117,7 @@ static int xircom_open(struct net_device
 static int xircom_close(struct net_device *dev);
 static void xircom_up(struct xircom_private *card);
 static struct net_device_stats *xircom_get_stats(struct net_device *dev);
-#if CONFIG_NET_POLL_CONTROLLER
+#ifdef CONFIG_NET_POLL_CONTROLLER
 static void xircom_poll_controller(struct net_device *dev);
 #endif
 
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -6852,7 +6852,10 @@ static inline char *airo_translate_scan(
 	/* Add frequency */
 	iwe.cmd = SIOCGIWFREQ;
 	iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
-	iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
+	/* iwe.u.freq.m containt the channel (starting 1), our 
+	 * frequency_list array start at index 0...
+	 */
+	iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
 	iwe.u.freq.e = 1;
 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
 
diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
--- a/drivers/s390/net/ctcmain.c
+++ b/drivers/s390/net/ctcmain.c
@@ -1,5 +1,5 @@
 /*
- * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
+ * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $
  *
  * CTC / ESCON network driver
  *
@@ -37,10 +37,9 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
+ * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $
  *
  */
-\f
 #undef DEBUG
 #include <linux/module.h>
 #include <linux/init.h>
@@ -135,7 +134,7 @@ static const char *dev_event_names[] = {
 	"TX down",
 	"Restart",
 };
-\f
+
 /**
  * Events of the channel statemachine
  */
@@ -249,7 +248,7 @@ static void
 print_banner(void)
 {
 	static int printed = 0;
-	char vbuf[] = "$Revision: 1.74 $";
+	char vbuf[] = "$Revision: 1.78 $";
 	char *version = vbuf;
 
 	if (printed)
@@ -334,7 +333,7 @@ static const char *ch_state_names[] = {
 	"Restarting",
 	"Not operational",
 };
-\f
+
 #ifdef DEBUG
 /**
  * Dump header and first 16 bytes of an sk_buff for debugging purposes.
@@ -671,7 +670,7 @@ static void
 fsm_action_nop(fsm_instance * fi, int event, void *arg)
 {
 }
-\f
+
 /**
  * Actions for channel - statemachines.
  *****************************************************************************/
@@ -1514,7 +1513,6 @@ ch_action_reinit(fsm_instance *fi, int e
  	fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, dev);
 }
 
-\f
 /**
  * The statemachine for a channel.
  */
@@ -1625,7 +1623,7 @@ static const fsm_node ch_fsm[] = {
 };
 
 static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
-\f
+
 /**
  * Functions related to setup and device detection.
  *****************************************************************************/
@@ -1976,7 +1974,7 @@ ctc_irq_handler(struct ccw_device *cdev,
 		fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
 
 }
-\f
+
 /**
  * Actions for interface - statemachine.
  *****************************************************************************/
@@ -2209,13 +2207,18 @@ transmit_skb(struct channel *ch, struct 
 	int rc = 0;
 
 	DBF_TEXT(trace, 5, __FUNCTION__);
+	/* we need to acquire the lock for testing the state
+	 * otherwise we can have an IRQ changing the state to 
+	 * TXIDLE after the test but before acquiring the lock.
+	 */
+	spin_lock_irqsave(&ch->collect_lock, saveflags);
 	if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
 		int l = skb->len + LL_HEADER_LENGTH;
 
-		spin_lock_irqsave(&ch->collect_lock, saveflags);
-		if (ch->collect_len + l > ch->max_bufsize - 2)
-			rc = -EBUSY;
-		else {
+		if (ch->collect_len + l > ch->max_bufsize - 2) {
+			spin_unlock_irqrestore(&ch->collect_lock, saveflags);
+			return -EBUSY;
+		} else {
 			atomic_inc(&skb->users);
 			header.length = l;
 			header.type = skb->protocol;
@@ -2231,7 +2234,7 @@ transmit_skb(struct channel *ch, struct 
 		int ccw_idx;
 		struct sk_buff *nskb;
 		unsigned long hi;
-
+		spin_unlock_irqrestore(&ch->collect_lock, saveflags);
 		/**
 		 * Protect skb against beeing free'd by upper
 		 * layers.
@@ -2256,6 +2259,7 @@ transmit_skb(struct channel *ch, struct 
 			if (!nskb) {
 				atomic_dec(&skb->users);
 				skb_pull(skb, LL_HEADER_LENGTH + 2);
+				ctc_clear_busy(ch->netdev);
 				return -ENOMEM;
 			} else {
 				memcpy(skb_put(nskb, skb->len),
@@ -2281,6 +2285,7 @@ transmit_skb(struct channel *ch, struct 
 				 */
 				atomic_dec(&skb->users);
 				skb_pull(skb, LL_HEADER_LENGTH + 2);
+				ctc_clear_busy(ch->netdev);
 				return -EBUSY;
 			}
 
@@ -2327,9 +2332,10 @@ transmit_skb(struct channel *ch, struct 
 		}
 	}
 
+	ctc_clear_busy(ch->netdev);
 	return rc;
 }
-\f
+
 /**
  * Interface API for upper network layers
  *****************************************************************************/
@@ -2421,7 +2427,6 @@ ctc_tx(struct sk_buff *skb, struct net_d
 	dev->trans_start = jiffies;
 	if (transmit_skb(privptr->channel[WRITE], skb) != 0)
 		rc = 1;
-	ctc_clear_busy(dev);
 	return rc;
 }
 
@@ -2610,7 +2615,6 @@ stats_write(struct device *dev, struct d
 	return count;
 }
 
-\f
 static void
 ctc_netdev_unregister(struct net_device * dev)
 {
@@ -2685,7 +2689,6 @@ ctc_proto_store(struct device *dev, stru
 	return count;
 }
 
-
 static ssize_t
 ctc_type_show(struct device *dev, struct device_attribute *attr, char *buf)
 {

^ permalink raw reply

* Re: [git patches] net driver fixes
From: Frank Pavlic @ 2005-09-14 15:38 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linux-kernel
In-Reply-To: <20050914131414.GA1095@havoc.gtf.org>

Jeff ,
didn't you get the qeth patches ? let me know if not I will resend them 
once again ....
Thanks



linux-kernel-owner@vger.kernel.org wrote on 14.09.2005 15:14:14:

> 
> Please pull from 'upstream-fixes' branch of
> rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
> 
> to obtain the following fixes:
> 
> 
>  drivers/net/Kconfig            |    2 
>  drivers/net/e100.c             |    4 -
>  drivers/net/e1000/e1000_main.c |    1 
>  drivers/net/ixgb/ixgb_main.c   |    2 
>  drivers/net/s2io.c             |    9 ++-
>  drivers/net/sk98lin/skge.c     |   12 ++---
>  drivers/net/skge.c             |   98 
> ++++++++++++++++++++++-------------------
>  drivers/net/skge.h             |    2 
>  drivers/net/tulip/xircom_cb.c  |    2 
>  drivers/net/wireless/airo.c    |    5 +-
>  drivers/s390/net/ctcmain.c     |   41 +++++++++--------
>  11 files changed, 94 insertions(+), 84 deletions(-)
> 
> 
> 
> Andrew Morton:
>   s2io warning fixes
> 
> Frank Pavlic:
>   s390: ctc driver fixes
> 
> John W. Linville:
>   e1000: correct rx_dropped counting
>   e100: correct rx_dropped and add rx_missed_errors
>   ixgb: correct rx_dropped counting
> 
> Keith Owens:
>   Correct xircom_cb use of CONFIG_NET_POLL_CONTROLLER
> 
> matthieu castet:
>   airo : fix channel number in scan
> 
> Stephen Hemminger:
>   sk98lin: remove PCI id info for cards for conflicting devices
>   skge: gmac register access errors in dual port
> 
> 
> 
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1951,7 +1951,7 @@ config SKGE
>     ---help---
>       This driver support the Marvell Yukon or SysKonnect 
SK-98xx/SK-95xx
>       and related Gigabit Ethernet adapters. It is a new smaller driver
> -     driver with better performance and more complete ethtool support.
> +     with better performance and more complete ethtool support.
> 
>       It does not support the link failover and network management 
>       features that "portable" vendor supplied sk98lin driver does.
> diff --git a/drivers/net/e100.c b/drivers/net/e100.c
> --- a/drivers/net/e100.c
> +++ b/drivers/net/e100.c
> @@ -1387,13 +1387,13 @@ static void e100_update_stats(struct nic
>        ns->collisions += nic->tx_collisions;
>        ns->tx_errors += le32_to_cpu(s->tx_max_collisions) +
>           le32_to_cpu(s->tx_lost_crs);
> -      ns->rx_dropped += le32_to_cpu(s->rx_resource_errors);
>        ns->rx_length_errors += le32_to_cpu(s->rx_short_frame_errors) +
>           nic->rx_over_length_errors;
>        ns->rx_crc_errors += le32_to_cpu(s->rx_crc_errors);
>        ns->rx_frame_errors += le32_to_cpu(s->rx_alignment_errors);
>        ns->rx_over_errors += le32_to_cpu(s->rx_overrun_errors);
>        ns->rx_fifo_errors += le32_to_cpu(s->rx_overrun_errors);
> +      ns->rx_missed_errors += le32_to_cpu(s->rx_resource_errors);
>        ns->rx_errors += le32_to_cpu(s->rx_crc_errors) +
>           le32_to_cpu(s->rx_alignment_errors) +
>           le32_to_cpu(s->rx_short_frame_errors) +
> @@ -1727,12 +1727,10 @@ static inline int e100_rx_indicate(struc
> 
>     if(unlikely(!(rfd_status & cb_ok))) {
>        /* Don't indicate if hardware indicates errors */
> -      nic->net_stats.rx_dropped++;
>        dev_kfree_skb_any(skb);
>     } else if(actual_size > ETH_DATA_LEN + VLAN_ETH_HLEN) {
>        /* Don't indicate oversized frames */
>        nic->rx_over_length_errors++;
> -      nic->net_stats.rx_dropped++;
>        dev_kfree_skb_any(skb);
>     } else {
>        nic->net_stats.rx_packets++;
> diff --git a/drivers/net/e1000/e1000_main.c 
b/drivers/net/e1000/e1000_main.c
> --- a/drivers/net/e1000/e1000_main.c
> +++ b/drivers/net/e1000/e1000_main.c
> @@ -2544,7 +2544,6 @@ e1000_update_stats(struct e1000_adapter 
>        adapter->stats.crcerrs + adapter->stats.algnerrc +
>        adapter->stats.rlec + adapter->stats.mpc + 
>        adapter->stats.cexterr;
> -   adapter->net_stats.rx_dropped = adapter->stats.mpc;
>     adapter->net_stats.rx_length_errors = adapter->stats.rlec;
>     adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
>     adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc;
> diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
> --- a/drivers/net/ixgb/ixgb_main.c
> +++ b/drivers/net/ixgb/ixgb_main.c
> @@ -1616,8 +1616,6 @@ ixgb_update_stats(struct ixgb_adapter *a
>         adapter->stats.icbc +
>         adapter->stats.ecbc + adapter->stats.mpc;
> 
> -   adapter->net_stats.rx_dropped = adapter->stats.mpc;
> -
>     /* see above
>      * adapter->net_stats.rx_length_errors = adapter->stats.rlec;
>      */
> diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
> --- a/drivers/net/s2io.c
> +++ b/drivers/net/s2io.c
> @@ -428,7 +428,7 @@ static int init_shared_mem(struct s2io_n
>              DBG_PRINT(INIT_DBG, 
>              "%s: Zero DMA address for TxDL. ", dev->name);
>              DBG_PRINT(INIT_DBG, 
> -            "Virtual address %llx\n", (u64)tmp_v);
> +            "Virtual address %p\n", tmp_v);
>              tmp_v = pci_alloc_consistent(nic->pdev,
>                         PAGE_SIZE, &tmp_p);
>              if (!tmp_v) {
> @@ -657,9 +657,10 @@ static void free_shared_mem(struct s2io_
>                     mac_control->zerodma_virt_addr,
>                     (dma_addr_t)0);
>           DBG_PRINT(INIT_DBG, 
> -         "%s: Freeing TxDL with zero DMA addr. ", dev->name);
> -         DBG_PRINT(INIT_DBG, "Virtual address %llx\n",
> -         (u64)(mac_control->zerodma_virt_addr));
> +              "%s: Freeing TxDL with zero DMA addr. ",
> +            dev->name);
> +         DBG_PRINT(INIT_DBG, "Virtual address %p\n",
> +            mac_control->zerodma_virt_addr);
>        }
>        kfree(mac_control->fifos[i].list_info);
>     }
> diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
> --- a/drivers/net/sk98lin/skge.c
> +++ b/drivers/net/sk98lin/skge.c
> @@ -5216,17 +5216,15 @@ static struct pci_device_id skge_pci_tbl
>     { PCI_VENDOR_ID_3COM, 0x80eb, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
>     { PCI_VENDOR_ID_SYSKONNECT, 0x4300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 
},
>     { PCI_VENDOR_ID_SYSKONNECT, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 
},
> -   { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> +/* DLink card does not have valid VPD so this driver gags
> + *   { PCI_VENDOR_ID_DLINK, 0x4c00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> + */
>     { PCI_VENDOR_ID_MARVELL, 0x4320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> -#if 0   /* don't handle Yukon2 cards at the moment -- 
> mlindner@syskonnect.de */
> -   { PCI_VENDOR_ID_MARVELL, 0x4360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> -   { PCI_VENDOR_ID_MARVELL, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> -#endif
>     { PCI_VENDOR_ID_MARVELL, 0x5005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
>     { PCI_VENDOR_ID_CNET, 0x434e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> -   { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> +   { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, },
>     { PCI_VENDOR_ID_LINKSYS, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
> -   { 0, }
> +   { 0 }
>  };
> 
>  MODULE_DEVICE_TABLE(pci, skge_pci_tbl);
> diff --git a/drivers/net/skge.c b/drivers/net/skge.c
> --- a/drivers/net/skge.c
> +++ b/drivers/net/skge.c
> @@ -42,7 +42,7 @@
>  #include "skge.h"
> 
>  #define DRV_NAME      "skge"
> -#define DRV_VERSION      "0.9"
> +#define DRV_VERSION      "1.0"
>  #define PFX         DRV_NAME " "
> 
>  #define DEFAULT_TX_RING_SIZE   128
> @@ -669,7 +669,7 @@ static void skge_led(struct skge_port *s
>                   PHY_M_LED_BLINK_RT(BLINK_84MS) |
>                   PHY_M_LEDC_TX_CTRL |
>                   PHY_M_LEDC_DP_CTRL);
> - 
> +
>           gm_phy_write(hw, port, PHY_MARV_LED_OVER,
>                   PHY_M_LED_MO_RX(MO_LED_OFF) |
>                   (skge->speed == SPEED_100 ?
> @@ -876,7 +876,7 @@ static int skge_rx_fill(struct skge_port
> 
>  static void skge_link_up(struct skge_port *skge)
>  {
> -   skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), 
> +   skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG),
>            LED_BLK_OFF|LED_SYNC_OFF|LED_ON);
> 
>     netif_carrier_on(skge->netdev);
> @@ -987,6 +987,8 @@ static void genesis_reset(struct skge_hw
>  {
>     const u8 zero[8]  = { 0 };
> 
> +   skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
> +
>     /* reset the statistics module */
>     xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT);
>     xm_write16(hw, port, XM_IMSK, 0xffff);   /* disable XMAC IRQs */
> @@ -1021,8 +1023,6 @@ static void bcom_check_link(struct skge_
>     (void) xm_phy_read(hw, port, PHY_BCOM_STAT);
>     status = xm_phy_read(hw, port, PHY_BCOM_STAT);
> 
> -   pr_debug("bcom_check_link status=0x%x\n", status);
> -
>     if ((status & PHY_ST_LSYNC) == 0) {
>        u16 cmd = xm_read16(hw, port, XM_MMU_CMD);
>        cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX);
> @@ -1106,8 +1106,6 @@ static void bcom_phy_init(struct skge_po
>        { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 },
>     };
> 
> -   pr_debug("bcom_phy_init\n");
> -
>     /* read Id from external PHY (all have the same address) */
>     id1 = xm_phy_read(hw, port, PHY_XMAC_ID1);
> 
> @@ -1340,6 +1338,8 @@ static void genesis_stop(struct skge_por
>     int port = skge->port;
>     u32 reg;
> 
> +   genesis_reset(hw, port);
> +
>     /* Clear Tx packet arbiter timeout IRQ */
>     skge_write16(hw, B3_PA_CTRL,
>             port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
> @@ -1465,7 +1465,6 @@ static void genesis_link_up(struct skge_
>     u16 cmd;
>     u32 mode, msk;
> 
> -   pr_debug("genesis_link_up\n");
>     cmd = xm_read16(hw, port, XM_MMU_CMD);
> 
>     /*
> @@ -1578,7 +1577,6 @@ static void yukon_init(struct skge_hw *h
>     struct skge_port *skge = netdev_priv(hw->dev[port]);
>     u16 ctrl, ct1000, adv;
> 
> -   pr_debug("yukon_init\n");
>     if (skge->autoneg == AUTONEG_ENABLE) {
>        u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
> 
> @@ -1677,9 +1675,11 @@ static void yukon_mac_init(struct skge_h
> 
>     /* WA code for COMA mode -- set PHY reset */
>     if (hw->chip_id == CHIP_ID_YUKON_LITE &&
> -       hw->chip_rev >= CHIP_REV_YU_LITE_A3)
> -      skge_write32(hw, B2_GP_IO,
> -              (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9));
> +       hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
> +      reg = skge_read32(hw, B2_GP_IO);
> +      reg |= GP_DIR_9 | GP_IO_9;
> +      skge_write32(hw, B2_GP_IO, reg);
> +   }
> 
>     /* hard reset */
>     skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
> @@ -1687,10 +1687,12 @@ static void yukon_mac_init(struct skge_h
> 
>     /* WA code for COMA mode -- clear PHY reset */
>     if (hw->chip_id == CHIP_ID_YUKON_LITE &&
> -       hw->chip_rev >= CHIP_REV_YU_LITE_A3)
> -      skge_write32(hw, B2_GP_IO,
> -              (skge_read32(hw, B2_GP_IO) | GP_DIR_9)
> -              & ~GP_IO_9);
> +       hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
> +      reg = skge_read32(hw, B2_GP_IO);
> +      reg |= GP_DIR_9;
> +      reg &= ~GP_IO_9;
> +      skge_write32(hw, B2_GP_IO, reg);
> +   }
> 
>     /* Set hardware config mode */
>     reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP |
> @@ -1729,7 +1731,7 @@ static void yukon_mac_init(struct skge_h
>     }
> 
>     gma_write16(hw, port, GM_GP_CTRL, reg);
> -   skge_read16(hw, GMAC_IRQ_SRC);
> +   skge_read16(hw, SK_REG(port, GMAC_IRQ_SRC));
> 
>     yukon_init(hw, port);
> 
> @@ -1801,20 +1803,26 @@ static void yukon_stop(struct skge_port 
>     struct skge_hw *hw = skge->hw;
>     int port = skge->port;
> 
> -   if (hw->chip_id == CHIP_ID_YUKON_LITE &&
> -       hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
> -      skge_write32(hw, B2_GP_IO,
> -              skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9);
> -   }
> +   skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), 0);
> +   yukon_reset(hw, port);
> 
>     gma_write16(hw, port, GM_GP_CTRL,
>            gma_read16(hw, port, GM_GP_CTRL)
>            & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
>     gma_read16(hw, port, GM_GP_CTRL);
> 
> +   if (hw->chip_id == CHIP_ID_YUKON_LITE &&
> +       hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
> +      u32 io = skge_read32(hw, B2_GP_IO);
> +
> +      io |= GP_DIR_9 | GP_IO_9;
> +      skge_write32(hw, B2_GP_IO, io);
> +      skge_read32(hw, B2_GP_IO);
> +   }
> +
>     /* set GPHY Control reset */
> -   skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
> -   skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
> +   skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
> +   skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET);
>  }
> 
>  static void yukon_get_stats(struct skge_port *skge, u64 *data)
> @@ -1873,10 +1881,8 @@ static void yukon_link_up(struct skge_po
>     int port = skge->port;
>     u16 reg;
> 
> -   pr_debug("yukon_link_up\n");
> -
>     /* Enable Transmit FIFO Underrun */
> -   skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK);
> +   skge_write8(hw, SK_REG(port, GMAC_IRQ_MSK), GMAC_DEF_MSK);
> 
>     reg = gma_read16(hw, port, GM_GP_CTRL);
>     if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE)
> @@ -1896,7 +1902,6 @@ static void yukon_link_down(struct skge_
>     int port = skge->port;
>     u16 ctrl;
> 
> -   pr_debug("yukon_link_down\n");
>     gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);
> 
>     ctrl = gma_read16(hw, port, GM_GP_CTRL);
> @@ -2112,7 +2117,6 @@ static int skge_up(struct net_device *de
>     skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | 
CSR_IRQ_CL_F);
>     skge_led(skge, LED_MODE_ON);
> 
> -   pr_debug("skge_up completed\n");
>     return 0;
> 
>   free_rx_ring:
> @@ -2135,15 +2139,20 @@ static int skge_down(struct net_device *
> 
>     netif_stop_queue(dev);
> 
> +   skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
> +   if (hw->chip_id == CHIP_ID_GENESIS)
> +      genesis_stop(skge);
> +   else
> +      yukon_stop(skge);
> +
> +   hw->intr_mask &= ~portirqmask[skge->port];
> +   skge_write32(hw, B0_IMSK, hw->intr_mask);
> +
>     /* Stop transmitter */
>     skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP);
>     skge_write32(hw, RB_ADDR(txqaddr[port], RB_CTRL),
>             RB_RST_SET|RB_DIS_OP_MD);
> 
> -   if (hw->chip_id == CHIP_ID_GENESIS)
> -      genesis_stop(skge);
> -   else
> -      yukon_stop(skge);
> 
>     /* Disable Force Sync bit and Enable Alloc bit */
>     skge_write8(hw, SK_REG(port, TXA_CTRL),
> @@ -2367,8 +2376,6 @@ static void genesis_set_multicast(struct
>     u32 mode;
>     u8 filter[8];
> 
> -   pr_debug("genesis_set_multicast flags=%x count=%d\n", 
> dev->flags, dev->mc_count);
> -
>     mode = xm_read32(hw, port, XM_MODE);
>     mode |= XM_MD_ENA_HASH;
>     if (dev->flags & IFF_PROMISC)
> @@ -2530,8 +2537,6 @@ static int skge_poll(struct net_device *
>     unsigned int to_do = min(dev->quota, *budget);
>     unsigned int work_done = 0;
> 
> -   pr_debug("skge_poll\n");
> -
>     for (e = ring->to_clean; work_done < to_do; e = e->next) {
>        struct skge_rx_desc *rd = e->desc;
>        struct sk_buff *skb;
> @@ -2672,9 +2677,9 @@ static void skge_error_irq(struct skge_h
>     if (hw->chip_id == CHIP_ID_GENESIS) {
>        /* clear xmac errors */
>        if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1))
> -         skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT);
> +         skge_write16(hw, RX_MFF_CTRL1, MFF_CLR_INSTAT);
>        if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2))
> -         skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT);
> +         skge_write16(hw, RX_MFF_CTRL2, MFF_CLR_INSTAT);
>     } else {
>        /* Timestamp (unused) overflow */
>        if (hwstatus & IS_IRQ_TIST_OV)
> @@ -3000,9 +3005,6 @@ static int skge_reset(struct skge_hw *hw
> 
>     skge_write32(hw, B0_IMSK, hw->intr_mask);
> 
> -   if (hw->chip_id != CHIP_ID_GENESIS)
> -      skge_write8(hw, GMAC_IRQ_MSK, 0);
> -
>     spin_lock_bh(&hw->phy_lock);
>     for (i = 0; i < hw->ports; i++) {
>        if (hw->chip_id == CHIP_ID_GENESIS)
> @@ -3230,6 +3232,11 @@ static void __devexit skge_remove(struct
>     dev0 = hw->dev[0];
>     unregister_netdev(dev0);
> 
> +   skge_write32(hw, B0_IMSK, 0);
> +   skge_write16(hw, B0_LED, LED_STAT_OFF);
> +   skge_pci_clear(hw);
> +   skge_write8(hw, B0_CTST, CS_RST_SET);
> +
>     tasklet_kill(&hw->ext_tasklet);
> 
>     free_irq(pdev->irq, hw);
> @@ -3238,7 +3245,7 @@ static void __devexit skge_remove(struct
>     if (dev1)
>        free_netdev(dev1);
>     free_netdev(dev0);
> -   skge_write16(hw, B0_LED, LED_STAT_OFF);
> +
>     iounmap(hw->regs);
>     kfree(hw);
>     pci_set_drvdata(pdev, NULL);
> @@ -3257,7 +3264,10 @@ static int skge_suspend(struct pci_dev *
>           struct skge_port *skge = netdev_priv(dev);
>           if (netif_running(dev)) {
>              netif_carrier_off(dev);
> -            skge_down(dev);
> +            if (skge->wol)
> +               netif_stop_queue(dev);
> +            else
> +               skge_down(dev);
>           }
>           netif_device_detach(dev);
>           wol |= skge->wol;
> diff --git a/drivers/net/skge.h b/drivers/net/skge.h
> --- a/drivers/net/skge.h
> +++ b/drivers/net/skge.h
> @@ -2008,7 +2008,7 @@ enum {
>     GM_IS_RX_FF_OR   = 1<<1,   /* Receive FIFO Overrun */
>     GM_IS_RX_COMPL   = 1<<0,   /* Frame Reception Complete */
> 
> -#define GMAC_DEF_MSK   (GM_IS_TX_CO_OV | GM_IS_RX_CO_OV | 
GM_IS_TX_FF_UR)
> +#define GMAC_DEF_MSK   (GM_IS_RX_FF_OR | GM_IS_TX_FF_UR)
> 
>  /*   GMAC_LINK_CTRL   16 bit   GMAC Link Control Reg (YUKON only) */
>                    /* Bits 15.. 2:   reserved */
> diff --git a/drivers/net/tulip/xircom_cb.c 
b/drivers/net/tulip/xircom_cb.c
> --- a/drivers/net/tulip/xircom_cb.c
> +++ b/drivers/net/tulip/xircom_cb.c
> @@ -117,7 +117,7 @@ static int xircom_open(struct net_device
>  static int xircom_close(struct net_device *dev);
>  static void xircom_up(struct xircom_private *card);
>  static struct net_device_stats *xircom_get_stats(struct net_device 
*dev);
> -#if CONFIG_NET_POLL_CONTROLLER
> +#ifdef CONFIG_NET_POLL_CONTROLLER
>  static void xircom_poll_controller(struct net_device *dev);
>  #endif
> 
> diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
> --- a/drivers/net/wireless/airo.c
> +++ b/drivers/net/wireless/airo.c
> @@ -6852,7 +6852,10 @@ static inline char *airo_translate_scan(
>     /* Add frequency */
>     iwe.cmd = SIOCGIWFREQ;
>     iwe.u.freq.m = le16_to_cpu(bss->dsChannel);
> -   iwe.u.freq.m = frequency_list[iwe.u.freq.m] * 100000;
> +   /* iwe.u.freq.m containt the channel (starting 1), our 
> +    * frequency_list array start at index 0...
> +    */
> +   iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
>     iwe.u.freq.e = 1;
>     current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 
> IW_EV_FREQ_LEN);
> 
> diff --git a/drivers/s390/net/ctcmain.c b/drivers/s390/net/ctcmain.c
> --- a/drivers/s390/net/ctcmain.c
> +++ b/drivers/s390/net/ctcmain.c
> @@ -1,5 +1,5 @@
>  /*
> - * $Id: ctcmain.c,v 1.74 2005/03/24 09:04:17 mschwide Exp $
> + * $Id: ctcmain.c,v 1.78 2005/09/07 12:18:02 pavlic Exp $
>   *
>   * CTC / ESCON network driver
>   *
> @@ -37,10 +37,9 @@
>   * along with this program; if not, write to the Free Software
>   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
>   *
> - * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.74 $
> + * RELEASE-TAG: CTC/ESCON network driver $Revision: 1.78 $
>   *
>   */
> -\f
>  #undef DEBUG
>  #include <linux/module.h>
>  #include <linux/init.h>
> @@ -135,7 +134,7 @@ static const char *dev_event_names[] = {
>     "TX down",
>     "Restart",
>  };
> -\f
> +
>  /**
>   * Events of the channel statemachine
>   */
> @@ -249,7 +248,7 @@ static void
>  print_banner(void)
>  {
>     static int printed = 0;
> -   char vbuf[] = "$Revision: 1.74 $";
> +   char vbuf[] = "$Revision: 1.78 $";
>     char *version = vbuf;
> 
>     if (printed)
> @@ -334,7 +333,7 @@ static const char *ch_state_names[] = {
>     "Restarting",
>     "Not operational",
>  };
> -\f
> +
>  #ifdef DEBUG
>  /**
>   * Dump header and first 16 bytes of an sk_buff for debugging purposes.
> @@ -671,7 +670,7 @@ static void
>  fsm_action_nop(fsm_instance * fi, int event, void *arg)
>  {
>  }
> -\f
> +
>  /**
>   * Actions for channel - statemachines.
> 
> 
*****************************************************************************/
> @@ -1514,7 +1513,6 @@ ch_action_reinit(fsm_instance *fi, int e
>      fsm_addtimer(&privptr->restart_timer, 1000, DEV_EVENT_RESTART, 
dev);
>  }
> 
> -\f
>  /**
>   * The statemachine for a channel.
>   */
> @@ -1625,7 +1623,7 @@ static const fsm_node ch_fsm[] = {
>  };
> 
>  static const int CH_FSM_LEN = sizeof (ch_fsm) / sizeof (fsm_node);
> -\f
> +
>  /**
>   * Functions related to setup and device detection.
> 
> 
*****************************************************************************/
> @@ -1976,7 +1974,7 @@ ctc_irq_handler(struct ccw_device *cdev,
>        fsm_event(ch->fsm, CH_EVENT_IRQ, ch);
> 
>  }
> -\f
> +
>  /**
>   * Actions for interface - statemachine.
> 
> 
*****************************************************************************/
> @@ -2209,13 +2207,18 @@ transmit_skb(struct channel *ch, struct 
>     int rc = 0;
> 
>     DBF_TEXT(trace, 5, __FUNCTION__);
> +   /* we need to acquire the lock for testing the state
> +    * otherwise we can have an IRQ changing the state to 
> +    * TXIDLE after the test but before acquiring the lock.
> +    */
> +   spin_lock_irqsave(&ch->collect_lock, saveflags);
>     if (fsm_getstate(ch->fsm) != CH_STATE_TXIDLE) {
>        int l = skb->len + LL_HEADER_LENGTH;
> 
> -      spin_lock_irqsave(&ch->collect_lock, saveflags);
> -      if (ch->collect_len + l > ch->max_bufsize - 2)
> -         rc = -EBUSY;
> -      else {
> +      if (ch->collect_len + l > ch->max_bufsize - 2) {
> +         spin_unlock_irqrestore(&ch->collect_lock, saveflags);
> +         return -EBUSY;
> +      } else {
>           atomic_inc(&skb->users);
>           header.length = l;
>           header.type = skb->protocol;
> @@ -2231,7 +2234,7 @@ transmit_skb(struct channel *ch, struct 
>        int ccw_idx;
>        struct sk_buff *nskb;
>        unsigned long hi;
> -
> +      spin_unlock_irqrestore(&ch->collect_lock, saveflags);
>        /**
>         * Protect skb against beeing free'd by upper
>         * layers.
> @@ -2256,6 +2259,7 @@ transmit_skb(struct channel *ch, struct 
>           if (!nskb) {
>              atomic_dec(&skb->users);
>              skb_pull(skb, LL_HEADER_LENGTH + 2);
> +            ctc_clear_busy(ch->netdev);
>              return -ENOMEM;
>           } else {
>              memcpy(skb_put(nskb, skb->len),
> @@ -2281,6 +2285,7 @@ transmit_skb(struct channel *ch, struct 
>               */
>              atomic_dec(&skb->users);
>              skb_pull(skb, LL_HEADER_LENGTH + 2);
> +            ctc_clear_busy(ch->netdev);
>              return -EBUSY;
>           }
> 
> @@ -2327,9 +2332,10 @@ transmit_skb(struct channel *ch, struct 
>        }
>     }
> 
> +   ctc_clear_busy(ch->netdev);
>     return rc;
>  }
> -\f
> +
>  /**
>   * Interface API for upper network layers
> 
> 
*****************************************************************************/
> @@ -2421,7 +2427,6 @@ ctc_tx(struct sk_buff *skb, struct net_d
>     dev->trans_start = jiffies;
>     if (transmit_skb(privptr->channel[WRITE], skb) != 0)
>        rc = 1;
> -   ctc_clear_busy(dev);
>     return rc;
>  }
> 
> @@ -2610,7 +2615,6 @@ stats_write(struct device *dev, struct d
>     return count;
>  }
> 
> -\f
>  static void
>  ctc_netdev_unregister(struct net_device * dev)
>  {
> @@ -2685,7 +2689,6 @@ ctc_proto_store(struct device *dev, stru
>     return count;
>  }
> 
> -
>  static ssize_t
>  ctc_type_show(struct device *dev, struct device_attribute *attr, char 
*buf)
>  {
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" 
in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply

* Re: [PATCH 1/3] orinoco: WE-18 support
From: Pavel Roskin @ 2005-09-14 15:39 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Orinoco Development List, netdev-u79uwXL29TY76Z2rM5mHXA,
	Jean Tourrilhes
In-Reply-To: <43281824.7000705-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org>

On Wed, 2005-09-14 at 08:31 -0400, Jeff Garzik wrote:
> Pavel Roskin wrote:
> > Author: Jean Tourrilhes <jt-sDzT885Ts8HQT0dZR+AlfA@public.gmane.org>
> > Signed-off-by: Pavel Roskin <proski-mXXj517/zsQ@public.gmane.org>
> > 
> > Use new Wireless Extension API for wireless stats.
> 
> Applied patch #1, the rest failed:

Thanks!  The rest will be resubmitted shortly.

-- 
Regards,
Pavel Roskin



-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. 
Download it for free - -and be entered to win a 42" plasma tv or your very
own Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php

^ permalink raw reply

* Re: [git patches] net driver fixes
From: Jeff Garzik @ 2005-09-14 15:40 UTC (permalink / raw)
  To: Frank Pavlic; +Cc: netdev, linux-kernel
In-Reply-To: <OFA34209F3.7B24497C-ONC125707C.0056132C-C125707C.0056326B@de.ibm.com>

On Wed, Sep 14, 2005 at 05:38:26PM +0200, Frank Pavlic wrote:
> Jeff ,
> didn't you get the qeth patches ? let me know if not I will resend them 
> once again ....

You only resent patch #2, so please do resend patches 3 and 4.

Thanks,

	Jeff

^ permalink raw reply

* [patch 3/4] s390: TSO related fixes in qeth driver
From: Frank Pavlic @ 2005-09-14 16:03 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linux-kernel

Jeff, 
I'm sorry seems that they have not been sent out either ...
ok here they come ...

[patch 3/4] s390: TSO related fixes in qeth driver 

From: Frank Pavlic <pavlic@de.ibm.com>
	TSO related fixes :
	  - changing value of large_send attribute while network traffic
	    is running caused program check and thus device recovery.
	  - Due to hardware restriction discard packet when it exceeds 60K
	    otherwise qeth will cause program checks and thus traffic stall 
	    when trying to send such huge packets.

Signed-off-by: Frank Pavlic <pavlic@de.ibm.com>

diffstat:
 qeth.h      |    4 ++--
 qeth_main.c |   33 +++++++++++++++++++++------------
 qeth_sys.c  |   10 +++-------
 3 files changed, 26 insertions(+), 21 deletions(-)

diff -Naupr linux-2.6-orig/drivers/s390/net/qeth.h linux-2.6-patched/drivers/s390/net/qeth.h
--- linux-2.6-orig/drivers/s390/net/qeth.h	2005-09-05 11:46:56.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth.h	2005-09-05 12:16:08.000000000 +0200
@@ -24,7 +24,7 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H 		"$Revision: 1.139 $"
+#define VERSION_QETH_H 		"$Revision: 1.141 $"
 
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6 	":IPv6"
@@ -1172,7 +1172,7 @@ extern int
 qeth_realloc_buffer_pool(struct qeth_card *, int);
 
 extern int
-qeth_set_large_send(struct qeth_card *);
+qeth_set_large_send(struct qeth_card *, enum qeth_large_send_types);
 
 extern void
 qeth_fill_header(struct qeth_card *, struct qeth_hdr *,
diff -Naupr linux-2.6-orig/drivers/s390/net/qeth_main.c linux-2.6-patched/drivers/s390/net/qeth_main.c
--- linux-2.6-orig/drivers/s390/net/qeth_main.c	2005-09-05 11:46:56.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth_main.c	2005-09-05 12:17:38.000000000 +0200
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.214 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.219 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *			  Frank Pavlic (pavlic@de.ibm.com) and
  *		 	  Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.214 $	 $Date: 2005/05/04 20:19:18 $
+ *    $Revision: 1.219 $	 $Date: 2005/05/04 20:19:18 $
  *
  * 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
@@ -80,7 +80,7 @@ qeth_eyecatcher(void)
 #include "qeth_eddp.h"
 #include "qeth_tso.h"
 
-#define VERSION_QETH_C "$Revision: 1.214 $"
+#define VERSION_QETH_C "$Revision: 1.219 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -3795,12 +3795,16 @@ static inline int
 qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
 		 struct qeth_hdr **hdr, int ipv)
 {
+	int rc;
 #ifdef CONFIG_QETH_VLAN
 	u16 *tag;
 #endif
 
 	QETH_DBF_TEXT(trace, 6, "prepskb");
 
+        rc = qeth_realloc_headroom(card, skb, sizeof(struct qeth_hdr));
+        if (rc)
+                return rc;
 #ifdef CONFIG_QETH_VLAN
 	if (card->vlangrp && vlan_tx_tag_present(*skb) &&
 	    ((ipv == 6) || card->options.layer2) ) {
@@ -4251,7 +4255,8 @@ out:
 }
 
 static inline int
-qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb)
+qeth_get_elements_no(struct qeth_card *card, void *hdr, 
+		     struct sk_buff *skb, int elems)
 {
 	int elements_needed = 0;
 
@@ -4261,9 +4266,10 @@ qeth_get_elements_no(struct qeth_card *c
         if (elements_needed == 0 )
                 elements_needed = 1 + (((((unsigned long) hdr) % PAGE_SIZE)
                                         + skb->len) >> PAGE_SHIFT);
-        if (elements_needed > QETH_MAX_BUFFER_ELEMENTS(card)){
+	if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)){
                 PRINT_ERR("qeth_do_send_packet: invalid size of "
-                          "IP packet. Discarded.");
+                          "IP packet (Number=%d / Length=%d). Discarded.\n",
+                          (elements_needed+elems), skb->len);
                 return 0;
         }
         return elements_needed;
@@ -4337,9 +4343,11 @@ qeth_send_packet(struct qeth_card *card,
 			return -EINVAL;
 		}
 	} else {
-		elements_needed += qeth_get_elements_no(card,(void*) hdr, skb);
-		if (!elements_needed)
+		int elems = qeth_get_elements_no(card,(void*) hdr, skb,
+						 elements_needed);
+		if (!elems)
 			return -EINVAL;
+		elements_needed += elems;
 	}
 
 	if (card->info.type != QETH_CARD_TYPE_IQD)
@@ -7038,14 +7046,16 @@ qeth_setrouting_v6(struct qeth_card *car
 }
 
 int
-qeth_set_large_send(struct qeth_card *card)
+qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
 {
 	int rc = 0;
 
-	if (card->dev == NULL)
+	if (card->dev == NULL) {
+		card->options.large_send = type;
 		return 0;
-
+	}
 	netif_stop_queue(card->dev);
+	card->options.large_send = type;
 	switch (card->options.large_send) {
 	case QETH_LARGE_SEND_EDDP:
 		card->dev->features |= NETIF_F_TSO | NETIF_F_SG;
@@ -7066,7 +7076,6 @@ qeth_set_large_send(struct qeth_card *ca
 		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
 		break;
 	}
-
 	netif_wake_queue(card->dev);
 	return rc;
 }
diff -Naupr linux-2.6-orig/drivers/s390/net/qeth_sys.c linux-2.6-patched/drivers/s390/net/qeth_sys.c
--- linux-2.6-orig/drivers/s390/net/qeth_sys.c	2005-09-05 11:46:56.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth_sys.c	2005-09-05 12:14:30.000000000 +0200
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.51 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.53 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.51 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.53 $";
 
 /*****************************************************************************/
 /*                                                                           */
@@ -771,9 +771,7 @@ qeth_dev_large_send_store(struct device 
 
 	if (!card)
 		return -EINVAL;
-
 	tmp = strsep((char **) &buf, "\n");
-
 	if (!strcmp(tmp, "no")){
 		type = QETH_LARGE_SEND_NO;
 	} else if (!strcmp(tmp, "EDDP")) {
@@ -786,10 +784,8 @@ qeth_dev_large_send_store(struct device 
 	}
 	if (card->options.large_send == type)
 		return count;
-	card->options.large_send = type;
-	if ((rc = qeth_set_large_send(card)))
+	if ((rc = qeth_set_large_send(card, type)))	
 		return rc;
-
 	return count;
 }
 

^ permalink raw reply

* [patch 4/4] s390: qeth driver fixes
From: Frank Pavlic @ 2005-09-14 16:05 UTC (permalink / raw)
  To: jgarzik; +Cc: linux-kernel, netdev


[patch 4/4] s390: qeth driver fixes .

From: Frank Pavlic <pavlic@de.ibm.com>
	- Clear read channel first prior to using ccw_device_set_offline.
	- use QETH_DBF_TEXT instead of QETH_DBF_SPRINTF
	- invoke qeth_halt_channel and qeth_clear_channel for all channels,
	  even if halt/clear for one of the channel fails.
	- enable qeth_arp_query function for GuestLAN devices

Signed-off-by: Frank Pavlic <pavlic@de.ibm.com>

diffstat:
 qeth.h      |    2 -
 qeth_main.c |  106 +++++++++++++++++++++++++-----------------------------------
 qeth_sys.c  |   11 +++---
 3 files changed, 53 insertions(+), 66 deletions(-)

diff -Naupr linux-2.6-orig/drivers/s390/net/qeth.h linux-2.6-patched/drivers/s390/net/qeth.h
--- linux-2.6-orig/drivers/s390/net/qeth.h	2005-09-05 13:53:40.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth.h	2005-09-05 14:00:46.000000000 +0200
@@ -24,7 +24,7 @@
 
 #include "qeth_mpc.h"
 
-#define VERSION_QETH_H 		"$Revision: 1.141 $"
+#define VERSION_QETH_H 		"$Revision: 1.142 $"
 
 #ifdef CONFIG_QETH_IPV6
 #define QETH_VERSION_IPV6 	":IPv6"
diff -Naupr linux-2.6-orig/drivers/s390/net/qeth_main.c linux-2.6-patched/drivers/s390/net/qeth_main.c
--- linux-2.6-orig/drivers/s390/net/qeth_main.c	2005-09-05 13:53:40.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth_main.c	2005-09-05 14:05:43.000000000 +0200
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_main.c ($Revision: 1.219 $)
+ * linux/drivers/s390/net/qeth_main.c ($Revision: 1.224 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  *
@@ -12,7 +12,7 @@
  *			  Frank Pavlic (pavlic@de.ibm.com) and
  *		 	  Thomas Spatzier <tspat@de.ibm.com>
  *
- *    $Revision: 1.219 $	 $Date: 2005/05/04 20:19:18 $
+ *    $Revision: 1.224 $	 $Date: 2005/05/04 20:19:18 $
  *
  * 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
@@ -29,14 +29,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-/***
- * eye catcher; just for debugging purposes
- */
-void volatile
-qeth_eyecatcher(void)
-{
-	return;
-}
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -80,7 +72,7 @@ qeth_eyecatcher(void)
 #include "qeth_eddp.h"
 #include "qeth_tso.h"
 
-#define VERSION_QETH_C "$Revision: 1.219 $"
+#define VERSION_QETH_C "$Revision: 1.224 $"
 static const char *version = "qeth S/390 OSA-Express driver";
 
 /**
@@ -2759,11 +2751,9 @@ qeth_flush_buffers(struct qeth_qdio_out_
 		queue->card->perf_stats.outbound_do_qdio_start_time;
 #endif
 	if (rc){
-		QETH_DBF_SPRINTF(trace, 0, "qeth_flush_buffers: do_QDIO "
-				 "returned error (%i) on device %s.",
-				 rc, CARD_DDEV_ID(queue->card));
 		QETH_DBF_TEXT(trace, 2, "flushbuf");
 		QETH_DBF_TEXT_(trace, 2, " err%d", rc);
+		QETH_DBF_TEXT_(trace, 2, "%s", CARD_DDEV_ID(queue->card));
 		queue->card->stats.tx_errors += count;
 		/* this must not happen under normal circumstances. if it
 		 * happens something is really wrong -> recover */
@@ -2909,11 +2899,8 @@ qeth_qdio_output_handler(struct ccw_devi
 	QETH_DBF_TEXT(trace, 6, "qdouhdl");
 	if (status & QDIO_STATUS_LOOK_FOR_ERROR) {
 		if (status & QDIO_STATUS_ACTIVATE_CHECK_CONDITION){
-			QETH_DBF_SPRINTF(trace, 2, "On device %s: "
-					 "received active check "
-				         "condition (0x%08x).",
-					 CARD_BUS_ID(card), status);
-			QETH_DBF_TEXT(trace, 2, "chkcond");
+			QETH_DBF_TEXT(trace, 2, "achkcond");
+			QETH_DBF_TEXT_(trace, 2, "%s", CARD_BUS_ID(card));
 			QETH_DBF_TEXT_(trace, 2, "%08x", status);
 			netif_stop_queue(card->dev);
 			qeth_schedule_recovery(card);
@@ -3356,26 +3343,32 @@ qeth_halt_channel(struct qeth_channel *c
 static int
 qeth_halt_channels(struct qeth_card *card)
 {
-	int rc = 0;
+	int rc1 = 0, rc2=0, rc3 = 0;
 
 	QETH_DBF_TEXT(trace,3,"haltchs");
-	if ((rc = qeth_halt_channel(&card->read)))
-		return rc;
-	if ((rc = qeth_halt_channel(&card->write)))
-		return rc;
-	return  qeth_halt_channel(&card->data);
+	rc1 = qeth_halt_channel(&card->read);
+	rc2 = qeth_halt_channel(&card->write);
+	rc3 = qeth_halt_channel(&card->data);
+	if (rc1)
+		return rc1;
+	if (rc2) 
+		return rc2;
+	return rc3;
 }
 static int
 qeth_clear_channels(struct qeth_card *card)
 {
-	int rc = 0;
+	int rc1 = 0, rc2=0, rc3 = 0;
 
 	QETH_DBF_TEXT(trace,3,"clearchs");
-	if ((rc = qeth_clear_channel(&card->read)))
-		return rc;
-	if ((rc = qeth_clear_channel(&card->write)))
-		return rc;
-	return  qeth_clear_channel(&card->data);
+	rc1 = qeth_clear_channel(&card->read);
+	rc2 = qeth_clear_channel(&card->write);
+	rc3 = qeth_clear_channel(&card->data);
+	if (rc1)
+		return rc1;
+	if (rc2) 
+		return rc2;
+	return rc3;
 }
 
 static int
@@ -3445,23 +3438,23 @@ qeth_mpc_initialize(struct qeth_card *ca
 	}
 	if ((rc = qeth_cm_enable(card))){
 		QETH_DBF_TEXT_(setup, 2, "2err%d", rc);
-		return rc;
+		goto out_qdio;
 	}
 	if ((rc = qeth_cm_setup(card))){
 		QETH_DBF_TEXT_(setup, 2, "3err%d", rc);
-		return rc;
+		goto out_qdio;
 	}
 	if ((rc = qeth_ulp_enable(card))){
 		QETH_DBF_TEXT_(setup, 2, "4err%d", rc);
-		return rc;
+		goto out_qdio;
 	}
 	if ((rc = qeth_ulp_setup(card))){
 		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
-		return rc;
+		goto out_qdio;
 	}
 	if ((rc = qeth_alloc_qdio_buffers(card))){
 		QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
-		return rc;
+		goto out_qdio;
 	}
 	if ((rc = qeth_qdio_establish(card))){
 		QETH_DBF_TEXT_(setup, 2, "6err%d", rc);
@@ -4281,7 +4274,7 @@ qeth_send_packet(struct qeth_card *card,
 	int ipv = 0;
 	int cast_type;
 	struct qeth_qdio_out_q *queue;
-	struct qeth_hdr *hdr;
+	struct qeth_hdr *hdr = NULL;
 	int elements_needed = 0;
 	enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
 	struct qeth_eddp_context *ctx = NULL;
@@ -4512,7 +4505,11 @@ qeth_arp_set_no_entries(struct qeth_card
 
 	QETH_DBF_TEXT(trace,3,"arpstnoe");
 
-	/* TODO: really not supported by GuestLAN? */
+	/*
+	 * currently GuestLAN only supports the ARP assist function
+	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_SET_NO_ENTRIES;
+	 * thus we say EOPNOTSUPP for this ARP function
+	 */
 	if (card->info.guestlan)
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
@@ -4689,14 +4686,6 @@ qeth_arp_query(struct qeth_card *card, c
 
 	QETH_DBF_TEXT(trace,3,"arpquery");
 
-	/*
-	 * currently GuestLAN  does only deliver all zeros on query arp,
-	 * even though arp processing is supported (according to IPA supp.
-	 * funcs flags); since all zeros is no valueable information,
-	 * we say EOPNOTSUPP for all ARP functions
-	 */
-	/*if (card->info.guestlan)
-		return -EOPNOTSUPP; */
 	if (!qeth_is_supported(card,/*IPA_QUERY_ARP_ADDR_INFO*/
 			       IPA_ARP_PROCESSING)) {
 		PRINT_WARN("ARP processing not supported "
@@ -4902,10 +4891,9 @@ qeth_arp_add_entry(struct qeth_card *car
 	QETH_DBF_TEXT(trace,3,"arpadent");
 
 	/*
-	 * currently GuestLAN  does only deliver all zeros on query arp,
-	 * even though arp processing is supported (according to IPA supp.
-	 * funcs flags); since all zeros is no valueable information,
-	 * we say EOPNOTSUPP for all ARP functions
+	 * currently GuestLAN only supports the ARP assist function
+	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_ADD_ENTRY;
+	 * thus we say EOPNOTSUPP for this ARP function
 	 */
 	if (card->info.guestlan)
 		return -EOPNOTSUPP;
@@ -4945,10 +4933,9 @@ qeth_arp_remove_entry(struct qeth_card *
 	QETH_DBF_TEXT(trace,3,"arprment");
 
 	/*
-	 * currently GuestLAN  does only deliver all zeros on query arp,
-	 * even though arp processing is supported (according to IPA supp.
-	 * funcs flags); since all zeros is no valueable information,
-	 * we say EOPNOTSUPP for all ARP functions
+	 * currently GuestLAN only supports the ARP assist function
+	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_REMOVE_ENTRY;
+	 * thus we say EOPNOTSUPP for this ARP function
 	 */
 	if (card->info.guestlan)
 		return -EOPNOTSUPP;
@@ -4986,11 +4973,10 @@ qeth_arp_flush_cache(struct qeth_card *c
 	QETH_DBF_TEXT(trace,3,"arpflush");
 
 	/*
-	 * currently GuestLAN  does only deliver all zeros on query arp,
-	 * even though arp processing is supported (according to IPA supp.
-	 * funcs flags); since all zeros is no valueable information,
-	 * we say EOPNOTSUPP for all ARP functions
-	 */
+	 * currently GuestLAN only supports the ARP assist function
+	 * IPA_CMD_ASS_ARP_QUERY_INFO, but not IPA_CMD_ASS_ARP_FLUSH_CACHE;
+	 * thus we say EOPNOTSUPP for this ARP function
+	*/
 	if (card->info.guestlan || (card->info.type == QETH_CARD_TYPE_IQD))
 		return -EOPNOTSUPP;
 	if (!qeth_is_supported(card,IPA_ARP_PROCESSING)) {
@@ -8266,7 +8252,6 @@ qeth_init(void)
 {
 	int rc=0;
 
-	qeth_eyecatcher();
 	PRINT_INFO("loading %s (%s/%s/%s/%s/%s/%s/%s %s %s)\n",
 		   version, VERSION_QETH_C, VERSION_QETH_H,
 		   VERSION_QETH_MPC_H, VERSION_QETH_MPC_C,
@@ -8347,7 +8332,6 @@ again:
 	printk("qeth: removed\n");
 }
 
-EXPORT_SYMBOL(qeth_eyecatcher);
 module_init(qeth_init);
 module_exit(qeth_exit);
 MODULE_AUTHOR("Frank Pavlic <pavlic@de.ibm.com>");
diff -Naupr linux-2.6-orig/drivers/s390/net/qeth_sys.c linux-2.6-patched/drivers/s390/net/qeth_sys.c
--- linux-2.6-orig/drivers/s390/net/qeth_sys.c	2005-09-05 13:53:40.000000000 +0200
+++ linux-2.6-patched/drivers/s390/net/qeth_sys.c	2005-09-05 14:00:46.000000000 +0200
@@ -1,6 +1,6 @@
 /*
  *
- * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.53 $)
+ * linux/drivers/s390/net/qeth_sys.c ($Revision: 1.54 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to sysfs.
@@ -20,7 +20,7 @@
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_SYS_C = "$Revision: 1.53 $";
+const char *VERSION_QETH_SYS_C = "$Revision: 1.54 $";
 
 /*****************************************************************************/
 /*                                                                           */
@@ -722,10 +722,13 @@ qeth_dev_layer2_store(struct device *dev
 
 	if (!card)
 		return -EINVAL;
+	if (card->info.type == QETH_CARD_TYPE_IQD) {
+                PRINT_WARN("Layer2 on Hipersockets is not supported! \n");
+                return -EPERM;
+        }
 
 	if (((card->state != CARD_STATE_DOWN) &&
-	     (card->state != CARD_STATE_RECOVER)) ||
-	    (card->info.type != QETH_CARD_TYPE_OSAE))
+	     (card->state != CARD_STATE_RECOVER)))
 		return -EPERM;
 
 	i = simple_strtoul(buf, &tmp, 16);

^ permalink raw reply

* Re: [patch 3/4] s390: TSO related fixes in qeth driver
From: Jeff Garzik @ 2005-09-14 16:15 UTC (permalink / raw)
  To: Frank Pavlic; +Cc: netdev, linux-kernel
In-Reply-To: <20050914160326.GA3458@pavlic>

applied patch #3 and #4, thanks for resending.

	Jeff

^ permalink raw reply

* Re: [PATCH 1/2] New PowerPC 4xx on-chip ethernet controller driver
From: Eugene Surovegin @ 2005-09-14 16:18 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linuxppc-embedded
In-Reply-To: <43281B7D.5000106@pobox.com>

On Wed, Sep 14, 2005 at 08:45:49AM -0400, Jeff Garzik wrote:
> Eugene Surovegin wrote:
> >Remove old PPC4xx EMAC driver
> >
> >Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
> 
> Please post a diff, along with a description of the changes.
> 
> One huge patch to "remove emac driver" and another huge patch to "add 
> emac driver" is quite silly.

Jeff, it's not silly. I can post combined patch, but you won't be 
able to read it (and combined patch is still big).

As I said, it's a _complete_ re-write. It's a _new_ driver, not just 
some "changes". Description of what was done was in the first e-mail.

I've split it into two parts specifically, so _you_ will be able to 
read new patch and comment on it.

-- 
Eugene

^ permalink raw reply

* [PATCH] New PowerPC 4xx on-chip ethernet controller driver
From: Eugene Surovegin @ 2005-09-14 17:08 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, linuxppc-embedded
In-Reply-To: <43281B7D.5000106@pobox.com>

On Wed, Sep 14, 2005 at 08:45:49AM -0400, Jeff Garzik wrote:
> Eugene Surovegin wrote:
> >Remove old PPC4xx EMAC driver
> >
> >Signed-off-by: Eugene Surovegin <ebs@ebshome.net>
> 
> Please post a diff, along with a description of the changes.
> 
> One huge patch to "remove emac driver" and another huge patch to "add 
> emac driver" is quite silly.

This patch replaces current PowerPC 4xx EMAC driver with
new, re-written version.

New driver uses NAPI, it solves stability problems under heavy packet 
load and low memory, corrects chip register access and fixes numerous 
small bugs I don't even remember now :).

This patch has been tested on all supported in 2.6 PPC 4xx boards.
It's been used in production for almost a year now on custom
4xx hardware. PPC32 specific parts are already upstream.

Patch was acked by the current EMAC driver maintainer (Matt Porter). I
will be maintaining this new version.

Signed-off-by: Eugene Surovegin <ebs@ebshome.net>

--

 Kconfig                   |   72
 ibm_emac/Makefile         |   13
 ibm_emac/ibm_emac.h       |  418 +++--
 ibm_emac/ibm_emac_core.c  | 3391 ++++++++++++++++++++++++----------------------
 ibm_emac/ibm_emac_core.h  |  313 ++--
 ibm_emac/ibm_emac_debug.c |  377 ++---
 ibm_emac/ibm_emac_debug.h |   63
 ibm_emac/ibm_emac_mal.c   |  671 +++++----
 ibm_emac/ibm_emac_mal.h   |  336 +++-
 ibm_emac/ibm_emac_phy.c   |  335 ++--
 ibm_emac/ibm_emac_phy.h   |  105 -
 ibm_emac/ibm_emac_rgmii.c |  202 ++
 ibm_emac/ibm_emac_rgmii.h |   68
 ibm_emac/ibm_emac_tah.c   |  111 +
 ibm_emac/ibm_emac_tah.h   |   96 -
 ibm_emac/ibm_emac_zmii.c  |  256 +++
 ibm_emac/ibm_emac_zmii.h  |  114 -
 17 files changed, 4119 insertions(+), 2822 deletions(-)

Patch is quite big (~234K) because there is virtualy 0% of common code 
between old and new version.

It can be found at http://kernel.ebshome.net/emac/4xx_napi_emac.diff

^ permalink raw reply

* [PATCH] gt96100: stop using pci_find_device()
From: Alexey Dobriyan @ 2005-09-14 18:51 UTC (permalink / raw)
  To: Ralf Baechle; +Cc: Scott Feldman, netdev, linux-mips

From: Scott Feldman <sfeldma@pobox.com>

Replace pci_find_device with pci_get_device/pci_dev_put to plug race
with pci_find_device.

Signed-off-by: Scott Feldman <sfeldma@pobox.com>
Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
Signed-off-by: Domen Puncer <domen@coderock.org>
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
---

 drivers/net/gt96100eth.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

--- a/drivers/net/gt96100eth.c
+++ b/drivers/net/gt96100eth.c
@@ -615,9 +615,9 @@ static int gt96100_init_module(void)
 	/*
 	 * Stupid probe because this really isn't a PCI device
 	 */
-	if (!(pci = pci_find_device(PCI_VENDOR_ID_MARVELL,
+	if (!(pci = pci_get_device(PCI_VENDOR_ID_MARVELL,
 	                            PCI_DEVICE_ID_MARVELL_GT96100, NULL)) &&
-	    !(pci = pci_find_device(PCI_VENDOR_ID_MARVELL,
+	    !(pci = pci_get_device(PCI_VENDOR_ID_MARVELL,
 		                    PCI_DEVICE_ID_MARVELL_GT96100A, NULL))) {
 		printk(KERN_ERR __FILE__ ": GT96100 not found!\n");
 		return -ENODEV;
@@ -627,12 +627,14 @@ static int gt96100_init_module(void)
 	if (cpuConfig & (1<<12)) {
 		printk(KERN_ERR __FILE__
 		       ": must be in Big Endian mode!\n");
+		pci_dev_put(pci);
 		return -ENODEV;
 	}
 
 	for (i=0; i < NUM_INTERFACES; i++)
 		retval |= gt96100_probe1(pci, i);
 
+	pci_dev_put(pci);
 	return retval;
 }
 

^ permalink raw reply

* Re: [PATCH] gt96100: stop using pci_find_device()
From: Jeff Garzik @ 2005-09-14 19:00 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: Ralf Baechle, Scott Feldman, netdev, linux-mips
In-Reply-To: <20050914185136.GE19491@mipter.zuzino.mipt.ru>

Alexey Dobriyan wrote:
> From: Scott Feldman <sfeldma@pobox.com>
> 
> Replace pci_find_device with pci_get_device/pci_dev_put to plug race
> with pci_find_device.
> 
> Signed-off-by: Scott Feldman <sfeldma@pobox.com>
> Signed-off-by: Maximilian Attems <janitor@sternwelten.at>
> Signed-off-by: Domen Puncer <domen@coderock.org>
> Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
> ---
> 
>  drivers/net/gt96100eth.c |    6 ++++--
>  1 files changed, 4 insertions(+), 2 deletions(-)
> 
> --- a/drivers/net/gt96100eth.c
> +++ b/drivers/net/gt96100eth.c
> @@ -615,9 +615,9 @@ static int gt96100_init_module(void)
>  	/*
>  	 * Stupid probe because this really isn't a PCI device
>  	 */
> -	if (!(pci = pci_find_device(PCI_VENDOR_ID_MARVELL,
> +	if (!(pci = pci_get_device(PCI_VENDOR_ID_MARVELL,
>  	                            PCI_DEVICE_ID_MARVELL_GT96100, NULL)) &&
> -	    !(pci = pci_find_device(PCI_VENDOR_ID_MARVELL,
> +	    !(pci = pci_get_device(PCI_VENDOR_ID_MARVELL,
>  		                    PCI_DEVICE_ID_MARVELL_GT96100A, NULL))) {
>  		printk(KERN_ERR __FILE__ ": GT96100 not found!\n");
>  		return -ENODEV;
> @@ -627,12 +627,14 @@ static int gt96100_init_module(void)
>  	if (cpuConfig & (1<<12)) {
>  		printk(KERN_ERR __FILE__
>  		       ": must be in Big Endian mode!\n");
> +		pci_dev_put(pci);
>  		return -ENODEV;

NAK -- convert it to use standard PCI driver API.

	Jeff

^ permalink raw reply

* Re: Fw: masquerading failure for at least icmp and tcp+sack on amd64
From: Marc Lehmann @ 2005-09-14 19:09 UTC (permalink / raw)
  To: Patrick McHardy
  Cc: Andrew Morton, netdev, Netfilter Development Mailinglist,
	Stephen Hemminger
In-Reply-To: <43243AB9.9000705@trash.net>

On Sun, Sep 11, 2005 at 04:10:01PM +0200, Patrick McHardy <kaber@trash.net> wrote:
> >>What network driver are you using?
> >
> >Happens with both skge and sk98.
> 
> Are you sure the same checksum error happens?

No, of course not.

I have two similar network cards in that machine (a normal sk98 pci card
and an onboard one that skge calls Yukon lite and the sk98lin driver calls
9521. The onboard one does not, though, work with sk98lin).

What I did test was with skge and the onboard card, and sk98_lin with
the pci card, and in both cases I couldn't get masquerading to work, but
everything else worked fine.

> ip_summed to CHECKSUM_HW, it uses either CHECKSUM_UNNECESSARY for
> HW checksummed packets, in which case the check is skipped in
> ip_conntrack, or it uses CHECKSUM_NONE, in which case the checksum
> in the packet must be invalid if the check fails and the packet
> wouldn't be accepted by the final receipient anyway. skge uses 
> CHECKSUM_HW for every packet, so they have nothing in common wrt.
> HW checksumming. This would normally mean we can rule out HW
> checksumming, but for some reason turning it off on skge seems
> to help in your case.

... and I have not tried turning it off with sk98lin (and would like to
avoid it, as it requires reconfiguration to test). If any additional tests
arre required, I will do them, though.

> >   nfs_acl                 3136  1 nfsd
> >   sunrpc                142632  13 nfsd,lockd,nfs_acl
> >
> >However, it happens with init=/bin/bash and loading the single iptables
> >rule I sent in the original report, for either eth0/1 or the ppp
> >interface. I can send you my 278 other rules if you want, but they have
> >had no effect on the problem here.
> 
> No, thanks. But your entire .config might help ..

Sorry for the delay :( It's here:

http://data.plan9.de/config.doom

This is the currently-running 2.6.13 config, when testing 2.6.11, i just
did "make oldconfig" on this one.

-- 
                The choice of a
      -----==-     _GNU_
      ----==-- _       generation     Marc Lehmann
      ---==---(_)__  __ ____  __      pcg@goof.com
      --==---/ / _ \/ // /\ \/ /      http://schmorp.de/
      -=====/_/_//_/\_,_/ /_/\_\      XX11-RIPE

^ permalink raw reply

* Re: [PATCH] gt96100: stop using pci_find_device()
From: Ralf Baechle @ 2005-09-14 19:40 UTC (permalink / raw)
  To: Alexey Dobriyan; +Cc: Scott Feldman, netdev, linux-mips
In-Reply-To: <20050914185136.GE19491@mipter.zuzino.mipt.ru>

On Wed, Sep 14, 2005 at 10:51:37PM +0400, Alexey Dobriyan wrote:

> Replace pci_find_device with pci_get_device/pci_dev_put to plug race
> with pci_find_device.

The system is a little odd; the race condition probably doens't exist on
this particular chipset.

  Ralf

^ permalink raw reply

* VPN server over windows XP
From: Alaa Dalghan @ 2005-09-14 20:18 UTC (permalink / raw)
  To: linux-crypto, linux-kernel, linux-net, linux-security-module,
	netdev

hello everyone,

I am trying to setup a windows xp machine as a vpn server that accepts 
multiple ipsec tunnels from other windows xp machines.

My restrictions are the following:

1- I need to set the vpn server on windows XP (not windows 2000 server, nor 
2003, nor ISA server, etc.)

2- I need to use tunnel mode ipsec

3- The vpn server should accept MULTIPLE vpn tunnels.

The first problem I faced is that windows xp does not support ipsec tunnel 
mode between 2 xp machines. It only supports transport mode which is not 
what I want.
To overcome this lack of IP tunneling I tried to use the built-in tunneling 
capabilities such as PPTP and L2TP/ipsec, and it worked. But the problem 
here is that a windows xp can not accept more than ONE SINGLE incoming 
connection at a time, and I need multiple connections.

I think the solution could be one of the following:

1-Installing a third party FREE vpn server (or L2TP server) on windows XP. 
If you know one please tell me.

2-Importing some features from windows 2000 server or 2003 server (some 
executables or services or plugins that enable xp to run as a vpn server and 
accept multiple connections). If you know what to import please tell me.

3- Installing a pure IP tunneling solution on windows xp so that it can be 
combined with ipsec encryption to yield tunnel mode encryption.

I appreciate any help,

Alaadin

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today - it's FREE! 
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


-
Linux-crypto:  cryptography in and on the Linux system
Archive:       http://mail.nl.linux.org/linux-crypto/

^ permalink raw reply

* Re: VPN server over windows XP
From: Redeeman @ 2005-09-14 20:29 UTC (permalink / raw)
  To: Alaa Dalghan
  Cc: linux-crypto, linux-kernel, linux-net, linux-security-module,
	netdev
In-Reply-To: <BAY106-F29965CB20274069D3A5BA5AB9F0@phx.gbl>

On Wed, 2005-09-14 at 20:18 +0000, Alaa Dalghan wrote:
> hello everyone,
<snip>
this really isnt the place for this discussion
> 
> Alaadin
> 
> _________________________________________________________________
> Express yourself instantly with MSN Messenger! Download today - it's FREE! 
> http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 


^ permalink raw reply

* Re: [RFC] hippi: change to not use skb private
From: David S. Miller @ 2005-09-15  4:03 UTC (permalink / raw)
  To: shemminger; +Cc: jes, netdev, linux-kernel
In-Reply-To: <20050913113858.440d3a0f@localhost.localdomain>

From: Stephen Hemminger <shemminger@osdl.org>
Date: Tue, 13 Sep 2005 11:38:58 -0700

> It looks like the following would fix hippi to not have to put
> fields in sk_buff. The ifield looks appears to to be additional
> header information that is being passed in the skb but could just
> be put in the header.

Stephen this patch is against 2.6.13 or something.  We already
put this thing into a SKB control block for 2.6.14-rc1.  Do you
want to keep things that way or update your patch for 2.6.14-rc1?

^ permalink raw reply

* [PATCH 1/3] NETFILTER: CLUSTERIP entry refcounting
From: Harald Welte @ 2005-09-15 14:51 UTC (permalink / raw)
  To: David Miller; +Cc: Linux Netdev List, Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 6847 bytes --]

Hi Dave, please push this bugfix to mainline.

CLUSTERIP: introduce reference counting for entries

The CLUSTERIP target creates a procfs entry for all different cluster
IPs.  Although more than one rules can refer to a single cluster IP (and
thus a single config structure), removal of the procfs entry is done
unconditionally in destroy(). In more complicated situations involving
deferred dereferencing of the config structure by procfs and creating a
new rule with the same cluster IP it's also possible that no entry will
be created for the new rule.

This patch fixes the problem by counting the number of entries
referencing a given config structure and moving the config list
manipulation and procfs entry deletion parts to the
clusterip_config_entry_put() function.

Signed-off-by: KOVACS Krisztian <hidden@balabit.hu>
Signed-off-by: Harald Welte <laforge@netfilter.org>

---
commit 8d5367b6545c19e551564c26adc808861624ef15
tree 33e3c99394a7f9fae6cc09e5f328144f4786c9f0
parent 8e662a0c0b3aa1257641dd32d5c92d880c110623
author Harald Welte <laforge@netfilter.org> Di, 13 Sep 2005 14:53:17 +0200
committer Harald Welte <laforge@netfilter.org> Di, 13 Sep 2005 14:53:17 +0200

 net/ipv4/netfilter/ipt_CLUSTERIP.c |   80 ++++++++++++++++++++++++++++--------
 1 files changed, 62 insertions(+), 18 deletions(-)

diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -49,6 +49,8 @@ MODULE_DESCRIPTION("iptables target for 
 struct clusterip_config {
 	struct list_head list;			/* list of all configs */
 	atomic_t refcount;			/* reference count */
+	atomic_t entries;			/* number of entries/rules
+						 * referencing us */
 
 	u_int32_t clusterip;			/* the IP address */
 	u_int8_t clustermac[ETH_ALEN];		/* the MAC address */
@@ -76,23 +78,48 @@ static struct proc_dir_entry *clusterip_
 #endif
 
 static inline void
-clusterip_config_get(struct clusterip_config *c) {
+clusterip_config_get(struct clusterip_config *c)
+{
 	atomic_inc(&c->refcount);
 }
 
 static inline void
-clusterip_config_put(struct clusterip_config *c) {
-	if (atomic_dec_and_test(&c->refcount)) {
+clusterip_config_put(struct clusterip_config *c)
+{
+	if (atomic_dec_and_test(&c->refcount))
+		kfree(c);
+}
+
+/* increase the count of entries(rules) using/referencing this config */
+static inline void
+clusterip_config_entry_get(struct clusterip_config *c)
+{
+	atomic_inc(&c->entries);
+}
+
+/* decrease the count of entries using/referencing this config.  If last
+ * entry(rule) is removed, remove the config from lists, but don't free it
+ * yet, since proc-files could still be holding references */
+static inline void
+clusterip_config_entry_put(struct clusterip_config *c)
+{
+	if (atomic_dec_and_test(&c->entries)) {
 		write_lock_bh(&clusterip_lock);
 		list_del(&c->list);
 		write_unlock_bh(&clusterip_lock);
+
 		dev_mc_delete(c->dev, c->clustermac, ETH_ALEN, 0);
 		dev_put(c->dev);
-		kfree(c);
+
+		/* In case anyone still accesses the file, the open/close
+		 * functions are also incrementing the refcount on their own,
+		 * so it's safe to remove the entry even if it's in use. */
+#ifdef CONFIG_PROC_FS
+		remove_proc_entry(c->pde->name, c->pde->parent);
+#endif
 	}
 }
 
-
 static struct clusterip_config *
 __clusterip_config_find(u_int32_t clusterip)
 {
@@ -111,7 +138,7 @@ __clusterip_config_find(u_int32_t cluste
 }
 
 static inline struct clusterip_config *
-clusterip_config_find_get(u_int32_t clusterip)
+clusterip_config_find_get(u_int32_t clusterip, int entry)
 {
 	struct clusterip_config *c;
 
@@ -122,6 +149,8 @@ clusterip_config_find_get(u_int32_t clus
 		return NULL;
 	}
 	atomic_inc(&c->refcount);
+	if (entry)
+		atomic_inc(&c->entries);
 	read_unlock_bh(&clusterip_lock);
 
 	return c;
@@ -148,6 +177,7 @@ clusterip_config_init(struct ipt_cluster
 	c->hash_mode = i->hash_mode;
 	c->hash_initval = i->hash_initval;
 	atomic_set(&c->refcount, 1);
+	atomic_set(&c->entries, 1);
 
 #ifdef CONFIG_PROC_FS
 	/* create proc dir entry */
@@ -415,8 +445,26 @@ checkentry(const char *tablename,
 
 	/* FIXME: further sanity checks */
 
-	config = clusterip_config_find_get(e->ip.dst.s_addr);
-	if (!config) {
+	config = clusterip_config_find_get(e->ip.dst.s_addr, 1);
+	if (config) {
+		if (cipinfo->config != NULL) {
+			/* Case A: This is an entry that gets reloaded, since
+			 * it still has a cipinfo->config pointer. Simply
+			 * increase the entry refcount and return */
+			if (cipinfo->config != config) {
+				printk(KERN_ERR "CLUSTERIP: Reloaded entry "
+				       "has invalid config pointer!\n");
+				return 0;
+			}
+			clusterip_config_entry_get(cipinfo->config);
+		} else {
+			/* Case B: This is a new rule referring to an existing
+			 * clusterip config. */
+			cipinfo->config = config;
+			clusterip_config_entry_get(cipinfo->config);
+		}
+	} else {
+		/* Case C: This is a completely new clusterip config */
 		if (!(cipinfo->flags & CLUSTERIP_FLAG_NEW)) {
 			printk(KERN_WARNING "CLUSTERIP: no config found for %u.%u.%u.%u, need 'new'\n", NIPQUAD(e->ip.dst.s_addr));
 			return 0;
@@ -443,10 +491,9 @@ checkentry(const char *tablename,
 			}
 			dev_mc_add(config->dev,config->clustermac, ETH_ALEN, 0);
 		}
+		cipinfo->config = config;
 	}
 
-	cipinfo->config = config;
-
 	return 1;
 }
 
@@ -455,13 +502,10 @@ static void destroy(void *matchinfo, uns
 {
 	struct ipt_clusterip_tgt_info *cipinfo = matchinfo;
 
-	/* we first remove the proc entry and then drop the reference
-	 * count.  In case anyone still accesses the file, the open/close
-	 * functions are also incrementing the refcount on their own */
-#ifdef CONFIG_PROC_FS
-	remove_proc_entry(cipinfo->config->pde->name,
-			  cipinfo->config->pde->parent);
-#endif
+	/* if no more entries are referencing the config, remove it
+	 * from the list and destroy the proc entry */
+	clusterip_config_entry_put(cipinfo->config);
+
 	clusterip_config_put(cipinfo->config);
 }
 
@@ -533,7 +577,7 @@ arp_mangle(unsigned int hook,
 
 	/* if there is no clusterip configuration for the arp reply's 
 	 * source ip, we don't want to mangle it */
-	c = clusterip_config_find_get(payload->src_ip);
+	c = clusterip_config_find_get(payload->src_ip, 0);
 	if (!c)
 		return NF_ACCEPT;
 
-- 
- Harald Welte <laforge@netfilter.org>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox