An error occurred fetching the project authors.
  1. 20 Feb, 2014 3 commits
    • Johannes Berg's avatar
      mac80211: fix station wakeup powersave race · e3685e03
      Johannes Berg authored
      Consider the following (relatively unlikely) scenario:
       1) station goes to sleep while frames are buffered in driver
       2) driver blocks wakeup (until no more frames are buffered)
       3) station wakes up again
       4) driver unblocks wakeup
      
      In this case, the current mac80211 code will do the following:
       1) WLAN_STA_PS_STA set
       2) WLAN_STA_PS_DRIVER set
       3) - nothing -
       4) WLAN_STA_PS_DRIVER cleared
      
      As a result, no frames will be delivered to the client, even
      though it is awake, until it sends another frame to us that
      triggers ieee80211_sta_ps_deliver_wakeup() in sta_ps_end().
      
      Since we now take the PS spinlock, we can fix this while at
      the same time removing the complexity with the pending skb
      queue function. This was broken since my commit 50a9432d
      ("mac80211: fix powersaving clients races") due to removing
      the clearing of WLAN_STA_PS_STA in the RX path.
      
      While at it, fix a cleanup path issue when a station is
      removed while the driver is still blocking its wakeup.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      e3685e03
    • Johannes Berg's avatar
      mac80211: insert stations before adding to driver · 5108ca82
      Johannes Berg authored
      There's a race condition in mac80211 because we add stations
      to the internal lists after adding them to the driver, which
      means that (for example) the following can happen:
       1. a station connects and is added
       2. first, it is added to the driver
       3. then, it is added to the mac80211 lists
      
      If the station goes to sleep between steps 2 and 3, and the
      firmware/hardware records it as being asleep, mac80211 will
      never instruct the driver to wake it up again as it never
      realized it went to sleep since the RX path discarded the
      frame as a "spurious class 3 frame", no station entry was
      present yet.
      
      Fix this by adding the station in software first, and only
      then adding it to the driver. That way, any state that the
      driver changes will be reflected properly in mac80211's
      station state. The problematic part is the roll-back if the
      driver fails to add the station, in that case a bit more is
      needed. To not make that overly complex prevent starting BA
      sessions in the meantime.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      5108ca82
    • Emmanuel Grumbach's avatar
      mac80211: fix AP powersave TX vs. wakeup race · 1d147bfa
      Emmanuel Grumbach authored
      There is a race between the TX path and the STA wakeup: while
      a station is sleeping, mac80211 buffers frames until it wakes
      up, then the frames are transmitted. However, the RX and TX
      path are concurrent, so the packet indicating wakeup can be
      processed while a packet is being transmitted.
      
      This can lead to a situation where the buffered frames list
      is emptied on the one side, while a frame is being added on
      the other side, as the station is still seen as sleeping in
      the TX path.
      
      As a result, the newly added frame will not be send anytime
      soon. It might be sent much later (and out of order) when the
      station goes to sleep and wakes up the next time.
      
      Additionally, it can lead to the crash below.
      
      Fix all this by synchronising both paths with a new lock.
      Both path are not fastpath since they handle PS situations.
      
      In a later patch we'll remove the extra skb queue locks to
      reduce locking overhead.
      
      BUG: unable to handle kernel
      NULL pointer dereference at 000000b0
      IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
      *pde = 00000000
      Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
      EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
      EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
      EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
      ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
       DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
      CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
      DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
      DR6: ffff0ff0 DR7: 00000400
      Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
      iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
      Stack:
       e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
       ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
       ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
      Call Trace:
       [<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
       [<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
       [<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
       [<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
       [<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
       [<c149ef70>] dev_hard_start_xmit+0x450/0x950
       [<c14b9aa9>] sch_direct_xmit+0xa9/0x250
       [<c14b9c9b>] __qdisc_run+0x4b/0x150
       [<c149f732>] dev_queue_xmit+0x2c2/0xca0
      
      Cc: stable@vger.kernel.org
      Reported-by: default avatarYaara Rozenblum <yaara.rozenblum@intel.com>
      Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
      Reviewed-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
      [reword commit log, use a separate lock]
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      1d147bfa
  2. 10 Jan, 2014 3 commits
    • Johannes Berg's avatar
      mac80211: handle MMPDUs at EOSP correctly · b77cf4f8
      Johannes Berg authored
      If a uAPSD service period ends with an MMPDU, we currently just
      send that MMPDU, but it obviously won't get the EOSP bit set as
      it doesn't have a QoS header. This contradicts the standard, so
      add a QoS-nulldata frame after the MMPDU to properly terminate
      the service period with a frame that has EOSP set.
      
      Also fix a bug wrt. the TID for the MMPDU, it shouldn't be set
      to 0 unconditionally but use the actual TID that was assigned.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      b77cf4f8
    • Johannes Berg's avatar
      mac80211: release multiple ACs in uAPSD, fix more-data bug · f9f760b4
      Johannes Berg authored
      When a response for PS-Poll or a uAPSD trigger frame is sent, the
      more-data bit should be set according to 802.11-2012 11.2.1.5 h),
      meaning that it should indicate more data on the relevant ACs
      (delivery-enabled or nondelivery-enabled for uAPSD or PS-Poll.)
      
      In, for example, the following scenario:
       * 1 frame on VO queue (either in driver or in mac80211)
       * at least 1 frame on VI queue (in the driver)
       * both VO/VI are delivery-enabled
       * uAPSD trigger frame received
      
      The more-data flag to the driver would not be set, even though
      it should be.
      
      While fixing this, I noticed that we should really release frames
      from multiple ACs where there's data buffered in the driver for
      the corresponding TIDs.
      
      To address all this, restructure the code a bit to consider all
      ACs if we only release driver frames or only buffered frames.
      This also addresses the more-data bug described above as now the
      TIDs will all be marked as released, so the driver will have to
      check the number of frames.
      
      While at it, clarify some code and comments and remove the found
      variable, replacing it with the appropriate sw/hw release check.
      Reported-by: default avatarEliad Peller <eliad@wizery.com>
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      f9f760b4
    • Johannes Berg's avatar
      mac80211: fix PS-Poll driver release TID · 0a1cb809
      Johannes Berg authored
      Using ffs() for the PS-Poll release TID is wrong, it will cause
      frames to be released in order 0 1 2 3 4 5 6 7 instead of the
      correct 7 6 5 4 3 0 2 1. Fix this by adding a new function that
      implements "highest priority TID" properly.
      Reported-by: default avatarEliad Peller <eliad@wizery.com>
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      0a1cb809
  3. 06 Jan, 2014 2 commits
  4. 16 Dec, 2013 6 commits
    • Johannes Berg's avatar
      mac80211: optimise mixed AP/VLAN station removal · e716251d
      Johannes Berg authored
      Teach sta_info_flush() to optionally also remove stations
      from all VLANs associated with an AP interface to optimise
      the station removal (in particular, synchronize_net().)
      
      To not have to add the vlans argument throughout, do some
      refactoring.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      e716251d
    • Johannes Berg's avatar
      mac80211: optimise synchronize_net() for sta_info_flush · d778207b
      Johannes Berg authored
      There's no reason to have one synchronize_net() for each
      removed station, refactor the code slightly to have just
      a single synchronize_net() for all stations.
      
      Note that this is currently useless as hostapd removes
      stations one by one and this coalescing never happens.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      d778207b
    • Johannes Berg's avatar
      mac80211: move synchronize_net() before sta key removal · c8782078
      Johannes Berg authored
      There's no reason to do this inside the sta key removal
      since the keys can only be reached through the sta (and
      not by the driver at all) so once the sta can no longer
      be reached, the keys are safe.
      
      This will allow further optimisation opportunities with
      multiple stations.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      c8782078
    • Johannes Berg's avatar
      mac80211: don't delay station destruction · d34ba216
      Johannes Berg authored
      If we can assume that stations are never referenced by the
      driver after sta_state returns (and this is true since the
      previous iwlmvm patch and for all other drivers) then we
      don't need to delay station destruction, and don't need to
      play tricks with rcu_barrier() etc.
      
      This should speed up some scenarios like hostapd shutdown.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      d34ba216
    • Johannes Berg's avatar
      mac80211: move 4-addr sta pointer clearing before synchronize_rcu() · a710c816
      Johannes Berg authored
      The pointer should be cleared before synchronize_rcu() so that the
      consequently dead station won't be found by any lookups in the TX
      or RX paths.
      
      Also check that the station is actually the one being removed, the
      check is not needed because each 4-addr VLAN can only have a single
      station and non-4-addr VLANs always have a NULL pointer there, but
      the code is clearer this way (and we avoid the memory write.)
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      a710c816
    • Johannes Berg's avatar
      mac80211: add pre-RCU-sync sta removal driver operation · 6a9d1b91
      Johannes Berg authored
      Currently, mac80211 allows drivers to keep RCU-protected station
      references that are cleared when the station is removed from the
      driver and consequently needs to synchronize twice, once before
      removing the station from the driver (so it can guarantee that
      the station is no longer used in TX towards the driver) and once
      after the station is removed from the driver.
      
      Add a new pre-RCU-synchronisation station removal operation to
      the API to allow drivers to clear/invalidate their RCU-protected
      station pointers before the RCU synchronisation.
      
      This will allow removing the second synchronisation by changing
      the driver API so that the driver may no longer assume a valid
      RCU-protected pointer after sta_remove/sta_state returns.
      
      The alternative to this would be to synchronize_rcu() in all the
      drivers that currently rely on this behaviour (only iwlmvm) but
      that would defeat the purpose.
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      6a9d1b91
  5. 05 Dec, 2013 1 commit
  6. 02 Dec, 2013 1 commit
  7. 25 Nov, 2013 3 commits
  8. 28 Oct, 2013 1 commit
    • Emmanuel Grumbach's avatar
      mac80211: implement SMPS for AP · 687da132
      Emmanuel Grumbach authored
      When the driver requests to move to STATIC or DYNAMIC SMPS,
      we send an action frame to each associated station and
      reconfigure the channel context / driver.
      Of course, non-MIMO stations are ignored.
      
      The beacon isn't updated. The association response will
      include the original capabilities. Stations that associate
      while in non-OFF SMPS mode will get an action frame right
      after association to inform them about our current state.
      Note that we wait until the end of the EAPOL. Sending an
      action frame before the EAPOL is finished can be an issue
      for a few clients. Clients aren't likely to send EAPOL
      frames in MIMO anyway.
      
      When the SMPS configuration gets more permissive (e.g.
      STATIC -> OFF), we don't wake up stations that are asleep
      We remember that they don't know about the change and send
      the action frame when they wake up.
      
      When the SMPS configuration gets more restrictive (e.g.
      OFF -> STATIC), we set the TIM bit for every sleeping STA.
      uAPSD stations might send MIMO until they poll the action
      frame, but this is for a short period of time.
      Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
      [fix vht streams loop, initialisation]
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      687da132
  9. 24 Jun, 2013 1 commit
  10. 12 Jun, 2013 1 commit
  11. 04 Jun, 2013 1 commit
  12. 16 May, 2013 1 commit
  13. 11 Mar, 2013 2 commits
  14. 07 Mar, 2013 2 commits
  15. 06 Mar, 2013 3 commits
    • Johannes Berg's avatar
      mac80211: always synchronize_net() during station removal · 27a737ff
      Johannes Berg authored
      If there are keys left during station removal, then a
      synchronize_net() will be done (for each key, I have a
      patch to address this for 3.10), otherwise it won't be
      done at all which causes issues because the station
      could be used for TX while it's being removed from the
      driver -- that might confuse the driver.
      
      Fix this by always doing synchronize_net() if no key
      was present any more.
      
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      27a737ff
    • Thomas Pedersen's avatar
      mac80211: init mesh timer for user authed STAs · 87f59c70
      Thomas Pedersen authored
      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: default avatarThomas Pedersen <thomas@cozybit.com>
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      87f59c70
    • Johannes Berg's avatar
      mac80211: defer tailroom counter manipulation when roaming · 8d1f7ecd
      Johannes Berg authored
      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: default avatarJohannes Berg <johannes.berg@intel.com>
      8d1f7ecd
  16. 15 Feb, 2013 3 commits
  17. 11 Feb, 2013 1 commit
    • Thomas Pedersen's avatar
      mac80211: fix mesh sta teardown · 45b5028e
      Thomas Pedersen authored
      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: default avatarThomas Pedersen <thomas@cozybit.com>
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      45b5028e
  18. 04 Feb, 2013 1 commit
    • Marco Porsch's avatar
      mac80211: mesh power save basics · 3f52b7e3
      Marco Porsch authored
      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: default avatarMarco Porsch <marco@cozybit.com>
      Signed-off-by: default avatarIvan Bezyazychnyy <ivan.bezyazychnyy@gmail.com>
      Signed-off-by: default avatarMike Krinkin <krinkin.m.u@gmail.com>
      Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
      Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
      3f52b7e3
  19. 24 Jan, 2013 1 commit
  20. 03 Jan, 2013 3 commits