* Re: [PATCH v3] AX25: kill user triggable printks
From: David Miller @ 2008-01-10 11:58 UTC (permalink / raw)
To: max; +Cc: netdev
In-Reply-To: <1199874070-9524-1-git-send-email-max@stro.at>
From: maximilian attems <max@stro.at>
Date: Wed, 9 Jan 2008 11:21:10 +0100
> sfuzz can easily trigger any of those.
>
> move the printk message to the corresponding comment:
> makes the intention of the code clear and easy
> to pick up on an scheduled removal.
> as bonus simplify the braces placement.
>
> Signed-off-by: maximilian attems <max@stro.at>
Applied, thanks.
^ permalink raw reply
* Re: [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
From: David Miller @ 2008-01-10 11:56 UTC (permalink / raw)
To: dada1; +Cc: herbert, paulmck, dipankar, netdev
In-Reply-To: <20080109113727.50eae500.dada1@cosmosbay.com>
From: Eric Dumazet <dada1@cosmosbay.com>
Date: Wed, 9 Jan 2008 11:37:27 +0100
> [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
>
> In rt_cache_get_next(), no need to guard seq->private by a rcu_dereference()
> since seq is private to the thread running this function. Reading seq.private
> once (as guaranted bu rcu_dereference()) or several time if compiler really is
> dumb enough wont change the result.
>
> But we miss real spots where rcu_dereference() are needed, both in
> rt_cache_get_first() and rt_cache_get_next()
>
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
I've applied this to net-2.6, thanks!
^ permalink raw reply
* Re: [PATCH 2.6.25] [NEIGH] Make /proc/net/arp opening consistent with seq_net_open semantics
From: David Miller @ 2008-01-10 11:53 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110113219.GA16233@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:32:19 +0300
> seq_open_net requires that first field of the seq->private data to be
> struct seq_net_private. In reality this is a single pointer to a struct net
> for now. The patch makes code consistent.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks for correcting this.
^ permalink raw reply
* Re: [PATCH 2.6.25] [ATM] Simplify /proc/net/atm/arp opening
From: David Miller @ 2008-01-10 11:52 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110113044.GA16213@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:30:44 +0300
> The iterator state->ns.neigh_sub_iter initialization is moved from
> arp_seq_open to clip_seq_start for convinience. This should not be a problem
> as the iterator will be used only after the seq_start callback.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH 2.6.25] [ATM] Oops reading net/atm/arp
From: David Miller @ 2008-01-10 11:51 UTC (permalink / raw)
To: den; +Cc: dlezcano, xemul, netdev, containers, devel
In-Reply-To: <20080110112853.GA16173@iris.sw.ru>
From: "Denis V. Lunev" <den@openvz.org>
Date: Thu, 10 Jan 2008 14:28:53 +0300
> cat /proc/net/atm/arp causes the NULL pointer dereference in the
> get_proc_net+0xc/0x3a. This happens as proc_get_net believes that the
> parent proc dir entry contains struct net.
>
> Fix this assumption for "net/atm" case.
>
> The problem is introduced by the commit c0097b07abf5f92ab135d024dd41bd2aada1512f
> from Eric W. Biederman/Daniel Lezcano.
>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH][NEIGH] Fix race between neigh_parms_release and neightbl_fill_parms
From: David Miller @ 2008-01-10 11:50 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel
In-Reply-To: <4785F9F5.6070502@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 10 Jan 2008 13:56:53 +0300
> The neightbl_fill_parms() is called under the write-locked
> tbl->lock and accesses the parms->dev. The negh_parm_release()
> calls the dev_put(parms->dev) without this lock. This
> creates a tiny race window on which the parms contains
> potentially stale dev pointer.
>
> To fix this race it's enough to move the dev_put() upper
> under the tbl->lock, but note, that the parms are held by
> neighbors and thus can live after the neigh_parms_release()
> is called, so we still can have a parm with bad dev pointer.
>
> I didn't find where the neigh->parms->dev is accessed, but
> still think that putting the dev is to be done in a place,
> where the parms are really freed. Am I right with that?
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
It is accessed in lookup_neigh_parms(), neightbl_fill_parms(), and
neightbl_fill_info() (hmmm, that BUG_ON(tbl->parms.dev) is cute).
You fix looks correct, patch applied, thanks!
^ permalink raw reply
* Re: [PATCH netns-2.6.25 0/19] routing virtualization v2
From: David Miller @ 2008-01-10 11:38 UTC (permalink / raw)
To: den; +Cc: benjamin.thery, dlezcano, devel, containers, netdev, xemul
In-Reply-To: <47850C57.60907@openvz.org>
From: "Denis V. Lunev" <den@openvz.org>
Date: Wed, 09 Jan 2008 21:03:03 +0300
> This set adds namespace support for routing tables & rules
> manipulation in the different namespaces. So, one could create a
> namespace and setup IPv4 routing there how he wants.
All 19 patches applied, thanks Denis.
^ permalink raw reply
* Re: FW: ccid2/ccid3 oopses
From: Gerrit Renker @ 2008-01-10 11:31 UTC (permalink / raw)
To: devzero; +Cc: Arnaldo Carvalho de Melo, dccp, netdev
In-Reply-To: <95473050@web.de>
| > So maybe the cause triggering this oops is somewhere else.
|
| yes, probably. sorry - i didn`t tell or maybe i didn`t know when writing
| my first mail to module authors and forget to add that before forwarding here.
|
| for me , the problem does not happen with suse kernel of the day
| (2.6.24-rc6-git7-20080102160500-default, .config attached) but it happens
| with vanilla 2.6.24-rc6 (mostly allmodconfig, also attached)
|
There are 256 differences between the two .config files. I think there are other
people on the list who will be able to give more information regarding the .config
files. The differences that struck me in the one which doesn't work is
-- CONFIG_DEBUG_KERNEL and
-- CONFIG_DEBUG_BUGVERBOSE were not set. Both are very useful for bug-hunting,
the latter is much better for decoding oopses.
Can't say anything about the Suse kernel. We use the plain kernel from www.kernel.org,
specifically the netdev-tree:
git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
If you can't get further here, try with a kernel.org kernel or check Suse forums.
1. the tests yesterday were done on the DCCP test tree based on the above netdev-2.6
2.6.24-rc7 tree from git://eden-feed.erg.abdn.ac.uk/dccp_exp (dccp subtree)
Tested your for-loop 60 seconds each for CCID3/4 -- no oops.
2. also repeated the tests on an unmodified 2.6.24-rc7 tree from netdev-2.6 (today)
120 seconds for-loop each -- no oops.
As said, if the above does not help, try a www.kernel.org kernel (or one of the
above trees) first.
|
| >| > >> the easiest way to reproduce is:
| > | > >>
| > | > >> while true;do modprobe dccp_ccid2/3;modprobe -r dccp_ccid2/3;done
| > | > >> after short time, the kernel oopses (messages below)
| > | > >>
^ permalink raw reply
* Re: Linux IPv6 DAD not full conform to RFC 4862 ?
From: Karsten Keil @ 2008-01-10 11:29 UTC (permalink / raw)
To: netdev
In-Reply-To: <20080109.153212.144388472.davem@davemloft.net>
On Wed, Jan 09, 2008 at 03:32:12PM -0800, David Miller wrote:
> From: Karsten Keil <kkeil@suse.de>
> Date: Wed, 9 Jan 2008 16:36:56 +0100
>
> > If the address is a link-local address formed from an interface
> > identifier based on the hardware address, which is supposed to be
> > uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP
> > operation on the interface SHOULD be disabled. By disabling IP
> > operation, the node will then:
> >
> > - not send any IP packets from the interface,
> >
> > - silently drop any IP packets received on the interface, and
> >
> > - not forward any IP packets to the interface (when acting as a
> > router or processing a packet with a Routing header).
>
> I question any RFC mandate that shuts down IP communication on a node
> because of packets received from remote systems.
>
> If the TAHI test can trigger this, so can a compromised system on your
> network and won't that be fun? :-)
I agree, but on the other side, a interface with a real duplicate HW address
sending packets on the network can also cause very serious problems, and
maybe is not so easy to detect as a system where the interface never come
up because of this. So maybe it makes sense to implement it as option, not
as default.
And the DOS scenario is already here, also without disabling IP completely,
since you can deny any IPv6 address assignments with faked DAD pakets.
--
Karsten Keil
SuSE Labs
SUSE LINUX Products GmbH, Maxfeldstr.5 90409 Nuernberg, GF: Markus Rex, HRB 16746 (AG Nuernberg)
^ permalink raw reply
* [PATCH 2.6.25] [NEIGH] Make /proc/net/arp opening consistent with seq_net_open semantics
From: Denis V. Lunev @ 2008-01-10 11:32 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
seq_open_net requires that first field of the seq->private data to be
struct seq_net_private. In reality this is a single pointer to a struct net
for now. The patch makes code consistent.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index a9dda29..09f9fc6 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -223,7 +223,7 @@ extern void __neigh_for_each_release(struct neigh_table *tbl, int (*cb)(struct n
extern void pneigh_for_each(struct neigh_table *tbl, void (*cb)(struct pneigh_entry *));
struct neigh_seq_state {
- struct net *net;
+ struct seq_net_private p;
struct neigh_table *tbl;
void *(*neigh_sub_iter)(struct neigh_seq_state *state,
struct neighbour *n, loff_t *pos);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 8024933..19c0dd1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2142,7 +2142,7 @@ EXPORT_SYMBOL(__neigh_for_each_release);
static struct neighbour *neigh_get_first(struct seq_file *seq)
{
struct neigh_seq_state *state = seq->private;
- struct net *net = state->net;
+ struct net *net = state->p.net;
struct neigh_table *tbl = state->tbl;
struct neighbour *n = NULL;
int bucket = state->bucket;
@@ -2183,7 +2183,7 @@ static struct neighbour *neigh_get_next(struct seq_file *seq,
loff_t *pos)
{
struct neigh_seq_state *state = seq->private;
- struct net *net = state->net;
+ struct net *net = state->p.net;
struct neigh_table *tbl = state->tbl;
if (state->neigh_sub_iter) {
@@ -2243,7 +2243,7 @@ static struct neighbour *neigh_get_idx(struct seq_file *seq, loff_t *pos)
static struct pneigh_entry *pneigh_get_first(struct seq_file *seq)
{
struct neigh_seq_state *state = seq->private;
- struct net * net = state->net;
+ struct net * net = state->p.net;
struct neigh_table *tbl = state->tbl;
struct pneigh_entry *pn = NULL;
int bucket = state->bucket;
@@ -2266,7 +2266,7 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
loff_t *pos)
{
struct neigh_seq_state *state = seq->private;
- struct net * net = state->net;
+ struct net * net = state->p.net;
struct neigh_table *tbl = state->tbl;
pn = pn->next;
^ permalink raw reply related
* [PATCH 2.6.25] [ATM] Simplify /proc/net/atm/arp opening
From: Denis V. Lunev @ 2008-01-10 11:30 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
The iterator state->ns.neigh_sub_iter initialization is moved from
arp_seq_open to clip_seq_start for convinience. This should not be a problem
as the iterator will be used only after the seq_start callback.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 47fbdc0..de5b780 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -903,6 +903,8 @@ static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
{
+ struct clip_seq_state *state = seq->private;
+ state->ns.neigh_sub_iter = clip_seq_sub_iter;
return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
}
@@ -932,49 +934,15 @@ static const struct seq_operations arp_seq_ops = {
static int arp_seq_open(struct inode *inode, struct file *file)
{
- struct clip_seq_state *state;
- struct seq_file *seq;
- int rc = -EAGAIN;
-
- state = kzalloc(sizeof(*state), GFP_KERNEL);
- if (!state) {
- rc = -ENOMEM;
- goto out_kfree;
- }
- state->ns.neigh_sub_iter = clip_seq_sub_iter;
-
- rc = seq_open(file, &arp_seq_ops);
- if (rc)
- goto out_kfree;
-
- seq = file->private_data;
- seq->private = state;
- state->ns.net = get_proc_net(inode);
- if (!state->ns.net) {
- seq_release_private(inode, file);
- rc = -ENXIO;
- }
-out:
- return rc;
-
-out_kfree:
- kfree(state);
- goto out;
-}
-
-static int arp_seq_release(struct inode *inode, struct file *file)
-{
- struct seq_file *seq = file->private_data;
- struct clip_seq_state *state = seq->private;
- put_net(state->ns.net);
- return seq_release_private(inode, file);
+ return seq_open_net(inode, file, &arp_seq_ops,
+ sizeof(struct clip_seq_state));
}
static const struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = arp_seq_release,
+ .release = seq_release_net,
.owner = THIS_MODULE
};
#endif
^ permalink raw reply related
* [PATCH 2.6.25] [ATM] Oops reading net/atm/arp
From: Denis V. Lunev @ 2008-01-10 11:28 UTC (permalink / raw)
To: davem; +Cc: dlezcano, xemul, netdev, containers, devel
cat /proc/net/atm/arp causes the NULL pointer dereference in the
get_proc_net+0xc/0x3a. This happens as proc_get_net believes that the
parent proc dir entry contains struct net.
Fix this assumption for "net/atm" case.
The problem is introduced by the commit c0097b07abf5f92ab135d024dd41bd2aada1512f
from Eric W. Biederman/Daniel Lezcano.
Signed-off-by: Denis V. Lunev <den@openvz.org>
---
diff --git a/fs/proc/proc_net.c b/fs/proc/proc_net.c
index cfc4f6c..4823c96 100644
--- a/fs/proc/proc_net.c
+++ b/fs/proc/proc_net.c
@@ -96,6 +96,17 @@ static struct proc_dir_entry *proc_net_shadow(struct task_struct *task,
return task->nsproxy->net_ns->proc_net;
}
+struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+ struct proc_dir_entry *parent)
+{
+ struct proc_dir_entry *pde;
+ pde = proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
+ if (pde != NULL)
+ pde->data = net;
+ return pde;
+}
+EXPORT_SYMBOL_GPL(proc_net_mkdir);
+
static __net_init int proc_net_ns_init(struct net *net)
{
struct proc_dir_entry *root, *netd, *net_statd;
@@ -107,18 +118,16 @@ static __net_init int proc_net_ns_init(struct net *net)
goto out;
err = -EEXIST;
- netd = proc_mkdir("net", root);
+ netd = proc_net_mkdir(net, "net", root);
if (!netd)
goto free_root;
err = -EEXIST;
- net_statd = proc_mkdir("stat", netd);
+ net_statd = proc_net_mkdir(net, "stat", netd);
if (!net_statd)
goto free_net;
root->data = net;
- netd->data = net;
- net_statd->data = net;
net->proc_net_root = root;
net->proc_net = netd;
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index a531682..8f92546 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -201,6 +201,8 @@ static inline struct proc_dir_entry *create_proc_info_entry(const char *name,
extern struct proc_dir_entry *proc_net_fops_create(struct net *net,
const char *name, mode_t mode, const struct file_operations *fops);
extern void proc_net_remove(struct net *net, const char *name);
+extern struct proc_dir_entry *proc_net_mkdir(struct net *net, const char *name,
+ struct proc_dir_entry *parent);
#else
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 5d9d5ff..565e75e 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -476,7 +476,7 @@ static void atm_proc_dirs_remove(void)
if (e->dirent)
remove_proc_entry(e->name, atm_proc_root);
}
- remove_proc_entry("atm", init_net.proc_net);
+ proc_net_remove(&init_net, "atm");
}
int __init atm_proc_init(void)
@@ -484,7 +484,7 @@ int __init atm_proc_init(void)
static struct atm_proc_entry *e;
int ret;
- atm_proc_root = proc_mkdir("atm", init_net.proc_net);
+ atm_proc_root = proc_net_mkdir(&init_net, "atm", init_net.proc_net);
if (!atm_proc_root)
goto err_out;
for (e = atm_proc_ents; e->name; e++) {
^ permalink raw reply related
* Re: No idea about shaping trough many pc
From: Badalian Vyacheslav @ 2008-01-10 11:23 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <20080110103708.M15442@visp.net.lb>
Thanks for answer!
1 PC have more then 15k TC rules.... tc get many cpu si...
I don't wont split networks on cisco, becouse i need HA. If PC do
shutdown - another must get all function. BGP work great for this solution.
But have troubles in control common traffic from users.
Will be great if i can create common TC rules that share to all PC and
its have common data (statistic, info, tokens, and e.t.c.). Maybe netdev
think about system mode that we have one OS on many PC (Like HA
Cluster). Linux may do great routing solution!
Will be great if all 20 PC may be 1 logical PC that have many CPU and
may process lots of interrupts!
Thanks =)
> For proper link bandwidth sharing i guess something like network counters
> have to be shared between PC's (with proper locking). I didn't heard anything
> like this
>
> IMHO a ways to do this:
> Split destination network to multiple parts and do routes on Cisco. Let's say
> you have:
> 192.168.0.0/16
> and u have 4 balancing PC's
> total bandwidth 1Gbit/s (speed conforming to IEC 1000Mbit/s in 1Gbit/s)
>
> Then u do on cisco :
> 192.168.0.0/18 via PC1(shared speed 250Mbit/s)
> 192.168.64.0/18 via PC2(shared speed 250Mbit/s)
> 192.168.128.0/18 via PC3(shared speed 250Mbit/s)
> 192.168.192.0/18 via PC4(shared speed 250Mbit/s)
>
> Probably you can do some scripts to check, if there is in some PC too much
> available bandwidth (average 5 minutes), then you can give some other PC
> which is need more bandwidth - more bandwidth. For example:
>
> Average counters for 5minute shows:
> PC1 - occupy 100Mbit/s
> PC2 - -//- 50Mbit/s
> PC3 - -//- 150Mbit/s
> PC4 - -//- 230Mbit/s
>
> Then u change link speed:
> PC1 max 200
> PC2 max 150
> PC3 max 250
> PC4 max 400 (100 from PC2 and 50 from PC1)
>
> Sure PC must be capable to pass this traffic. And my IMHO it is not normal
> that your PC's not able to handle more than 200Mbps of traffic. I have
> complicated setup, with 4 LAN 8139 cards, which is passing totally 200Mbps
> traffic. I am sure it can handle up to 300mbps, but already i am changing it
> to PC with PCI-E e1000/broadcom netxtreme with offloading capabilities, large
> buffers and proper drivers with NAPI. I have such hardware handling now for
> example 160Mbps and counters is:
> 12:50:41 CPU %user %nice %sys %iowait %irq %soft %steal
> %idle intr/s
> 12:50:42 all 0.00 0.00 0.00 0.00 0.25 1.24 0.00
> 98.51 4009.90
> 12:50:43 all 0.00 0.00 0.00 0.00 0.00 1.25 0.00
> 98.75 4024.75
> 12:50:44 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
> 98.50 4181.82
> 12:50:45 all 0.25 0.00 0.00 0.00 0.00 1.50 0.00
> 98.25 4626.73
> 12:50:46 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
> 98.50 4351.52
> 12:50:47 all 0.25 0.00 0.00 0.00 0.00 1.75 0.00
> 98.00 4805.88
>
> It is 2.6.23.8 with some mistakes during configuration, i am doing to try
> 2.6.24-rc7 and some optimizations.
>
> Right now profile looks like:
> 10957 17.0675 mwait_idle_with_hints
> 7454 11.6110 read_hpet
> 3883 6.0485 _raw_spin_lock
> 1605 2.5001 timer_interrupt
> 1363 2.1231 irq_entries_start
>
> So maybe i will have to try change timers to TSC, disable nmi_watchdog and
> try to tune up network driver (bnx2).
> Probably you have to check such things too.
>
> On Thu, 10 Jan 2008 12:06:35 +0300, Badalian Vyacheslav wrote
>
>> Hello all.
>> I try more then 2 month resolve problem witch my shaping. Maybe you
>> can help for me?
>>
>> Sheme:
>> +-------------------+
>> + ----- | Shaping PC 1 | ---------+
>> / +-------------------+ \
>> +--------+ / +--------------------+ \
>> + --------+ | Cisco | +-------- | Shaping PC N | -----------+ --
>> ---| CISCO | +--------+ \ +--------------------+
>> / +---------+ \ +---------
>> ------------+ / + ----- | Shaping PC
>> 20 | --------+ +---------------------+
>>
>> Network - Over 10k users. Common bandwidth to INTERNET more then 1
>> GBs All computers have BGP and turn on multipath. Cisco can't do
>> load sharing by Packet (its can resolve all my problems =((( ). Only
>> by DST IP, SRC IP, or +Level4. Ok. User must have speed 1mbs. Lets
>> look variants:
>> 1. Create rules to user = (1mbs/N computers). If user use N
>> connection all great, but if it use 1 connection his speed = 1mbs/N -
>> its not look good. All be great if cisco can PER PACKET load
>> sharing =(
>> 2. Create rules to user = 1mbs. If user use 1 connection all great,
>> but if it use N connection his speed much more then needed limit =(
>>
>> Why i use 20 PC? Becouse 1 pc normal forward 100-150mbs... when it
>> have 100% cpu usage on Sofware Interrupts...
>>
>> Any idea how to resolve this problem?
>>
>> In my dreams (feature request to netdev ;) ):
>> Get PC - title: MASTER TC. All 20 PC syncronize statistic with
>> MASTER and have common rules and statistic. Then i use variant 2 and
>> will be happy... but its not real? =( Maybe have other variants?
>>
>> Thanks for help!
>> Slavon.
>> P.S. Sorry for my english =(
>> --
>> To unsubscribe from this list: send the line "unsubscribe netdev" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>
>
> --
> Denys Fedoryshchenko
> Technical Manager
> Virtual ISP S.A.L.
>
>
>
^ permalink raw reply
* Re: Linux IPv6 DAD not full conform to RFC 4862 ?
From: Karsten Keil @ 2008-01-10 11:16 UTC (permalink / raw)
To: netdev
In-Reply-To: <20080109202653.GA26160@pingi.kke.suse.de>
Hi,
On Wed, Jan 09, 2008 at 09:26:53PM +0100, Karsten Keil wrote:
> >
> > Reading the section you reference, we do follow all the MUST requirements, and
> > we log an error. Given that the disable section is a SHOULD, I think we can at
> > least be somewhat more restrictive in our implementation. Perhaps we should
> > just disable the interface iff the failed address is link-local AND there are no
> > other functional address assigned to the interface.
>
> I agree here, but it seems that currently the IPv6 Logo Committee thinks
> that it has to be disable the interface to get the IPv6 ready Logo in
> future. I already claim that on a discussion at the TAHI users list.
>
JFYI, here the answer from the TAHI list.
Hi, Karsten.
Thanks for your comments.
I know that it is SHOULD,
but our test tool supports the test specification
published by IPv6 Ready Logo Program <http://www.ipv6ready.org/>,
and basically the test specification supports all of MUST and SHOULD.
You may know,
now IPv6 Ready Logo Committee is also discussing
about the next major revision up of test specification.
RFC 4862 Section 5.4.5 is one of discussing point.
The public review has been over,
but if you have strong concern about it,
I recommend to comment to <ipv6ready-info@ipv6ready.org>.
Personally,
I think that mandating this function is the best way.
But vendor's input will really important for them.
Regards,
Yukiyo Akisada
So it would be good if some of the networking experts complain there.
--
Karsten Keil
SuSE Labs
ISDN and VOIP development
SUSE LINUX Products GmbH, Maxfeldstr.5 90409 Nuernberg, GF: Markus Rex, HRB 16746 (AG Nuernberg)
^ permalink raw reply
* Re: [patch net-2.6.25 00/10][NETNS][IPV6] make sysctl per namespace - V3
From: David Miller @ 2008-01-10 11:15 UTC (permalink / raw)
To: dlezcano; +Cc: netdev, benjamin.thery
In-Reply-To: <20080109164533.695191040@localhost.localdomain>
From: Daniel Lezcano <dlezcano@fr.ibm.com>
Date: Wed, 09 Jan 2008 17:45:33 +0100
> The following patchset makes the ipv6 sysctl to handle multiple
> network namespaces. Each instance of a network namespace as its own
> set of sysctl values, that means the behavior of the ipv6 stack can be
> different depending on the sysctl values setup in the different
> network namespaces.
I applied all of this to net-2.6.25 but what a rough half hour
it was :-/
Starting at patch #5 there were tons of "space before tab" errors.
And as I fixed them up, this made subsequent patches need rediffing
since the contextual lines in patches after #5 needed the whitespace
fixed up as well.
I didn't push this back to you because this was already the 3rd round,
but please show me some love and check this stuff out before
submission. GIT gives you effective ways to verify the whitespace
without even applying the patch.
~davem/bin/pcheck:
#!/bin/sh
set -x
git apply --check --whitespace=error-all $1
^ permalink raw reply
* Re: No idea about shaping trough many pc
From: Denys Fedoryshchenko @ 2008-01-10 11:00 UTC (permalink / raw)
To: Badalian Vyacheslav, netdev
In-Reply-To: <4785E01B.3080900@bigtelecom.ru>
For proper link bandwidth sharing i guess something like network counters
have to be shared between PC's (with proper locking). I didn't heard anything
like this
IMHO a ways to do this:
Split destination network to multiple parts and do routes on Cisco. Let's say
you have:
192.168.0.0/16
and u have 4 balancing PC's
total bandwidth 1Gbit/s (speed conforming to IEC 1000Mbit/s in 1Gbit/s)
Then u do on cisco :
192.168.0.0/18 via PC1(shared speed 250Mbit/s)
192.168.64.0/18 via PC2(shared speed 250Mbit/s)
192.168.128.0/18 via PC3(shared speed 250Mbit/s)
192.168.192.0/18 via PC4(shared speed 250Mbit/s)
Probably you can do some scripts to check, if there is in some PC too much
available bandwidth (average 5 minutes), then you can give some other PC
which is need more bandwidth - more bandwidth. For example:
Average counters for 5minute shows:
PC1 - occupy 100Mbit/s
PC2 - -//- 50Mbit/s
PC3 - -//- 150Mbit/s
PC4 - -//- 230Mbit/s
Then u change link speed:
PC1 max 200
PC2 max 150
PC3 max 250
PC4 max 400 (100 from PC2 and 50 from PC1)
Sure PC must be capable to pass this traffic. And my IMHO it is not normal
that your PC's not able to handle more than 200Mbps of traffic. I have
complicated setup, with 4 LAN 8139 cards, which is passing totally 200Mbps
traffic. I am sure it can handle up to 300mbps, but already i am changing it
to PC with PCI-E e1000/broadcom netxtreme with offloading capabilities, large
buffers and proper drivers with NAPI. I have such hardware handling now for
example 160Mbps and counters is:
12:50:41 CPU %user %nice %sys %iowait %irq %soft %steal
%idle intr/s
12:50:42 all 0.00 0.00 0.00 0.00 0.25 1.24 0.00
98.51 4009.90
12:50:43 all 0.00 0.00 0.00 0.00 0.00 1.25 0.00
98.75 4024.75
12:50:44 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
98.50 4181.82
12:50:45 all 0.25 0.00 0.00 0.00 0.00 1.50 0.00
98.25 4626.73
12:50:46 all 0.00 0.00 0.00 0.00 0.00 1.50 0.00
98.50 4351.52
12:50:47 all 0.25 0.00 0.00 0.00 0.00 1.75 0.00
98.00 4805.88
It is 2.6.23.8 with some mistakes during configuration, i am doing to try
2.6.24-rc7 and some optimizations.
Right now profile looks like:
10957 17.0675 mwait_idle_with_hints
7454 11.6110 read_hpet
3883 6.0485 _raw_spin_lock
1605 2.5001 timer_interrupt
1363 2.1231 irq_entries_start
So maybe i will have to try change timers to TSC, disable nmi_watchdog and
try to tune up network driver (bnx2).
Probably you have to check such things too.
On Thu, 10 Jan 2008 12:06:35 +0300, Badalian Vyacheslav wrote
> Hello all.
> I try more then 2 month resolve problem witch my shaping. Maybe you
> can help for me?
>
> Sheme:
> +-------------------+
> + ----- | Shaping PC 1 | ---------+
> / +-------------------+ \
> +--------+ / +--------------------+ \
> + --------+ | Cisco | +-------- | Shaping PC N | -----------+ --
> ---| CISCO | +--------+ \ +--------------------+
> / +---------+ \ +---------
> ------------+ / + ----- | Shaping PC
> 20 | --------+ +---------------------+
>
> Network - Over 10k users. Common bandwidth to INTERNET more then 1
> GBs All computers have BGP and turn on multipath. Cisco can't do
> load sharing by Packet (its can resolve all my problems =((( ). Only
> by DST IP, SRC IP, or +Level4. Ok. User must have speed 1mbs. Lets
> look variants:
> 1. Create rules to user = (1mbs/N computers). If user use N
> connection all great, but if it use 1 connection his speed = 1mbs/N -
> its not look good. All be great if cisco can PER PACKET load
> sharing =(
> 2. Create rules to user = 1mbs. If user use 1 connection all great,
> but if it use N connection his speed much more then needed limit =(
>
> Why i use 20 PC? Becouse 1 pc normal forward 100-150mbs... when it
> have 100% cpu usage on Sofware Interrupts...
>
> Any idea how to resolve this problem?
>
> In my dreams (feature request to netdev ;) ):
> Get PC - title: MASTER TC. All 20 PC syncronize statistic with
> MASTER and have common rules and statistic. Then i use variant 2 and
> will be happy... but its not real? =( Maybe have other variants?
>
> Thanks for help!
> Slavon.
> P.S. Sorry for my english =(
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Denys Fedoryshchenko
Technical Manager
Virtual ISP S.A.L.
^ permalink raw reply
* [PATCH][NEIGH] Fix race between neigh_parms_release and neightbl_fill_parms
From: Pavel Emelyanov @ 2008-01-10 10:56 UTC (permalink / raw)
To: David Miller; +Cc: Linux Netdev List, devel
The neightbl_fill_parms() is called under the write-locked
tbl->lock and accesses the parms->dev. The negh_parm_release()
calls the dev_put(parms->dev) without this lock. This
creates a tiny race window on which the parms contains
potentially stale dev pointer.
To fix this race it's enough to move the dev_put() upper
under the tbl->lock, but note, that the parms are held by
neighbors and thus can live after the neigh_parms_release()
is called, so we still can have a parm with bad dev pointer.
I didn't find where the neigh->parms->dev is accessed, but
still think that putting the dev is to be done in a place,
where the parms are really freed. Am I right with that?
Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
---
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 29b8ee4..cc8a2f1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1316,8 +1316,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
*p = parms->next;
parms->dead = 1;
write_unlock_bh(&tbl->lock);
- if (parms->dev)
- dev_put(parms->dev);
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
return;
}
@@ -1328,6 +1326,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
void neigh_parms_destroy(struct neigh_parms *parms)
{
+ if (parms->dev)
+ dev_put(parms->dev);
kfree(parms);
}
^ permalink raw reply related
* Re: [PATCH] drivers/net/niu: Support for Marvell PHY
From: David Miller @ 2008-01-10 10:24 UTC (permalink / raw)
To: mlindner; +Cc: netdev
In-Reply-To: <1199957581.5290.21.camel@mlindner-lin.skd.de>
From: Mirko Lindner <mlindner@marvell.com>
Date: Thu, 10 Jan 2008 10:33:01 +0100
> This patch makes necessary changes in the Neptune driver to support
> the new Marvell PHY. It also adds support for the LED blinking
> on Neptune cards with Marvell PHY. All registers are using defines
> in the niu.h header file as is already done for the BCM8704 registers.
Applied. Please provide a proper "Signed-off-by: " line next
time as documented in linux/Documentation/SubmittingPatches
Also there were a lot of coding style and other errors. I
fixed them up because I already put you through the ringer
to fix up the original patch.
I'll note most of them, but reading linux/CodingStyle would be a great
idea:
> -static int xcvr_init_10g(struct niu *np)
> +void mrvl88x2011_act_led(struct niu *np, int val)
...
> +void mrvl88x2011_led_blink_rate(struct niu *np, int rate)
> +{
Both of these functions should be marked "static", return an "int" and
check and return all errors indicated by mdio_read() and mdio_write().
> +static int xcvr_init_10g_mrvl88x2011(struct niu *np)
> +{
...
> + /* Set LED functions */
> + mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
> + mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF); /* led activity */
Longer than 80-column lines, no error checking.
> + err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
> + MRVL88X2011_GENERAL_CTL);
> + if (err < 0) {
> + return(err);
> + }
Extraneous openning and closing braces wasting precious screen
real-estate. "return" is not a function taking an argument, don't
surround simple values with parenthesis.
These happened a lot, I won't mention the other instances.
> + err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
> + MRVL88X2011_GENERAL_CTL, err);
Bad indentation, the argument on the second line of the mdio_write()
call should line up with the initial "np" initial arg on the
previous line.
If necessary, use tools or editors that help do this automatically for
you. Several folks (including me) use Emacs's C mode with coding
style set to "linux" for that purpose.
> +static int xcvr_init_10g(struct niu *np)
> +{
> + int err;
> + u64 val;
> + int phy_id;
Multiple variables of the same type should be on one single line
unless it would make the line too long.
> + /* handle different phy types */
> + switch((phy_id & NIU_PHY_ID_MASK)) {
Space is needed between "switch" keyword and openning parenthesis.
Only one set of parenthesis is sufficient here.
> -static int link_status_10g(struct niu *np, int *link_up_p)
> +static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
> {
> - unsigned long flags;
> - int err, link_up;
> + int err;
> + int link_up = 0;
> + int pma_status;
> + int pcs_status;
No tabs please between variable type and names, and again list
multiple variables of the same type on one single line in order to
save previous screen real-estate.
> + pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
Spaces are needed to make this easier to read "? 1 : 0".
> + if (err == (
> + PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
> + PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
> + PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC | 0x800)) {
This "err == (" line should hold the first line of bit values, again
to save lines.
> + mrvl88x2011_act_led(np, link_up ? MRVL88X2011_LED_CTL_PCS_ACT:MRVL88X2011_LED_CTL_OFF);
Line excessively exceeds 80 columns.
> if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
> - if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
> + if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
> + ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
Not indented properly, the second line in the inner "if" statement
should have it's initial parenthesis match up with the second openning
parenthesis on the previous line.
> +/* MRVL88X2011 register control */
> +#define MRVL88X2011_ENA_XFPREFCLK 0x0001
> +#define MRVL88X2011_ENA_PMDTX 0x0000
> +#define MRVL88X2011_LOOPBACK 0x1
> +#define MRVL88X2011_LED_ACT 0x1
> +#define MRVL88X2011_LNK_STATUS_OK 0x4
> +#define MRVL88X2011_LED_BLKRATE_MASK 0x70
> +#define MRVL88X2011_LED_BLKRATE_034MS 0x0
> +#define MRVL88X2011_LED_BLKRATE_067MS 0x1
> +#define MRVL88X2011_LED_BLKRATE_134MS 0x2
> +#define MRVL88X2011_LED_BLKRATE_269MS 0x3
> +#define MRVL88X2011_LED_BLKRATE_538MS 0x4
> +#define MRVL88X2011_LED_CTL_OFF 0x0
> +#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
> +#define MRVL88X2011_LED_CTL_MASK 0x7
> +#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
> +#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
These lines inconsistently use tabs vs. spaces to create the
indentation between the macro name and it's definition.
Anyways, after cleaning up all of that the patch I ended up checking
in looks like the following.
BTW, I just checked in several bug fixes to the Neptune driver
upstream, you might want to check them out.
Thanks.
[NIU]: Support for Marvell PHY
From: Mirko Lindner <mlindner@marvell.com>
This patch makes necessary changes in the Neptune driver to support
the new Marvell PHY. It also adds support for the LED blinking
on Neptune cards with Marvell PHY. All registers are using defines
in the niu.h header file as is already done for the BCM8704 registers.
[ Coding style, etc. cleanups -DaveM ]
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/niu.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++-----
drivers/net/niu.h | 33 ++++++++
2 files changed, 231 insertions(+), 20 deletions(-)
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 9a0c6d3..3bbcea1 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -801,22 +801,90 @@ static int bcm8704_init_user_dev3(struct niu *np)
return 0;
}
-static int xcvr_init_10g(struct niu *np)
+static int mrvl88x2011_act_led(struct niu *np, int val)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL);
+ if (err < 0)
+ return err;
+
+ err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
+ err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
+
+ return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL, err);
+}
+
+static int mrvl88x2011_led_blink_rate(struct niu *np, int rate)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL);
+ if (err >= 0) {
+ err &= ~MRVL88X2011_LED_BLKRATE_MASK;
+ err |= (rate << 4);
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL, err);
+ }
+
+ return err;
+}
+
+static int xcvr_init_10g_mrvl88x2011(struct niu *np)
+{
+ int err;
+
+ /* Set LED functions */
+ err = mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
+ if (err)
+ return err;
+
+ /* led activity */
+ err = mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF);
+ if (err)
+ return err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL);
+ if (err < 0)
+ return err;
+
+ err |= MRVL88X2011_ENA_XFPREFCLK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL, err);
+ if (err < 0)
+ return err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1);
+ if (err < 0)
+ return err;
+
+ if (np->link_config.loopback_mode == LOOPBACK_MAC)
+ err |= MRVL88X2011_LOOPBACK;
+ else
+ err &= ~MRVL88X2011_LOOPBACK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1, err);
+ if (err < 0)
+ return err;
+
+ /* Enable PMD */
+ return mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
+}
+
+static int xcvr_init_10g_bcm8704(struct niu *np)
{
struct niu_link_config *lp = &np->link_config;
u16 analog_stat0, tx_alarm_status;
int err;
- u64 val;
-
- val = nr64_mac(XMAC_CONFIG);
- val &= ~XMAC_CONFIG_LED_POLARITY;
- val |= XMAC_CONFIG_FORCE_LED_ON;
- nw64_mac(XMAC_CONFIG, val);
-
- /* XXX shared resource, lock parent XXX */
- val = nr64(MIF_CONFIG);
- val |= MIF_CONFIG_INDIRECT_MODE;
- nw64(MIF_CONFIG, val);
err = bcm8704_reset(np);
if (err)
@@ -896,6 +964,38 @@ static int xcvr_init_10g(struct niu *np)
return 0;
}
+static int xcvr_init_10g(struct niu *np)
+{
+ int phy_id, err;
+ u64 val;
+
+ val = nr64_mac(XMAC_CONFIG);
+ val &= ~XMAC_CONFIG_LED_POLARITY;
+ val |= XMAC_CONFIG_FORCE_LED_ON;
+ nw64_mac(XMAC_CONFIG, val);
+
+ /* XXX shared resource, lock parent XXX */
+ val = nr64(MIF_CONFIG);
+ val |= MIF_CONFIG_INDIRECT_MODE;
+ nw64(MIF_CONFIG, val);
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch (phy_id & NIU_PHY_ID_MASK) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = xcvr_init_10g_mrvl88x2011(np);
+ break;
+
+ default: /* bcom 8704 */
+ err = xcvr_init_10g_bcm8704(np);
+ break;
+ }
+
+ return 0;
+}
+
static int mii_reset(struct niu *np)
{
int limit, err;
@@ -1082,19 +1182,68 @@ static int niu_link_status_common(struct niu *np, int link_up)
return 0;
}
-static int link_status_10g(struct niu *np, int *link_up_p)
+static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
{
- unsigned long flags;
- int err, link_up;
+ int err, link_up, pma_status, pcs_status;
link_up = 0;
- spin_lock_irqsave(&np->lock, flags);
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_STATUS_2);
+ if (err < 0)
+ goto out;
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
+ /* Check PMA/PMD Register: 1.0001.2 == 1 */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+ /* Check PMC Register : 3.0001.2 == 1: read twice */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0)
+ goto out;
+
+ pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1 : 0);
+
+ /* Check XGXS Register : 4.0018.[0-3,12] */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
+ MRVL88X2011_10G_XGXS_LANE_STAT);
+ if (err < 0)
goto out;
+ if (err == (PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
+ PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
+ PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC |
+ 0x800))
+ link_up = (pma_status && pcs_status) ? 1 : 0;
+
+ np->link_config.active_speed = SPEED_10000;
+ np->link_config.active_duplex = DUPLEX_FULL;
+ err = 0;
+out:
+ mrvl88x2011_act_led(np, (link_up ?
+ MRVL88X2011_LED_CTL_PCS_ACT :
+ MRVL88X2011_LED_CTL_OFF));
+
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g_bcom(struct niu *np, int *link_up_p)
+{
+ int err, link_up;
+
+ link_up = 0;
+
err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET);
if (err < 0)
@@ -1134,9 +1283,37 @@ static int link_status_10g(struct niu *np, int *link_up_p)
err = 0;
out:
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g(struct niu *np, int *link_up_p)
+{
+ unsigned long flags;
+ int err = -EINVAL;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
+ int phy_id;
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch (phy_id & NIU_PHY_ID_MASK) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = link_status_10g_mrvl(np, link_up_p);
+ break;
+
+ default: /* bcom 8704 */
+ err = link_status_10g_bcom(np, link_up_p);
+ break;
+ }
+ }
+
spin_unlock_irqrestore(&np->lock, flags);
- *link_up_p = link_up;
return err;
}
@@ -6297,7 +6474,8 @@ static int __devinit phy_record(struct niu_parent *parent,
if (dev_id_1 < 0 || dev_id_2 < 0)
return 0;
if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
- if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
+ if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
+ ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
return 0;
} else {
if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index 10e3f11..0e8626a 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK 0xfffff0f0
#define NIU_PHY_ID_BCM8704 0x00206030
#define NIU_PHY_ID_BCM5464R 0x002060b0
+#define NIU_PHY_ID_MRVL88X2011 0x01410020
+
+/* MRVL88X2011 register addresses */
+#define MRVL88X2011_USER_DEV1_ADDR 1
+#define MRVL88X2011_USER_DEV2_ADDR 2
+#define MRVL88X2011_USER_DEV3_ADDR 3
+#define MRVL88X2011_USER_DEV4_ADDR 4
+#define MRVL88X2011_PMA_PMD_CTL_1 0x0000
+#define MRVL88X2011_PMA_PMD_STATUS_1 0x0001
+#define MRVL88X2011_10G_PMD_STATUS_2 0x0008
+#define MRVL88X2011_10G_PMD_TX_DIS 0x0009
+#define MRVL88X2011_10G_XGXS_LANE_STAT 0x0018
+#define MRVL88X2011_GENERAL_CTL 0x8300
+#define MRVL88X2011_LED_BLINK_CTL 0x8303
+#define MRVL88X2011_LED_8_TO_11_CTL 0x8306
+
+/* MRVL88X2011 register control */
+#define MRVL88X2011_ENA_XFPREFCLK 0x0001
+#define MRVL88X2011_ENA_PMDTX 0x0000
+#define MRVL88X2011_LOOPBACK 0x1
+#define MRVL88X2011_LED_ACT 0x1
+#define MRVL88X2011_LNK_STATUS_OK 0x4
+#define MRVL88X2011_LED_BLKRATE_MASK 0x70
+#define MRVL88X2011_LED_BLKRATE_034MS 0x0
+#define MRVL88X2011_LED_BLKRATE_067MS 0x1
+#define MRVL88X2011_LED_BLKRATE_134MS 0x2
+#define MRVL88X2011_LED_BLKRATE_269MS 0x3
+#define MRVL88X2011_LED_BLKRATE_538MS 0x4
+#define MRVL88X2011_LED_CTL_OFF 0x0
+#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
+#define MRVL88X2011_LED_CTL_MASK 0x7
+#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
+#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
#define BCM8704_PMA_PMD_DEV_ADDR 1
#define BCM8704_PCS_DEV_ADDR 2
--
1.5.4.rc2.84.gf85fd
^ permalink raw reply related
* [PATCH] drivers/net/niu: Support for Marvell PHY
From: Mirko Lindner @ 2008-01-10 9:33 UTC (permalink / raw)
To: netdev; +Cc: davem
This patch makes necessary changes in the Neptune driver to support
the new Marvell PHY. It also adds support for the LED blinking
on Neptune cards with Marvell PHY. All registers are using defines
in the niu.h header file as is already done for the BCM8704 registers.
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/net/niu.c linux-2.6-changed/drivers/net/niu.c
--- linux-2.6/drivers/net/niu.c 2007-12-10 14:14:04.000000000 +0100
+++ linux-2.6-changed/drivers/net/niu.c 2008-01-09 14:32:59.000000000 +0100
@@ -801,22 +801,86 @@ static int bcm8704_init_user_dev3(struct
return 0;
}
-static int xcvr_init_10g(struct niu *np)
+void mrvl88x2011_act_led(struct niu *np, int val)
+{
+ int err;
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL);
+ err &= ~MRVL88X2011_LED(MRVL88X2011_LED_ACT,MRVL88X2011_LED_CTL_MASK);
+ err |= MRVL88X2011_LED(MRVL88X2011_LED_ACT,val);
+
+ (void) mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_8_TO_11_CTL, err);
+}
+
+void mrvl88x2011_led_blink_rate(struct niu *np, int rate)
+{
+ int err;
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL);
+ if (err >= 0) {
+ err &= ~MRVL88X2011_LED_BLKRATE_MASK;
+ err |= (rate << 4);
+
+ (void) mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV2_ADDR,
+ MRVL88X2011_LED_BLINK_CTL, err);
+ }
+}
+
+static int xcvr_init_10g_mrvl88x2011(struct niu *np)
+{
+ int err;
+
+ /* Set LED functions */
+ mrvl88x2011_led_blink_rate(np, MRVL88X2011_LED_BLKRATE_134MS);
+ mrvl88x2011_act_led(np, MRVL88X2011_LED_CTL_OFF); /* led activity */
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL);
+ if (err < 0) {
+ return(err);
+ }
+
+ err |= MRVL88X2011_ENA_XFPREFCLK;
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_GENERAL_CTL, err);
+ if (err < 0) {
+ return(err);
+ }
+
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1);
+ if (err < 0) {
+ return(err);
+ }
+
+ if (np->link_config.loopback_mode == LOOPBACK_MAC) {
+ err |= MRVL88X2011_LOOPBACK;
+ }
+ else {
+ err &= ~MRVL88X2011_LOOPBACK;
+ }
+
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_CTL_1, err);
+ if (err < 0) {
+ return(err);
+ }
+
+ /* Enable PMD */
+ err = mdio_write(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_10G_PMD_TX_DIS, MRVL88X2011_ENA_PMDTX);
+
+ return (err);
+}
+
+static int xcvr_init_10g_bcm8704(struct niu *np)
{
struct niu_link_config *lp = &np->link_config;
u16 analog_stat0, tx_alarm_status;
int err;
- u64 val;
-
- val = nr64_mac(XMAC_CONFIG);
- val &= ~XMAC_CONFIG_LED_POLARITY;
- val |= XMAC_CONFIG_FORCE_LED_ON;
- nw64_mac(XMAC_CONFIG, val);
-
- /* XXX shared resource, lock parent XXX */
- val = nr64(MIF_CONFIG);
- val |= MIF_CONFIG_INDIRECT_MODE;
- nw64(MIF_CONFIG, val);
err = bcm8704_reset(np);
if (err)
@@ -896,6 +960,39 @@ static int xcvr_init_10g(struct niu *np)
return 0;
}
+static int xcvr_init_10g(struct niu *np)
+{
+ int err;
+ u64 val;
+ int phy_id;
+
+ val = nr64_mac(XMAC_CONFIG);
+ val &= ~XMAC_CONFIG_LED_POLARITY;
+ val |= XMAC_CONFIG_FORCE_LED_ON;
+ nw64_mac(XMAC_CONFIG, val);
+
+ /* XXX shared resource, lock parent XXX */
+ val = nr64(MIF_CONFIG);
+ val |= MIF_CONFIG_INDIRECT_MODE;
+ nw64(MIF_CONFIG, val);
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch((phy_id & NIU_PHY_ID_MASK)) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = xcvr_init_10g_mrvl88x2011(np);
+ break;
+
+ default: /* bcom 8704 */
+ err = xcvr_init_10g_bcm8704(np);
+ break;
+ }
+
+ return 0;
+}
+
static int mii_reset(struct niu *np)
{
int limit, err;
@@ -1082,18 +1179,71 @@ static int niu_link_status_common(struct
return 0;
}
-static int link_status_10g(struct niu *np, int *link_up_p)
+static int link_status_10g_mrvl(struct niu *np, int *link_up_p)
{
- unsigned long flags;
- int err, link_up;
+ int err;
+ int link_up = 0;
+ int pma_status;
+ int pcs_status;
- link_up = 0;
- spin_lock_irqsave(&np->lock, flags);
+ err = mdio_read(np, np->phy_addr,
+ MRVL88X2011_USER_DEV1_ADDR, MRVL88X2011_10G_PMD_STATUS_2);
+ if (err < 0) {
+ goto out;
+ }
- err = -EINVAL;
- if (np->link_config.loopback_mode != LOOPBACK_DISABLED)
+ /* Check PMA/PMD Register: 1.0001.2 == 1 */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV1_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
goto out;
+ }
+
+ pma_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
+
+ /* Check PMC Register : 3.0001.2 == 1: read twice */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
+ goto out;
+ }
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV3_ADDR,
+ MRVL88X2011_PMA_PMD_STATUS_1);
+ if (err < 0) {
+ goto out;
+ }
+ pcs_status = ((err & MRVL88X2011_LNK_STATUS_OK) ? 1:0);
+
+ /* Check XGXS Register : 4.0018.[0-3,12] */
+ err = mdio_read(np, np->phy_addr, MRVL88X2011_USER_DEV4_ADDR,
+ MRVL88X2011_10G_XGXS_LANE_STAT);
+ if (err < 0) {
+ goto out;
+ }
+
+ if (err == (
+ PHYXS_XGXS_LANE_STAT_ALINGED | PHYXS_XGXS_LANE_STAT_LANE3 |
+ PHYXS_XGXS_LANE_STAT_LANE2 | PHYXS_XGXS_LANE_STAT_LANE1 |
+ PHYXS_XGXS_LANE_STAT_LANE0 | PHYXS_XGXS_LANE_STAT_MAGIC | 0x800)) {
+
+ link_up = (pma_status && pcs_status) ? 1 : 0;
+ }
+
+ np->link_config.active_speed = SPEED_10000;
+ np->link_config.active_duplex = DUPLEX_FULL;
+ err = 0;
+out:
+ mrvl88x2011_act_led(np, link_up ? MRVL88X2011_LED_CTL_PCS_ACT:MRVL88X2011_LED_CTL_OFF);
+
+ *link_up_p = link_up;
+ return err;
+}
+
+static int link_status_10g_bcom(struct niu *np, int *link_up_p)
+{
+ int err;
+ int link_up = 0;
err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
BCM8704_PMD_RCV_SIGDET);
@@ -1134,12 +1284,42 @@ static int link_status_10g(struct niu *n
err = 0;
out:
- spin_unlock_irqrestore(&np->lock, flags);
-
*link_up_p = link_up;
return err;
}
+static int link_status_10g(struct niu *np, int *link_up_p)
+{
+ unsigned long flags;
+ int err;
+
+ err = -EINVAL;
+
+ spin_lock_irqsave(&np->lock, flags);
+
+ if (np->link_config.loopback_mode == LOOPBACK_DISABLED) {
+ int phy_id;
+
+ phy_id = phy_decode(np->parent->port_phy, np->port);
+ phy_id = np->parent->phy_probe_info.phy_id[phy_id][np->port];
+
+ /* handle different phy types */
+ switch((phy_id & NIU_PHY_ID_MASK)) {
+ case NIU_PHY_ID_MRVL88X2011:
+ err = link_status_10g_mrvl(np, link_up_p);
+ break;
+
+ default: /* bcom 8704 */
+ err = link_status_10g_bcom(np, link_up_p);
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&np->lock, flags);
+
+ return(err);
+}
+
static int link_status_1g(struct niu *np, int *link_up_p)
{
u16 current_speed, bmsr;
@@ -6281,8 +6461,10 @@ static int __devinit phy_record(struct n
if (dev_id_1 < 0 || dev_id_2 < 0)
return 0;
+
if (type == PHY_TYPE_PMA_PMD || type == PHY_TYPE_PCS) {
- if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704)
+ if (((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM8704) &&
+ ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_MRVL88X2011))
return 0;
} else {
if ((id & NIU_PHY_ID_MASK) != NIU_PHY_ID_BCM5464R)
diff -uprN -X linux-2.6/Documentation/dontdiff linux-2.6/drivers/net/niu.h linux-2.6-changed/drivers/net/niu.h
--- linux-2.6/drivers/net/niu.h 2007-12-10 14:14:04.000000000 +0100
+++ linux-2.6-changed/drivers/net/niu.h 2008-01-09 14:22:23.000000000 +0100
@@ -2538,6 +2538,39 @@ struct fcram_hash_ipv6 {
#define NIU_PHY_ID_MASK 0xfffff0f0
#define NIU_PHY_ID_BCM8704 0x00206030
#define NIU_PHY_ID_BCM5464R 0x002060b0
+#define NIU_PHY_ID_MRVL88X2011 0x01410020
+
+/* MRVL88X2011 register addresses */
+#define MRVL88X2011_USER_DEV1_ADDR 1
+#define MRVL88X2011_USER_DEV2_ADDR 2
+#define MRVL88X2011_USER_DEV3_ADDR 3
+#define MRVL88X2011_USER_DEV4_ADDR 4
+#define MRVL88X2011_PMA_PMD_CTL_1 0x0000
+#define MRVL88X2011_PMA_PMD_STATUS_1 0x0001
+#define MRVL88X2011_10G_PMD_STATUS_2 0x0008
+#define MRVL88X2011_10G_PMD_TX_DIS 0x0009
+#define MRVL88X2011_10G_XGXS_LANE_STAT 0x0018
+#define MRVL88X2011_GENERAL_CTL 0x8300
+#define MRVL88X2011_LED_BLINK_CTL 0x8303
+#define MRVL88X2011_LED_8_TO_11_CTL 0x8306
+
+/* MRVL88X2011 register control */
+#define MRVL88X2011_ENA_XFPREFCLK 0x0001
+#define MRVL88X2011_ENA_PMDTX 0x0000
+#define MRVL88X2011_LOOPBACK 0x1
+#define MRVL88X2011_LED_ACT 0x1
+#define MRVL88X2011_LNK_STATUS_OK 0x4
+#define MRVL88X2011_LED_BLKRATE_MASK 0x70
+#define MRVL88X2011_LED_BLKRATE_034MS 0x0
+#define MRVL88X2011_LED_BLKRATE_067MS 0x1
+#define MRVL88X2011_LED_BLKRATE_134MS 0x2
+#define MRVL88X2011_LED_BLKRATE_269MS 0x3
+#define MRVL88X2011_LED_BLKRATE_538MS 0x4
+#define MRVL88X2011_LED_CTL_OFF 0x0
+#define MRVL88X2011_LED_CTL_PCS_ACT 0x5
+#define MRVL88X2011_LED_CTL_MASK 0x7
+#define MRVL88X2011_LED(n,v) ((v)<<((n)*4))
+#define MRVL88X2011_LED_STAT(n,v) ((v)>>((n)*4))
#define BCM8704_PMA_PMD_DEV_ADDR 1
#define BCM8704_PCS_DEV_ADDR 2
^ permalink raw reply
* Re: [git patches] net driver fixes
From: Meelis Roos @ 2008-01-10 9:24 UTC (permalink / raw)
To: David Miller; +Cc: jeff, netdev, shemminger
In-Reply-To: <20080107.135621.259663114.davem@davemloft.net>
> > Well, it's 2.6.24-rc7 already - any news?
>
> I put this into my net-2.6 tree last night since Jeff asked
> me to look over critical networking driver stuff for a little
> while.
Thanks, they are upstream now and it did fix tulip in my PPC - network
is stable again.
--
Meelis Roos (mroos@linux.ee)
^ permalink raw reply
* Re: : Emit event stream compat iw_point objects correctly.
From: David Miller @ 2008-01-10 9:16 UTC (permalink / raw)
To: mokuno; +Cc: linux-wireless, netdev
In-Reply-To: <20071227181439.6F59.40F06B3A@sm.sony.co.jp>
From: Masakazu Mokuno <mokuno@sm.sony.co.jp>
Date: Thu, 27 Dec 2007 18:24:40 +0900
> On ppc64 (PS3), IW_EV_LCP_LEN is 8, not 4.
>
> include/linux/wireless.h:
>
> #define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
>
> where sizeof(struct iw_event) == 24, sizeof(union iwreq_data) == 16 on
> PS3.
Here is a new version of the last patch (#12), it should handle
all of these cases properly now.
Let me know if you spot any more errors.
Thanks!
[WEXT]: Emit event stream entries correctly when compat.
Three major portions to this change:
1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF,
and IW_EV_COMPAT_POINT_LEN helper defines.
2) Delete iw_stream_check_add_*(), they are unused.
3) Add iw_request_info argument to iwe_stream_add_*(), and use it to
size the event and pointer lengths correctly depending upon whether
IW_REQUEST_FLAG_COMPAT is set or not.
4) The mechanical transformations to the drivers and wireless stack
bits to get the iw_request_info passed down into the routines
modified in #3.
With help from Masakazu Mokuno
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/wireless/airo.c | 39 +++++---
drivers/net/wireless/atmel.c | 24 ++++-
drivers/net/wireless/hostap/hostap.h | 3 +-
drivers/net/wireless/hostap/hostap_ap.c | 32 +++---
drivers/net/wireless/hostap/hostap_ioctl.c | 54 ++++++-----
drivers/net/wireless/libertas/scan.c | 35 ++++---
drivers/net/wireless/orinoco.c | 30 ++++--
drivers/net/wireless/prism54/isl_ioctl.c | 45 +++++----
drivers/net/wireless/wl3501_cs.c | 10 +-
drivers/net/wireless/zd1201.c | 21 +++--
include/linux/wireless.h | 16 +++
include/net/iw_handler.h | 150 ++++++++--------------------
net/ieee80211/ieee80211_wx.c | 44 +++++----
net/mac80211/ieee80211_i.h | 5 +-
net/mac80211/ieee80211_ioctl.c | 2 +-
net/mac80211/ieee80211_sta.c | 59 ++++++-----
16 files changed, 293 insertions(+), 276 deletions(-)
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 074055e..ad4f140 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -7234,6 +7234,7 @@ out:
* format that the Wireless Tools will understand - Jean II
*/
static inline char *airo_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *current_ev,
char *end_buf,
BSSListRid *bss)
@@ -7249,7 +7250,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -7259,7 +7261,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -7269,7 +7272,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add frequency */
@@ -7280,7 +7284,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
*/
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);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -7298,7 +7303,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
| IW_QUAL_DBM;
}
iwe.u.qual.noise = ai->wstats.qual.noise;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -7307,7 +7313,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
@@ -7324,7 +7331,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -7336,7 +7345,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
}
@@ -7370,8 +7380,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev,
+ end_buf, &iwe,
+ (char *) info_element);
}
break;
@@ -7379,8 +7391,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev, end_buf,
+ &iwe, (char *) info_element);
break;
default:
@@ -7419,7 +7432,7 @@ static int airo_get_scan(struct net_device *dev,
list_for_each_entry (net, &ai->network_list, list) {
/* Translate to WE format this entry */
- current_ev = airo_translate_scan(dev, current_ev,
+ current_ev = airo_translate_scan(dev, info, current_ev,
extra + dwrq->length,
&net->bss);
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 059ce3f..985068e 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2320,30 +2320,40 @@ static int atmel_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_ADDR_LEN);
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
if (iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, priv->BSSinfo[i].SSID);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = priv->BSSinfo[i].BSStype;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = priv->BSSinfo[i].channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level;
/* iwe.u.qual.noise = SOMETHING */
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_QUAL_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -2352,7 +2362,9 @@ static int atmel_get_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, NULL);
}
/* Length of data */
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 547ba84..3a386a6 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 6bbdb76..8131e84 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2381,7 +2381,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
/* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer)
{
struct hostap_interface *iface;
local_info_t *local;
@@ -2410,8 +2411,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or
* an Access Point */
@@ -2422,8 +2423,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
else
iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Some quality */
memset(&iwe, 0, sizeof(iwe));
@@ -2438,8 +2439,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
iwe.u.qual.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) {
@@ -2447,8 +2448,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -2458,10 +2459,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
- sta->u.ap.ssid
- /* 0 byte memcpy */);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
+ sta->u.ap.ssid);
if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) {
@@ -2471,7 +2471,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
* 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(
- current_ev, end_buf, &iwe,
+ info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -2480,8 +2480,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
sprintf(buf, "beacon_interval=%d",
sta->listen_interval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index d8f5efc..5b04054 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1794,6 +1794,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
#ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss,
char *current_ev, char *end_buf)
@@ -1824,7 +1825,7 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -1833,7 +1834,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
@@ -1848,8 +1850,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1865,8 +1867,8 @@ static char * __prism2_translate_scan(local_info_t *local,
if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
}
if (scan) {
@@ -1885,8 +1887,8 @@ static char * __prism2_translate_scan(local_info_t *local,
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1896,7 +1898,7 @@ static char * __prism2_translate_scan(local_info_t *local,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
if (scan) {
@@ -1910,7 +1912,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value(
- current_ev, current_val, end_buf, &iwe,
+ info, current_ev, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any event */
@@ -1925,15 +1927,15 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1941,8 +1943,8 @@ static char * __prism2_translate_scan(local_info_t *local,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
}
kfree(buf);
@@ -1951,16 +1953,16 @@ static char * __prism2_translate_scan(local_info_t *local,
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
return current_ev;
@@ -1970,6 +1972,7 @@ static char * __prism2_translate_scan(local_info_t *local,
/* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
char *buffer, int buflen)
{
struct hfa384x_hostscan_result *scan;
@@ -2000,13 +2003,14 @@ static inline int prism2_translate_scan(local_info_t *local,
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1;
current_ev = __prism2_translate_scan(
- local, scan, bss, current_ev, end_buf);
+ local, info, scan, bss, current_ev,
+ end_buf);
found++;
}
}
if (!found) {
current_ev = __prism2_translate_scan(
- local, scan, NULL, current_ev, end_buf);
+ local, info, scan, NULL, current_ev, end_buf);
}
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2024,7 +2028,7 @@ static inline int prism2_translate_scan(local_info_t *local,
bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included)
continue;
- current_ev = __prism2_translate_scan(local, NULL, bss,
+ current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf);
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2071,7 +2075,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
}
local->scan_timestamp = 0;
- res = prism2_translate_scan(local, extra, data->length);
+ res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) {
data->length = res;
@@ -2104,7 +2108,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
* Jean II */
/* Translate to WE format */
- res = prism2_ap_translate_scan(dev, extra);
+ res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index ad1e67d..9dbd932 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -1444,8 +1444,9 @@ out:
#define MAX_CUSTOM_LEN 64
static inline char *libertas_translate_scan(wlan_private *priv,
- char *start, char *stop,
- struct bss_descriptor *bss)
+ struct iw_request_info *info,
+ char *start, char *stop,
+ struct bss_descriptor *bss)
{
wlan_adapter *adapter = priv->adapter;
struct chan_freq_power *cfp;
@@ -1470,24 +1471,24 @@ static inline char *libertas_translate_scan(wlan_private *priv,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
/* Mode */
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = bss->mode;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -1523,7 +1524,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf);
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -1533,7 +1534,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
current_val = start + IW_EV_LCP_LEN;
@@ -1545,8 +1546,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
/* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC)
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
@@ -1554,8 +1555,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
bss->ssid, bss->ssid_len)
&& adapter->adhoccreate) {
iwe.u.bitrate.value = 22 * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -1567,7 +1568,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1576,7 +1577,7 @@ static inline char *libertas_translate_scan(wlan_private *priv,
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
if (bss->mesh) {
@@ -1588,7 +1589,8 @@ static inline char *libertas_translate_scan(wlan_private *priv,
"mesh-type: olpc");
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, custom);
}
out:
@@ -1650,7 +1652,8 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
}
/* Translate to WE format this entry */
- next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
+ next_ev = libertas_translate_scan(priv, info, ev, stop,
+ iter_bss);
if (next_ev == NULL)
continue;
ev = next_ev;
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index ca6c2da..9141b8f 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3909,6 +3909,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
* format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */
static inline int orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *buffer,
char *scan,
int scan_len)
@@ -3979,7 +3980,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -3989,7 +3991,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -3999,7 +4002,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_UINT_LEN);
}
channel = atom->s.channel;
@@ -4008,8 +4013,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_FREQ_LEN);
}
/* Add quality statistics */
@@ -4023,7 +4029,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
else
iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -4032,7 +4039,8 @@ static inline int orinoco_translate_scan(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Bit rate is not available in Lucent/Agere firmwares */
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
@@ -4055,9 +4063,9 @@ static inline int orinoco_translate_scan(struct net_device *dev,
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -4102,7 +4110,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
/* We have some results to push back to user space */
/* Translate to WE format */
- int ret = orinoco_translate_scan(dev, extra,
+ int ret = orinoco_translate_scan(dev, info, extra,
priv->scan_result,
priv->scan_len);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 6d80ca4..4dc0b5e 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -572,8 +572,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
*/
static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
- char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+ char *current_ev, char *end_buf, struct obj_bss *bss,
+ char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
@@ -585,8 +586,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -594,7 +595,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets);
/* Capabilities */
@@ -611,9 +612,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (cap & CAP_CRYPT)
@@ -622,14 +622,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
@@ -637,16 +638,16 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, wpa_ie);
}
/* Do the bitrates */
{
@@ -663,9 +664,9 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
mask <<= 1;
}
@@ -711,7 +712,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
/* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) {
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
@@ -2705,6 +2706,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
struct prism2_hostapd_param *param)
{
islpci_private *priv = netdev_priv(ndev);
+ struct iw_request_info info;
int i, rvalue;
struct obj_bsslist *bsslist;
u32 noise = 0;
@@ -2728,9 +2730,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
+ info.cmd = PRISM54_HOSTAPD;
+ info.flags = 0;
+
/* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, current_ev, &info,
extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]),
noise);
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 42a36b3..3771419 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index d5c0c66..10c8642 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = zd->rxdata[i+16];
iwe.u.data.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+ cev = iwe_stream_add_point(info, cev, end_buf,
+ &iwe, zd->rxdata+i+18);
iwe.cmd = SIOCGIWMODE;
if (zd->rxdata[i+14]&0x01)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = zd->rxdata[i+0];
iwe.u.freq.e = 0;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.disabled = 0;
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
- cev=iwe_stream_add_event(cev, end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ cev=iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
iwe.cmd = SIOCGIWENCODE;
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev,
iwe.u.data.flags = IW_ENCODE_ENABLED;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = zd->rxdata[i+4];
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
iwe.u.qual.updated = 7;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
if (!enabled_save)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 2088524..bec73df 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1098,6 +1098,22 @@ struct iw_event
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF)
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+struct __compat_iw_event {
+ __u16 len; /* Real lenght of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+ compat_caddr_t pointer;
+};
+#define IW_EV_COMPAT_LCP_LEN \
+ (sizeof(struct __compat_iw_event) - sizeof(compat_caddr_t))
+#define IW_EV_COMPAT_POINT_OFF (((char *) \
+ &(((struct compat_iw_point *) NULL)->length)) - \
+ (char *) NULL)
+#define IW_EV_COMPAT_POINT_LEN \
+ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
+ IW_EV_COMPAT_POINT_OFF)
+#endif
+
/* Size of the Event prefix when packed in stream */
#define IW_EV_LCP_PK_LEN (4)
/* Size of the various events when packed in stream */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index c99a8ee..d6f0c51 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -483,19 +483,26 @@ extern void wireless_spy_update(struct net_device * dev,
* Wrapper to add an Wireless Event to a stream of events.
*/
static inline char *
-iwe_stream_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
+iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, int event_len)
{
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len -= IW_EV_LCP_LEN;
+ event_len += IW_EV_COMPAT_LCP_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+ }
+#endif
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
/* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
+ memcpy(stream + lcp_len,
+ ((char *) iwe) + lcp_len,
+ event_len - lcp_len);
stream += event_len;
}
return stream;
@@ -507,104 +514,33 @@ iwe_stream_add_event(char * stream, /* Stream of events */
* stream of events.
*/
static inline char *
-iwe_stream_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra) /* More payload */
+iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, char *extra)
{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
- stream += event_len;
+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
+ int point_len = IW_EV_POINT_LEN;
+ int lcp_len = IW_EV_LCP_LEN;
+ int point_off = IW_EV_POINT_OFF;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len = IW_EV_COMPAT_POINT_LEN + iwe->u.data.length;
+ point_len = IW_EV_COMPAT_POINT_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+ point_off = IW_EV_COMPAT_POINT_OFF;
}
- return stream;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add a value to a Wireless Event in a stream of events.
- * Be careful, this one is tricky to use properly :
- * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- */
-static inline char *
-iwe_stream_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
-{
- /* Don't duplicate LCP */
- event_len -= IW_EV_LCP_LEN;
+#endif
/* Check if it's possible */
- if(likely((value + event_len) < ends)) {
- /* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
- value += event_len;
- /* Patch LCP */
- iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
- }
- return value;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an Wireless Event to a stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
-{
- /* Check if it's possible, set error if not */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
- /* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
- stream += event_len;
- } else
- *perr = -E2BIG;
- return stream;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an short Wireless Event containing a pointer to a
- * stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra, /* More payload */
- int * perr) /* Error report */
-{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+ memcpy(stream + lcp_len,
+ ((char *) iwe) + lcp_len + point_off,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
+ memcpy(stream + point_len, extra, iwe->u.data.length);
stream += event_len;
- } else
- *perr = -E2BIG;
+ }
return stream;
}
@@ -613,29 +549,29 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
* Wrapper to add a value to a Wireless Event in a stream of events.
* Be careful, this one is tricky to use properly :
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- * Same as above, with explicit error check...
*/
static inline char *
-iwe_stream_check_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
+iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
+ char *ends, struct iw_event *iwe, int event_len)
{
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+#endif
/* Don't duplicate LCP */
event_len -= IW_EV_LCP_LEN;
/* Check if it's possible */
if(likely((value + event_len) < ends)) {
/* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
+ memcpy(value, (char *) iwe + lcp_len, event_len);
value += event_len;
/* Patch LCP */
iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
- } else
- *perr = -E2BIG;
+ memcpy(event, (char *) iwe, lcp_len);
+ }
return value;
}
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index d309e8f..cba556c 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -43,8 +43,9 @@ static const char *ieee80211_modes[] = {
#define MAX_CUSTOM_LEN 64
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network)
+ char *start, char *stop,
+ struct ieee80211_network *network,
+ struct iw_request_info *info)
{
char custom[MAX_CUSTOM_LEN];
char *p;
@@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* Remaining entries will be displayed in the order we provide them */
@@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.data.flags = 1;
if (network->flags & NETWORK_EMPTY_ESSID) {
iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, "<hidden>");
} else {
iwe.u.data.length = min(network->ssid_len, (u8) 32);
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
else
iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add channel and frequency */
@@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
iwe.u.freq.e = 6;
iwe.u.freq.i = 0;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -104,7 +108,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
/* Add basic and extended rates */
/* Rate : stuffing multiple values in a single event require a bit
@@ -124,14 +129,16 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
for (; j < network->rates_ex_len; j++) {
rate = network->rates_ex[j] & 0x7F;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any rate */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -181,14 +188,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
iwe.u.qual.level = network->stats.signal;
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
iwe.cmd = IWEVCUSTOM;
p = custom;
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
memset(&iwe, 0, sizeof(iwe));
if (network->wpa_ie_len) {
@@ -196,7 +203,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -205,7 +212,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
/* Add EXTRA: Age to display seconds since last beacon/probe response
@@ -217,7 +224,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
jiffies_to_msecs(jiffies - network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
/* Add spectrum management information */
iwe.cmd = -1;
@@ -238,7 +245,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
if (iwe.cmd == IWEVCUSTOM) {
iwe.u.data.length = p - custom;
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
}
return start;
@@ -272,7 +279,8 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
if (ieee->scan_age == 0 ||
time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = ieee80211_translate_scan(ieee, ev, stop, network);
+ ev = ieee80211_translate_scan(ieee, ev, stop, network,
+ info);
else
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
"%s)' due to age (%dms).\n",
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 72e1c93..b8306aa 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
#include <net/wireless.h>
+#include <net/iw_handler.h>
#include "ieee80211_key.h"
#include "sta_info.h"
@@ -748,7 +749,9 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid);
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
void ieee80211_sta_req_auth(struct net_device *dev,
struct ieee80211_if_sta *ifsta);
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len);
void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status);
void ieee80211_rx_bss_list_init(struct net_device *dev);
diff --git a/net/mac80211/ieee80211_ioctl.c b/net/mac80211/ieee80211_ioctl.c
index 7027eed..0f686f1 100644
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -560,7 +560,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
if (local->sta_scanning)
return -EAGAIN;
- res = ieee80211_sta_scan_results(dev, extra, data->length);
+ res = ieee80211_sta_scan_results(dev, info, extra, data->length);
if (res >= 0) {
data->length = res;
return 0;
diff --git a/net/mac80211/ieee80211_sta.c b/net/mac80211/ieee80211_sta.c
index bee8080..b176e13 100644
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2881,6 +2881,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
static char *
ieee80211_sta_scan_result(struct net_device *dev,
+ struct iw_request_info *info,
struct ieee80211_sta_bss *bss,
char *current_ev, char *end_buf)
{
@@ -2907,15 +2908,15 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = bss->ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
memset(&iwe, 0, sizeof(iwe));
@@ -2924,20 +2925,20 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.u.freq.m = bss->freq * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
@@ -2945,8 +2946,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.u.qual.level = bss->rssi;
iwe.u.qual.noise = bss->noise;
iwe.u.qual.updated = local->wstats_flags;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWENCODE;
@@ -2955,22 +2956,22 @@ ieee80211_sta_scan_result(struct net_device *dev,
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
if (bss && bss->wpa_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
if (bss && bss->supp_rates_len > 0) {
@@ -2986,8 +2987,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
for (i = 0; i < bss->supp_rates_len; i++) {
iwe.u.bitrate.value = ((bss->supp_rates[i] &
0x7f) * 500000);
- p = iwe_stream_add_value(current_ev, p,
- end_buf, &iwe, IW_EV_PARAM_LEN);
+ p = iwe_stream_add_value(info, current_ev, p, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
current_ev = p;
}
@@ -3000,8 +3001,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
kfree(buf);
}
}
@@ -3020,15 +3021,15 @@ ieee80211_sta_scan_result(struct net_device *dev,
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beacon_int);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "capab=0x%04x", bss->capability);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
break;
@@ -3038,7 +3039,9 @@ ieee80211_sta_scan_result(struct net_device *dev,
}
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
char *current_ev = buf;
@@ -3051,8 +3054,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
spin_unlock_bh(&local->sta_bss_lock);
return -E2BIG;
}
- current_ev = ieee80211_sta_scan_result(dev, bss, current_ev,
- end_buf);
+ current_ev = ieee80211_sta_scan_result(dev, info, bss,
+ current_ev, end_buf);
}
spin_unlock_bh(&local->sta_bss_lock);
return current_ev - buf;
--
1.5.4.rc2.84.gf85fd
^ permalink raw reply related
* No idea about shaping trough many pc
From: Badalian Vyacheslav @ 2008-01-10 9:06 UTC (permalink / raw)
To: netdev
Hello all.
I try more then 2 month resolve problem witch my shaping. Maybe you can
help for me?
Sheme:
+-------------------+
+ ----- | Shaping PC 1 | ---------+
/ +-------------------+ \
+--------+ / +--------------------+ \
+ --------+
| Cisco | +-------- | Shaping PC N | -----------+ -----| CISCO |
+--------+ \ +--------------------+ /
+---------+
\ +---------------------+ /
+ ----- | Shaping PC 20 | --------+
+---------------------+
Network - Over 10k users. Common bandwidth to INTERNET more then 1 GBs
All computers have BGP and turn on multipath.
Cisco can't do load sharing by Packet (its can resolve all my problems
=((( ). Only by DST IP, SRC IP, or +Level4.
Ok. User must have speed 1mbs.
Lets look variants:
1. Create rules to user = (1mbs/N computers). If user use N connection
all great, but if it use 1 connection his speed = 1mbs/N - its not look
good. All be great if cisco can PER PACKET load sharing =(
2. Create rules to user = 1mbs. If user use 1 connection all great, but
if it use N connection his speed much more then needed limit =(
Why i use 20 PC? Becouse 1 pc normal forward 100-150mbs... when it have
100% cpu usage on Sofware Interrupts...
Any idea how to resolve this problem?
In my dreams (feature request to netdev ;) ):
Get PC - title: MASTER TC. All 20 PC syncronize statistic with MASTER
and have common rules and statistic. Then i use variant 2 and will be
happy... but its not real? =(
Maybe have other variants?
Thanks for help!
Slavon.
P.S. Sorry for my english =(
^ permalink raw reply
* Re : Re : Re : Re : Bonding : Monitoring of 4965 wireless card
From: patnel972-linux @ 2008-01-10 8:37 UTC (permalink / raw)
To: Jay Vosburgh; +Cc: netdev
Yes it's what i'm looking for. I don't understand how to change the arp_ip_target with the gateway, arp_ip_target is a module option.
----- Message d'origine ----
De : Jay Vosburgh <fubar@us.ibm.com>
À : patnel972-linux@yahoo.fr
Cc : netdev@vger.kernel.org
Envoyé le : Jeudi, 10 Janvier 2008, 0h26mn 38s
Objet : Re: Re : Re : Re : Bonding : Monitoring of 4965 wireless card
patnel972-linux@yahoo.fr wrote:
>I mean that instead of arp test an ip in lan or else, i want it to
test 127.0.0.1 but in order to do this it must go out and re-enter and
then use wlan0 to go out.
In other words, what I think you're saying (and I'm not entirely
sure here) is that you want probes to go to a remote node on the
network, and back, without having to actually know the identity of the
remote node (because, presumably, on a roaming type of wireless
configuration, your gateway and whatnot can change from time to time).
Is that what you're looking for?
That isn't available now, but might be straightforward to plug
into the address update system to keep the arp_ip_target up to date as
the current gateway as the gateway changes. I haven't looked into the
details of doing that, but in theory it sounds straightforward.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
>
>----- Message d'origine ----
>De : Jay Vosburgh <fubar@us.ibm.com>
>À : patnel972-linux@yahoo.fr
>Cc : John W. Linville <linville@tuxdriver.com>; netdev@vger.kernel.org
>Envoyé le : Mercredi, 9 Janvier 2008, 22h36mn 00s
>Objet : Re: Re : Re : Bonding : Monitoring of 4965 wireless card
>
>patnel972-linux@yahoo.fr wrote:
>
>>I ignore it, but it seems like it prevent bonding detect link of
> wlan0. I enslave wlan0 and i already use use_carrier=1;
>
> The default for bonding is use_carrier=1, which makes bonding
>use the device driver's netif_carrier_on/off state for link detection.
>Bonding only checks via ethtool/mii if use_carrier=0.
>
>>I'll try arp monitoring but this is annoying i c'ant test localhost.
> Is there a way to test localhost with arp, without pass through lo ?
>
> What do you mean by "test localhost with arp, without pass
>through lo"? ARP monitoring issues probes (ARPs) to a remote
>destination to confirm that there is connectivity; I'm not sure what
>localhost has to do with it.
>
> In general, though, I have not tested bonding with wireless
>adapters, so I'm unfamiliar with how well it does or does not work.
>
> -J
>
>---
> -Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
>
>
>
>
>
>
_____________________________________________________________________________
>Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers
Yahoo! Mail http://mail.yahoo.fr
>--
>To unsubscribe from this list: send the line "unsubscribe netdev" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail http://mail.yahoo.fr
^ permalink raw reply
* ipg.c bugs
From: linux @ 2008-01-10 7:28 UTC (permalink / raw)
To: linux, romieu; +Cc: akpm, davem, netdev
In-Reply-To: <20080109233056.GA5673@electric-eye.fr.zoreil.com>
I'm just about to test that second memory leak patch, but I gave the
original code a careful reading, and found a few problems:
* Huge monstrous glaring bug
In ipg_interrupt_handler the code to habdle a shared interrupt
not caused by this device:
if (!(status & IPG_IS_RSVD_MASK))
goto out_enable
is *before* spin_lock(&sp->lock), but the code following
out_enable does spin_unlock(&sp->lock).
Thus, the sp->lock is all f*ed up. The lack of any sort of
locking between the interrupt handler and hard_start_xmit
could cause all sort of issues.
I'm not actually sure if it's even necessary; I'd think some
suitable atomic access to sp->tx_current would suffice.
* Lesser bugs
There's a general pattern of loops over the range from
s->rx_current to sp->rx_dirty. Some of them are call code
that refers to s->rx_current, even though that hasn't been
updated yet.
One instance is in ipg_nic_check_frame_type.
A second is in ipg_nic_check_error.
In ipg_nic_set_multicast(), the code to enable the multicast flags
is of the form "if (dev->flags & IFF_MULTICAST & (dev->mc_count > ...))".
But IFF_MULTI CAST is not 1, so this will always be false.
The seond & needs to be && (2x).
In ipg_io_config(), there's
/* Transmitter and receiver must be disabled before setting
* IFSSelect.
*/
ipg_w32((origmacctrl & (IPG_MC_RX_DISABLE | IPG_MC_TX_DISABLE)) &
IPG_MC_RSVD_MASK, MAC_CTRL);
I don't know what's going on there, but unless the IPG_MC_RX_DISABLE
bit is already set in origmacctrl, that's going to write 0, which
won't disable anything.
Immediately following, there's some similarly buggy code doing something
I don't understand with IPG_MC_IFS_96BIT.
The setting of curr in ipg_nic_txfree, with that bizarre do_div, can't
possibly be working right.
* Possible bugs
I'm not very sanguine about the handling in init_rfdlist, of the
code that handles a failed ipg_get_rxbuff. In particular, it leaves
rxfd->frag_info uninitialized in that case, but does set rxfd->rfs to
"buffer ready to be received into", which could lead to receiving into
random memory locations.
In ipg_nic_hard_start_xmit(), the code
if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH))
netif_wake_queue(dev);
shouldn't that *stop* the queue if the TFDLIST is full?
I think that the places where the rxfd->rfs and txfd->tfc fields
are filled in (containing the hardware-handoff flag) should
have memory barriers.
* Stupid code
In ipg_io_config, there are three writes to DEBUG_CTRL "Per silicon
B3 eratta". First, that's "errata". But more significantly,
can those writes be combined into one? Is it necessary to read
the DEBUG_CTRL register each time?
The initialization of rxfd->rfs in init_rfdlist() and ipg_nix_rxrestore()
should be moved into ipg_get_rxbuf(). And since the ready bit is there,
it should be set AFTER the pointer fields AND there should be a barrier
so the hardware doesn't read the fields out of order.
In ipg_nic_txcleanup(), there's code to call netif_wake_queue every
time through the loop in 10 MBit mode (to balance some bug-workaround
call that stops the queue every packet in that case), which is
quite unnecessary, as ipg_nic_txfree() will do it.
The IPG_INSERT_MANUAL_VLAN_TAG code (fortunately disabled by default)
is just plain bizarre. What exactly is the use of assigning a tag of
0xABC to every packet?
The code in ipg_hw_init to set up dev->dev_addr reads each of the
16-bit address reigsters twice, for no apparent reason.
There's a lots of code in e.g. ipg_nic_rx() that does endless
manipulation of rxfd->rfs with an le64_to_cpu() call around each
instance, that should copy it to a CPU-ordered native value and be
done with it. (Some sparse annotations would help, too.)
Likewise for messing with txfd->tfc in ipg_nic_hard_start_xmit().
The Frame_WithEnd enum is a very strange value (decimal 10) to use as
a bitmapped status flag.
The four frame fragment functions
nic_rx_with_start_and_end
nic_rx_with_start
nic_rx_with_end
nic_rx_so_start_no_end
could easily be unified into one.
* Performance left on the floor
The hardware supports scallter/gather, hardware checksums, VLAN tagging,
and 64-bit (well, 40-bit) DMA, but the driver sets no feature flags.
The jumbo frame reception code could generate fragmented skbs rather
that doing all those memcopies.
Would it be worth splitting the 64-bit ->rfs and ->txc fields into
two 32-bit fields?
Would it be worth copying small incoming packets to small skbs and
keeping the large skb in the receive queue?
* Questions
In net_device_stats, are all those statistics registers cleared by
a read?
How do we determine the silicon revision numbers, so we can stop enabling
bug workarounds on versions that don't need it?
Where can I find docs about the scatter/gather features? The bitfield
definitions are a bit vague.
^ permalink raw reply
* Re: Top 10 kernel oopses for the week ending January 5th, 2008
From: Al Viro @ 2008-01-10 5:53 UTC (permalink / raw)
To: Neil Brown
Cc: Linus Torvalds, Kevin Winchester, J. Bruce Fields,
Arjan van de Ven, Linux Kernel Mailing List, Andrew Morton,
NetDev, gregkh
In-Reply-To: <18309.39804.31974.851666@notabene.brown>
On Thu, Jan 10, 2008 at 03:13:48PM +1100, Neil Brown wrote:
> > What guarantees that it doesn't happen before we get to callback? AFAICS,
> > nothing whatsoever...
>
> Yes, that's bad isn't it :-)
>
> I think I should be using sysfs_schedule_callback here. That makes the
> required 'get' and 'put' calls.... but it can fail with -ENOMEM. I
> wonder what I do if -ENOMEM??? Maybe I'll just continue to roll my
> one :-(
How about this instead (completely untested)
* split failure exits
* switch to kick_rdev_from_array()
* fold unbind_rdev_from_array() into it (no other callers anymore)
* take export_rdev() into failure case in bind_rdev_to_array()
* in kick_rdev_from_array() do what export_rdev() does sans
kobject_put() and do that before schedule_work(). Take kobject_put() into
delayed_delete().
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
diff --git a/drivers/md/md.c b/drivers/md/md.c
index cef9ebd..116cc5a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1344,6 +1344,39 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
static LIST_HEAD(pending_raid_disks);
+static void unlock_rdev(mdk_rdev_t *rdev)
+{
+ struct block_device *bdev = rdev->bdev;
+ rdev->bdev = NULL;
+ if (!bdev)
+ MD_BUG();
+ bd_release(bdev);
+ blkdev_put(bdev);
+}
+
+void md_autodetect_dev(dev_t dev);
+
+static void __export_rdev(mdk_rdev_t * rdev)
+{
+ char b[BDEVNAME_SIZE];
+ printk(KERN_INFO "md: export_rdev(%s)\n",
+ bdevname(rdev->bdev,b));
+ if (rdev->mddev)
+ MD_BUG();
+ free_disk_sb(rdev);
+ list_del_init(&rdev->same_set);
+#ifndef MODULE
+ md_autodetect_dev(rdev->bdev->bd_dev);
+#endif
+ unlock_rdev(rdev);
+}
+
+static void export_rdev(mdk_rdev_t * rdev)
+{
+ __export_rdev(rdev);
+ kobject_put(&rdev->kobj);
+}
+
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
char b[BDEVNAME_SIZE];
@@ -1353,7 +1386,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (rdev->mddev) {
MD_BUG();
- return -EINVAL;
+ err = -EINVAL;
+ goto out;
}
/* make sure rdev->size exceeds mddev->size */
if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
@@ -1362,8 +1396,10 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
* If mddev->level <= 0, then we don't care
* about aligning sizes (e.g. linear)
*/
- if (mddev->level > 0)
- return -ENOSPC;
+ if (mddev->level > 0) {
+ err = -ENOSPC;
+ goto out;
+ }
} else
mddev->size = rdev->size;
}
@@ -1379,12 +1415,16 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
choice++;
rdev->desc_nr = choice;
} else {
- if (find_rdev_nr(mddev, rdev->desc_nr))
- return -EBUSY;
+ if (find_rdev_nr(mddev, rdev->desc_nr)) {
+ err = -EBUSY;
+ goto out;
+ }
}
bdevname(rdev->bdev,b);
- if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0)
- return -ENOMEM;
+ if (kobject_set_name(&rdev->kobj, "dev-%s", b) < 0) {
+ err = -ENOMEM;
+ goto out;
+ }
while ( (s=strchr(rdev->kobj.k_name, '/')) != NULL)
*s = '!';
@@ -1407,9 +1447,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk);
return 0;
- fail:
+fail:
printk(KERN_WARNING "md: failed to register dev-%s for %s\n",
b, mdname(mddev));
+out:
+ export_rdev(rdev);
return err;
}
@@ -1417,19 +1459,22 @@ static void delayed_delete(struct work_struct *ws)
{
mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work);
kobject_del(&rdev->kobj);
+ kobject_put(&rdev->kobj);
}
-static void unbind_rdev_from_array(mdk_rdev_t * rdev)
+static void kick_rdev_from_array(mdk_rdev_t * rdev)
{
char b[BDEVNAME_SIZE];
if (!rdev->mddev) {
MD_BUG();
+ export_rdev(rdev);
return;
}
bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk);
list_del_init(&rdev->same_set);
printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b));
rdev->mddev = NULL;
+ __export_rdev(rdev);
sysfs_remove_link(&rdev->kobj, "block");
/* We need to delay this, otherwise we can deadlock when
@@ -1467,40 +1512,6 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev)
return err;
}
-static void unlock_rdev(mdk_rdev_t *rdev)
-{
- struct block_device *bdev = rdev->bdev;
- rdev->bdev = NULL;
- if (!bdev)
- MD_BUG();
- bd_release(bdev);
- blkdev_put(bdev);
-}
-
-void md_autodetect_dev(dev_t dev);
-
-static void export_rdev(mdk_rdev_t * rdev)
-{
- char b[BDEVNAME_SIZE];
- printk(KERN_INFO "md: export_rdev(%s)\n",
- bdevname(rdev->bdev,b));
- if (rdev->mddev)
- MD_BUG();
- free_disk_sb(rdev);
- list_del_init(&rdev->same_set);
-#ifndef MODULE
- md_autodetect_dev(rdev->bdev->bd_dev);
-#endif
- unlock_rdev(rdev);
- kobject_put(&rdev->kobj);
-}
-
-static void kick_rdev_from_array(mdk_rdev_t * rdev)
-{
- unbind_rdev_from_array(rdev);
- export_rdev(rdev);
-}
-
static void export_array(mddev_t *mddev)
{
struct list_head *tmp;
@@ -2576,8 +2587,10 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
mdk_rdev_t, same_set);
err = super_types[mddev->major_version]
.load_super(rdev, rdev0, mddev->minor_version);
- if (err < 0)
- goto out;
+ if (err < 0) {
+ export_rdev(rdev);
+ return err;
+ }
}
} else
rdev = md_import_device(dev, -1, -1);
@@ -2585,9 +2598,6 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len)
if (IS_ERR(rdev))
return PTR_ERR(rdev);
err = bind_rdev_to_array(rdev, mddev);
- out:
- if (err)
- export_rdev(rdev);
return err ? err : len;
}
@@ -3637,8 +3647,7 @@ static void autorun_devices(int part)
printk(KERN_INFO "md: created %s\n", mdname(mddev));
ITERATE_RDEV_GENERIC(candidates,rdev,tmp) {
list_del_init(&rdev->same_set);
- if (bind_rdev_to_array(rdev, mddev))
- export_rdev(rdev);
+ bind_rdev_to_array(rdev, mddev);
}
autorun_array(mddev);
mddev_unlock(mddev);
@@ -3807,7 +3816,6 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
return -EOVERFLOW;
if (!mddev->raid_disks) {
- int err;
/* expecting a device which has a superblock */
rdev = md_import_device(dev, mddev->major_version, mddev->minor_version);
if (IS_ERR(rdev)) {
@@ -3830,10 +3838,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
return -EINVAL;
}
}
- err = bind_rdev_to_array(rdev, mddev);
- if (err)
- export_rdev(rdev);
- return err;
+ return bind_rdev_to_array(rdev, mddev);
}
/*
@@ -3887,10 +3892,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
validate_super(mddev, rdev);
err = mddev->pers->hot_add_disk(mddev, rdev);
if (err)
- unbind_rdev_from_array(rdev);
+ kick_rdev_from_array(rdev);
}
- if (err)
- export_rdev(rdev);
md_update_sb(mddev, 1);
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
@@ -3908,7 +3911,6 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
}
if (!(info->state & (1<<MD_DISK_FAULTY))) {
- int err;
rdev = md_import_device (dev, -1, 0);
if (IS_ERR(rdev)) {
printk(KERN_WARNING
@@ -3938,11 +3940,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
rdev->sb_offset = calc_dev_sboffset(rdev->bdev);
rdev->size = calc_dev_size(rdev, mddev->chunk_size);
- err = bind_rdev_to_array(rdev, mddev);
- if (err) {
- export_rdev(rdev);
- return err;
- }
+ return bind_rdev_to_array(rdev, mddev);
}
return 0;
@@ -4018,15 +4016,15 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
printk(KERN_WARNING
"md: can not hot-add faulty %s disk to %s!\n",
bdevname(rdev->bdev,b), mdname(mddev));
- err = -EINVAL;
- goto abort_export;
+ export_rdev(rdev);
+ return -EINVAL;
}
clear_bit(In_sync, &rdev->flags);
rdev->desc_nr = -1;
rdev->saved_raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
if (err)
- goto abort_export;
+ return err;
/*
* The rest should better be atomic, we can have disk failures
@@ -4036,8 +4034,8 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
if (rdev->desc_nr == mddev->max_disks) {
printk(KERN_WARNING "%s: can not hot-add to full array!\n",
mdname(mddev));
- err = -EBUSY;
- goto abort_unbind_export;
+ kick_rdev_from_array(rdev);
+ return -EBUSY;
}
rdev->raid_disk = -1;
@@ -4052,13 +4050,6 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
md_wakeup_thread(mddev->thread);
md_new_event(mddev);
return 0;
-
-abort_unbind_export:
- unbind_rdev_from_array(rdev);
^ permalink raw reply related
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