There is a corner case which wasn't being covered:
userspace may authenticate and allocate stations,
but still leave the peering up to the kernel.
Initialize the peering timer if the MPM is not in
userspace, in a path which is taken by both the kernel and
userspace when allocating stations.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
During roaming, the crypto_tx_tailroom_needed_cnt counter
will often take values 2,1,0,1,2 because first keys are
removed and then new keys are added. This is inefficient
because during the 0->1 transition, synchronize_net must
be called to avoid packet races, although typically no
packets would be flowing during that time.
To avoid that, defer the decrement (2->1, 1->0) when keys
are removed (by half a second). This means the counter
will really have the values 2,2,2,3,4 ... 2, thus never
reaching 0 and having to do the 0->1 transition.
Note that this patch entirely disregards the drivers for
which this optimisation was done to start with, for them
the key removal itself will be expensive because it has
to synchronize_net() after the counter is incremented to
remove the key from HW crypto. For them the sequence will
look like this: 0,1,0,1,0,1,0,1,0 (*) which is clearly a
lot more inefficient. This could be addressed separately,
during key removal the 0->1->0 sequence isn't necessary.
(*) it starts at 0 because HW crypto is on, then goes to
1 when HW crypto is disabled for a key, then back to
0 because the key is deleted; this happens for both
keys in the example. When new keys are added, it goes
to 1 first because they're added in software; when a
key is moved to hardware it goes back to 0
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Instead of modifying the HT SMPS capability field
for stations, track the SMPS mode explicitly in a
new field in the station struct and use it in the
drivers that care about it. This simplifies the
code using it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
There's no need to use _irqsave() as the lock
is never used in interrupt context.
This also fixes a problem in the iwlwifi MVM
driver that calls spin_unlock_bh() within its
set_tim() callback.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
In my commit 1672c0e319
("mac80211: start auth/assoc timeout on frame status")
I broke auth/assoc timeout handling: in case we wait
for the TX status, it now leaves the timeout field set
to 0, which is a valid time and can compare as being
before now ("jiffies"). Thus, if the work struct runs
for some other reason, the auth/assoc is treated as
having timed out.
Fix this by introducing a separate "timeout_started"
variable that tracks whether the timeout has started
and is checked before timing out.
Additionally, for proper TX status handling the change
requires that the skb->dev pointer is set up for all
the frames, so set it up for all frames in mac80211.
Reported-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
Tested-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The patch "mac80211: clean up mesh sta allocation warning"
moved some mesh initialization into a path which is only
called when the kernel handles peering. This causes a hang
when mac80211 tries to clean up a userspace-allocated
station entry and delete a timer which has never been
initialized.
To avoid this, only do any mesh sta peering teardown if
the kernel is actually handling it.
The same is true when quiescing before suspend.
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Add routines to
- maintain a PS mode for each peer and a non-peer PS mode
- indicate own PS mode in transmitted frames
- track neighbor STAs power modes
- buffer frames when neighbors are in PS mode
- add TIM and Awake Window IE to beacons
- release frames in Mesh Peer Service Periods
Add local_pm to sta_info to represent the link-specific power
mode at this station towards the remote station. When a peer
link is established, use the default power mode stored in mesh
config. Update the PS status if the peering status of a neighbor
changes.
Maintain a mesh power mode for non-peer mesh STAs. Set the
non-peer power mode to active mode during peering. Authenticated
mesh peering is currently not working when either node is
configured to be in power save mode.
Indicate the current power mode in transmitted frames. Use QoS
Nulls to indicate mesh power mode transitions.
For performance reasons, calls to the function setting the frame
flags are placed in HWMP routing routines, as there the STA
pointer is already available.
Add peer_pm to sta_info to represent the peer's link-specific
power mode towards the local station. Add nonpeer_pm to
represent the peer's power mode towards all non-peer stations.
Track power modes based on received frames.
Add the ps_data structure to ieee80211_if_mesh (for TIM map, PS
neighbor counter and group-addressed frame buffer).
Set WLAN_STA_PS flag for STA in PS mode to use the unicast frame
buffering routines in the tx path. Update num_sta_ps to buffer
and release group-addressed frames after DTIM beacons.
Announce the awake window duration in beacons if in light or
deep sleep mode towards any peer or non-peer. Create a TIM IE
similarly to AP mode and add it to mesh beacons. Parse received
Awake Window IEs and check TIM IEs for buffered frames.
Release frames towards peers in mesh Peer Service Periods. Use
the corresponding trigger frames and monitor the MPSP status.
Append a QoS Null as trigger frame if neccessary to properly end
the MPSP. Currently, in HT channels MPSPs behave imperfectly and
show large delay spikes and frame losses.
Signed-off-by: Marco Porsch <marco@cozybit.com>
Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
Signed-off-by: Mike Krinkin <krinkin.m.u@gmail.com>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This refactoring fixes a "scheduling while atomic" warning
when allocating a mesh station entry while holding the RCU
read lock. Fix this by creating a new function
mesh_sta_info_get(), which correctly handles the locking
and returns under RCU.
Also move some unnecessarily #ifdefed mesh station init
code from sta_info_alloc() to __mesh_sta_info_alloc().
Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
[change code flow to make sparse happy]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The initiator/tx doesn't really identify why an
aggregation session is stopped, give a reason
for stopping that more clearly identifies what's
going on. This will help tell the driver clearly
what is expected of it.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
If there are VLANs, stopping an AP is inefficient as it
calls rcu_barrier() once for each interface (the VLANs
and the AP itself). Optimise this by moving rcu_barrier()
out of the station cleanups and calling it only once for
all interfaces combined.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
The last fixes re-added the RCU synchronize penalty
on roaming to fix the races. Split up sta_info_flush()
now to get rid of that again, and let managed mode
(and only it) delay the actual destruction.
Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
When all interfaces have been removed, there can't
be any stations left over, so there's no need to
flush again. Remove this, and all code associated
with it, which also simplifies the function.
Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This is a very old bug, but there's nothing that prevents the
timer from running while the module is being removed when we
only do del_timer() instead of del_timer_sync().
The timer should normally not be running at this point, but
it's not clearly impossible (or we could just remove this.)
Cc: stable@vger.kernel.org
Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Unfortunately, commit b22cfcfcae, intended to speed up roaming
by avoiding the synchronize_rcu() broke AP/mesh modes as it moved
some code into that work item that will still call into the driver
at a time where it's no longer expected to handle this: after the
AP or mesh has been stopped.
To fix this problem remove the per-station work struct, maintain a
station cleanup list instead and flush this list when stations are
flushed. To keep this patch smaller for stable, do this when the
stations are flushed (sta_info_flush()). This unfortunately brings
back the original roaming delay; I'll fix that again in a separate
patch.
Also, Ben reported that the original commit could sometimes (with
many interfaces) cause long delays when an interface is set down,
due to blocking on flush_workqueue(). Since we now maintain the
cleanup list, this particular change of the original patch can be
reverted.
Cc: stable@vger.kernel.org [3.7]
Reported-by: Ben Greear <greearb@candelatech.com>
Tested-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Convert mac80211 (and where necessary, some drivers a
little bit) to the new channel definition struct.
This will allow extending mac80211 for VHT, which is
currently restricted to channel contexts since there
are no drivers using that which makes it easier. As
I also don't care about VHT for drivers not using the
channel context API, I won't convert the previous API
to VHT support.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Introduce IEEE80211_NUM_TIDS in the generic 802.11
header file and use it in place of STA_TID_NUM and
NUM_RX_DATA_QUEUES which are both really the number
of TIDs.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Fixes more wifi status skb leaks, leading to hostapd/wpa_supplicant hangs.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@vger.kernel.org
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
These are accessed without a lock when ending STA PSM. If the
sta_cleanup timer accesses these lists at the same time, we might crash.
This may fix some mysterious crashes we had during
ieee80211_sta_ps_deliver_wakeup.
Cc: stable@vger.kernel.org
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This patch prepares mac80211 for a later implementation of mesh or
ad-hoc powersave clients.
The structures related to powersave (buffer, TIM map, counters) are
moved from the AP-specific interface structure to a generic structure
that can be embedded into any interface type.
The functions related to powersave are prepared to allow easy
extension with different interface types. For example with:
+ } else if (sta->sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
+ ps = &sdata->u.mesh.ps;
Some references to the AP's beacon structure are removed where they
were obviously not used.
The patch compiles without warning and has been briefly tested as AP
interface with one client in PS mode.
Signed-off-by: Marco Porsch <marco.porsch@etit.tu-chemnitz.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
ieee80211_sta_expire will be called by both IBSS and mesh
interfaces to account for inactive stations, so it would be more
appropriate to use sta_dbg instead of ibss_dbg.
Signed-off-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Instead of operating on a single channel only,
use the new channel context infrastructure in
all mac80211 code.
This enables drivers that want to use the new
channel context infrastructure to use multiple
channels, while nothing should change for all
the other drivers that don't support it.
Right now this disables both TX power settings
and spatial multiplexing powersave. Both need
to be re-enabled on a channel context basis.
Additionally, when channel contexts are used
drop the connection when channel switch is
received rather than trying to handle it. This
will have to be improved later.
[With fixes from Eliad and Emmanuel incorporated]
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Free tx status skbs when draining power save buffers, pending frames, or
when tearing down a vif.
Fixes remaining conditions that can lead to hostapd/wpa_supplicant hangs when
running out of socket write memory.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Cc: stable@vger.kernel.org
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When a station is removed and we stop the aggregation
sessions, it's not useful to send delBA since this is
due to us or the station disassociating or dropping
the connection in some other way, so change that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
mac80211 calls synchronize_rcu() on sta deletion,
which increase the roaming time significantly.
Convert it into a call_rcu() mechanism, in order
to avoid blocking. Since some of the cleanup
functions might sleep, schedule from the call_rcu
callback a new work that will do the actual cleanup.
In order to make sure the cleanup occurs before
the interface went down, flush local->workqueue
on ieee80211_do_stop().
Signed-off-by: Yoni Divinsky <yoni.divinsky@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
There are a few things that make the logging and
debugging in mac80211 less useful than it should
be right now:
* a lot of messages should be pr_info, not pr_debug
* wholesale use of pr_debug makes it require *both*
Kconfig and dynamic configuration
* there are still a lot of ifdefs
* the style is very inconsistent, sometimes the
sdata->name is printed in front
Clean up everything, introducing new macros and
separating out the station MLME debugging into
a new Kconfig symbol.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Simplify the use of #ifdef CONFIG_MAC80211_IBSS_DEBUG/#endif
by adding a logging macro to encapsulate the test.
Convert the appropriate uses too.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Standardize the debugging to be able to use dynamic_debug.
Coalesce formats, align arguments.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
sta_info_cleanup locks the sta_list using rcu_read_lock however
the delete operation isn't rcu safe. A race between sta_info_cleanup
timer being called and a STA being removed can occur which leads
to a panic while traversing sta_list. Fix this by switching to the
RCU-safe versions.
Cc: stable@vger.kernel.org
Reported-by: Eyal Shapira <eyal@wizery.com>
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script:
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Moving a STA to an AP VLAN prevents num_mcast_sta from being decremented
once the STA leaves, because sta->sdata changes. Fix this by checking
for AP VLANs as well.
Also exclude 4-addr VLAN stations from num_mcast_sta - remote 4-addr
stations ignore 3-address multicast frames anyway. In a typical bridge
configuration they receive the same packets as 4-address unicast.
This patch also fixes clearing the sdata->u.vlan.sta pointer when the
STA is removed from a 4-addr VLAN.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
It is only used to test for BSS multicast receivers.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Because of the constant size and guaranteed 16 bit alignment, the inline
compare_ether_addr function is much cheaper than calling memcmp.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This renames the IEEE80211_TX_CTL_POLL_RESPONSE
TX flag to IEEE80211_TX_CTL_NO_PS_BUFFER and also
uses it for non-bufferable MMPDUs (all MMPDUs but
deauth, disassoc and action frames.)
Previously, mac80211 would let the MMPDU through
but not set the flag so drivers supporting some
hardware aids for avoiding the PS races would
then reject the frame.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The comment for sta_info_flush() states
"Returns the number of removed STA entries"
but that isn't actually true. Consequently,
the warning when a station is still around
on interface removal can never trigger and
this delayed finding the timer issue the
previous patch fixed. Fix the return value
here to make that warning useful again.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When not debugging mac80211 code, station state transitions do not need to
show up in the kernel log.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The dummy STA support was added because I didn't
want to change the driver API at the time. Now
that we have state transitions triggering station
add/remove in the driver, we only call add once a
station reaches ASSOCIATED, so we can remove the
dummy station stuff again.
While at it, tighten the RX check and accept only
port control (EAP) frames from the AP station if
it's not associated yet -- in other cases there's
no race.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Instead of maintaining separate sta_add/sta_remove
callsites, implement it in sta_state when the driver
has no sta_state implementation.
The only behavioural change this should cause is in
secure mesh mode: with this the station entries will
only be created after the stations are set to AUTH.
Given which drivers support mesh, this seems to not
be a problem.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
(based on Eliad's patch)
Add a callback to notify the low-level driver whenever
the state of a station changes. The driver is only
notified when the station is actually in the mac80211
hash table, not for pre-insert state transitions.
To allow the driver to replace sta_add/remove calls
with this, call extra transitions with the NOTEXIST
state.
This callback can fail, so we need to be careful in
handling it when a station is inserted, particularly
in the IBSS case where we still keep the station entry
around for mac80211 purposes.
Signed-off-by: Eliad Peller <eliad@wizery.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This will be used by drivers later if they
need to have stations inserted all the time,
in mac80211 has no purpose, is never used
and sta_state starts out in NONE.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Setting keys and updating TKIP keys must use the
BSS sdata (not AP_VLAN), so we translate. Move
the translation into driver-ops wrappers instead
of having it inline in the code to simplify the
normal code flow.
The same can be done for sta_add/remove which
already does the translation in the wrapper.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Unted the assumption that the sta struct is still accessible before the
synchronize_rcu call we should move the num_sta_ps counter decrement
after synchronize_rcu to avoid incorrect decrements if num_sta_ps.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
If the driver blocked this specific STA with the help of
ieee80211_sta_block_awake we won't clear WLAN_STA_PS_STA later but
still decrement num_sta_ps. Hence, the next data frame from this
STA will trigger ap_sta_ps_end again and also decrement num_sta_ps
again leading to an incorrect num_sta_ps counter.
This can result in problems with powersaving clients not waking up
from PS because the TIM calculation might be skipped due to the
incorrect num_sta_ps counter.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When WLAN_STA_PS_DRIVER is set by ieee80211_sta_block_awake the
num_sta_ps counter is not incremented. Hence, we shouldn't decrement
it in __sta_info_destroy if only WLAN_STA_PS_DRIVER is set. This
could result in an incorrect num_sta_ps counter leading to strange side
effects with associated powersaving clients.
Fix this by only decrementing num_sta_ps when WLAN_STA_PS_STA was set
before.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
In the future, when we start notifying drivers,
state transitions could potentially fail. To make
it easier to distinguish between programming bugs
and driver failures:
* rename sta_info_move_state() to
sta_info_pre_move_state() which can only be
called before the station is inserted (and
check this with a new station flag).
* rename sta_info_move_state_checked() to just
plain sta_info_move_state(), as it will be
the regular function that can fail for more
than just one reason (bad transition or an
error from the driver)
This makes the programming model easier -- one of
the functions can only be called before insertion
and can't fail, the other can fail.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
It seems exceedingly unlikely that we'll ever
support swapping rate control algorithms at
runtime, so remove the unused refcounting code.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Yogesh's patch to destroy aggregation sessions when
stations are destroyed was needed, but unnecessarily
complex. Clean up this code.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
All other code paths in sta_unblock synchronize with the network
softirq by using local_bh_disable/enable. Do the same around
ieee80211_sta_ps_deliver_wakeup.
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
commit a9b3cd7f32 (rcu: convert uses of rcu_assign_pointer(x, NULL) to
RCU_INIT_POINTER) did a lot of incorrect changes, since it did a
complete conversion of rcu_assign_pointer(x, y) to RCU_INIT_POINTER(x,
y).
We miss needed barriers, even on x86, when y is not NULL.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
CC: Stephen Hemminger <shemminger@vyatta.com>
CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
The IBSS merge code calls ieee80211_sta_expire() with a relatively
short expire timeout that purges other clients prematurely. The
expire function has to check that only the clients belonging to
the vif in question are purged.
Signed-off-by: Marek Lindner <lindner_marek@yahoo.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The commit 42624d4913
created following sparse warning
>net/mac80211/sta_info.c:965:24: warning: incorrect type in assignment (different address spaces)
>net/mac80211/sta_info.c:965:24: expected struct tid_ampdu_tx *tid_tx
>net/mac80211/sta_info.c:965:24: got struct tid_ampdu_tx [noderef] <asn:4>*<noident>
Making use of rcu_dereference_protected to fix the problem.
V2:
- Replacing rcu_dereference with rcu_dereference_protected
as suggested by Johannes.
- Adding mutex_lock/unlock to satisfy the condition at
rcu_dereference_protected
Cc: Nishant Sarmukadam <nishants@marvell.com>
Reported-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Now that IBSS no longer needs to insert stations
from atomic context, we can get rid of all the
special cases for that, and even get rid of the
sta_lock (though it needs to stay as tim_lock.)
This makes the station management code much more
straight-forward.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
In order to notify drivers and simplify the station
management code, defer IBSS station insertion to a
work item and don't do it directly while receiving
a frame.
This increases the complexity in IBSS a little bit,
but it's pretty straight forward and it allows us
to reduce the station management complexity (next
patch) considerably.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
No real changes, just note that they are const.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Currently, each AP interface will send multicast
traffic if any interface has a station entry even
if that station entry is allocated only. With the
new station state management we can easily fix it
by adding a counter that counts each authorized
station only and send multicast traffic only when
the correct interface has at least one authorized
station.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Station entries can have various states, the most
important ones being auth, assoc and authorized.
This patch prepares us for telling the driver about
these states, we don't want to confuse drivers with
strange transitions, so with this we enforce that
they move in the right order between them (back and
forth); some transitions might happen before the
driver even knows about the station, but at least
runtime transitions will be ordered correctly.
As a consequence, IBSS and MESH stations will now
have the ASSOC flag set (so they can transition to
AUTHORIZED), and we can get rid of a special case
in TX processing.
When freeing a station, unwind the state so that
other parts of the code (or drivers later) can rely
on the transitions.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When a station leaves suddenly while ampdu traffic to that station is still
running, there is a possibility that the ampdu pending queues are not freed due
to a race condition leading to memory leaks. In '__sta_info_destroy' when we
attempt to destroy the ampdu sessions in 'ieee80211_sta_tear_down_BA_sessions',
the driver calls 'ieee80211_stop_tx_ba_cb_irqsafe' to delete the ampdu
structures (tid_tx) and splice the pending queues and this job gets queued in
sdata workqueue. However, the sta entry can get destroyed before the above work
gets scheduled and hence the race.
Purging the queues and freeing the tid_tx to avoid the leak. The better solution
would be to fix the race, but that can be taken up in a separate patch.
Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This fixes frequent WARN_ONs when using AP VLAN + aggregation, as these vifs
are virtual and not registered with drivers.
Use sta_info_get_bss instead of sta_info_get in aggregation callbacks, so
that these callbacks can find the station entry when called with the AP vif.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Set IEEE80211_FCTL_MOREDATA bit also in case we have buffered
frames (more than one) only for one AC.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The queue mapping/TID for non-QoS null data
responses to is never set, making it default
to BK. Fix that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
iwlwifi has a separate EOSP notification from
the device, and to make use of that properly
it needs to be passed to mac80211. To be able
to mix with tx_status_irqsafe and rx_irqsafe
it also needs to be an "_irqsafe" version in
the sense that it goes through the tasklet,
the actual flag clearing would be IRQ-safe
but doing it directly would cause reordering
issues.
This is needed in the case of a P2P GO going
into an absence period without transmitting
any frames that should be driver-released as
in this case there's no other way to inform
mac80211 that the service period ended. Note
that for drivers that don't use the _irqsafe
functions another version of this function
will be required.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
iwlwifi needs to know the number of frames that are
going to be sent to a station while it is asleep so
it can properly handle the uCode blocking of that
station.
Before uAPSD, we got by by telling the device that
a single frame was going to be released whenever we
encountered IEEE80211_TX_CTL_POLL_RESPONSE. With
uAPSD, however, that is no longer possible since
there could be more than a single frame.
To support this model, add a new callback to notify
drivers when frames are going to be released.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The flaglock in struct sta_info has long been
something that I wanted to get rid of, this
finally does the conversion to atomic bitops.
The conversion itself is straight-forward in
most places, a few things needed to change a
bit since we can no longer use multiple bits
at the same time.
On x86-64, this is a fairly significant code
size reduction:
text data bss dec hex
427861 23648 1008 452517 6e7a5 before
425383 23648 976 450007 6ddd7 after
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
If a PS-poll frame is retried (but was received)
there is no way to detect that since it has no
sequence number. As a consequence, the standard
asks us to not react to PS-poll frames until the
response to one made it out (was ACKed or lost).
Implement this by using the WLAN_STA_SP flags to
also indicate a PS-Poll "service period" and the
IEEE80211_TX_STATUS_EOSP flag for the response
packet to indicate the end of the "SP" as usual.
We could use separate flags, but that will most
likely completely confuse drivers, and while the
standard doesn't exclude simultaneously polling
using uAPSD and PS-Poll, doing that seems quite
problematic.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
For PS-poll, there's a possible race between
us expiring a frame and the station polling
for it -- send it a null frame in that case.
For uAPSD, the standard says that we have to
send a frame in each SP, so send null if we
don't have any other frames.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Add uAPSD support to mac80211. This is probably not
possible with all devices, so advertising it with
the cfg80211 flag will be left up to drivers that
want it.
Due to my previous patches it is now a fairly
straight-forward extension. Drivers need to have
accurate TX status reporting for the EOSP frame.
For drivers that buffer themselves, the provided
APIs allow releasing the right number of frames,
but then drivers need to set EOSP and more-data
themselves. This is documented in more detail in
the new code itself.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
If there are frames for a station buffered in
the driver, mac80211 announces those in the TIM
IE but there's no way to release them. Add new
API to release such frames and use it when the
station polls for a frame.
Since the API will soon also be used for uAPSD
it is easily extensible.
Note that before this change drivers announcing
driver-buffered frames in the TIM bit actually
will respond to a PS-Poll with a potentially
lower priority frame (if there are any frames
buffered in mac80211), after this patch a driver
that hasn't been changed will no longer respond
at all. This only affects ath9k, which will need
to be fixed to implement the new API.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
For uAPSD support we'll need to have per-AC PS
buffers. As this is a major undertaking, split
the buffers before really adding support for
uAPSD. This already makes some reference to the
uapsd_queues variable, but for now that will
never be non-zero.
Since book-keeping is complicated, also change
the logic for keeping a maximum of frames only
and allow 64 frames per AC (up from 128 for a
station).
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
mac80211 will expire normal PS-buffered frames, but
if the device rejected some frames for a sleeping
station, these won't be on the ps_tx_buf queue but
on the tx_filtered queue instead; this is done to
avoid reordering.
However, mac80211 will not expire frames from the
filtered queue, let's fix that.
Also add a more comments to what all this expiry is
doing and how it works.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Currently, the TIM bit for a given station is set
and cleared all over the place. Since the logic to
set/clear it will become much more complex when we
add uAPSD support, as a first step let's collect
the entire logic in one place. This requires a few
small adjustments to other places.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
For uAPSD implementation, it is necessary to know on
which ACs frames are buffered. mac80211 obviously
knows about the frames it has buffered itself, but
with aggregation many drivers buffer frames. Thus,
mac80211 needs to be informed about this.
For now, since we don't have APSD in any form, this
will unconditionally set the TIM bit for the station
but later with uAPSD only some ACs might cause the
TIM bit to be set.
ath9k is the only driver using this API and I only
modify it in the most basic way, it won't be able
to implement uAPSD with this yet. But it can't do
that anyway since there's no way to selectively
release frames to the peer yet.
Since drivers will buffer frames per TID, let them
inform mac80211 on a per TID basis, mac80211 will
then sort out the AC mapping itself.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Juuso optimised the timer to not run all the
time in commit 3393a608c4.
However, after that it will still run once
more even if all frames just expired. Fixing
that also makes the function return value a
little clearer in the process.
Also, while at it, change the return value
to bool (instead of int).
Cc: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Since my commit 34e895075e
("mac80211: allow station add/remove to sleep") there is
a race in mac80211 when it clears the TIM bit because a
sleeping station disconnected, the spinlock isn't held
around the relevant code any more. Use the right API to
acquire the spinlock correctly.
Cc: stable@kernel.org [2.6.34+]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When associating to an AP, the station might miss the first EAP
packet that the AP sends due to a race condition between the association
success procedure and the rx flow in mac80211.
In such cases, the packet might fall in ieee80211_rx_h_check due to
the fact that the relevant rx->sta wasn't allocated yet.
Allocation of the relevant station info struct before actually
sending the association request and setting it with a new
dummy_sta flag solve this problem.
The station will accept only EAP packets from the AP while it
is in the pre-association/dummy state.
This dummy station entry is not seen by normal sta_info_get()
calls, only by sta_info_get_bss_rx().
The driver is not notified for the first insertion of the
dummy station. The driver is notified only after the association
is complete and the dummy flag is removed from the station entry.
That way, all the rest of the code flow should be untouched by
this change.
Signed-off-by: Guy Eilam <guy@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Divided the sta_info_insert_rcu function to 3 mini-functions:
sta_info_insert_check - the initial checks done when inserting
a new station
sta_info_insert_ibss - the function that handles the station
addition for IBSS interfaces
sta_info_insert_non_ibss - the function that handles the station
addition in other cases
The outer API was not changed.
The refactoring was done for better usage of the different
stages in the station addition in new scenarios added
in the next commit.
Signed-off-by: Guy Eilam <guy@wizery.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Add a comment pointing out the use of enum station_info_flags for
all new struct station_info fields. In addition, memset the sinfo
buffer to zero before use on all paths in the current tree to avoid
leaving uninitialized pointers in the data.
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
When assigning a NULL value to an RCU protected pointer, no barrier
is needed. The rcu_assign_pointer, used to handle that but will soon
change to not handle the special case.
Convert all rcu_assign_pointer of NULL value.
//smpl
@@ expression P; @@
- rcu_assign_pointer(P, NULL)
+ RCU_INIT_POINTER(P, NULL)
// </smpl>
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Since ca5ecddf (rcu: define __rcu address space modifier for sparse)
rcu_dereference_check use rcu_read_lock_held as a part of condition
automatically so callers do not have to do that as well.
Signed-off-by: Michal Hocko <mhocko@suse.cz>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
These definitions need to be exposed now that we can set the peer link
states via NL80211_ATTR_STA_PLINK_STATE. They were already being
(opaquely) reported by NL80211_STA_INFO_PLINK_STATE.
Signed-off-by: Javier Cardona <javier@cozybit.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This adds sparse RCU annotations to most of
mac80211, only the mesh code remains to be
done.
Due the the previous patches, the annotations
are pretty simple. The only thing that this
actually changes is removing the RCU usage of
key->sta in debugfs since this pointer isn't
actually an RCU-managed pointer (it only has
a single assignment done before the key even
goes live). As that is otherwise harmless, I
decided to make it part of this patch.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
The code here is only not racy because all the
places that assign the pointers it uses are
holding the sta_mtx as well as the key_mtx and
so can't race against this because this code
holds the sta_mtx. But that's not intuitive,
so fix it to hold the key_mtx.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
These warnings are exposed by gcc 4.6.
net/mac80211/sta_info.c: In function 'sta_info_cleanup_expire_buffered':
net/mac80211/sta_info.c:590:32: warning: variable 'sdata' set but not used
net/mac80211/ibss.c: In function 'ieee80211_rx_mgmt_auth_ibss':
net/mac80211/ibss.c:43:34: warning: variable 'status_code' set but not used
net/mac80211/work.c: In function 'ieee80211_send_assoc':
net/mac80211/work.c:203:9: warning: variable 'len' set but not used
net/mac80211/tx.c: In function '__ieee80211_parse_tx_radiotap':
net/mac80211/tx.c:1039:35: warning: variable 'sband' set but not used
net/mac80211/mesh.c: In function 'ieee80211_mesh_rx_queued_mgmt':
net/mac80211/mesh.c:616:28: warning: variable 'ifmsh' set but not used
...
Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This allows a driver to buffer frames for a PS station and tell mac80211
to wake it up even though mac80211 does not have any buffered frames for
it.
This is necessary for properly handling aggregation related buffering,
in ath9k, because the driver needs to keep its frames in order to keep
track of the Block-ACK window.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>