* Re: [Patch net-next] tcp: add a global sysctl to control TCP delayed ack
From: Rick Jones @ 2013-04-08 16:39 UTC (permalink / raw)
To: Cong Wang
Cc: David Miller, netdev, eric.dumazet, shemminger, tgraf,
David.Laight
In-Reply-To: <1365385541.31063.0.camel@cr0>
On 04/07/2013 06:45 PM, Cong Wang wrote:
> On Sun, 2013-04-07 at 17:09 -0400, David Miller wrote:
>>
>> I'm not applying a patch that adds a global parameter for
>> an attribute which has per-path scope.
>
> Ok, I will make it per-route.
Is setting a per-route attribute to cover the backside of an application
for which source code is not available in this day and age really all
that much easier than hitting that application with an LD_PRELOAD
library to make the desired setsockopt() call?
rick jones
having flashbacks to similar conversations in other contexts in the 1990s...
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 17:22 UTC (permalink / raw)
To: David Miller, Eric Dumazet; +Cc: netdev, mvadkert
In-Reply-To: <20130408.121434.1965501143066047212.davem@davemloft.net>
On Monday, April 08, 2013 12:14:34 PM David Miller wrote:
> From: Paul Moore <pmoore@redhat.com>
> Date: Mon, 08 Apr 2013 11:45:19 -0400
>
> > Commit 90ba9b1986b5ac4b2d184575847147ea7c4280a2 converted
> > tcp_make_synack() to use alloc_skb() directly instead of calling
> > sock_wmalloc(), the goal being the elimination of two atomic
> > operations. Unfortunately, in doing so the change broke certain
> > SELinux/NetLabel configurations by no longer correctly assigning
> > the sock to the outgoing packet.
> >
> > This patch fixes this regression by doing the skb->sk assignment
> > directly inside tcp_make_synack().
> >
> > Reported-by: Miroslav Vadkerti <mvadkert@redhat.com>
> > Signed-off-by: Paul Moore <pmoore@redhat.com>
>
> Setting skb->sk without the destructor results in an SKB that can live
> potentially forever with a stale reference to a destroyed socket.
>
> You cannot fix the problem in this way.
Okay, no worries, I'll work on v2. For some reason I missed the destructor
assignment in skb_set_owner_w(); I guess I was spending so much time hunting
around looking for the missing skb->sk assignment that once I found it I
declared victory ... a bit too soon.
Looking at the code again, I think the right solution is to call
skb_set_owner_w() instead of doing the assignment directly but that is
starting to bring us back to sock_wmalloc(force == 1) which gets back to
Eric's comments ... (below) ...
On Monday, April 08, 2013 09:19:23 AM Eric Dumazet wrote:
> Keeping a pointer on a socket without taking a refcount is not going to
> work.
>
> We are trying to make the stack scale, so you need to add a selinux call
> to take a ref count only if needed.
>
> That is : If selinux is not used, we don't need to slow down the stack.
Contrary to popular belief, my goal is to not destroy the scalability and/or
performance of our network stack, I just want to make sure we have a quality
network stack that is not only fast and scalable, but also preserves the
security functionality that makes Linux attractive to a number of users. To
that end, we could put a #ifdef in the middle of tcp_make_synack(), but that
seems very ugly to me and I think sets a bad precedence for the network stack
and kernel as a whole.
So a question for Dave, et al. - would you prefer that I fix this by:
1. Restore the original sock_wmalloc() call?
2. Keep things as-is with skb_alloc() but add skb_set_owner_w()?
3. Add a #ifdef depending on SELinux (probably the LSM in general to be safe)
and use sock_wmalloc() if enabled, skb_alloc() if not?
I guess I'm leaning towards #1 for the sake of simplicity, but I'd be happy
with either #1 or #2. The #3 option seems like a hack and makes me a bit
afraid of the future. I am also open to suggestions; to me, the most
important thing is that we fix this regression, I'm less concerned about how
we do it.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 17:36 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <3541094.5siDbVn1lC@sifl>
On Mon, 2013-04-08 at 13:22 -0400, Paul Moore wrote:
> On Monday, April 08, 2013 12:14:34 PM David Miller wrote:
> > From: Paul Moore <pmoore@redhat.com>
> > Date: Mon, 08 Apr 2013 11:45:19 -0400
> >
> > > Commit 90ba9b1986b5ac4b2d184575847147ea7c4280a2 converted
> > > tcp_make_synack() to use alloc_skb() directly instead of calling
> > > sock_wmalloc(), the goal being the elimination of two atomic
> > > operations. Unfortunately, in doing so the change broke certain
> > > SELinux/NetLabel configurations by no longer correctly assigning
> > > the sock to the outgoing packet.
> > >
> > > This patch fixes this regression by doing the skb->sk assignment
> > > directly inside tcp_make_synack().
> > >
> > > Reported-by: Miroslav Vadkerti <mvadkert@redhat.com>
> > > Signed-off-by: Paul Moore <pmoore@redhat.com>
> >
> > Setting skb->sk without the destructor results in an SKB that can live
> > potentially forever with a stale reference to a destroyed socket.
> >
> > You cannot fix the problem in this way.
>
> Okay, no worries, I'll work on v2. For some reason I missed the destructor
> assignment in skb_set_owner_w(); I guess I was spending so much time hunting
> around looking for the missing skb->sk assignment that once I found it I
> declared victory ... a bit too soon.
>
> Looking at the code again, I think the right solution is to call
> skb_set_owner_w() instead of doing the assignment directly but that is
> starting to bring us back to sock_wmalloc(force == 1) which gets back to
> Eric's comments ... (below) ...
>
> On Monday, April 08, 2013 09:19:23 AM Eric Dumazet wrote:
> > Keeping a pointer on a socket without taking a refcount is not going to
> > work.
> >
> > We are trying to make the stack scale, so you need to add a selinux call
> > to take a ref count only if needed.
> >
> > That is : If selinux is not used, we don't need to slow down the stack.
>
> Contrary to popular belief, my goal is to not destroy the scalability and/or
> performance of our network stack, I just want to make sure we have a quality
> network stack that is not only fast and scalable, but also preserves the
> security functionality that makes Linux attractive to a number of users. To
> that end, we could put a #ifdef in the middle of tcp_make_synack(), but that
> seems very ugly to me and I think sets a bad precedence for the network stack
> and kernel as a whole.
>
> So a question for Dave, et al. - would you prefer that I fix this by:
>
> 1. Restore the original sock_wmalloc() call?
> 2. Keep things as-is with skb_alloc() but add skb_set_owner_w()?
> 3. Add a #ifdef depending on SELinux (probably the LSM in general to be safe)
> and use sock_wmalloc() if enabled, skb_alloc() if not?
Didnt we had the same issue with RST packets ?
Please take a look at commit 3a7c384ffd57ef5fbd95f48edaa2ca4eb3d9f2ee
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 17:40 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <1365442586.3887.26.camel@edumazet-glaptop>
On Monday, April 08, 2013 10:36:26 AM Eric Dumazet wrote:
> On Mon, 2013-04-08 at 13:22 -0400, Paul Moore wrote:
> > On Monday, April 08, 2013 12:14:34 PM David Miller wrote:
> > > From: Paul Moore <pmoore@redhat.com>
> > > Date: Mon, 08 Apr 2013 11:45:19 -0400
> > >
> > > > Commit 90ba9b1986b5ac4b2d184575847147ea7c4280a2 converted
> > > > tcp_make_synack() to use alloc_skb() directly instead of calling
> > > > sock_wmalloc(), the goal being the elimination of two atomic
> > > > operations. Unfortunately, in doing so the change broke certain
> > > > SELinux/NetLabel configurations by no longer correctly assigning
> > > > the sock to the outgoing packet.
> > > >
> > > > This patch fixes this regression by doing the skb->sk assignment
> > > > directly inside tcp_make_synack().
> > > >
> > > > Reported-by: Miroslav Vadkerti <mvadkert@redhat.com>
> > > > Signed-off-by: Paul Moore <pmoore@redhat.com>
> > >
> > > Setting skb->sk without the destructor results in an SKB that can live
> > > potentially forever with a stale reference to a destroyed socket.
> > >
> > > You cannot fix the problem in this way.
> >
> > Okay, no worries, I'll work on v2. For some reason I missed the
> > destructor assignment in skb_set_owner_w(); I guess I was spending so much
> > time hunting around looking for the missing skb->sk assignment that once I
> > found it I declared victory ... a bit too soon.
> >
> > Looking at the code again, I think the right solution is to call
> > skb_set_owner_w() instead of doing the assignment directly but that is
> > starting to bring us back to sock_wmalloc(force == 1) which gets back to
> > Eric's comments ... (below) ...
> >
> > On Monday, April 08, 2013 09:19:23 AM Eric Dumazet wrote:
> > > Keeping a pointer on a socket without taking a refcount is not going to
> > > work.
> > >
> > > We are trying to make the stack scale, so you need to add a selinux call
> > > to take a ref count only if needed.
> > >
> > > That is : If selinux is not used, we don't need to slow down the stack.
> >
> > Contrary to popular belief, my goal is to not destroy the scalability
> > and/or performance of our network stack, I just want to make sure we have
> > a quality network stack that is not only fast and scalable, but also
> > preserves the security functionality that makes Linux attractive to a
> > number of users. To that end, we could put a #ifdef in the middle of
> > tcp_make_synack(), but that seems very ugly to me and I think sets a bad
> > precedence for the network stack and kernel as a whole.
> >
> > So a question for Dave, et al. - would you prefer that I fix this by:
> >
> > 1. Restore the original sock_wmalloc() call?
> > 2. Keep things as-is with skb_alloc() but add skb_set_owner_w()?
> > 3. Add a #ifdef depending on SELinux (probably the LSM in general to be
> > safe) and use sock_wmalloc() if enabled, skb_alloc() if not?
>
> Didnt we had the same issue with RST packets ?
>
> Please take a look at commit 3a7c384ffd57ef5fbd95f48edaa2ca4eb3d9f2ee
Sort of a similar problem, but not really the same. Also, arguably, there is
no real associated sock/socket for a RST so orphaning the packet makes sense.
In the case of a SYNACK we can, and should, associate the packet with a
sock/socket.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 17:47 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <1558855.HGIqa4tJdt@sifl>
On Mon, 2013-04-08 at 13:40 -0400, Paul Moore wrote:
> Sort of a similar problem, but not really the same. Also, arguably, there is
> no real associated sock/socket for a RST so orphaning the packet makes sense.
> In the case of a SYNACK we can, and should, associate the packet with a
> sock/socket.
What is the intent ?
This kind of requirement has a huge cost, and thats why I want a hook
instead of a 'generic thing'
Please read :
http://workshop.netfilter.org/2013/wiki/images/3/3a/NFWS-TCP.pdf
^ permalink raw reply
* [PATCH 0/3] bridge: implement restricted forwarding policy
From: Antonio Quartulli @ 2013-04-08 17:41 UTC (permalink / raw)
To: David S. Miller, Stephen Hemminger; +Cc: bridge, netdev, Antonio Quartulli
Hello,
with this patchset I would like to introduce a new feature to be added to the
bridge module that is later going to be one of the building block of a
distributed technique implemented using batman-adv.
The scenario where we want to play is a Layer2 mesh network handled by
the batman-adv module. For who may not know how it works, batman-adv creates a
sort of "extended broadcast domain" shared among nodes that are not directly
connected to each other.
This mechanism provides every node the view of the batman-adv network
as it was a very big Ethernet switch.
The goal we want to achieve by adding this feature consists in selecting a
subset of the interfaces available on all the hosts participating to the mesh
network and to prevent packets from being forwarded from one of them to another.
Looking again at the "very big switch" abstraction this would allow a mesh
network administrator to define a sort of "not forwarding policy network wide"
between some of the big switch's port.
This patchset is introducing the small piece needed by every hosts in the
network to handle the policy locally. In particular, I'm adding a new flag for
the net_device->flags member (IFF_BRIDGE_RESTRICTED) and a new attribute to the
sk_buff structure (bridge_restricted), then the bridge code is modified to
obey the following rule:
* do not forward any skb with the bridge_restricted attribute set to interfaces
marked with the IFF_BRIDGE_RESTRICTED flag.
Later, a change to batman-adv will follow which will make it spit out skbs with
the bridge_restricted member set depending on its distributed logic.
I am not entirely sure if I chose the very best place for those flags. If not,
please advise :)
Thanks a lot.
Cheers,
Antonio Quartulli (3):
if.h: add IFF_BRIDGE_RESTRICTED flag
sk_buff: add bridge_restricted flag
bridge: implement restricted port forwarding policy
include/linux/skbuff.h | 3 ++-
include/uapi/linux/if.h | 1 +
net/bridge/br_forward.c | 18 +++++++++++++++++-
net/bridge/br_input.c | 6 ++++++
net/core/dev.c | 2 +-
5 files changed, 27 insertions(+), 3 deletions(-)
--
1.8.1.5
^ permalink raw reply
* [PATCH 3/3] bridge: implement restricted port forwarding policy
From: Antonio Quartulli @ 2013-04-08 17:41 UTC (permalink / raw)
To: David S. Miller, Stephen Hemminger; +Cc: bridge, netdev, Antonio Quartulli
In-Reply-To: <1365442863-32394-1-git-send-email-antonio@open-mesh.com>
Prevent an skb with the bridge_restricted attribute set from
being forwarded to devices marked with the
IFF_BRIDGE_RESTRICTED flag.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
net/bridge/br_forward.c | 18 +++++++++++++++++-
net/bridge/br_input.c | 6 ++++++
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 092b20e..52b9031 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -26,13 +26,29 @@ static int deliver_clone(const struct net_bridge_port *prev,
void (*__packet_hook)(const struct net_bridge_port *p,
struct sk_buff *skb));
+/**
+ * should_restrict - check if incoming and outgoing ports are restricted
+ * @skb: the incoming packet
+ * @dev: the outgoing port
+ *
+ * Return true if the skb is coming from a restricted port and out_dev is
+ * restricted too. False otherwise
+ */
+static inline int should_restrict(const struct sk_buff *skb,
+ const struct net_device *out_dev)
+{
+ return skb->bridge_restricted &&
+ (out_dev->flags & IFF_BRIDGE_RESTRICTED);
+}
+
/* Don't forward packets to originating port or forwarding diasabled */
static inline int should_deliver(const struct net_bridge_port *p,
const struct sk_buff *skb)
{
return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
br_allowed_egress(p->br, nbp_get_vlan_info(p), skb) &&
- p->state == BR_STATE_FORWARDING);
+ p->state == BR_STATE_FORWARDING &&
+ !should_restrict(skb, p->dev));
}
static inline unsigned int packet_length(const struct sk_buff *skb)
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 828e2bc..73b4d4d 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -169,6 +169,12 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
p = br_port_get_rcu(skb->dev);
+ /* if this skb has been generated by a restricted port, mark it as well
+ * so that a "remote bridge" does not forward it to another restricted
+ * device
+ */
+ skb->bridge_restricted = !!(skb->dev->flags & IFF_BRIDGE_RESTRICTED);
+
if (unlikely(is_link_local_ether_addr(dest))) {
/*
* See IEEE 802.1D Table 7-10 Reserved addresses
--
1.8.1.5
^ permalink raw reply related
* [PATCH 1/3] if.h: add IFF_BRIDGE_RESTRICTED flag
From: Antonio Quartulli @ 2013-04-08 17:41 UTC (permalink / raw)
To: David S. Miller, Stephen Hemminger; +Cc: bridge, netdev, Antonio Quartulli
In-Reply-To: <1365442863-32394-1-git-send-email-antonio@open-mesh.com>
This new flag tells whether a network device has to be
considered as restricted in the new bridge forwarding logic.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
include/uapi/linux/if.h | 1 +
net/core/dev.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
index 1ec407b..5c3a9bd 100644
--- a/include/uapi/linux/if.h
+++ b/include/uapi/linux/if.h
@@ -83,6 +83,7 @@
#define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
#define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address
* change when it's running */
+#define IFF_BRIDGE_RESTRICTED 0x200000 /* device is bridge-restricted */
#define IF_GET_IFACE 0x0001 /* for querying only */
diff --git a/net/core/dev.c b/net/core/dev.c
index 3655ff9..49eafc8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4627,7 +4627,7 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags)
dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP |
IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |
- IFF_AUTOMEDIA)) |
+ IFF_AUTOMEDIA | IFF_BRIDGE_RESTRICTED)) |
(dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |
IFF_ALLMULTI));
--
1.8.1.5
^ permalink raw reply related
* [PATCH 2/3] sk_buff: add bridge_restricted flag
From: Antonio Quartulli @ 2013-04-08 17:41 UTC (permalink / raw)
To: David S. Miller, Stephen Hemminger; +Cc: bridge, netdev, Antonio Quartulli
In-Reply-To: <1365442863-32394-1-git-send-email-antonio@open-mesh.com>
This new flag tells whether the skb has been originated by
an interface marked with the IFF_BRIDGE_RESTRICTED flag.
This information can be used to prevent a packet from being
forwarded to another restricted interface.
Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
---
include/linux/skbuff.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index e27d1c7..2054073 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -492,7 +492,8 @@ struct sk_buff {
* headers if needed
*/
__u8 encapsulation:1;
- /* 7/9 bit hole (depending on ndisc_nodetype presence) */
+ __u8 bridge_restricted:1;
+ /* 9/11 bit hole (depending on ndisc_nodetype presence) */
kmemcheck_bitfield_end(flags2);
#ifdef CONFIG_NET_DMA
--
1.8.1.5
^ permalink raw reply related
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Sergei Shtylyov @ 2013-04-08 18:03 UTC (permalink / raw)
To: Paul Moore; +Cc: netdev, Miroslav Vadkerti
In-Reply-To: <20130408154519.18177.57709.stgit@localhost>
Hello.
On 04/08/2013 07:45 PM, Paul Moore wrote:
> Commit 90ba9b1986b5ac4b2d184575847147ea7c4280a2
Please also specify that commit's summary line in parens
(DaveM seems to also require double quotes inside the parens).
> converted
> tcp_make_synack() to use alloc_skb() directly instead of calling
> sock_wmalloc(), the goal being the elimination of two atomic
> operations. Unfortunately, in doing so the change broke certain
> SELinux/NetLabel configurations by no longer correctly assigning
> the sock to the outgoing packet.
>
> This patch fixes this regression by doing the skb->sk assignment
> directly inside tcp_make_synack().
>
> Reported-by: Miroslav Vadkerti <mvadkert@redhat.com>
> Signed-off-by: Paul Moore <pmoore@redhat.com>
WBR, Sergei
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 18:01 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <1365443267.3887.28.camel@edumazet-glaptop>
On Mon, 2013-04-08 at 10:47 -0700, Eric Dumazet wrote:
> This kind of requirement has a huge cost, and thats why I want a hook
> instead of a 'generic thing'
I meant " I would like ... "
We for example have security_inet_csk_clone()
We could have security_skb_owned_by(skb, sk)
I probably can send a patch, it seems quite easy.
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 18:12 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev, mvadkert
In-Reply-To: <1365443267.3887.28.camel@edumazet-glaptop>
On Monday, April 08, 2013 10:47:47 AM Eric Dumazet wrote:
> On Mon, 2013-04-08 at 13:40 -0400, Paul Moore wrote:
> > Sort of a similar problem, but not really the same. Also, arguably, there
> > is no real associated sock/socket for a RST so orphaning the packet makes
> > sense. In the case of a SYNACK we can, and should, associate the packet
> > with a sock/socket.
>
> What is the intent ?
We have to do a number of painful things in SELinux because we aren't allowed
a proper security blob (void *security) in a sk_buff. One of those things is
using the security blob in the originating sock as a stand-in for the packet's
own security blob; as a result, when skb->sk is not set we have to make some
guesses about the security attributes of packet. We do have methods to handle
packets without a valid sock pointer, but those are used primarily for non-
local packets (e.g. forwarded traffic) and some limited local use cases (e.g.
TCP RST packets).
Also, don't mention skb->secmark; unfortunately that was used for something
else and doesn't apply to this conversation.
> On Mon, 2013-04-08 at 10:47 -0700, Eric Dumazet wrote:
> > This kind of requirement has a huge cost, and thats why I want a hook
> > instead of a 'generic thing'
>
> I meant " I would like ... "
>
> We for example have security_inet_csk_clone()
>
> We could have security_skb_owned_by(skb, sk)
>
> I probably can send a patch, it seems quite easy.
It seems a bit fragile to me, perhaps even hacky, but in some ways I guess it
isn't anymore fragile than relying on skb->sk - as this problem demonstrates.
My other concern is that adding this hook *correctly* is likely to touch a lot
of files and may be a bit much so late in the 3.9 cycle, Dave, what say you?
Assuming that this is the preferred option, Eric, would you be open to
reverting your patch for 3.9 with the assumption that I promise to add the
hook for 3.10? You've got my word that I'll have it done ASAP.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 18:12 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: netdev, Miroslav Vadkerti
In-Reply-To: <51630675.8040608@cogentembedded.com>
On Monday, April 08, 2013 10:03:33 PM Sergei Shtylyov wrote:
> Hello.
>
> On 04/08/2013 07:45 PM, Paul Moore wrote:
> > Commit 90ba9b1986b5ac4b2d184575847147ea7c4280a2
>
> Please also specify that commit's summary line in parens
> (DaveM seems to also require double quotes inside the parens).
Noted for future reference.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* Re: how to test multipe unicast MAC address
From: Rayagond K @ 2013-04-08 18:13 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1365430604.3887.8.camel@edumazet-glaptop>
On Mon, Apr 8, 2013 at 7:46 PM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Mon, 2013-04-08 at 12:38 +0530, Rayagond K wrote:
>> Hi All,
>>
>> How to assign multiple unicast MAC address to single interface ?
>> How to test multiple unicast MAC address filtering ?
>>
>> Thanks in advance.
>>
>
> Standard way would be to use macvlan
>
> ip link add link eth0 name foo02 addr 44:44:44:44:00:02 type macvlan
> ip link add link eth0 name foo03 addr 44:44:44:44:00:03 type macvlan
I tried this, but this won't update the uc address and in netdev
struct and won't call .ndo_set_multicast_list.
I am planning to use vlan through vconfig as below,
#vconfig add eth0 100
#ifconfig eth0.100 10.144.134.1 netmask 255.255.255.0 up
#ifconfig eth0.100 hw ether 00:55:22:44:f7:80
This will update uc in netdev and calls .ndo_set_multicast_list.
>
>
^ permalink raw reply
* Re: [PATCH] rtnetlink: Call nlmsg_parse() with correct header length
From: Rustad, Mark D @ 2013-04-08 18:13 UTC (permalink / raw)
To: Michael Riesch
Cc: <netdev@vger.kernel.org>, David S. Miller,
Greg Kroah-Hartman, Jiri Benc, Theodore Ts'o,
<linux-kernel@vger.kernel.org>
In-Reply-To: <e04bc546-fcf6-41d2-a585-5fddff388e06@mary.at.omicron.at>
On Apr 8, 2013, at 8:45 AM, Michael Riesch <michael.riesch@omicron.at> wrote:
>
> Signed-off-by: Michael Riesch <michael.riesch@omicron.at>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Jiri Benc <jbenc@redhat.com>
> Cc: "Theodore Ts'o" <tytso@mit.edu>
> Cc: linux-kernel@vger.kernel.org
> ---
> Habidere,
>
> I encountered a netlink kernel warning when running avahi 0.6.31 on my system
> with kernel v3.4.35 (it appears several times):
>
> netlink: 12 bytes leftover after parsing attributes.
>
> Searching the web showed that commit "115c9b81928360d769a76c632bae62d15206a94a
> rtnetlink: Fix problem with buffer allocation" introduced this behaviour[1].
>
> Now I - knowing nothing about netlink whatsoever - assume that the nlmsg_parse
> function is called with the wrong header length. In user space the request
> message consists out of the message header (struct nlmsghdr, 16 bytes) and an
> ifinfomsg (struct ifinfomsg, 16 bytes). After that, request attributes could
> follow. nlmsg_parse checks for this attributes after a given header length. In
> rtnl_get_link() this header length is sizeof(struct ifinfomsg), but in
> rtnl_calcit() as well as in rntl_dump_ifinfo() the header length is
> sizeof(struct rtgenmsg), which is 1 byte.
>
> With this patch I got rid of these warnings. However, I do not know whether
> this is the correct solution, so I am looking forward to your comments.
> Regards, Michael
>
> [1] http://lists.infradead.org/pipermail/libnl/2012-April/000515.html
>
> net/core/rtnetlink.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 900fc61..ebf6ace 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -1065,7 +1065,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
> rcu_read_lock();
> cb->seq = net->dev_base_seq;
>
> - if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
> + if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
> ifla_policy) >= 0) {
>
> if (tb[IFLA_EXT_MASK])
> @@ -1909,7 +1909,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
> u32 ext_filter_mask = 0;
> u16 min_ifinfo_dump_size = 0;
>
> - if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
> + if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX,
> ifla_policy) >= 0) {
> if (tb[IFLA_EXT_MASK])
> ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
> --
> 1.7.9.5
I found that fcoemon has also been triggering these messages for some time. I found the same problem and arrived at exactly the same solution. I would have already sent it, but it is still in validation. As far as I am concerned:
Acked-by: Mark Rustad <mark.d.rustad@intel.com>
--
Mark Rustad, Networking Division, Intel Corporation
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 18:21 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <1725553.maWFXblPLa@sifl>
On Mon, 2013-04-08 at 14:12 -0400, Paul Moore wrote:
>
> It seems a bit fragile to me, perhaps even hacky, but in some ways I guess it
> isn't anymore fragile than relying on skb->sk - as this problem demonstrates.
> My other concern is that adding this hook *correctly* is likely to touch a lot
> of files and may be a bit much so late in the 3.9 cycle, Dave, what say you?
I don't get it, 90ba9b1986b5ac4b2d18 was in 3.6, why do you care of
3.9 ?
I am preparing a fix right now. Not a revert, thank you.
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 18:26 UTC (permalink / raw)
To: Eric Dumazet, David Miller; +Cc: netdev, mvadkert
In-Reply-To: <1365445303.3887.33.camel@edumazet-glaptop>
On Monday, April 08, 2013 11:21:43 AM Eric Dumazet wrote:
> On Mon, 2013-04-08 at 14:12 -0400, Paul Moore wrote:
> > It seems a bit fragile to me, perhaps even hacky, but in some ways I guess
> > it isn't anymore fragile than relying on skb->sk - as this problem
> > demonstrates. My other concern is that adding this hook *correctly* is
> > likely to touch a lot of files and may be a bit much so late in the 3.9
> > cycle, Dave, what say you?
>
> I don't get it, 90ba9b1986b5ac4b2d18 was in 3.6, why do you care of
> 3.9 ?
I wasn't made aware of the particular bug until just recently. When I see a
regression I generally try to get it fixed as soon as possible.
> I am preparing a fix right now. Not a revert, thank you.
I guess we'll have to wait and see then; the more I think about the new hook
you proposed the less enthused I am about it.
I'm still curious to hear what Dave has to say on this.
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* [PATCH net-next] net: cdc_ncm: demote "unexpected notification" to debug level
From: Bjørn Mork @ 2013-04-08 18:26 UTC (permalink / raw)
To: netdev; +Cc: linux-usb, Bjørn Mork, Alexey Orishko
Receiving unhandled notifications is most certainly not an error
and should not be logged as one. Knowing that the device sends
notifications we don't handle is useful for developers, but there
is very little a user can do about this. The message is therefore
just annoying noise to most users with devices sending unhandled
notifications like e.g. USB_CDC_NOTIFY_RESPONSE_AVAILABLE
Cc: Alexey Orishko <alexey.orishko@stericsson.com>
Signed-off-by: Bjørn Mork <bjorn@mork.no>
---
drivers/net/usb/cdc_ncm.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
index 44a989c..67012cb 100644
--- a/drivers/net/usb/cdc_ncm.c
+++ b/drivers/net/usb/cdc_ncm.c
@@ -1124,8 +1124,9 @@ static void cdc_ncm_status(struct usbnet *dev, struct urb *urb)
break;
default:
- dev_err(&dev->udev->dev, "NCM: unexpected "
- "notification 0x%02x!\n", event->bNotificationType);
+ dev_dbg(&dev->udev->dev,
+ "NCM: unexpected notification 0x%02x!\n",
+ event->bNotificationType);
break;
}
}
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 18:30 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <1365445303.3887.33.camel@edumazet-glaptop>
On Mon, 2013-04-08 at 11:21 -0700, Eric Dumazet wrote:
> On Mon, 2013-04-08 at 14:12 -0400, Paul Moore wrote:
>
> >
> > It seems a bit fragile to me, perhaps even hacky, but in some ways I guess it
> > isn't anymore fragile than relying on skb->sk - as this problem demonstrates.
> > My other concern is that adding this hook *correctly* is likely to touch a lot
> > of files and may be a bit much so late in the 3.9 cycle, Dave, what say you?
>
> I don't get it, 90ba9b1986b5ac4b2d18 was in 3.6, why do you care of
> 3.9 ?
>
> I am preparing a fix right now. Not a revert, thank you.
>
Is the following patch not good enough ?
include/linux/security.h | 7 +++++++
net/ipv4/tcp_output.c | 1 +
security/security.c | 6 ++++++
3 files changed, 14 insertions(+)
diff --git a/include/linux/security.h b/include/linux/security.h
index eee7478..1bde8bb 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -2588,6 +2588,8 @@ int security_tun_dev_attach_queue(void *security);
int security_tun_dev_attach(struct sock *sk, void *security);
int security_tun_dev_open(void *security);
+void security_skb_owned_by(struct sk_buff *skb, struct sock *sk);
+
#else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct sock *sock,
struct sock *other,
@@ -2779,6 +2781,11 @@ static inline int security_tun_dev_open(void *security)
{
return 0;
}
+
+static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+}
+
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5d0b438..b44cf81 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2709,6 +2709,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
skb_reserve(skb, MAX_TCP_HEADER);
skb_dst_set(skb, dst);
+ security_skb_owned_by(skb, sk);
mss = dst_metric_advmss(dst);
if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
diff --git a/security/security.c b/security/security.c
index 7b88c6a..cdabd4d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -25,6 +25,7 @@
#include <linux/personality.h>
#include <linux/backing-dev.h>
#include <net/flow.h>
+#include <net/sock.h>
#define MAX_LSM_EVM_XATTR 2
@@ -1290,6 +1291,11 @@ int security_tun_dev_open(void *security)
}
EXPORT_SYMBOL(security_tun_dev_open);
+void security_skb_owned_by(struct sk_buff *skb, struct sock *sk)
+{
+ skb_set_owner_w(skb, sk);
+}
+
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
^ permalink raw reply related
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Paul Moore @ 2013-04-08 18:32 UTC (permalink / raw)
To: David Miller
Cc: Eric Dumazet, netdev, mvadkert, selinux, linux-security-module
In-Reply-To: <1725553.maWFXblPLa@sifl>
On Monday, April 08, 2013 02:12:01 PM Paul Moore wrote:
> On Monday, April 08, 2013 10:47:47 AM Eric Dumazet wrote:
> > On Mon, 2013-04-08 at 13:40 -0400, Paul Moore wrote:
> > > Sort of a similar problem, but not really the same. Also, arguably,
> > > there is no real associated sock/socket for a RST so orphaning the
> > > packet makes sense. In the case of a SYNACK we can, and should,
> > > associate the packet with a sock/socket.
> >
> > What is the intent ?
>
> We have to do a number of painful things in SELinux because we aren't
> allowed a proper security blob (void *security) in a sk_buff. One of those
> things ...
Actually, I wonder if this problem means it is a good time to revisit the no-
security-blob-in-sk_buff decision? The management of the blob would be hidden
behind the LSM hooks like everything else and it would have a number of
advantages including making problems like we are seeing here easier to fix or
avoid entirely. It would also make life much easier for those of working on
LSM stuff and it would pave the way for including network access controls in
the stacked-LSM stuff Casey is kicking around.
I'm aware of all the arguments against, but thought it would be worth bringing
it up again, if for no other reason than I haven't heard enough shouting yet
today :)
--
paul moore
security and virtualization @ redhat
^ permalink raw reply
* Re: [PATCH] tcp: assign the sock correctly to an outgoing SYNACK packet
From: Eric Dumazet @ 2013-04-08 18:34 UTC (permalink / raw)
To: Paul Moore; +Cc: David Miller, netdev, mvadkert
In-Reply-To: <10426929.HS2uObfqRU@sifl>
On Mon, 2013-04-08 at 14:26 -0400, Paul Moore wrote:
> I guess we'll have to wait and see then; the more I think about the new hook
> you proposed the less enthused I am about it.
>
> I'm still curious to hear what Dave has to say on this.
>
90ba9b1986b5ac4b2 is 10 months old, and nobody complained until today ?
This sounds like a very small issue to me, a revert is simply overkill.
Lets go forward instead of applying blind fixes.
^ permalink raw reply
* Re: [PATCH net-next] ixgbe: Remove unnecessary #ifdef CONFIG_DEBUG_FS tests
From: Jeff Kirsher @ 2013-04-08 18:47 UTC (permalink / raw)
To: Joe Perches; +Cc: e1000-devel, netdev
In-Reply-To: <1365384453.8922.20.camel@joe-AO722>
[-- Attachment #1: Type: text/plain, Size: 423 bytes --]
On Sun, 2013-04-07 at 18:27 -0700, Joe Perches wrote:
> Add some empty static inlines instead to make
> the code more readable.
>
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 5 +++++
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 10 ----------
> 2 files changed, 5 insertions(+), 10 deletions(-)
Thanks Joe, I have added the patch to my queue.
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH 1/3] if.h: add IFF_BRIDGE_RESTRICTED flag
From: Stephen Hemminger @ 2013-04-08 18:58 UTC (permalink / raw)
To: Antonio Quartulli; +Cc: netdev, bridge, David S. Miller
In-Reply-To: <1365442863-32394-2-git-send-email-antonio@open-mesh.com>
The standard way to do this is to use netfilter. Considering the
additional device flags and skb flag changes, I am not sure that your
method is better.
On Mon, Apr 8, 2013 at 10:41 AM, Antonio Quartulli
<antonio@open-mesh.com> wrote:
> This new flag tells whether a network device has to be
> considered as restricted in the new bridge forwarding logic.
>
> Signed-off-by: Antonio Quartulli <antonio@open-mesh.com>
> ---
> include/uapi/linux/if.h | 1 +
> net/core/dev.c | 2 +-
> 2 files changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/if.h b/include/uapi/linux/if.h
> index 1ec407b..5c3a9bd 100644
> --- a/include/uapi/linux/if.h
> +++ b/include/uapi/linux/if.h
> @@ -83,6 +83,7 @@
> #define IFF_SUPP_NOFCS 0x80000 /* device supports sending custom FCS */
> #define IFF_LIVE_ADDR_CHANGE 0x100000 /* device supports hardware address
> * change when it's running */
> +#define IFF_BRIDGE_RESTRICTED 0x200000 /* device is bridge-restricted */
>
>
> #define IF_GET_IFACE 0x0001 /* for querying only */
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 3655ff9..49eafc8 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -4627,7 +4627,7 @@ int __dev_change_flags(struct net_device *dev, unsigned int flags)
>
> dev->flags = (flags & (IFF_DEBUG | IFF_NOTRAILERS | IFF_NOARP |
> IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |
> - IFF_AUTOMEDIA)) |
> + IFF_AUTOMEDIA | IFF_BRIDGE_RESTRICTED)) |
> (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |
> IFF_ALLMULTI));
>
> --
> 1.8.1.5
>
^ permalink raw reply
* 3.9-rc6 (only) one particular tap device putted into forwarding state
From: Toralf Förster @ 2013-04-08 19:03 UTC (permalink / raw)
To: netdev, Linux Kernel
I realized these new syslog messages at a 32 bit stable Gentoo, which have
4 configured TAP devices attached to a bridge :
2013-04-08T19:55:20.048+02:00 n22 kernel: br0: port 4(tap3) entered forwarding state
2013-04-08T19:55:20.048+02:00 n22 kernel: br0: port 4(tap3) entered forwarding state
2013-04-08T19:55:20.316+02:00 n22 kernel: br0: port 4(tap3) entered disabled state
This happened one time only and only for one device (for tap3, and all 4 devices are identical configured)
for one boot attempt till now - no configuration were changed.
--
MfG/Sincerely
Toralf Förster
pgp finger print: 7B1A 07F4 EC82 0F90 D4C2 8936 872A E508 7DB6 9DA3
^ permalink raw reply
* pull request: wireless 2013-04-08
From: John W. Linville @ 2013-04-08 19:21 UTC (permalink / raw)
To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
[-- Attachment #1: Type: text/plain, Size: 31953 bytes --]
Dave,
Please consider this set of fixes for the 3.9 stream...
For the cfg80211 fix, Johannes says:
"I have another straggler for 3.9, adding locking forgotten in a previous
fix."
On top of that:
Bing Zhao provides an mwifiex fix to properly order a scan completion.
Franky Lin gives us a brcmfmac fix to fail at the firmware loading
stage if the nvram cannot be downloaded.
Gabor Juhos brings what at first looks like a rather big rt2x00 patch.
I think it is OK because it is really just reorganizing some code
within the rt2x00 driver in order to fix a build failure.
Hante Meuleman offers a trio of brcmfmac fixes related to running in
AP mode.
Robert Shade sends an ath9k fix to reenable interrupts even if a
channel change fails.
Tim Gardner gives us an rt2x00 fix to cut-down on some log SPAM.
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit b50b72de2f2feed4adfbd8e18610a393b5a04cc7:
net: mvneta: enable features before registering the driver (2013-04-08 12:16:38 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
for you to fetch changes up to 64e5751918b4d03015b185750a46ecd050e1ce77:
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem (2013-04-08 14:26:57 -0400)
----------------------------------------------------------------
Artem Savkov (1):
cfg80211: sched_scan_mtx lock in cfg80211_conn_work()
Bing Zhao (1):
mwifiex: complete last internal scan
Franky Lin (1):
brcmfmac: do not proceed if fail to download nvram to dongle
Gabor Juhos (1):
rt2x00: rt2x00pci: fix build error on Ralink RT3x5x SoCs
Hante Meuleman (3):
brcmfmac: fix tkip mic tx/rx ap swap bug.
brcmfmac: fix stopping AP.
brcmfmac: fix returning cipher_suite for get_key operation.
John W. Linville (2):
Merge branch 'for-john' of git://git.kernel.org/.../jberg/mac80211
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Robert Shade (1):
ath9k: Re-enable interrupts after a channel change failure
Tim Gardner (1):
rt2x00: rt2x00pci_regbusy_read() - only print register access failure once
drivers/net/wireless/ath/ath9k/main.c | 4 +
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 6 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 46 +++--
drivers/net/wireless/mwifiex/scan.c | 11 +-
drivers/net/wireless/rt2x00/Kconfig | 7 +
drivers/net/wireless/rt2x00/Makefile | 1 +
drivers/net/wireless/rt2x00/rt2400pci.c | 1 +
drivers/net/wireless/rt2x00/rt2500pci.c | 1 +
drivers/net/wireless/rt2x00/rt2800pci.c | 1 +
drivers/net/wireless/rt2x00/rt2x00mmio.c | 216 +++++++++++++++++++++
drivers/net/wireless/rt2x00/rt2x00mmio.h | 119 ++++++++++++
drivers/net/wireless/rt2x00/rt2x00pci.c | 176 -----------------
drivers/net/wireless/rt2x00/rt2x00pci.h | 88 ---------
drivers/net/wireless/rt2x00/rt61pci.c | 1 +
net/wireless/sme.c | 2 +
15 files changed, 390 insertions(+), 290 deletions(-)
create mode 100644 drivers/net/wireless/rt2x00/rt2x00mmio.c
create mode 100644 drivers/net/wireless/rt2x00/rt2x00mmio.h
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 6e66f9c..988372d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -280,6 +280,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan)
if (r) {
ath_err(common,
"Unable to reset channel, reset status %d\n", r);
+
+ ath9k_hw_enable_interrupts(ah);
+ ath9k_queue_reset(sc, RESET_TYPE_BB_HANG);
+
goto out;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 4469321..35fc68b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -3317,15 +3317,15 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
goto err;
}
- /* External image takes precedence if specified */
if (brcmf_sdbrcm_download_code_file(bus)) {
brcmf_err("dongle image file download failed\n");
goto err;
}
- /* External nvram takes precedence if specified */
- if (brcmf_sdbrcm_download_nvram(bus))
+ if (brcmf_sdbrcm_download_nvram(bus)) {
brcmf_err("dongle nvram file download failed\n");
+ goto err;
+ }
/* Take arm out of reset */
if (brcmf_sdbrcm_download_state(bus, false)) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 2af9c0f..ec46fff 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1891,8 +1891,10 @@ static s32
brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
u8 key_idx, const u8 *mac_addr, struct key_params *params)
{
+ struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_wsec_key key;
s32 err = 0;
+ u8 keybuf[8];
memset(&key, 0, sizeof(key));
key.index = (u32) key_idx;
@@ -1916,8 +1918,9 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
memcpy(key.data, params->key, key.len);
- if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
- u8 keybuf[8];
+ if ((ifp->vif->mode != WL_MODE_AP) &&
+ (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
+ brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
memcpy(keybuf, &key.data[24], sizeof(keybuf));
memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2013,7 +2016,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
break;
case WLAN_CIPHER_SUITE_TKIP:
if (ifp->vif->mode != WL_MODE_AP) {
- brcmf_dbg(CONN, "Swapping key\n");
+ brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
memcpy(keybuf, &key.data[24], sizeof(keybuf));
memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
memcpy(&key.data[16], keybuf, sizeof(keybuf));
@@ -2118,8 +2121,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
err = -EAGAIN;
goto done;
}
- switch (wsec & ~SES_OW_ENABLED) {
- case WEP_ENABLED:
+ if (wsec & WEP_ENABLED) {
sec = &profile->sec;
if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
params.cipher = WLAN_CIPHER_SUITE_WEP40;
@@ -2128,16 +2130,13 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
params.cipher = WLAN_CIPHER_SUITE_WEP104;
brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
}
- break;
- case TKIP_ENABLED:
+ } else if (wsec & TKIP_ENABLED) {
params.cipher = WLAN_CIPHER_SUITE_TKIP;
brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
- break;
- case AES_ENABLED:
+ } else if (wsec & AES_ENABLED) {
params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
- break;
- default:
+ } else {
brcmf_err("Invalid algo (0x%x)\n", wsec);
err = -EINVAL;
goto done;
@@ -3824,8 +3823,9 @@ exit:
static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
{
struct brcmf_if *ifp = netdev_priv(ndev);
- s32 err = -EPERM;
+ s32 err;
struct brcmf_fil_bss_enable_le bss_enable;
+ struct brcmf_join_params join_params;
brcmf_dbg(TRACE, "Enter\n");
@@ -3833,16 +3833,21 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
/* Due to most likely deauths outstanding we sleep */
/* first to make sure they get processed by fw. */
msleep(400);
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
- if (err < 0) {
- brcmf_err("setting AP mode failed %d\n", err);
- goto exit;
- }
+
+ memset(&join_params, 0, sizeof(join_params));
+ err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
+ &join_params, sizeof(join_params));
+ if (err < 0)
+ brcmf_err("SET SSID error (%d)\n", err);
err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
- if (err < 0) {
+ if (err < 0)
brcmf_err("BRCMF_C_UP error %d\n", err);
- goto exit;
- }
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
+ if (err < 0)
+ brcmf_err("setting AP mode failed %d\n", err);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
+ if (err < 0)
+ brcmf_err("setting INFRA mode failed %d\n", err);
} else {
bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
bss_enable.enable = cpu_to_le32(0);
@@ -3855,7 +3860,6 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
-exit:
return err;
}
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index d215b4d..e7f6dea 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1393,8 +1393,10 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
queue_work(adapter->workqueue, &adapter->main_work);
/* Perform internal scan synchronously */
- if (!priv->scan_request)
+ if (!priv->scan_request) {
+ dev_dbg(adapter->dev, "wait internal scan\n");
mwifiex_wait_queue_complete(adapter, cmd_node);
+ }
} else {
spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
flags);
@@ -1793,7 +1795,12 @@ check_next_scan:
/* Need to indicate IOCTL complete */
if (adapter->curr_cmd->wait_q_enabled) {
adapter->cmd_wait_q.status = 0;
- mwifiex_complete_cmd(adapter, adapter->curr_cmd);
+ if (!priv->scan_request) {
+ dev_dbg(adapter->dev,
+ "complete internal scan\n");
+ mwifiex_complete_cmd(adapter,
+ adapter->curr_cmd);
+ }
}
if (priv->report_scan_result)
priv->report_scan_result = false;
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index 2bf4efa..76cd47e 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -20,6 +20,7 @@ if RT2X00
config RT2400PCI
tristate "Ralink rt2400 (PCI/PCMCIA) support"
depends on PCI
+ select RT2X00_LIB_MMIO
select RT2X00_LIB_PCI
select EEPROM_93CX6
---help---
@@ -31,6 +32,7 @@ config RT2400PCI
config RT2500PCI
tristate "Ralink rt2500 (PCI/PCMCIA) support"
depends on PCI
+ select RT2X00_LIB_MMIO
select RT2X00_LIB_PCI
select EEPROM_93CX6
---help---
@@ -43,6 +45,7 @@ config RT61PCI
tristate "Ralink rt2501/rt61 (PCI/PCMCIA) support"
depends on PCI
select RT2X00_LIB_PCI
+ select RT2X00_LIB_MMIO
select RT2X00_LIB_FIRMWARE
select RT2X00_LIB_CRYPTO
select CRC_ITU_T
@@ -57,6 +60,7 @@ config RT2800PCI
tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support"
depends on PCI || SOC_RT288X || SOC_RT305X
select RT2800_LIB
+ select RT2X00_LIB_MMIO
select RT2X00_LIB_PCI if PCI
select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X
select RT2X00_LIB_FIRMWARE
@@ -185,6 +189,9 @@ endif
config RT2800_LIB
tristate
+config RT2X00_LIB_MMIO
+ tristate
+
config RT2X00_LIB_PCI
tristate
select RT2X00_LIB
diff --git a/drivers/net/wireless/rt2x00/Makefile b/drivers/net/wireless/rt2x00/Makefile
index 349d5b8..f069d8b 100644
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile
@@ -9,6 +9,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE) += rt2x00firmware.o
rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS) += rt2x00leds.o
obj-$(CONFIG_RT2X00_LIB) += rt2x00lib.o
+obj-$(CONFIG_RT2X00_LIB_MMIO) += rt2x00mmio.o
obj-$(CONFIG_RT2X00_LIB_PCI) += rt2x00pci.o
obj-$(CONFIG_RT2X00_LIB_SOC) += rt2x00soc.o
obj-$(CONFIG_RT2X00_LIB_USB) += rt2x00usb.o
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 221beaa..dcfb54e 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include "rt2x00.h"
+#include "rt2x00mmio.h"
#include "rt2x00pci.h"
#include "rt2400pci.h"
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 39edc59..e1d2dc9 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -34,6 +34,7 @@
#include <linux/slab.h>
#include "rt2x00.h"
+#include "rt2x00mmio.h"
#include "rt2x00pci.h"
#include "rt2500pci.h"
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index ded73da..ba5a056 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -41,6 +41,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00mmio.h"
#include "rt2x00pci.h"
#include "rt2x00soc.h"
#include "rt2800lib.h"
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.c b/drivers/net/wireless/rt2x00/rt2x00mmio.c
new file mode 100644
index 0000000..d84a680
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.c
@@ -0,0 +1,216 @@
+/*
+ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00mmio
+ Abstract: rt2x00 generic mmio device routines.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#include "rt2x00.h"
+#include "rt2x00mmio.h"
+
+/*
+ * Register access.
+ */
+int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ const struct rt2x00_field32 field,
+ u32 *reg)
+{
+ unsigned int i;
+
+ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+ return 0;
+
+ for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+ rt2x00pci_register_read(rt2x00dev, offset, reg);
+ if (!rt2x00_get_field32(*reg, field))
+ return 1;
+ udelay(REGISTER_BUSY_DELAY);
+ }
+
+ printk_once(KERN_ERR "%s() Indirect register access failed: "
+ "offset=0x%.08x, value=0x%.08x\n", __func__, offset, *reg);
+ *reg = ~0;
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
+
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue = rt2x00dev->rx;
+ struct queue_entry *entry;
+ struct queue_entry_priv_pci *entry_priv;
+ struct skb_frame_desc *skbdesc;
+ int max_rx = 16;
+
+ while (--max_rx) {
+ entry = rt2x00queue_get_entry(queue, Q_INDEX);
+ entry_priv = entry->priv_data;
+
+ if (rt2x00dev->ops->lib->get_entry_state(entry))
+ break;
+
+ /*
+ * Fill in desc fields of the skb descriptor
+ */
+ skbdesc = get_skb_frame_desc(entry->skb);
+ skbdesc->desc = entry_priv->desc;
+ skbdesc->desc_len = entry->queue->desc_size;
+
+ /*
+ * DMA is already done, notify rt2x00lib that
+ * it finished successfully.
+ */
+ rt2x00lib_dmastart(entry);
+ rt2x00lib_dmadone(entry);
+
+ /*
+ * Send the frame to rt2x00lib for further processing.
+ */
+ rt2x00lib_rxdone(entry, GFP_ATOMIC);
+ }
+
+ return !max_rx;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
+
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
+{
+ unsigned int i;
+
+ for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
+ msleep(10);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
+
+/*
+ * Device initialization handlers.
+ */
+static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
+ struct data_queue *queue)
+{
+ struct queue_entry_priv_pci *entry_priv;
+ void *addr;
+ dma_addr_t dma;
+ unsigned int i;
+
+ /*
+ * Allocate DMA memory for descriptor and buffer.
+ */
+ addr = dma_alloc_coherent(rt2x00dev->dev,
+ queue->limit * queue->desc_size,
+ &dma, GFP_KERNEL);
+ if (!addr)
+ return -ENOMEM;
+
+ memset(addr, 0, queue->limit * queue->desc_size);
+
+ /*
+ * Initialize all queue entries to contain valid addresses.
+ */
+ for (i = 0; i < queue->limit; i++) {
+ entry_priv = queue->entries[i].priv_data;
+ entry_priv->desc = addr + i * queue->desc_size;
+ entry_priv->desc_dma = dma + i * queue->desc_size;
+ }
+
+ return 0;
+}
+
+static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
+ struct data_queue *queue)
+{
+ struct queue_entry_priv_pci *entry_priv =
+ queue->entries[0].priv_data;
+
+ if (entry_priv->desc)
+ dma_free_coherent(rt2x00dev->dev,
+ queue->limit * queue->desc_size,
+ entry_priv->desc, entry_priv->desc_dma);
+ entry_priv->desc = NULL;
+}
+
+int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+ int status;
+
+ /*
+ * Allocate DMA
+ */
+ queue_for_each(rt2x00dev, queue) {
+ status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
+ if (status)
+ goto exit;
+ }
+
+ /*
+ * Register interrupt handler.
+ */
+ status = request_irq(rt2x00dev->irq,
+ rt2x00dev->ops->lib->irq_handler,
+ IRQF_SHARED, rt2x00dev->name, rt2x00dev);
+ if (status) {
+ ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
+ rt2x00dev->irq, status);
+ goto exit;
+ }
+
+ return 0;
+
+exit:
+ queue_for_each(rt2x00dev, queue)
+ rt2x00pci_free_queue_dma(rt2x00dev, queue);
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
+
+void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
+{
+ struct data_queue *queue;
+
+ /*
+ * Free irq line.
+ */
+ free_irq(rt2x00dev->irq, rt2x00dev);
+
+ /*
+ * Free DMA
+ */
+ queue_for_each(rt2x00dev, queue)
+ rt2x00pci_free_queue_dma(rt2x00dev, queue);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
+
+/*
+ * rt2x00mmio module information.
+ */
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("rt2x00 mmio library");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/wireless/rt2x00/rt2x00mmio.h b/drivers/net/wireless/rt2x00/rt2x00mmio.h
new file mode 100644
index 0000000..4ecaf60
--- /dev/null
+++ b/drivers/net/wireless/rt2x00/rt2x00mmio.h
@@ -0,0 +1,119 @@
+/*
+ Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
+ <http://rt2x00.serialmonkey.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the
+ Free Software Foundation, Inc.,
+ 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ Module: rt2x00mmio
+ Abstract: Data structures for the rt2x00mmio module.
+ */
+
+#ifndef RT2X00MMIO_H
+#define RT2X00MMIO_H
+
+#include <linux/io.h>
+
+/*
+ * Register access.
+ */
+static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u32 *value)
+{
+ *value = readl(rt2x00dev->csr.base + offset);
+}
+
+static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ void *value, const u32 length)
+{
+ memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
+}
+
+static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ u32 value)
+{
+ writel(value, rt2x00dev->csr.base + offset);
+}
+
+static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ const void *value,
+ const u32 length)
+{
+ __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
+}
+
+/**
+ * rt2x00pci_regbusy_read - Read from register with busy check
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ * @offset: Register offset
+ * @field: Field to check if register is busy
+ * @reg: Pointer to where register contents should be stored
+ *
+ * This function will read the given register, and checks if the
+ * register is busy. If it is, it will sleep for a couple of
+ * microseconds before reading the register again. If the register
+ * is not read after a certain timeout, this function will return
+ * FALSE.
+ */
+int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
+ const unsigned int offset,
+ const struct rt2x00_field32 field,
+ u32 *reg);
+
+/**
+ * struct queue_entry_priv_pci: Per entry PCI specific information
+ *
+ * @desc: Pointer to device descriptor
+ * @desc_dma: DMA pointer to &desc.
+ * @data: Pointer to device's entry memory.
+ * @data_dma: DMA pointer to &data.
+ */
+struct queue_entry_priv_pci {
+ __le32 *desc;
+ dma_addr_t desc_dma;
+};
+
+/**
+ * rt2x00pci_rxdone - Handle RX done events
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ *
+ * Returns true if there are still rx frames pending and false if all
+ * pending rx frames were processed.
+ */
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00pci_flush_queue - Flush data queue
+ * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
+ *
+ * This will wait for a maximum of 100ms, waiting for the queues
+ * to become empty.
+ */
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
+
+/*
+ * Device initialization handlers.
+ */
+int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
+void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
+
+#endif /* RT2X00MMIO_H */
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index a0c8cae..e87865e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -33,182 +33,6 @@
#include "rt2x00pci.h"
/*
- * Register access.
- */
-int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- const struct rt2x00_field32 field,
- u32 *reg)
-{
- unsigned int i;
-
- if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
- return 0;
-
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00pci_register_read(rt2x00dev, offset, reg);
- if (!rt2x00_get_field32(*reg, field))
- return 1;
- udelay(REGISTER_BUSY_DELAY);
- }
-
- ERROR(rt2x00dev, "Indirect register access failed: "
- "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
- *reg = ~0;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
-
-bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue = rt2x00dev->rx;
- struct queue_entry *entry;
- struct queue_entry_priv_pci *entry_priv;
- struct skb_frame_desc *skbdesc;
- int max_rx = 16;
-
- while (--max_rx) {
- entry = rt2x00queue_get_entry(queue, Q_INDEX);
- entry_priv = entry->priv_data;
-
- if (rt2x00dev->ops->lib->get_entry_state(entry))
- break;
-
- /*
- * Fill in desc fields of the skb descriptor
- */
- skbdesc = get_skb_frame_desc(entry->skb);
- skbdesc->desc = entry_priv->desc;
- skbdesc->desc_len = entry->queue->desc_size;
-
- /*
- * DMA is already done, notify rt2x00lib that
- * it finished successfully.
- */
- rt2x00lib_dmastart(entry);
- rt2x00lib_dmadone(entry);
-
- /*
- * Send the frame to rt2x00lib for further processing.
- */
- rt2x00lib_rxdone(entry, GFP_ATOMIC);
- }
-
- return !max_rx;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
-
-void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
-{
- unsigned int i;
-
- for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
- msleep(10);
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
-
-/*
- * Device initialization handlers.
- */
-static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
-{
- struct queue_entry_priv_pci *entry_priv;
- void *addr;
- dma_addr_t dma;
- unsigned int i;
-
- /*
- * Allocate DMA memory for descriptor and buffer.
- */
- addr = dma_alloc_coherent(rt2x00dev->dev,
- queue->limit * queue->desc_size,
- &dma, GFP_KERNEL);
- if (!addr)
- return -ENOMEM;
-
- memset(addr, 0, queue->limit * queue->desc_size);
-
- /*
- * Initialize all queue entries to contain valid addresses.
- */
- for (i = 0; i < queue->limit; i++) {
- entry_priv = queue->entries[i].priv_data;
- entry_priv->desc = addr + i * queue->desc_size;
- entry_priv->desc_dma = dma + i * queue->desc_size;
- }
-
- return 0;
-}
-
-static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
- struct data_queue *queue)
-{
- struct queue_entry_priv_pci *entry_priv =
- queue->entries[0].priv_data;
-
- if (entry_priv->desc)
- dma_free_coherent(rt2x00dev->dev,
- queue->limit * queue->desc_size,
- entry_priv->desc, entry_priv->desc_dma);
- entry_priv->desc = NULL;
-}
-
-int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
- int status;
-
- /*
- * Allocate DMA
- */
- queue_for_each(rt2x00dev, queue) {
- status = rt2x00pci_alloc_queue_dma(rt2x00dev, queue);
- if (status)
- goto exit;
- }
-
- /*
- * Register interrupt handler.
- */
- status = request_irq(rt2x00dev->irq,
- rt2x00dev->ops->lib->irq_handler,
- IRQF_SHARED, rt2x00dev->name, rt2x00dev);
- if (status) {
- ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
- rt2x00dev->irq, status);
- goto exit;
- }
-
- return 0;
-
-exit:
- queue_for_each(rt2x00dev, queue)
- rt2x00pci_free_queue_dma(rt2x00dev, queue);
-
- return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_initialize);
-
-void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev)
-{
- struct data_queue *queue;
-
- /*
- * Free irq line.
- */
- free_irq(rt2x00dev->irq, rt2x00dev);
-
- /*
- * Free DMA
- */
- queue_for_each(rt2x00dev, queue)
- rt2x00pci_free_queue_dma(rt2x00dev, queue);
-}
-EXPORT_SYMBOL_GPL(rt2x00pci_uninitialize);
-
-/*
* PCI driver handlers.
*/
static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h
index e2c99f2..60d90b2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.h
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.h
@@ -36,94 +36,6 @@
#define PCI_DEVICE_DATA(__ops) .driver_data = (kernel_ulong_t)(__ops)
/*
- * Register access.
- */
-static inline void rt2x00pci_register_read(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- u32 *value)
-{
- *value = readl(rt2x00dev->csr.base + offset);
-}
-
-static inline void rt2x00pci_register_multiread(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- void *value, const u32 length)
-{
- memcpy_fromio(value, rt2x00dev->csr.base + offset, length);
-}
-
-static inline void rt2x00pci_register_write(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- u32 value)
-{
- writel(value, rt2x00dev->csr.base + offset);
-}
-
-static inline void rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- const void *value,
- const u32 length)
-{
- __iowrite32_copy(rt2x00dev->csr.base + offset, value, length >> 2);
-}
-
-/**
- * rt2x00pci_regbusy_read - Read from register with busy check
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- * @offset: Register offset
- * @field: Field to check if register is busy
- * @reg: Pointer to where register contents should be stored
- *
- * This function will read the given register, and checks if the
- * register is busy. If it is, it will sleep for a couple of
- * microseconds before reading the register again. If the register
- * is not read after a certain timeout, this function will return
- * FALSE.
- */
-int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
- const unsigned int offset,
- const struct rt2x00_field32 field,
- u32 *reg);
-
-/**
- * struct queue_entry_priv_pci: Per entry PCI specific information
- *
- * @desc: Pointer to device descriptor
- * @desc_dma: DMA pointer to &desc.
- * @data: Pointer to device's entry memory.
- * @data_dma: DMA pointer to &data.
- */
-struct queue_entry_priv_pci {
- __le32 *desc;
- dma_addr_t desc_dma;
-};
-
-/**
- * rt2x00pci_rxdone - Handle RX done events
- * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
- *
- * Returns true if there are still rx frames pending and false if all
- * pending rx frames were processed.
- */
-bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
-
-/**
- * rt2x00pci_flush_queue - Flush data queue
- * @queue: Data queue to stop
- * @drop: True to drop all pending frames.
- *
- * This will wait for a maximum of 100ms, waiting for the queues
- * to become empty.
- */
-void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
-
-/*
- * Device initialization handlers.
- */
-int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev);
-void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev);
-
-/*
* PCI driver handlers.
*/
int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index f95792c..9e3c8ff 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -35,6 +35,7 @@
#include <linux/eeprom_93cx6.h>
#include "rt2x00.h"
+#include "rt2x00mmio.h"
#include "rt2x00pci.h"
#include "rt61pci.h"
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 09d994d..482c70e 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -224,6 +224,7 @@ void cfg80211_conn_work(struct work_struct *work)
rtnl_lock();
cfg80211_lock_rdev(rdev);
mutex_lock(&rdev->devlist_mtx);
+ mutex_lock(&rdev->sched_scan_mtx);
list_for_each_entry(wdev, &rdev->wdev_list, list) {
wdev_lock(wdev);
@@ -248,6 +249,7 @@ void cfg80211_conn_work(struct work_struct *work)
wdev_unlock(wdev);
}
+ mutex_unlock(&rdev->sched_scan_mtx);
mutex_unlock(&rdev->devlist_mtx);
cfg80211_unlock_rdev(rdev);
rtnl_unlock();
--
John W. Linville Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ 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