aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_hostap.c
Commit message (Collapse)AuthorAgeFilesLines
* net: clean up empty lines in .c and .h filesMateusz Guzik2020-09-011-3/+3
| | | | Notes: svn path=/head/; revision=365071
* [net80211] Migrate HT/legacy protection mode and preamble calculation to ↵Adrian Chadd2020-07-011-10/+14
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | per-VAP flags The later firmware devices (including iwn!) support multiple configuration contexts for a lot of things, leaving it up to the firmware to decide which channel and vap is active. This allows for things like off-channel p2p sta/ap operation and other weird things. However, net80211 is still focused on a "net80211 drives all" when it comes to driving the NIC, and as part of this history a lot of these options are global and not per-VAP. This is fine when net80211 drives things and all VAPs share a single channel - these parameters importantly really reflect the state of the channel! - but it will increasingly be not fine when we start supporting more weird configurations and more recent NICs. Yeah, recent like iwn/iwm. Anyway - so, migrate all of the HT protection, legacy protection and preamble stuff to be per-VAP. The global flags are still there; they're now calculated in a deferred taskqueue that mirrors the old behaviour. Firmware based drivers which have per-VAP configuration of these parameters can now just listen to the per-VAP options. What do I mean by per-channel? Well, the above configuration parameters really are about interoperation with other devices on the same channel. Eg, HT protection mode will flip to legacy/mixed if it hears ANY BSS that supports non-HT stations or indicates it has non-HT stations associated. So, these flags really should be per-channel rather than per-VAP, and then for things like "do i need short preamble or long preamble?" turn into a "do I need it for this current operating channel". Then any VAP using it can query the channel that it's on, reflecting the real required state. This patch does none of the above paragraph just yet. I'm also cheating a bit - I'm currently not using separate taskqueues for the beacon updates and the per-VAP configuration updates. I can always further split it later if I need to but I didn't think it was SUPER important here. So: * Create vap taskqueue entries for ERP/protection, HT protection and short/long preamble; * Migrate the HT station count, short/long slot station count, etc - into per-VAP variables rather than global; * Fix a bug with my WME work from a while ago which made it per-VAP - do the WME beacon update /after/ the WME update taskqueue runs, not before; * Any time the HT protmode configuration changes or the ERP protection mode config changes - schedule the task, which will call the driver without the net80211 lock held and all correctly serialised; * Use the global flags for beacon IEs and VAP flags for probe responses and other IE situations. The primary consumer of this is ath10k. iwn could use it when sending RXON, but we don't support IBSS or AP modes on it yet, and I'm not yet sure whether it's required in STA mode (ie whether the firmware parses beacons to change protection mode or whether we need to.) Tested: * AR9280, STA/AP * AR9380, DWDS STA+STA/AP * ath10k work, STA/AP * Intel 6235, STA * Various rtwn / run NICs, DWDS STA and STA configurations Notes: svn path=/head/; revision=362815
* [net80211] Add initial U-APSD negotiation support.Adrian Chadd2020-06-161-1/+13
| | | | | | | | | | | | | | | | | | | | | | | | U-APSD (unscheduled automatic power save delivery) is a power save method that's a bit better than legacy PS-POLL - stations can mark frames with an extra flag that tells the AP to leak out more frames after it sends its own frames rather than needing to send a PS-POLL to get another frame from the AP. Now, this code just handles the negotiation bits; it doesn't actually implement U-APSD. That's up to drivers, and nothing in the tree yet implements this. I /may/ implement this for ath(4) if I eventually care enough but right now I plan on just implementing it for firmware offload based NICs that handle this in the NIC. I'll commit the ifconfig bit after this and I may have some follow-up commits as this gets used more by me in local testing. This should be a glorious no-op for everyone else. If things change for anyone that isn't fixed by a complete recompile then please reach out to me. Notes: svn path=/head/; revision=362210
* net80211(4): hide casts for 'i_seq' field offset calculation insideAndriy Voskoboinyk2019-02-101-5/+3
| | | | | | | | | | | ieee80211_getqos() and reuse it in various places. Checked with RTL8188EE, HOSTAP mode + RTL8188CUS, STA mode. MFC after: 2 weeks Notes: svn path=/head/; revision=343990
* sys: general adoption of SPDX licensing ID tags.Pedro F. Giffuni2017-11-271-0/+2
| | | | | | | | | | | | | | | | | Mainly focus on files that use BSD 2-Clause license, however the tool I was using misidentified many licenses so this was mostly a manual - error prone - task. The Software Package Data Exchange (SPDX) group provides a specification to make it easier for automated tools to detect and summarize well known opensource licenses. We are gradually adopting the specification, noting that the tags are considered only advisory and do not, in any way, superceed or replace the license texts. No functional change intended. Notes: svn path=/head/; revision=326272
* [net80211] prepare for A-MSDU/A-MPDU offload crypto / sequence number checking.Adrian Chadd2017-05-201-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | When doing AMSDU offload, the driver (for now!) presents 802.11 frames with the same sequence number and crypto sequence number / IV values up to the stack. But, this will trip afoul over the sequence number detection. So drivers now have a way to signify that a frame is part of an offloaded AMSDU group, so we can just ensure that we pass those frames up to the stack. The logic will be a bit messy - the TL;DR will be that if it's part of the previously seen sequence number then it belongs in the same burst. But if we get a repeat of the same sequence number (eg we sent an ACK but the receiver didn't hear it) then we shouldn't be passing those frames up. So, we can't just say "all subframes go up", we need to track whether we've seen the end of a burst of frames for the given sequence number or not, so we know whether to actually pass them up or not. The first part of doing all of this is to ensure the ieee80211_rx_stats struct is available in the RX sequence number check path and the RX ampdu reorder path. So, start by passing the pointer into these functions to avoid doing another lookup. The actual support will come in a subsequent commit once I know the functionality actually works! Notes: svn path=/head/; revision=318566
* [net80211] validate VHT IEs.Adrian Chadd2017-02-201-1/+11
| | | | Notes: svn path=/head/; revision=313986
* [net80211] fix up VHT IE comparison typoAdrian Chadd2017-02-201-1/+3
| | | | | | | Whilst here, add a comment that I need to validate VHT IEs. Notes: svn path=/head/; revision=313984
* [net80211] fix NULL pointer dereference in VHT operation in hostap mode.Adrian Chadd2017-02-201-1/+3
| | | | | | | | | | | | The vht IEs are NULL at this point, so we shouldn't upgrade a node to VHT. I'll fix the upgrade after this! Tested: * ath10k, hostap mode Notes: svn path=/head/; revision=313983
* [net80211] Initial VHT node upgrade/downgrade support and initial IE parsing.Adrian Chadd2017-01-131-0/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is the bulk of the magic to start enabling VHT channel negotiation. It is absolutely, positively not yet even a complete VHT wave-1 implementation. * parse IEs in scan, assoc req/resp, probe req/resp; * break apart the channel upgrade from the HT IE parsing - do it after the VHT IEs are parsed; * (dirty! sigh) add channel width decision making in ieee80211_ht.c htinfo_update_chw(). This is the main bit where negotiated channel promotion through IEs occur. * Shoehorn in VHT node init ,teardown, rate control, etc calls like the HT versions; * Do VHT channel adjustment where appropriate Tested: * monitor mode, ath10k port * STA mode, ath10k port - VHT20, VHT40, VHT80 modes TODO: * IBSS; * hostap; * (ignore mesh, wds for now); * finish 11n state engine - channel width change, opmode notifications, SMPS, etc; * VHT basic rate negotiation and acceptance criteria when scanning, associating, etc; * VHT control/management frame handling (group managment and operating mode being the two big ones); * Verify TX/RX VHT rate negotiation is actually working correctly. Whilst here, add some comments about seqno allocation and locking. To achieve the full VHT rates I need to push seqno allocation into the drivers and finally remove the IEEE80211_TX_LOCK() I added years ago to fix issues. :/ Notes: svn path=/head/; revision=312015
* [net80211] handle hardware encryption offload in the receive pathAdrian Chadd2016-11-191-6/+17
| | | | | | | | | | | | | | | | | | | * teach the crypto modules about receive offload - although I have to do some further reviewing in places where we /can't/ have an RX key * teach the RX data path about receive offload encryption - check the flag, handle NULL key, do decap and checking as appropriate. Tested: * iwn(4), STA mode * ath(4), STA and AP mode * ath10k port, STA mode (hardware encryption) Reviewed by: avos Differential Revision: https://reviews.freebsd.org/D8533 Notes: svn path=/head/; revision=308823
* net80211: switch from ieee80211_iterate_nodes() toAndriy Voskoboinyk2016-11-141-10/+12
| | | | | | | | ieee80211_iterate_nodes_vap() where possible; this should make the code a bit cleaner. Notes: svn path=/head/; revision=308656
* net80211: improve error checking in ieee80211_parse_{wpa,rsn}()Andriy Voskoboinyk2016-09-131-28/+100
| | | | | | | | | | | | | | | | | - Add few checks for group/pairwise ciphers into ieee80211_parse_{wpa,rsn}(). - Split error code and cipher value in wpa_cipher() / rsn_cipher(); current hack with (1 << 32) does not work - it's 1, not 0 (detected by CSA). - Return IEEE80211_REASON_UNSUPP_RSN_IE_VERSION instead of IEEE80211_REASON_IE_INVALID when version field is not equal to RSN_VERSION. Tested with wpi(4) / urtwn(4) (HOSTAP mode). Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D7887 Notes: svn path=/head/; revision=305785
* net80211: fix duplicate packet counter incrementation.Andriy Voskoboinyk2016-06-091-2/+2
| | | | | | | | | | | Remove 'if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);' from raw xmit and apbridge path; it will be incremented by ieee80211_tx_complete() after packet transmission. Noticed by: Imre Vadasz <imre@vdsz.com> Notes: svn path=/head/; revision=301722
* net80211: fix more compiler warnings.Andriy Voskoboinyk2016-05-191-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ieee80211.c: add_chanlist(): 'error' variable will be uninitialized if no channels were passed; return '0' instead. ieee80211_action.c: ieee80211_send_action_register(): drop 'break' after 'return'. ieee80211_crypto_none.c: none_encap(): 'keyid' is not used in non-debug builds; hide it behind IEEE80211_DEBUG ifdef. ieee80211_freebsd.c: Staticize global 'ieee80211_debug' variable (used only in this file). ieee80211_hostap.c: Fix a comment (associatio -> association). ieee80211_ht.c: ieee80211_setup_htrates(): initialize 'maxunequalmcs' to 0 to mute compiler warning. ieee80211_hwmp.c: hwmp_recv_preq(): copy 'prep' between conditional blocks to fix -Wshadow warning. ieee80211_mesh.c: mesh_newstate(): remove duplicate 'ni' definition. mesh_recv_group_data(): fix -Wempty-body warning in non-debug builds. ieee80211_phy.c: ieee80211_compute_duration(): remove 'break' after panic() call. ieee80211_scan_sta.c: Hide some TDMA-specific macros under IEEE80211_SUPPORT_TDMA ifdef adhoc_pick_bss(): remove 'ic' pointer redefinition. ieee80211_sta.c: sta_beacon_miss(): remove 'ic' pointer redefinition. ieee80211_superg.c: superg_ioctl_set80211(): drop unreachable return. Tested with clang 3.8.0, gcc 4.6.4 and gcc 5.3.0. Notes: svn path=/head/; revision=300232
* net80211: drop some unused variables / local macrosAndriy Voskoboinyk2016-05-121-11/+2
| | | | | | | | | | Most of them left after some commits (r178354, r191544, r287197 etc.); some were never used. Found by: Clang Static Analyzer Notes: svn path=/head/; revision=299575
* sys/net*: minor spelling fixes.Pedro F. Giffuni2016-05-031-1/+1
| | | | | | | No functional change. Notes: svn path=/head/; revision=298995
* net80211: hide subtype mask & shift in function call.Andriy Voskoboinyk2016-04-201-4/+2
| | | | | | | | | | | | | Hide subtype mask/shift (which is used for index calculation in ieee80211_mgt_subtype_name[] array) in function call. Tested with RTL8188CUS, STA mode. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D5369 Notes: svn path=/head/; revision=298376
* net80211: provide descriptions for reason codesAndriy Voskoboinyk2016-04-201-2/+4
| | | | | | | | | | | | Add text description for deauth/disassoc/etc reason codes in addition to 'reason: <number>' string. Reviewed by: adrian Obtained from: IEEE Std 802.11-2012, 8.4.1.7 "Reason Code field" Differential Revision: https://reviews.freebsd.org/D5367 Notes: svn path=/head/; revision=298364
* net80211 (trivial, noop): remove duplicate check from hostap_recv_mgmt()Andriy Voskoboinyk2016-04-201-5/+6
| | | | | | | Differential Revision: https://reviews.freebsd.org/D5483 Notes: svn path=/head/; revision=298360
* net80211: replace internal LE_READ_*/LE_WRITE_* macro with systemAndriy Voskoboinyk2016-04-201-12/+12
| | | | | | | | | | | | | | | | | | | | le*dec / le*enc functions. Replace net80211 specific macros with system-wide bytestream encoding/decoding functions: - LE_READ_2 -> le16dec - LE_READ_4 -> le32dec - LE_WRITE_2 -> le16enc - LE_WRITE_4 -> le32enc + drop ieee80211_input.h include, where it was included for these operations only. Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D6030 Notes: svn path=/head/; revision=298359
* [net80211] missed commit from last one - always cleanup superg state.Adrian Chadd2016-04-061-2/+6
| | | | Notes: svn path=/head/; revision=297604
* net80211: eliminate copy-paste nearby ieee80211_check_rxseq()Andriy Voskoboinyk2016-03-011-18/+1
| | | | | | | | Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D4043 Notes: svn path=/head/; revision=296254
* net80211: add few missing subtype names.Andriy Voskoboinyk2016-02-191-0/+1
| | | | | | | | | | | | | | - Add definitions for Timing Advertisement and Control Wrapper frames. - Refresh ieee80211_mgt_subtype_name and ieee80211_ctl_subtype_name arrays. - Count Timing Advertisement frames as discarded management frames in all modes. Approved by: adrian (mentor) Differential Revision: https://reviews.freebsd.org/D5331 Notes: svn path=/head/; revision=295795
* net80211: free node reference in the ieee80211_parent_xmitpkt() when error ↵Adrian Chadd2015-10-121-3/+2
| | | | | | | | | | | | | happened. Move error handling into ieee80211_parent_xmitpkt() instead of spreading it between functions. Submitted by: <s3erios@gmail.com> Differential Revision: https://reviews.freebsd.org/D3772 Notes: svn path=/head/; revision=289164
* Cleanup compat shims for FreeBSD versions that predate 10.0-RELEASE.Gleb Smirnoff2015-05-251-4/+0
| | | | | | | | | There are no plans to merge anything save a trivial bugfix to stable/9. Discussed with: adrian Notes: svn path=/head/; revision=283541
* Convert malloc/free back to #define's, as part of OS portability work.Adrian Chadd2015-05-251-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | DragonflyBSD uses the FreeBSD wireless stack and drivers. Their malloc() API is named differently, so they don't have userland/kernel symbol clashes like we do (think libuinet.) So, to make it easier for them and to port to other BSDs/other operating systems, start hiding the malloc specific bits behind defines in ieee80211_freebsd.h. DragonflyBSD can now put these portability defines in their local ieee80211_dragonflybsd.h. This should be a great big no-op for everyone running wifi. TODO: * kill M_WAITOK - some platforms just don't want you to use it * .. and/or handle it returning NULL rather than waiting forever. * MALLOC_DEFINE() ? * Migrate the well-known malloc names (eg M_TEMP) to net80211 namespace defines. Notes: svn path=/head/; revision=283538
* Begin plumbing ieee80211_rx_stats through the receive path.Adrian Chadd2015-05-251-5/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Smart NICs with firmware (eg wpi, iwn, the new atheros parts, the intel 7260 series, etc) support doing a lot of things in firmware. This includes but isn't limited to things like scanning, sending probe requests and receiving probe responses. However, net80211 doesn't know about any of this - it still drives the whole scan/probe infrastructure itself. In order to move towards suppoting smart NICs, the receive path needs to know about the channel/details for each received packet. In at least the iwn and 7260 firmware (and I believe wpi, but I haven't tried it yet) it will do the scanning, power-save and off-channel buffering for you - all you need to do is handle receiving beacons and probe responses on channels that aren't what you're currently on. However the whole receive path is peppered with ic->ic_curchan and manual scan/powersave handling. The beacon parsing code also checks ic->ic_curchan to determine if the received beacon is on the correct channel or not.[1] So: * add freq/ieee values to ieee80211_rx_stats; * change ieee80211_parse_beacon() to accept the 'current' channel as an argument; * modify the iv_input() and iv_recv_mgmt() methods to include the rx_stats; * add a new method - ieee80211_lookup_channel_rxstats() - that looks up a channel based on the contents of ieee80211_rx_stats; * if it exists, use it in the mgmt path to switch the current channel (which still defaults to ic->ic_curchan) over to something determined by rx_stats. This is enough to kick-start scan offload support in the Intel 7260 driver that Rui/I are working on. It also is a good start for scan offload support for a handful of existing NICs (wpi, iwn, some USB parts) and it'll very likely dramatically improve stability/performance there. It's not the whole thing - notably, we don't need to do powersave, we should not scan all channels, and we should leave probe request sending to the firmware and not do it ourselves. But, this allows for continued development on the above features whilst actually having a somewhat working NIC. TODO: * Finish tidying up how the net80211 input path works. Right now ieee80211_input / ieee80211_input_all act as the top-level that everything feeds into; it should change so the MIMO input routines are those and the legacy routines are phased out. * The band selection should be done by the driver, not by the net80211 layer. * ieee80211_lookup_channel_rxstats() only determines 11b or 11g channels for now - this is enough for scanning, but not 100% true in all cases. If we ever need to handle off-channel scan support for things like static-40MHz or static-80MHz, or turbo-G, or half/quarter rates, then we should extend this. [1] This is a side effect of frequency-hopping and CCK modes - you can receive beacons when you think you're on a different channel. In particular, CCK (which is used by the low 11b rates, eg beacons!) is decodable from adjacent channels - just at a low SNR. FH is a side effect of having the hardware/firmware do the frequency hopping - it may pick up beacons transmitted from other FH networks that are in a different phase of hopping frequencies. Notes: svn path=/head/; revision=283535
* Do not check sequence number for QoS Null frames; set it for generated QoS NullAdrian Chadd2015-05-121-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | frames to 0 From IEEE Std. 802.11-2012, 8.3.2.1 "Data frame format", p. 415 (513): "The Sequence Control field for QoS (+)Null frames is ignored by the receiver upon reception." At this moment, any <mode>_input() function interprets them as regular QoS data frames with TID = 0. As a result, stations, that use another TX sequence for QoS Null frames (e.g. wpi(4), where (QoS) Null frames are generated by the firmware), may experience significant packet loss with any other NIC in hostap mode. Tested: * wpi(4) (author) * iwn(4) - Intel 5100, STA mode (me) PR: kern/200128 Submitted by: Andriy Voskoboinyk <s3erios@gmail.com> Notes: svn path=/head/; revision=282820
* Prepare for supporting driver-overridden curchan when submitting scanAdrian Chadd2015-05-101-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | results. Right now the scan infrastructure assumes the channel is under net80211 control, and that when receiving beacon frames for scanning, the current channel is indeed what ic_curchan is set to. But firmware NICs with firmware scan support need more than this - they can do background scans whilst hiding the off-channel behaviour from net80211. Ie, net80211 still thinks everything is associated and on the main channel, but it's getting scan results from all the background traffic. However sta_add() pays attention to ic_curchan and discards scan results that aren't on the right channel. CCK beacon frames can be decoded from adjacent channels so the receive path and sta_add discard these as appropriate. This is fine for software scanning like for ath(4), but not for firmware NICs. So with those, the whole concept of background firmware scanning won't work without major hacks (eg, overriding ic_curchan before calling the beacon input / scan add.) As part of my scan overhaul, modify sta_add() and the scan_add() APIs to take an explicit current channel. The normal RX path will set it to ic_curchan so it's a no-op. However, drivers may decide to (eventually!) override the scan method to set the "right" current channel based on what the firmware reports the scan state is. So for example, iwn, rsu and other NICs will eventually do this: * driver issues scan start firmware command; * firmware sends a "scan start on channel X" notify; * firmware sends a bunch of beacon RX's as part of the scan results; * .. and the driver will replace scan_add() curchan with channel X, so scan results are correct. * firmware sends a "scan start on channel Y" notify; * firmware sends more beacons... * .. the driver replaces scan_add() curchan with channel Y. Note: * Eventually, net80211 should eventually grow the idea of a per-packet current channel. It's possible in various modes (eg WAVE, P2P, etc) that individual frames can come in from different channels and that is under firmware control rather than driver/net80211 control, so we should support that. Notes: svn path=/head/; revision=282742
* Mechanically convert to if_inc_counter().Gleb Smirnoff2014-09-191-4/+4
| | | | Notes: svn path=/head/; revision=271861
* Rename definition of IEEE80211_FC1_WEP to IEEE80211_FC1_PROTECTED.Kevin Lo2014-01-081-4/+4
| | | | | | | | | | | | | | The origin of WEP comes from IEEE Std 802.11-1997 where it defines whether the frame body of MAC frame has been encrypted using WEP algorithm or not. IEEE Std. 802.11-2007 changes WEP to Protected Frame, indicates whether the frame is protected by a cryptographic encapsulation algorithm. Reviewed by: adrian, rpaulo Notes: svn path=/head/; revision=260444
* The r48589 promised to remove implicit inclusion of if_var.h soon. PrepareGleb Smirnoff2013-10-261-0/+1
| | | | | | | | | | | to this event, adding if_var.h to files that do need it. Also, include all includes that now are included due to implicit pollution via if_var.h Sponsored by: Netflix Sponsored by: Nginx, Inc. Notes: svn path=/head/; revision=257176
* Add in some backwards compatability hacks to make -HEAD net80211 compileAdrian Chadd2013-08-221-0/+4
| | | | | | | on -9. Notes: svn path=/head/; revision=254640
* Add m_clrprotoflags() to clear protocol specific mbuf flags at up andAndre Oppermann2013-08-191-1/+2
| | | | | | | | | | | downwards layer crossings. Consistently use it within IP, IPv6 and ethernet protocols. Discussed with: trociny, glebius Notes: svn path=/head/; revision=254523
* Convert net80211 over to using if_transmit for the dispatch from theAdrian Chadd2013-08-081-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | upper layer(s). This eliminates the if_snd queue from net80211. Yay! This unfortunately has a few side effects: * It breaks ALTQ to net80211 for now - sorry everyone, but fixing parallelism and eliminating the if_snd queue is more important than supporting this broken traffic scheduling model. :-) * There's no VAP and IC flush methods just yet - I think I'll add some NULL methods for now just as placeholders. * It reduces throughput a little because now net80211 will drop packets rather than buffer them if the driver doesn't do its own buffering. This will be addressed in the future as I implement per-node software queues. Tested: * ath(4) and iwn(4) in STA operation Notes: svn path=/head/; revision=254082
* Bring over my initial work from the net80211 TX locking branch.Adrian Chadd2013-03-081-17/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patchset implements a new TX lock, covering both the per-VAP (and thus per-node) TX locking and the serialisation through to the underlying physical device. This implements the hard requirement that frames to the underlying physical device are scheduled to the underlying device in the same order that they are processed at the VAP layer. This includes adding extra encapsulation state (such as sequence numbers and CCMP IV numbers.) Any order mismatch here will result in dropped packets at the receiver. There are multiple transmit contexts from the upper protocol layers as well as the "raw" interface via the management and BPF transmit paths. All of these need to be correctly serialised or bad behaviour will result under load. The specifics: * add a new TX IC lock - it will eventually just be used for serialisation to the underlying physical device but for now it's used for both the VAP encapsulation/serialisation and the physical device dispatch. This lock is specifically non-recursive. * Methodize the parent transmit, vap transmit and ic_raw_xmit function pointers; use lock assertions in the parent/vap transmit routines. * Add a lock assertion in ieee80211_encap() - the TX lock must be held here to guarantee sensible behaviour. * Refactor out the packet sending code from ieee80211_start() - now ieee80211_start() is just a loop over the ifnet queue and it dispatches each VAP packet send through ieee80211_start_pkt(). Yes, I will likely rename ieee80211_start_pkt() to something that better reflects its status as a VAP packet transmit path. More on that later. * Add locking around the management and BAR TX sending - to ensure that encapsulation and TX are done hand-in-hand. * Add locking in the mesh code - again, to ensure that encapsulation and mesh transmit are done hand-in-hand. * Add locking around the power save queue and ageq handling, when dispatching to the parent interface. * Add locking around the WDS handoff. * Add a note in the mesh dispatch code that the TX path needs to be re-thought-out - right now it's doing a direct parent device transmit rather than going via the vap layer. It may "work", but it's likely incorrect (as it bypasses any possible per-node power save and aggregation handling.) Why not a per-VAP or per-node lock? Because in order to ensure per-VAP ordering, we'd have to hold the VAP lock across parent->if_transmit(). There are a few problems with this: * There's some state being setup during each driver transmit - specifically, the encryption encap / CCMP IV setup. That should eventually be dragged back into the encapsulation phase but for now it lives in the driver TX path. This should be locked. * Two drivers (ath, iwn) re-use the node->ni_txseqs array in order to allocate sequence numbers when doing transmit aggregation. This should also be locked. * Drivers may have multiple frames queued already - so when one calls if_transmit(), it may end up dispatching multiple frames for different VAPs/nodes, each needing a different lock when handling that particular end destination. So to be "correct" locking-wise, we'd end up needing to grab a VAP or node lock inside the driver TX path when setting up crypto / AMPDU sequence numbers, and we may already _have_ a TX lock held - mostly for the same destination vap/node, but sometimes it'll be for others. That could lead to LORs and thus deadlocks. So for now, I'm sticking with an IC TX lock. It has the advantage of papering over the above and it also has the added advantage that I can assert that it's being held when doing a parent device transmit. I'll look at splitting the locks out a bit more later on. General outstanding net80211 TX path issues / TODO: * Look into separating out the VAP serialisation and the IC handoff. It's going to be tricky as parent->if_transmit() doesn't give me the opportunity to split queuing from driver dispatch. See above. * Work with monthadar to fix up the mesh transmit path so it doesn't go via the parent interface when retransmitting frames. * Push the encryption handling back into the driver, if it's at all architectually sane to do so. I know it's possible - it's what mac80211 in Linux does. * Make ieee80211_raw_xmit() queue a frame into VAP or parent queue rather than doing a short-cut direct into the driver. There are QoS issues here - you do want your management frames to be encapsulated and pushed onto the stack sooner than the (large, bursty) amount of data frames that are queued. But there has to be a saner way to do this. * Fragments are still broken - drivers need to be upgraded to an if_transmit() implementation and then fragmentation handling needs to be properly fixed. Tested: * STA - AR5416, AR9280, Intel 5300 abgn wifi * Hostap - AR5416, AR9160, AR9280 * Mesh - some testing by monthadar@, more to come. Notes: svn path=/head/; revision=248069
* Handle ps-poll data frame if_transmit() failure.Adrian Chadd2013-01-061-1/+15
| | | | | | | | | | | | | | | If the data frame transmission failures, it may have a node reference that needs cleaning up. If the frame is marked as M_ENCAP then it should treat recvif as a node reference and clear it. Now - since the mbuf has been freed by calling if_transmit() (even on failure), the mbuf has to be treated as invalid. Hence why the ifp is used. Notes: svn path=/head/; revision=245098
* Remove a use of if_start() - instead, use if_transmit() to dispatch theAdrian Chadd2012-12-221-2/+1
| | | | | | | frame. Notes: svn path=/head/; revision=244576
* Mechanically substitute flags from historic mbuf allocator withGleb Smirnoff2012-12-051-1/+1
| | | | | | | | | | | | malloc(9) flags within sys. Exceptions: - sys/contrib not touched - sys/mbuf.h edited manually Notes: svn path=/head/; revision=243882
* Migrate the power-save functions to be overridable VAP methods.Adrian Chadd2012-10-021-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This turns ieee80211_node_pwrsave(), ieee80211_sta_pwrsave() and ieee80211_recv_pspoll() into methods. The intent is to let drivers override these and tie into the power save management pathway. For ath(4), this is the beginning of forcing a node software queue to stop and start as needed, as well as supporting "leaking" single frames from the software queue to the hardware. Right now, ieee80211_recv_pspoll() will attempt to transmit a single frame to the hardware (whether it be a data frame on the power-save queue or a NULL data frame) but the driver may have hardware/software queued frames queued up. This initial work is an attempt at providing the hooks required to implement correct behaviour. Allowing ieee80211_node_pwrsave() to be overridden allows the ath(4) driver to pause and unpause the entire software queue for a given node. It doesn't make sense to transmit anything whilst the node is asleep. Please note that there are other corner cases to correctly handle - specifically, setting the MORE data bit correctly on frames to a station, as well as keeping the TIM updated. Those particular issues can be addressed later. Notes: svn path=/head/; revision=241138
* Remove now redundant mac argument.Bernhard Schmidt2011-12-171-4/+2
| | | | | | | Discussed with: adrian@ Notes: svn path=/head/; revision=228622
* Modify the ACL code slightly to support a few nifty things:Adrian Chadd2011-12-151-1/+11
| | | | | | | | | | | | | | | | * Call it before sending probe responses, so the ACL code has the chance to reject sending them. * Pass the whole frame to the ACL code now, rather than just the destination MAC - that way the ACL module can look at the frame contents to determine what the response should be. This is part of some uncommitted work to support band steering. Sponsored by: Hobnob, Inc. Notes: svn path=/head/; revision=228514
* Fix some corner cases in the net80211 sequence number retransmissionAdrian Chadd2011-05-041-5/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | handling. The current sequence number code does a few things incorrectly: * It didn't try eliminating duplications from HT nodes. I guess it's assumed that out of order / retransmission handling would be handled by the AMPDU RX routines. If a HT node isn't doing AMPDU RX, then retransmissions need to be eliminated. Since most of my debugging is based on this (as AMPDU TX software packet aggregation isn't yet handled), handle this corner case. * When a sequence number of 4095 was received, any subsequent sequence number is going to be (by definition) less than 4095. So if the following sequence number (0) doesn't initially occur and the retransmit is received, it's incorrectly eliminated by the IEEE80211_FC1_RETRY && SEQ_LEQ() check. Try to handle this better. This almost completely eliminates out of order TCP statistics showing up during iperf testing for the 11a, 11g and non-aggregate 11n AMPDU RX case. The only other packet loss conditions leading to this are due to baseband resets or heavy interference. Notes: svn path=/head/; revision=221418
* Make sure to only accept and handle action frames which are for us. InBernhard Schmidt2011-02-221-4/+13
| | | | | | | | promiscuous mode we might receive stuff which otherwise gets filtered by hardware. Notes: svn path=/head/; revision=218958
* Add a new mgmt subtype "ACTION NO ACK" defined in 802.11n-2009, while hereBernhard Schmidt2011-02-211-3/+14
| | | | | | | | | | | | clean up parts of the *_recv_mgmt() functions. - make sure appropriate counters are bumped and debug messages are printed - order the unhandled subtypes by value and add a few missing ones - fix some whitespace nits - remove duplicate code in adhoc_recv_mgmt() - remove a useless comment, probably left in while c&p Notes: svn path=/head/; revision=218927
* Add a comment explaining the previous commit.Rui Paulo2010-03-281-0/+5
| | | | | | | Submitted by: sam Notes: svn path=/head/; revision=205791
* When receiving a management frame, pass the mbuf to bpf before callingRui Paulo2010-03-231-0/+3
| | | | | | | | | | | | | | iv_recv_mgmt(). iv_recv_mgmt() will generate management frame responses and pass them to bpf before the management frame that triggered the response. PR: 144323 Submitted by: Alexander Egorenkov <egorenar at gmail.com> MFC after: 2 weeks Sponsored by: iXsystems, inc. Notes: svn path=/head/; revision=205516
* When taking the AMPDU reorder fastpath, need_tap wasn't beingRui Paulo2010-02-031-2/+1
| | | | | | | | | initialized. Initialize on declaration to avoid this. Found with: clang static analyzer Notes: svn path=/head/; revision=203422
* Fix typo in commentRui Paulo2009-12-081-1/+1
| | | | | | | Submitted by: Paul B Mahol <onemda at gmail.com> Notes: svn path=/head/; revision=200242