* Re: DF, IP ID always 0 and the reassembly protections
From: David Miller @ 2006-06-21 0:43 UTC (permalink / raw)
To: rick.jones2; +Cc: netdev
In-Reply-To: <44989466.5070308@hp.com>
From: Rick Jones <rick.jones2@hp.com>
Date: Tue, 20 Jun 2006 17:35:50 -0700
> I thought the ID's even in non-fragmented datagrams gave an idea of how
> many IP datagrams had been sent along, and so an idea of how "unlikely"
> it was that a datagram with holes could be reassembled?
The code you are thinking about is in net/ipv4/ip_fragment.c and it
attempts to avoid ID wrapping corruption. It only looks at IP
fragments on input.
^ permalink raw reply
* Re: DF, IP ID always 0 and the reassembly protections
From: akepner @ 2006-06-21 0:38 UTC (permalink / raw)
To: Rick Jones; +Cc: David Miller, netdev
In-Reply-To: <44989466.5070308@hp.com>
On Tue, 20 Jun 2006, Rick Jones wrote:
> ....
> I thought the ID's even in non-fragmented datagrams gave an idea of how many
> IP datagrams had been sent along, and so an idea of how "unlikely" it was
> that a datagram with holes could be reassembled?
>
Only fragmented datagrams get counted. This is arguably
a weakness of the scheme, but it's still a big improvement
in practice. And the more common non-fragmented datagram
processing doesn't have to pay the price for the extra
checks.
--
Arthur
^ permalink raw reply
* Re: [PATCH 03/06] MLSXFRM: Add security sid to sock
From: Herbert Xu @ 2006-06-21 0:41 UTC (permalink / raw)
To: Venkat Yekkirala; +Cc: netdev, selinux
In-Reply-To: <44983D36.8070609@trustedcs.com>
On Tue, Jun 20, 2006 at 06:23:50PM +0000, Venkat Yekkirala wrote:
>
> --- linux-2.6.16.vanilla/include/net/sock.h 2006-06-19
> 17:02:23.000000000 -0500
> +++ linux-2.6.16/include/net/sock.h 2006-06-19 19:48:24.000000000 -0500
> @@ -964,6 +964,15 @@ static inline void sock_graft(struct soc
> write_unlock_bh(&sk->sk_callback_lock);
> }
>
> +static inline void sock_copy(struct sock *nsk, const struct sock *osk)
> +{
> + void *sptr = nsk->sk_security;
> +
> + memcpy(nsk, osk, osk->sk_prot->obj_size);
> + nsk->sk_security = sptr;
I don't get it. Why do you put sk_security away and then set it back.
Doesn't memcpy already do this for you?
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: DF, IP ID always 0 and the reassembly protections
From: Rick Jones @ 2006-06-21 0:35 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20060620.171912.70221261.davem@davemloft.net>
David Miller wrote:
> From: Rick Jones <rick.jones2@hp.com>
> Date: Tue, 20 Jun 2006 16:44:55 -0700
>
>
>>Doesn't that mechanism rely on watching the IP ID's between the pair of
>>IPs? For both fragmented and non-fragmented datagrams? If so, does
>>always setting the IP ID to zero when DF is set affect that mechanism?
>
>
> Only the IDs in packets with DF clear matter.
I thought the ID's even in non-fragmented datagrams gave an idea of how
many IP datagrams had been sent along, and so an idea of how "unlikely"
it was that a datagram with holes could be reassembled?
rick jones
^ permalink raw reply
* Re: Locking validator output on DCCP
From: Herbert Xu @ 2006-06-21 0:34 UTC (permalink / raw)
To: Ian McDonald, Ingo Molnar
Cc: netdev, DCCP Mailing List, Arnaldo Carvalho de Melo
In-Reply-To: <5640c7e00606201640wa1ad17fl46a32ceb49513867@mail.gmail.com>
On Tue, Jun 20, 2006 at 11:40:05PM +0000, Ian McDonald wrote:
>
> I am getting this when I am using DCCP with 2.6.17-rc6-mm2 with Ingo's
> lock dependency patch:
>
> Jun 21 09:38:58 localhost kernel: [ 102.068588]
> Jun 21 09:38:58 localhost kernel: [ 102.068592]
> =============================================
> Jun 21 09:38:58 localhost kernel: [ 102.068602] [ INFO: possible
> recursive locking detected ]
> Jun 21 09:38:58 localhost kernel: [ 102.068608]
> ---------------------------------------------
> Jun 21 09:38:58 localhost kernel: [ 102.068615] idle/0 is trying to
> acquire lock:
> Jun 21 09:38:58 localhost kernel: [ 102.068620]
> (&sk->sk_lock.slock#3){-+..}, at: [<c0245511>] sk_clone+0x5a/0x190
> Jun 21 09:38:58 localhost kernel: [ 102.068644]
> Jun 21 09:38:58 localhost kernel: [ 102.068646] but task is already
> holding lock:
> Jun 21 09:38:58 localhost kernel: [ 102.068651]
> (&sk->sk_lock.slock#3){-+..}, at: [<c024650d>]
> sk_receive_skb+0xe6/0xfe
...
> As I read this it is not a recursive lock as sk_clone is occurring
> second and is actually creating a new socket so they are trying to
> lock on different sockets.
>
> Can someone tell me whether I am correct in my thinking or not? If I
> am then I will work out how to tell the lock validator not to worry
> about it.
I agree, this looks bogus. Ingo, could you please take a look?
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: DF, IP ID always 0 and the reassembly protections
From: David Miller @ 2006-06-21 0:19 UTC (permalink / raw)
To: rick.jones2; +Cc: netdev
In-Reply-To: <44988877.2030205@hp.com>
From: Rick Jones <rick.jones2@hp.com>
Date: Tue, 20 Jun 2006 16:44:55 -0700
> Doesn't that mechanism rely on watching the IP ID's between the pair of
> IPs? For both fragmented and non-fragmented datagrams? If so, does
> always setting the IP ID to zero when DF is set affect that mechanism?
Only the IDs in packets with DF clear matter.
^ permalink raw reply
* Re: [PKT_SCHED]: PSCHED_TADD() and PSCHED_TADD2() can result,tv_usec >= 1000000
From: Shuya MAEDA @ 2006-06-21 0:16 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20060619.235105.82052619.davem@davemloft.net>
Thank you for the comment.
I made the patch that used the loop instead of the divide and modulus.
Are there any comments?
David Miller wrote:
> From: Shuya MAEDA <maeda-sxb@necst.nec.co.jp>
> Date: Mon, 19 Jun 2006 14:36:46 +0900
>
>> #define PSCHED_TADD2(tv, delta, tv_res) \
>> ({ \
>> - int __delta = (tv).tv_usec + (delta); \
>> - (tv_res).tv_sec = (tv).tv_sec; \
>> - if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
>> - (tv_res).tv_usec = __delta; \
>> + int __delta = (delta); \
>> + (tv_res) = (tv); \
>> + if((delta) > USEC_PER_SEC) { \
>> + (tv_res).tv_sec += (delta) / USEC_PER_SEC; \
>> + __delta -= (delta) % USEC_PER_SEC; \
>> + } \
>> + (tv_res).tv_usec += __delta; \
>> + if((tv_res).tv_usec >= USEC_PER_SEC) { \
>> + (tv_res).tv_sec++; \
>> + (tv_res).tv_usec -= USEC_PER_SEC; \
>> + } \
>> })
>
> Divide and modulus can be extremely expensive on some systems, so
> let's try to avoid using them.
>
> It is probably sufficient to adjust the passed in delta only once if
> it is >= USEC_PER_SEC, but if you feel that is an unsafe assumption
> then please use a simply loop like this:
>
> while (__delta >= USEC_PER_SEC) {
> (tv_res).tv_sec++;
> __delta -= USEC_PER_SEC;
> }
>
> And please provide a proper "Signed-off-by: " line in your next
> patch submission.
>
> Thank you very much.
Signed-off-by: Shuya MAEDA <maeda-sxb@necst.nec.co.jp>
diff -Nur linux-2.6.17.orig/include/net/pkt_sched.h linux-2.6.17.mypatch/include/net/pkt_sched.h
--- linux-2.6.17.orig/include/net/pkt_sched.h 2006-06-18 10:49:35.000000000 +0900
+++ linux-2.6.17.mypatch/include/net/pkt_sched.h 2006-06-20 17:17:34.000000000 +0900
@@ -169,17 +169,23 @@
#define PSCHED_TADD2(tv, delta, tv_res) \
({ \
- int __delta = (tv).tv_usec + (delta); \
- (tv_res).tv_sec = (tv).tv_sec; \
- if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \
+ int __delta = (delta); \
+ (tv_res) = (tv); \
+ while(__delta >= USEC_PER_SEC){ \
+ (tv_res).tv_sec++; \
+ __delta -= USEC_PER_SEC; \
+ } \
(tv_res).tv_usec = __delta; \
})
#define PSCHED_TADD(tv, delta) \
({ \
- (tv).tv_usec += (delta); \
- if ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \
- (tv).tv_usec -= USEC_PER_SEC; } \
+ int __delta = (delta); \
+ while(__delta >= USEC_PER_SEC){ \
+ (tv).tv_sec++; \
+ __delta -= USEC_PER_SEC; \
+ } \
+ (tv).tv_usec = __delta; \
})
/* Set/check that time is in the "past perfect";
--
Shuya MAEDA
^ permalink raw reply
* Re: [NET]: Prevent multiple qdisc runs
From: Herbert Xu @ 2006-06-20 23:52 UTC (permalink / raw)
To: jamal; +Cc: Robert Olsson, David S. Miller, netdev
In-Reply-To: <1150814526.5270.64.camel@jzny2>
On Tue, Jun 20, 2006 at 10:42:06AM -0400, jamal wrote:
>
> I apologize for hand-waving with % numbers above and using gut feeling
> instead of experimental facts - I dont have time to chase it. I have
> CCed Robert who may have time to see if this impacts forwarding
> performance for one. I will have more peace of mind to find out there is
> no impact.
Well my gut feeling is that multiple qdisc_run's on the same dev can't
be good for perfomance. The reason is that SMP is only good when the
CPUs work on different tasks. If you get two or more CPUs to work on
qdisc_run at the same time they can still only supply one skb to the
device at any time. What's worse is that they will now have to fight
over the two spin locks involved which means that their cache lines
will bounce back and forth.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* [NET]: Make illegal_highdma more anal
From: Herbert Xu @ 2006-06-20 23:49 UTC (permalink / raw)
To: David S. Miller, netdev
Hi:
This patch should prevent mistakes like the one I made earlier.
[NET]: Make illegal_highdma more anal
Rather than having illegal_highdma as a macro when HIGHMEM is off, we
can turn it into an inline function that returns zero. This will catch
callers that give it bad arguments.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Thanks,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/net/core/dev.c b/net/core/dev.c
index 9c68ab8..134d9d1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1234,7 +1234,6 @@ void netdev_rx_csum_fault(struct net_dev
EXPORT_SYMBOL(netdev_rx_csum_fault);
#endif
-#ifdef CONFIG_HIGHMEM
/* Actually, we should eliminate this check as soon as we know, that:
* 1. IOMMU is present and allows to map all the memory.
* 2. No high memory really exists on this machine.
@@ -1242,6 +1241,7 @@ #ifdef CONFIG_HIGHMEM
static inline int illegal_highdma(struct net_device *dev, struct sk_buff *skb)
{
+#ifdef CONFIG_HIGHMEM
int i;
if (dev->features & NETIF_F_HIGHDMA)
@@ -1251,11 +1251,9 @@ static inline int illegal_highdma(struct
if (PageHighMem(skb_shinfo(skb)->frags[i].page))
return 1;
+#endif
return 0;
}
-#else
-#define illegal_highdma(dev, skb) (0)
-#endif
struct dev_gso_cb {
void (*destructor)(struct sk_buff *skb);
^ permalink raw reply related
* Re: [2/5] [NET]: Add generic segmentation offload
From: Herbert Xu @ 2006-06-20 23:46 UTC (permalink / raw)
To: Michael Chan; +Cc: David S. Miller, netdev
In-Reply-To: <1150826089.17133.14.camel@rh4>
On Tue, Jun 20, 2006 at 10:54:48AM -0700, Michael Chan wrote:
>
> I think you need !illegal_highdma(skb->dev, skb)
Thanks for catching this. You can tell that I don't have HIGHMEM :)
Here is the fixed version:
[NET]: Add generic segmentation offload
This patch adds the infrastructure for generic segmentation offload.
The idea is to tap into the potential savings of TSO without hardware
support by postponing the allocation of segmented skb's until just
before the entry point into the NIC driver.
The same structure can be used to support software IPv6 TSO, as well as
UFO and segmentation offload for other relevant protocols, e.g., DCCP.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -406,6 +406,9 @@ struct net_device
struct list_head qdisc_list;
unsigned long tx_queue_len; /* Max frames per queue allowed */
+ /* Partially transmitted GSO packet. */
+ struct sk_buff *gso_skb;
+
/* ingress path synchronizer */
spinlock_t ingress_lock;
struct Qdisc *qdisc_ingress;
@@ -540,6 +543,7 @@ struct packet_type {
struct net_device *,
struct packet_type *,
struct net_device *);
+ struct sk_buff *(*gso_segment)(struct sk_buff *skb, int sg);
void *af_packet_priv;
struct list_head list;
};
@@ -690,7 +694,8 @@ extern int dev_change_name(struct net_d
extern int dev_set_mtu(struct net_device *, int);
extern int dev_set_mac_address(struct net_device *,
struct sockaddr *);
-extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
+extern int dev_hard_start_xmit(struct sk_buff *skb,
+ struct net_device *dev);
extern void dev_init(void);
@@ -964,6 +969,7 @@ extern int netdev_max_backlog;
extern int weight_p;
extern int netdev_set_master(struct net_device *dev, struct net_device *master);
extern int skb_checksum_help(struct sk_buff *skb, int inward);
+extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg);
#ifdef CONFIG_BUG
extern void netdev_rx_csum_fault(struct net_device *dev);
#else
diff --git a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -116,6 +116,7 @@
#include <asm/current.h>
#include <linux/audit.h>
#include <linux/dmaengine.h>
+#include <linux/err.h>
/*
* The list of packet types we will receive (as opposed to discard)
@@ -1048,7 +1049,7 @@ static inline void net_timestamp(struct
* taps currently in use.
*/
-void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
+static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
{
struct packet_type *ptype;
@@ -1186,6 +1187,40 @@ out:
return ret;
}
+/**
+ * skb_gso_segment - Perform segmentation on skb.
+ * @skb: buffer to segment
+ * @sg: whether scatter-gather is supported on the target.
+ *
+ * This function segments the given skb and returns a list of segments.
+ */
+struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg)
+{
+ struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
+ struct packet_type *ptype;
+ int type = skb->protocol;
+
+ BUG_ON(skb_shinfo(skb)->frag_list);
+ BUG_ON(skb->ip_summed != CHECKSUM_HW);
+
+ skb->mac.raw = skb->data;
+ skb->mac_len = skb->nh.raw - skb->data;
+ __skb_pull(skb, skb->mac_len);
+
+ rcu_read_lock();
+ list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type) & 15], list) {
+ if (ptype->type == type && !ptype->dev && ptype->gso_segment) {
+ segs = ptype->gso_segment(skb, sg);
+ break;
+ }
+ }
+ rcu_read_unlock();
+
+ return segs;
+}
+
+EXPORT_SYMBOL(skb_gso_segment);
+
/* Take action when hardware reception checksum errors are detected. */
#ifdef CONFIG_BUG
void netdev_rx_csum_fault(struct net_device *dev)
@@ -1222,6 +1257,86 @@ static inline int illegal_highdma(struct
#define illegal_highdma(dev, skb) (0)
#endif
+struct dev_gso_cb {
+ void (*destructor)(struct sk_buff *skb);
+};
+
+#define DEV_GSO_CB(skb) ((struct dev_gso_cb *)(skb)->cb)
+
+static void dev_gso_skb_destructor(struct sk_buff *skb)
+{
+ struct dev_gso_cb *cb;
+
+ do {
+ struct sk_buff *nskb = skb->next;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ kfree_skb(nskb);
+ } while (skb->next);
+
+ cb = DEV_GSO_CB(skb);
+ if (cb->destructor)
+ cb->destructor(skb);
+}
+
+/**
+ * dev_gso_segment - Perform emulated hardware segmentation on skb.
+ * @skb: buffer to segment
+ *
+ * This function segments the given skb and stores the list of segments
+ * in skb->next.
+ */
+static int dev_gso_segment(struct sk_buff *skb)
+{
+ struct net_device *dev = skb->dev;
+ struct sk_buff *segs;
+
+ segs = skb_gso_segment(skb, dev->features & NETIF_F_SG &&
+ !illegal_highdma(dev, skb));
+ if (unlikely(IS_ERR(segs)))
+ return PTR_ERR(segs);
+
+ skb->next = segs;
+ DEV_GSO_CB(skb)->destructor = skb->destructor;
+ skb->destructor = dev_gso_skb_destructor;
+
+ return 0;
+}
+
+int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ if (likely(!skb->next)) {
+ if (netdev_nit)
+ dev_queue_xmit_nit(skb, dev);
+
+ if (!netif_needs_gso(dev, skb))
+ return dev->hard_start_xmit(skb, dev);
+
+ if (unlikely(dev_gso_segment(skb)))
+ goto out_kfree_skb;
+ }
+
+ do {
+ struct sk_buff *nskb = skb->next;
+ int rc;
+
+ skb->next = nskb->next;
+ nskb->next = NULL;
+ rc = dev->hard_start_xmit(nskb, dev);
+ if (unlikely(rc)) {
+ skb->next = nskb;
+ return rc;
+ }
+ } while (skb->next);
+
+ skb->destructor = DEV_GSO_CB(skb)->destructor;
+
+out_kfree_skb:
+ kfree_skb(skb);
+ return 0;
+}
+
#define HARD_TX_LOCK(dev, cpu) { \
if ((dev->features & NETIF_F_LLTX) == 0) { \
netif_tx_lock(dev); \
@@ -1266,6 +1381,10 @@ int dev_queue_xmit(struct sk_buff *skb)
struct Qdisc *q;
int rc = -ENOMEM;
+ /* GSO will handle the following emulations directly. */
+ if (netif_needs_gso(dev, skb))
+ goto gso;
+
if (skb_shinfo(skb)->frag_list &&
!(dev->features & NETIF_F_FRAGLIST) &&
__skb_linearize(skb))
@@ -1290,6 +1409,7 @@ int dev_queue_xmit(struct sk_buff *skb)
if (skb_checksum_help(skb, 0))
goto out_kfree_skb;
+gso:
spin_lock_prefetch(&dev->queue_lock);
/* Disable soft irqs for various locks below. Also
@@ -1346,11 +1466,8 @@ int dev_queue_xmit(struct sk_buff *skb)
HARD_TX_LOCK(dev, cpu);
if (!netif_queue_stopped(dev)) {
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
-
rc = 0;
- if (!dev->hard_start_xmit(skb, dev)) {
+ if (!dev_hard_start_xmit(skb, dev)) {
HARD_TX_UNLOCK(dev);
goto out;
}
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -96,8 +96,11 @@ static inline int qdisc_restart(struct n
struct sk_buff *skb;
/* Dequeue packet */
- if ((skb = q->dequeue(q)) != NULL) {
+ if (((skb = dev->gso_skb)) || ((skb = q->dequeue(q)))) {
unsigned nolock = (dev->features & NETIF_F_LLTX);
+
+ dev->gso_skb = NULL;
+
/*
* When the driver has LLTX set it does its own locking
* in start_xmit. No need to add additional overhead by
@@ -134,10 +137,8 @@ static inline int qdisc_restart(struct n
if (!netif_queue_stopped(dev)) {
int ret;
- if (netdev_nit)
- dev_queue_xmit_nit(skb, dev);
- ret = dev->hard_start_xmit(skb, dev);
+ ret = dev_hard_start_xmit(skb, dev);
if (ret == NETDEV_TX_OK) {
if (!nolock) {
netif_tx_unlock(dev);
@@ -171,7 +172,10 @@ static inline int qdisc_restart(struct n
*/
requeue:
- q->ops->requeue(skb, q);
+ if (skb->next)
+ dev->gso_skb = skb;
+ else
+ q->ops->requeue(skb, q);
netif_schedule(dev);
return 1;
}
@@ -572,15 +576,19 @@ void dev_activate(struct net_device *dev
void dev_deactivate(struct net_device *dev)
{
struct Qdisc *qdisc;
+ struct sk_buff *skb;
spin_lock_bh(&dev->queue_lock);
qdisc = dev->qdisc;
dev->qdisc = &noop_qdisc;
+ skb = dev->gso_skb;
+ dev->gso_skb = NULL;
qdisc_reset(qdisc);
spin_unlock_bh(&dev->queue_lock);
+ kfree_skb(skb);
dev_watchdog_down(dev);
while (test_bit(__LINK_STATE_SCHED, &dev->state))
^ permalink raw reply
* DF, IP ID always 0 and the reassembly protections
From: Rick Jones @ 2006-06-20 23:44 UTC (permalink / raw)
To: Linux Network Development list
A while back (I cannot recall exactly when) the issue of always setting
the IP datagram ID to zero when the DF bit was set was brought-up. I
suggested it might not be a good idea because there are admittedly
broken devices out there that "helpfully" and silently clear DF and the
start to fragment. The counter point was that coding around such broken
hardware was silly.
I was just writing a missive to one of my co-workers on IP
fragmentation. It got me to thinking about the stuff (I think it
went-in?) to try to protect against "Frankengrams" during IP fragment
reassembly.
Doesn't that mechanism rely on watching the IP ID's between the pair of
IPs? For both fragmented and non-fragmented datagrams? If so, does
always setting the IP ID to zero when DF is set affect that mechanism?
rick jones
^ permalink raw reply
* Locking validator output on DCCP
From: Ian McDonald @ 2006-06-20 23:40 UTC (permalink / raw)
To: netdev, DCCP Mailing List, Arnaldo Carvalho de Melo
Folks,
I am getting this when I am using DCCP with 2.6.17-rc6-mm2 with Ingo's
lock dependency patch:
Jun 21 09:38:58 localhost kernel: [ 102.068588]
Jun 21 09:38:58 localhost kernel: [ 102.068592]
=============================================
Jun 21 09:38:58 localhost kernel: [ 102.068602] [ INFO: possible
recursive locking detected ]
Jun 21 09:38:58 localhost kernel: [ 102.068608]
---------------------------------------------
Jun 21 09:38:58 localhost kernel: [ 102.068615] idle/0 is trying to
acquire lock:
Jun 21 09:38:58 localhost kernel: [ 102.068620]
(&sk->sk_lock.slock#3){-+..}, at: [<c0245511>] sk_clone+0x5a/0x190
Jun 21 09:38:58 localhost kernel: [ 102.068644]
Jun 21 09:38:58 localhost kernel: [ 102.068646] but task is already
holding lock:
Jun 21 09:38:58 localhost kernel: [ 102.068651]
(&sk->sk_lock.slock#3){-+..}, at: [<c024650d>]
sk_receive_skb+0xe6/0xfe
Jun 21 09:38:58 localhost kernel: [ 102.068668]
Jun 21 09:38:58 localhost kernel: [ 102.068670] other info that might
help us debug this:
Jun 21 09:38:58 localhost kernel: [ 102.068676] 2 locks held by idle/0:
Jun 21 09:38:58 localhost kernel: [ 102.068679] #0:
(&tp->rx_lock){-+..}, at: [<e087d915>] rtl8139_poll+0x42/0x41c
[8139too]
Jun 21 09:38:58 localhost kernel: [ 102.068722] #1:
(&sk->sk_lock.slock#3){-+..}, at: [<c024650d>]
sk_receive_skb+0xe6/0xfe
Jun 21 09:38:58 localhost kernel: [ 102.068739]
Jun 21 09:38:58 localhost kernel: [ 102.068741] stack backtrace:
Jun 21 09:38:58 localhost kernel: [ 102.069053] [<c0103a2a>]
show_trace_log_lvl+0x53/0xff
Jun 21 09:38:58 localhost kernel: [ 102.069091] [<c0104078>]
show_trace+0x16/0x19
Jun 21 09:38:58 localhost kernel: [ 102.069121] [<c010411e>]
dump_stack+0x1a/0x1f
Jun 21 09:38:58 localhost kernel: [ 102.069151] [<c012d6cb>]
__lock_acquire+0x8e6/0x902
Jun 21 09:38:58 localhost kernel: [ 102.069363] [<c012d879>]
lock_acquire+0x4e/0x66
Jun 21 09:38:58 localhost kernel: [ 102.069562] [<c029779d>]
_spin_lock+0x24/0x32
Jun 21 09:38:58 localhost kernel: [ 102.069777] [<c0245511>]
sk_clone+0x5a/0x190
Jun 21 09:38:58 localhost kernel: [ 102.071244] [<c026cc93>]
inet_csk_clone+0xf/0x67
Jun 21 09:38:58 localhost kernel: [ 102.072932] [<e0cc7f31>]
dccp_create_openreq_child+0x17/0x2fe [dccp]
Jun 21 09:38:58 localhost kernel: [ 102.072993] [<e0b48c9b>]
dccp_v4_request_recv_sock+0x47/0x260 [dccp_ipv4]
Jun 21 09:38:58 localhost kernel: [ 102.073020] [<e0cc8340>]
dccp_check_req+0x128/0x264 [dccp]
Jun 21 09:38:58 localhost kernel: [ 102.073049] [<e0b48a38>]
dccp_v4_do_rcv+0x74/0x290 [dccp_ipv4]
Jun 21 09:38:58 localhost kernel: [ 102.073067] [<c0246492>]
sk_receive_skb+0x6b/0xfe
Jun 21 09:38:58 localhost kernel: [ 102.074607] [<e0b49e9c>]
dccp_v4_rcv+0x4ea/0x66e [dccp_ipv4]
Jun 21 09:38:58 localhost kernel: [ 102.074651] [<c0265540>]
ip_local_deliver+0x159/0x1f1
Jun 21 09:38:58 localhost kernel: [ 102.076322] [<c02653ba>]
ip_rcv+0x3e9/0x416
Jun 21 09:38:58 localhost kernel: [ 102.077995] [<c024b768>]
netif_receive_skb+0x287/0x317
Jun 21 09:38:58 localhost kernel: [ 102.079562] [<e087db67>]
rtl8139_poll+0x294/0x41c [8139too]
Jun 21 09:38:58 localhost kernel: [ 102.079610] [<c024d149>]
net_rx_action+0x8b/0x17c
Jun 21 09:38:58 localhost kernel: [ 102.081181] [<c011adf6>]
__do_softirq+0x54/0xb3
Jun 21 09:38:58 localhost kernel: [ 102.081357] [<c011ae84>]
do_softirq+0x2f/0x47
Jun 21 09:38:58 localhost kernel: [ 102.081482] [<c011b0a5>]
irq_exit+0x39/0x46
Jun 21 09:38:58 localhost kernel: [ 102.081608] [<c0104f73>] do_IRQ+0x77/0x84
Jun 21 09:38:58 localhost kernel: [ 102.081644] [<c0103561>]
common_interrupt+0x25/0x2c
Jun 21 09:38:58 localhost kernel: [ 154.463644] CCID: Registered CCID 3 (ccid3)
The code of sk_clone (net/core/sock.c) is:
struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
{
struct sock *newsk = sk_alloc(sk->sk_family, priority, sk->sk_prot, 0);
if (newsk != NULL) {
struct sk_filter *filter;
memcpy(newsk, sk, sk->sk_prot->obj_size);
/* SANITY */
sk_node_init(&newsk->sk_node);
sock_lock_init(newsk);
The relevant code is the sock_lock_init
The code of sk_receive_skb (net/core/sock.c) is:
int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
{
int rc = NET_RX_SUCCESS;
if (sk_filter(sk, skb, 0))
goto discard_and_relse;
skb->dev = NULL;
bh_lock_sock(sk);
The relevant code is the bh_lock_sock.
As I read this it is not a recursive lock as sk_clone is occurring
second and is actually creating a new socket so they are trying to
lock on different sockets.
Can someone tell me whether I am correct in my thinking or not? If I
am then I will work out how to tell the lock validator not to worry
about it.
Thanks,
Ian
--
Ian McDonald
Web: http://wand.net.nz/~iam4
Blog: http://imcdnzl.blogspot.com
WAND Network Research Group
Department of Computer Science
University of Waikato
New Zealand
^ permalink raw reply
* Re: [LARTC] Re: [PATCH 0/2] Runtime configuration of HTB's HYSTERESIS option
From: Russell Stuart @ 2006-06-20 23:13 UTC (permalink / raw)
To: Martin Devera; +Cc: Jesper Dangaard Brouer, netdev, Jamal Hadi Salim, lartc
In-Reply-To: <44912D27.4010503@cdi.cz>
On Thu, 2006-06-15 at 11:49 +0200, Martin Devera wrote:
> At time of HTB implementation I needed to reach 100MBit speed on
> relatively slow box. The hysteresis was a way. On other side I used
> hand-made TSC based measure tool to compute exact (15%) performance
> gain. Today I'd measure it using oprofile.
>
> When rethinking it again I'd suggest to re-measure real performance
> impact for both flat and deep class hierarchy and consider switching the
> hysteresis off by default (or even to remove the code if the gain is
> negligible). If it is the case then it is the cleanest solution IMHO.
I attended LCA 2006 this year. There was a presentation by
a group in New Zealand using Debian running on a embedded
box to bring the Internet to rural communities. Some of
these communities didn't have power or telephone, so the
setup ran over 802.11 over distances of up to 23Km using
solar cells for power. I don't recall exactly, but I think
the embedded box was using a 486 equivalent. I think they
had around 40 of these things up and going.
The point of the story is there are people out there who
use Linux on small processors, and often do imaginative
things with them. We would be doing them a disservice by
ripping out the code.
> On other side I see no problem with attached patches. Have you tested
> patched kernel with old "tc" tool ?
Yes.
^ permalink raw reply
* Re: [RFC] [patch 0/6] [Network namespace] introduction
From: Daniel Lezcano @ 2006-06-20 22:45 UTC (permalink / raw)
To: Al Viro; +Cc: linux-kernel, netdev, serue, haveblue, clg
In-Reply-To: <20060620212511.GW27946@ftp.linux.org.uk>
Al Viro wrote:
> On Tue, Jun 20, 2006 at 11:21:43PM +0200, Daniel Lezcano wrote:
>
>>Al Viro wrote:
>>
>>>On Fri, Jun 09, 2006 at 11:02:02PM +0200, dlezcano@fr.ibm.com wrote:
>>>- renaming an interface in one "namespace" affects everyone.
>>
>>Exact. If we ensure the interface can't be renamed if used in different
>>namespace, is it really a problem ?
>
>
> You _still_ have a single namespace; look in /sys/class/net and you'll see.
Yes, that's right. The network devices namespaces are not yet
implemented. There are potentially some conflicts with /proc and sysfs
but we will address them in a future.
BTW, do you have some ideas on how handle these conflicts ?
^ permalink raw reply
* [PATCH 6/6 resend] b44: update b44 Kconfig entry
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485574.8716.55.camel@dhcp-10-7-81-7.broadcom.com>
Deleted "EXPERIMENTAL" from b44 entry in Kconfig.
Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bdaaad8..4e57785 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1359,8 +1359,8 @@ config APRICOT
called apricot.
config B44
- tristate "Broadcom 4400 ethernet support (EXPERIMENTAL)"
- depends on NET_PCI && PCI && EXPERIMENTAL
+ tristate "Broadcom 4400 ethernet support"
+ depends on NET_PCI && PCI
select MII
help
If you have a network (Ethernet) controller of this type, say Y and
^ permalink raw reply related
* [PATCH 5/6 resend] b44: update version to 1.01
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485570.8716.54.camel@dhcp-10-7-81-7.broadcom.com>
Update the driver version to 1.01
Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 98c0675..a7e4ba5 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -29,8 +29,8 @@
#define DRV_MODULE_NAME "b44"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "1.00"
-#define DRV_MODULE_RELDATE "Apr 7, 2006"
+#define DRV_MODULE_VERSION "1.01"
+#define DRV_MODULE_RELDATE "Jun 16, 2006"
#define B44_DEF_MSG_ENABLE \
(NETIF_MSG_DRV | \
^ permalink raw reply related
* [PATCH 4/6 resend] b44: add wol for old nic
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485566.8716.53.camel@dhcp-10-7-81-7.broadcom.com>
This patch adds wol support for the older 440x nics that use pattern matching.
This patch is a redo thanks to feedback from Michael Chan and Francois Romieu.
Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 12fc67a..98c0675 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -75,6 +75,15 @@
/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
+/* b44 internal pattern match filter info */
+#define B44_PATTERN_BASE 0x400
+#define B44_PATTERN_SIZE 0x80
+#define B44_PMASK_BASE 0x600
+#define B44_PMASK_SIZE 0x10
+#define B44_MAX_PATTERNS 16
+#define B44_ETHIPV6UDP_HLEN 62
+#define B44_ETHIPV4UDP_HLEN 42
+
static char version[] __devinitdata =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
@@ -1457,6 +1466,103 @@ static void b44_poll_controller(struct n
}
#endif
+static void bwfilter_table(struct b44 *bp, u8 *pp, u32 bytes, u32 table_offset)
+{
+ u32 i;
+ u32 *pattern = (u32 *) pp;
+
+ for (i = 0; i < bytes; i += sizeof(u32)) {
+ bw32(bp, B44_FILT_ADDR, table_offset + i);
+ bw32(bp, B44_FILT_DATA, pattern[i / sizeof(u32)]);
+ }
+}
+
+static int b44_magic_pattern(u8 *macaddr, u8 *ppattern, u8 *pmask, int offset)
+{
+ int magicsync = 6;
+ int k, j, len = offset;
+ int ethaddr_bytes = ETH_ALEN;
+
+ memset(ppattern + offset, 0xff, magicsync);
+ for (j = 0; j < magicsync; j++)
+ set_bit(len++, (unsigned long *) pmask);
+
+ for (j = 0; j < B44_MAX_PATTERNS; j++) {
+ if ((B44_PATTERN_SIZE - len) >= ETH_ALEN)
+ ethaddr_bytes = ETH_ALEN;
+ else
+ ethaddr_bytes = B44_PATTERN_SIZE - len;
+ if (ethaddr_bytes <=0)
+ break;
+ for (k = 0; k< ethaddr_bytes; k++) {
+ ppattern[offset + magicsync +
+ (j * ETH_ALEN) + k] = macaddr[k];
+ len++;
+ set_bit(len, (unsigned long *) pmask);
+ }
+ }
+ return len - 1;
+}
+
+/* Setup magic packet patterns in the b44 WOL
+ * pattern matching filter.
+ */
+static void b44_setup_pseudo_magicp(struct b44 *bp)
+{
+
+ u32 val;
+ int plen0, plen1, plen2;
+ u8 *pwol_pattern;
+ u8 pwol_mask[B44_PMASK_SIZE];
+
+ pwol_pattern = kmalloc(B44_PATTERN_SIZE, GFP_KERNEL);
+ if (!pwol_pattern) {
+ printk(KERN_ERR PFX "Memory not available for WOL\n");
+ return;
+ }
+
+ /* Ipv4 magic packet pattern - pattern 0.*/
+ memset(pwol_pattern, 0, B44_PATTERN_SIZE);
+ memset(pwol_mask, 0, B44_PMASK_SIZE);
+ plen0 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
+ B44_ETHIPV4UDP_HLEN);
+
+ bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE, B44_PATTERN_BASE);
+ bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE, B44_PMASK_BASE);
+
+ /* Raw ethernet II magic packet pattern - pattern 1 */
+ memset(pwol_pattern, 0, B44_PATTERN_SIZE);
+ memset(pwol_mask, 0, B44_PMASK_SIZE);
+ plen1 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
+ ETH_HLEN);
+
+ bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE,
+ B44_PATTERN_BASE + B44_PATTERN_SIZE);
+ bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE,
+ B44_PMASK_BASE + B44_PMASK_SIZE);
+
+ /* Ipv6 magic packet pattern - pattern 2 */
+ memset(pwol_pattern, 0, B44_PATTERN_SIZE);
+ memset(pwol_mask, 0, B44_PMASK_SIZE);
+ plen2 = b44_magic_pattern(bp->dev->dev_addr, pwol_pattern, pwol_mask,
+ B44_ETHIPV6UDP_HLEN);
+
+ bwfilter_table(bp, pwol_pattern, B44_PATTERN_SIZE,
+ B44_PATTERN_BASE + B44_PATTERN_SIZE + B44_PATTERN_SIZE);
+ bwfilter_table(bp, pwol_mask, B44_PMASK_SIZE,
+ B44_PMASK_BASE + B44_PMASK_SIZE + B44_PMASK_SIZE);
+
+ kfree(pwol_pattern);
+
+ /* set these pattern's lengths: one less than each real length */
+ val = plen0 | (plen1 << 8) | (plen2 << 16) | WKUP_LEN_ENABLE_THREE;
+ bw32(bp, B44_WKUP_LEN, val);
+
+ /* enable wakeup pattern matching */
+ val = br32(bp, B44_DEVCTRL);
+ bw32(bp, B44_DEVCTRL, val | DEVCTRL_PFE);
+
+}
static void b44_setup_wol(struct b44 *bp)
{
@@ -1482,7 +1588,9 @@ static void b44_setup_wol(struct b44 *bp
val = br32(bp, B44_DEVCTRL);
bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE);
- }
+ } else {
+ b44_setup_pseudo_magicp(bp);
+ }
val = br32(bp, B44_SBTMSLOW);
bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 1f47777..4944507 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -24,6 +24,9 @@
#define WKUP_LEN_P3_MASK 0x7f000000 /* Pattern 3 */
#define WKUP_LEN_P3_SHIFT 24
#define WKUP_LEN_D3 0x80000000
+#define WKUP_LEN_DISABLE 0x80808080
+#define WKUP_LEN_ENABLE_TWO 0x80800000
+#define WKUP_LEN_ENABLE_THREE 0x80000000
#define B44_ISTAT 0x0020UL /* Interrupt Status */
#define ISTAT_LS 0x00000020 /* Link Change (B0 only) */
#define ISTAT_PME 0x00000040 /* Power Management Event */
^ permalink raw reply related
* [PATCH 3/6 resend] b44: add parameter
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485561.8716.52.camel@dhcp-10-7-81-7.broadcom.com>
This patch adds a parameter to init_hw() to not completely initialize
the nic for wol.
Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 73ca729..12fc67a 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -101,7 +101,7 @@ MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
static void b44_halt(struct b44 *);
static void b44_init_rings(struct b44 *);
-static void b44_init_hw(struct b44 *);
+static void b44_init_hw(struct b44 *, int);
static int dma_desc_align_mask;
static int dma_desc_sync_size;
@@ -873,7 +873,7 @@ static int b44_poll(struct net_device *n
spin_lock_irq(&bp->lock);
b44_halt(bp);
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
netif_wake_queue(bp->dev);
spin_unlock_irq(&bp->lock);
done = 1;
@@ -942,7 +942,7 @@ static void b44_tx_timeout(struct net_de
b44_halt(bp);
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
spin_unlock_irq(&bp->lock);
@@ -1059,7 +1059,7 @@ static int b44_change_mtu(struct net_dev
b44_halt(bp);
dev->mtu = new_mtu;
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
spin_unlock_irq(&bp->lock);
b44_enable_ints(bp);
@@ -1356,13 +1356,15 @@ static int b44_set_mac_addr(struct net_d
* packet processing. Invoked with bp->lock held.
*/
static void __b44_set_rx_mode(struct net_device *);
-static void b44_init_hw(struct b44 *bp)
+static void b44_init_hw(struct b44 *bp, int full_reset)
{
u32 val;
b44_chip_reset(bp);
- b44_phy_reset(bp);
- b44_setup_phy(bp);
+ if (full_reset) {
+ b44_phy_reset(bp);
+ b44_setup_phy(bp);
+ }
/* Enable CRC32, set proper LED modes and power on PHY */
bw32(bp, B44_MAC_CTRL, MAC_CTRL_CRC32_ENAB | MAC_CTRL_PHY_LEDCTRL);
@@ -1376,16 +1378,21 @@ static void b44_init_hw(struct b44 *bp)
bw32(bp, B44_TXMAXLEN, bp->dev->mtu + ETH_HLEN + 8 + RX_HEADER_LEN);
bw32(bp, B44_TX_WMARK, 56); /* XXX magic */
- bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
- bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
- bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
- (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
- bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
+ if (full_reset) {
+ bw32(bp, B44_DMATX_CTRL, DMATX_CTRL_ENABLE);
+ bw32(bp, B44_DMATX_ADDR, bp->tx_ring_dma + bp->dma_offset);
+ bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
+ (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
+ bw32(bp, B44_DMARX_ADDR, bp->rx_ring_dma + bp->dma_offset);
- bw32(bp, B44_DMARX_PTR, bp->rx_pending);
- bp->rx_prod = bp->rx_pending;
+ bw32(bp, B44_DMARX_PTR, bp->rx_pending);
+ bp->rx_prod = bp->rx_pending;
- bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
+ bw32(bp, B44_MIB_CTRL, MIB_CTRL_CLR_ON_READ);
+ } else {
+ bw32(bp, B44_DMARX_CTRL, (DMARX_CTRL_ENABLE |
+ (bp->rx_offset << DMARX_CTRL_ROSHIFT)));
+ }
val = br32(bp, B44_ENET_CTRL);
bw32(bp, B44_ENET_CTRL, (val | ENET_CTRL_ENABLE));
@@ -1401,7 +1408,7 @@ static int b44_open(struct net_device *d
goto out;
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
b44_check_phy(bp);
@@ -1511,7 +1518,7 @@ static int b44_close(struct net_device *
netif_poll_enable(dev);
if (bp->flags & B44_FLAG_WOL_ENABLE) {
- b44_init_hw(bp);
+ b44_init_hw(bp, 0);
b44_setup_wol(bp);
}
@@ -1786,7 +1793,7 @@ static int b44_set_ringparam(struct net_
b44_halt(bp);
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
netif_wake_queue(bp->dev);
spin_unlock_irq(&bp->lock);
@@ -1829,7 +1836,7 @@ static int b44_set_pauseparam(struct net
if (bp->flags & B44_FLAG_PAUSE_AUTO) {
b44_halt(bp);
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
} else {
__b44_set_flow_ctrl(bp, bp->flags);
}
@@ -2188,7 +2195,7 @@ static int b44_suspend(struct pci_dev *p
free_irq(dev->irq, dev);
if (bp->flags & B44_FLAG_WOL_ENABLE) {
- b44_init_hw(bp);
+ b44_init_hw(bp, 0);
b44_setup_wol(bp);
}
pci_disable_device(pdev);
@@ -2213,7 +2220,7 @@ static int b44_resume(struct pci_dev *pd
spin_lock_irq(&bp->lock);
b44_init_rings(bp);
- b44_init_hw(bp);
+ b44_init_hw(bp, 1);
netif_device_attach(bp->dev);
spin_unlock_irq(&bp->lock);
^ permalink raw reply related
* [PATCH 2/6 resend] b44: add wol
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485556.8716.51.camel@dhcp-10-7-81-7.broadcom.com>
Adds wol to the driver.
This is a redo of a previous patch thanks to feedback from Francois Romieu.
Signed-off-by Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 41b1618..81f434e 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1450,6 +1450,41 @@ static void b44_poll_controller(struct n
}
#endif
+
+static void b44_setup_wol(struct b44 *bp)
+{
+ u32 val;
+ u16 pmval;
+
+ bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
+
+ if (bp->flags & B44_FLAG_B0_ANDLATER) {
+
+ bw32(bp, B44_WKUP_LEN, WKUP_LEN_DISABLE);
+
+ val = bp->dev->dev_addr[2] << 24 |
+ bp->dev->dev_addr[3] << 16 |
+ bp->dev->dev_addr[4] << 8 |
+ bp->dev->dev_addr[5];
+ bw32(bp, B44_ADDR_LO, val);
+
+ val = bp->dev->dev_addr[0] << 8 |
+ bp->dev->dev_addr[1];
+ bw32(bp, B44_ADDR_HI, val);
+
+ val = br32(bp, B44_DEVCTRL);
+ bw32(bp, B44_DEVCTRL, val | DEVCTRL_MPM | DEVCTRL_PFE);
+
+ }
+
+ val = br32(bp, B44_SBTMSLOW);
+ bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
+
+ pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
+ pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
+
+}
+
static int b44_close(struct net_device *dev)
{
struct b44 *bp = netdev_priv(dev);
@@ -1475,6 +1510,11 @@ static int b44_close(struct net_device *
netif_poll_enable(dev);
+ if (bp->flags & B44_FLAG_WOL_ENABLE) {
+ b44_init_hw(bp);
+ b44_setup_wol(bp);
+ }
+
b44_free_consistent(bp);
return 0;
@@ -1831,12 +1871,40 @@ static void b44_get_ethtool_stats(struct
spin_unlock_irq(&bp->lock);
}
+static void b44_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct b44 *bp = netdev_priv(dev);
+
+ wol->supported = WAKE_MAGIC;
+ if (bp->flags & B44_FLAG_WOL_ENABLE)
+ wol->wolopts = WAKE_MAGIC;
+ else
+ wol->wolopts = 0;
+ memset(&wol->sopass, 0, sizeof(wol->sopass));
+}
+
+static int b44_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+ struct b44 *bp = netdev_priv(dev);
+
+ spin_lock_irq(&bp->lock);
+ if (wol->wolopts & WAKE_MAGIC)
+ bp->flags |= B44_FLAG_WOL_ENABLE;
+ else
+ bp->flags &= ~B44_FLAG_WOL_ENABLE;
+ spin_unlock_irq(&bp->lock);
+
+ return 0;
+}
+
static struct ethtool_ops b44_ethtool_ops = {
.get_drvinfo = b44_get_drvinfo,
.get_settings = b44_get_settings,
.set_settings = b44_set_settings,
.nway_reset = b44_nway_reset,
.get_link = ethtool_op_get_link,
+ .get_wol = b44_get_wol,
+ .set_wol = b44_set_wol,
.get_ringparam = b44_get_ringparam,
.set_ringparam = b44_set_ringparam,
.get_pauseparam = b44_get_pauseparam,
@@ -1915,6 +1983,10 @@ static int __devinit b44_get_invariants(
/* XXX - really required?
bp->flags |= B44_FLAG_BUGGY_TXPTR;
*/
+
+ if (ssb_get_core_rev(bp) >= 7)
+ bp->flags |= B44_FLAG_B0_ANDLATER;
+
out:
return err;
}
@@ -2115,6 +2187,10 @@ static int b44_suspend(struct pci_dev *p
spin_unlock_irq(&bp->lock);
free_irq(dev->irq, dev);
+ if (bp->flags & B44_FLAG_WOL_ENABLE) {
+ b44_init_hw(bp);
+ b44_setup_wol(bp);
+ }
pci_disable_device(pdev);
return 0;
}
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index b178662..1f47777 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -264,6 +264,8 @@
#define SBIDHIGH_VC_SHIFT 16
/* SSB PCI config space registers. */
+#define SSB_PMCSR 0x44
+#define SSB_PE 0x100
#define SSB_BAR0_WIN 0x80
#define SSB_BAR1_WIN 0x84
#define SSB_SPROM_CONTROL 0x88
@@ -420,6 +422,7 @@ struct b44 {
u32 dma_offset;
u32 flags;
+#define B44_FLAG_B0_ANDLATER 0x00000001
#define B44_FLAG_BUGGY_TXPTR 0x00000002
#define B44_FLAG_REORDER_BUG 0x00000004
#define B44_FLAG_PAUSE_AUTO 0x00008000
@@ -435,6 +438,7 @@ struct b44 {
#define B44_FLAG_INTERNAL_PHY 0x10000000
#define B44_FLAG_RX_RING_HACK 0x20000000
#define B44_FLAG_TX_RING_HACK 0x40000000
+#define B44_FLAG_WOL_ENABLE 0x80000000
u32 rx_offset;
^ permalink raw reply related
* [PATCH 1/6 resend] b44: fix manual speed/duplex/autoneg settings
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <1150485545.8716.50.camel@dhcp-10-7-81-7.broadcom.com>
Fixes for speed/duplex/autoneg settings and driver settings info.
This is a redo of a previous patch thanks to feedback from Jeff Garzik.
Signed-off-by: Gary Zambrano <zambrano@broadcom.com>
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index d8233e0..41b1618 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1620,8 +1620,6 @@ static int b44_get_settings(struct net_d
{
struct b44 *bp = netdev_priv(dev);
- if (!netif_running(dev))
- return -EAGAIN;
cmd->supported = (SUPPORTED_Autoneg);
cmd->supported |= (SUPPORTED_100baseT_Half |
SUPPORTED_100baseT_Full |
@@ -1649,6 +1647,12 @@ static int b44_get_settings(struct net_d
XCVR_INTERNAL : XCVR_EXTERNAL;
cmd->autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
AUTONEG_DISABLE : AUTONEG_ENABLE;
+ if (cmd->autoneg == AUTONEG_ENABLE)
+ cmd->advertising |= ADVERTISED_Autoneg;
+ if (!netif_running(dev)){
+ cmd->speed = 0;
+ cmd->duplex = 0xff;
+ }
cmd->maxtxpkt = 0;
cmd->maxrxpkt = 0;
return 0;
@@ -1658,9 +1662,6 @@ static int b44_set_settings(struct net_d
{
struct b44 *bp = netdev_priv(dev);
- if (!netif_running(dev))
- return -EAGAIN;
-
/* We do not support gigabit. */
if (cmd->autoneg == AUTONEG_ENABLE) {
if (cmd->advertising &
@@ -1677,28 +1678,39 @@ static int b44_set_settings(struct net_d
spin_lock_irq(&bp->lock);
if (cmd->autoneg == AUTONEG_ENABLE) {
- bp->flags &= ~B44_FLAG_FORCE_LINK;
- bp->flags &= ~(B44_FLAG_ADV_10HALF |
+ bp->flags &= ~(B44_FLAG_FORCE_LINK |
+ B44_FLAG_100_BASE_T |
+ B44_FLAG_FULL_DUPLEX |
+ B44_FLAG_ADV_10HALF |
B44_FLAG_ADV_10FULL |
B44_FLAG_ADV_100HALF |
B44_FLAG_ADV_100FULL);
- if (cmd->advertising & ADVERTISE_10HALF)
- bp->flags |= B44_FLAG_ADV_10HALF;
- if (cmd->advertising & ADVERTISE_10FULL)
- bp->flags |= B44_FLAG_ADV_10FULL;
- if (cmd->advertising & ADVERTISE_100HALF)
- bp->flags |= B44_FLAG_ADV_100HALF;
- if (cmd->advertising & ADVERTISE_100FULL)
- bp->flags |= B44_FLAG_ADV_100FULL;
+ if (cmd->advertising == 0) {
+ bp->flags |= (B44_FLAG_ADV_10HALF |
+ B44_FLAG_ADV_10FULL |
+ B44_FLAG_ADV_100HALF |
+ B44_FLAG_ADV_100FULL);
+ } else {
+ if (cmd->advertising & ADVERTISED_10baseT_Half)
+ bp->flags |= B44_FLAG_ADV_10HALF;
+ if (cmd->advertising & ADVERTISED_10baseT_Full)
+ bp->flags |= B44_FLAG_ADV_10FULL;
+ if (cmd->advertising & ADVERTISED_100baseT_Half)
+ bp->flags |= B44_FLAG_ADV_100HALF;
+ if (cmd->advertising & ADVERTISED_100baseT_Full)
+ bp->flags |= B44_FLAG_ADV_100FULL;
+ }
} else {
bp->flags |= B44_FLAG_FORCE_LINK;
+ bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
if (cmd->speed == SPEED_100)
bp->flags |= B44_FLAG_100_BASE_T;
if (cmd->duplex == DUPLEX_FULL)
bp->flags |= B44_FLAG_FULL_DUPLEX;
}
- b44_setup_phy(bp);
+ if (netif_running(dev))
+ b44_setup_phy(bp);
spin_unlock_irq(&bp->lock);
^ permalink raw reply related
* Re: [PATCH 1/6] b44: fix manual speed/duplex/autoneg settings
From: Gary Zambrano @ 2006-06-20 22:34 UTC (permalink / raw)
To: Jeff Garzik; +Cc: netdev
In-Reply-To: <4497B4FC.8000805@garzik.org>
On Tue, 2006-06-20 at 04:42 -0400, Jeff Garzik wrote:
> ACK patches 1-6, but unfortunately failed to apply against latest
> linux-2.6.git:
>
> > [jgarzik@pretzel netdev-2.6]$ git-applymbox /g/tmp/mbox ~/info/signoff.txt
> > 6 patch(es) to process.
> >
> > Applying 'b44: fix manual speed/duplex/autoneg settings'
> >
> > fatal: corrupt patch at line 8
Sorry about that.
They patch ok when using patch, however, the apply failure appears to be
related to me using git-stripspace on the patches before submitting
them.
I am resending patches that have not been git-stripspaced, so you should
not have the apply problem with the resend patches.
Thanks.
^ permalink raw reply
* Re: [FORCEDETH]: Fix xmit_lock/netif_tx_lock after merge
From: Linus Torvalds @ 2006-06-20 21:42 UTC (permalink / raw)
To: Herbert Xu; +Cc: Jeff Garzik, David S. Miller, netdev, Ayaz Abdulla
In-Reply-To: <20060620070450.GA12609@gondor.apana.org.au>
On Tue, 20 Jun 2006, Herbert Xu wrote:
>
> [FORCEDETH]: Fix xmit_lock/netif_tx_lock after merge
Btw, please don't use attachments in vain. Now I can't see it by default,
I can reply and quote it etc etc.
Linus
^ permalink raw reply
* ipv6 source address selection in addrconf.c (2.6.17)
From: Lukasz Stelmach @ 2006-06-20 21:38 UTC (permalink / raw)
To: netdev; +Cc: Łukasz Stelmach
[-- Attachment #1: Type: text/plain, Size: 944 bytes --]
Greetings.
net/ipv6/addrconf.c:971 is
/* Rule 2: Prefer appropriate scope */
if (hiscore.rule < 2) {
hiscore.scope = __ipv6_addr_src_scope(hiscore.addr_type);
hiscore.rule++;
}
I am afraid, that it does not make any sense for I find no place where a value
is assigned to hiscore.addr_type. There are some more references to
hiscore.addr_type below but the only assignment is when the whole structure is
cleaned with memset(3)
I found it when I was trying to figure out why when trying to connect to
2001:200:0:8002:203:47ff:fea5:3085 (www.kame.net)
with two global addresses assigned to the ethernet card
fd24:6f44:46bd:face::254
2002:531f:d667:face::254
rule 8 does not work and the first address is chosen.
Please CC answers.
--
Było mi bardzo miło. Czwarta pospolita klęska, [...]
>Łukasz< Już nie katolicka lecz złodziejska. (c)PP
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 254 bytes --]
^ permalink raw reply
* Re: [DOC]: generic netlink
From: Thomas Graf @ 2006-06-20 21:34 UTC (permalink / raw)
To: jamal; +Cc: Per Liden, Shailabh Nagar, Jay Lan, David S. Miller, netdev
In-Reply-To: <1150815697.5270.86.camel@jzny2>
Hello
> > > TODO:
> > > a) Add a more complete compiling kernel module with events.
> > > Have Thomas put his Mashimaro example and point to it.
> >
> > I guess we have a legal issue here ;)
> >
>
> change the name ;->
Ask Mr. Mashimaro has become my replacement for 8ball. Renaming
it would lead to a serious loss of coolness ;-)
> > > b) Describe some details on how user space -> kernel works
> > > probably using libnl??
> >
> > I'll take care of that.
>
> Whats the plan? To add to this doc or separate doc?
The status is that the code is there including userspace tools
to query the controller. Documentation is written as part of
the API reference (coming up with -pre6), no architectural notes
yet though. I think it's best to keep it separated and refer to
it both ways.
^ permalink raw reply
* Re: [GIT PATCH] TIPC updates
From: David Miller @ 2006-06-20 21:28 UTC (permalink / raw)
To: per.liden; +Cc: netdev
In-Reply-To: <Pine.LNX.4.64.0606201637050.29502@ulinpc219.uab.ericsson.se>
From: Per Liden <per.liden@ericsson.com>
Date: Tue, 20 Jun 2006 16:48:54 +0200 (CEST)
> Please pull from:
>
> git://tipc.cslab.ericsson.net/pub/git/tipc.git
Hi Per.
I agree with James, you should post the patches so that people
can review them.
But not all in one posting! :-)
Look at how other contributors submit their work. They make a set of
postings to the list, one for each patch, and each posting has
a subject that begins with something like "[PATCH 1/N] " where
the "1" increases for each patch and the "N" is the total number
of patches you are submitting for review.
People typically also give an initial "[PATCH 0/N] " posting
where the location of the GIT tree containing the patches lives
and also a general summary of what the upcoming set of patches
do.
There are automated scripts which can take a GIT tree and a given
range of changesets and prebuild the list postings for you. So
the amount of work you need to do for this is minimal.
For example, "git format-patch" and "git send-email" can help you a
lot here.
Thanks!
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox