Commit Graph

142 Commits

Author SHA1 Message Date
Pedro F. Giffuni
fe267a5590 sys: general adoption of SPDX licensing ID tags.
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.
2017-11-27 15:23:17 +00:00
Andriy Voskoboinyk
e2db307ebc net80211: fix possible panic when wlan(4) interface is destroyed.
If this is the last running vap wait until device will be powered off
(fixes panic when 'ifconfig wlan0 destroy' is executed for running iwn(4)
interface).

Tested with:
 - Intel 6205, STA mode.
 - RTL8188EU, STA / IBSS modes.
 - RTL8821AU, STA / HOSTAP modes.
2017-03-24 22:29:51 +00:00
Adrian Chadd
e3e94c963e [net80211] begin fleshing out per-VAP WME configurations.
As part of (eventual) p2p/tdls/multi-STA support, a lot of global configuration
parameters (WME, ERP (slot, preamble), channel width, HT protmode, etc are the
biggest offenders) should be per-VAP.

For multi-BSS VAP operation they may be linked, but for p2p/TDLS
operation that can be off-channel they can definitely be different
(think: 2GHz STA, 5GHz p2p.)

The global configuration view of these is mostly a "configure the current
non-smart-firmware NIC" view.  This should be split up into per-VAP state,
then a global non-smart-firmware-NIC management layer to handle channel
changes and such in software.

This is step one in a loooong road for this.  It should be a big non-functional
change for everyone.

* create a per-VAP WME update call.
* call it if its set, and call the global callback if it isn't

This still uses global WME state - it's just preparation for a future change
which will make the WME state per-VAP and fall through to a shared WME
configuration for hostap operation.

Note: this requires a full kernel recompile; the internal net80211 ABI has changed.

Reviewed by:	avos
Differential Revision:	https://reviews.freebsd.org/D9986
2017-03-13 16:44:06 +00:00
Andriy Voskoboinyk
dfabbaa0e0 net80211: fix ieee80211_htrateset setup, return EINVAL for an unsupported
ucast/mcast/mgmt HT rate.

- Init global ieee80211_htrateset only once; neither ic_htcaps nor
ic_txstream is changed when device is attached;
- Move global ieee80211_htrateset structure to ieee80211com;
there was a possible data race when more than 1 wireless device is
used simultaneously;
- Discard unsupported rates in ieee80211_ioctl_settxparams(); otherwise,
an unsupported value may break connectivity (actually,
'ifconfig wlan0 ucastrate 8' for RTL8188EU results in immediate
disconnect + infinite 'device timeout's after it).

Tested with:
 - Intel 6205, STA mode.
 - RTL8821AU, STA mode.

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D9871
2017-03-03 01:06:27 +00:00
Andriy Voskoboinyk
98ff1f7c6e net80211: fix flags setup for HT40 5GHz channels. 2017-01-22 23:45:59 +00:00
Adrian Chadd
67f4aa3878 [net80211] initial, somewhat incomplete VHT channel setup code and attach path.
This sets up:

* vht capabilities in vaps;
* calls vht_announce to announce VHT capabilities if any;
* sets up vht20, vht40 and vht80 channels, assuming the regulatory code
  does the right thing with 80MHz available ranges;
* adds support to the ieee80211_add_channel_list_5ghz() code to populate
  VHT channels, as this is the API my ath10k driver is using;
* add support for the freq1/freq2 field population and lookup that
  VHT channels require.

The VHT80 code assumes that the regulatory domain already has limited VHT80
bands to, well, 80MHz wide chunks.
2017-01-13 06:53:56 +00:00
Adrian Chadd
0c67d389f4 [net80211] add VHT mediatype initialisation and update helper functions. 2017-01-10 07:50:21 +00:00
Adrian Chadd
8e71a4aa83 [net80211] add syncflags methods for the VHT flags configuration.
I missed this in my last commit.  Pointy hat to me.
2017-01-07 07:35:27 +00:00
Adrian Chadd
781487cfc6 [net80211] turn the default TX key configuration (for WEP) into a vap callback.
The ath10k firmware supports hardware WEP offload, and in native wifi mode
(or 802.3 ethernet mode, for that matter) the WEP key isn't actually included
in the TX payload from net80211.  Instead, a separate firmware command is issued
that sets the default TX key to be the specified key.

However, net80211 doesn't at all inform the driver layer that this is
occuring - it just "expects" to be inserting WEP header information
when doing WEP TX, even with hardware encryption.

So, to better support the newer world order, turn the default TX key assignment
into a VAP method that can be overridden by the driver and ensure its wrapped
in a crypto begin/end set.  That way it should be correctly atomic from the
point of view of keychanges (as long as the driver does the right thing.)

It'd be nice if we passed through to the key_set call a flag that says
"also make this the default key" - that's captured here by calling the
deftxkey method after the key_set method.  Maybe I can do that later.

Note: this is a net80211 ABI change, and will require a kernel+modules
recompile.  Happy Holidays, etc.

Tested:

* ath10k driver port
* rtwn_usb, WEP station
2016-12-27 06:10:28 +00:00
Adrian Chadd
7aebd3e55d [net80211] sigh, course I would miss a commit from the 11ac prep commit. 2016-12-16 04:44:14 +00:00
Adrian Chadd
4774b99992 [net80211] prepare for 11ac aware NICs that want to know per-vdev channel and centre frequencies.
* ic_freq is the centre of the primary channel, not the centre of the
  HT40/HT80/etc channel.  Add a method to access that.
* Add a method to access the centre of the primary channel, including
  knowing the centre of the 5/10/20/40/80, versus the primary channel.
  Ie, it's the centre of the 40, 80, 160MHz channel.
* Add a method to access the centre frequency of the secondary 80MHz
  channel - we don't support VHT yet, but when we do.
* Add methods to access the current channel and the per-dev desired
  channel.  Ideally drivers that do full offload with a per-vap channel
  configuration should use the vap channel, NOT ic_curchan.
  Non-offload drivers that require net80211 to change the channel should
  be accessing ic_curchan.
2016-12-03 02:45:18 +00:00
Andriy Voskoboinyk
6dbbec9385 net80211: fix more compiler warnings.
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.
2016-05-19 21:08:33 +00:00
Andriy Voskoboinyk
7cde0202f7 net80211: unbreak 'show all vaps(/a)' ddb command
Replace ifnet list lookup (which is broken since r287197, because
IFT_IEEE80211 type is not used anymore) with iteration on
ieee80211com list.

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D6419
2016-05-17 16:38:18 +00:00
Pedro F. Giffuni
a4641f4eaa sys/net*: minor spelling fixes.
No functional change.
2016-05-03 18:05:43 +00:00
Andriy Voskoboinyk
355fec4842 net80211: provide a set of ieee80211_add_channel*() functions
This change adds few methods for net80211 channel table setup:

- ieee80211_add_channel()
- ieee80211_add_channel_ht40()
(primarily for drivers, that parse EEPROM to get channel list -
they will allow to hide implementation details).

- ieee80211_add_channel_list_2ghz()
- ieee80211_add_channel_list_5ghz()
(mostly as a replacement for ieee80211_init_channels() - they will allow
to specify non-default channel list; may be used in ic_getradiocaps()).

Tested with wpi(4) (add_channel) and rum(4) (add_channel_list_2ghz).

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D6124
2016-04-29 21:18:14 +00:00
Andriy Voskoboinyk
6459bd2843 net80211: enable promiscuous mode state change for non-monitor/ahdemo modes
- Allow to enable/disable promiscuous mode when:
  * interface is not a member of bridge, or;
  * request was issued by user (ifconfig wlan0 promisc), or;
  * interface is in MONITOR or AHDEMO mode.
- Drop local workarounds in mwl(4) and malo(4).

Tested with:
- Intel 3945BG, STA mode;
- RTL8188CUS, MONITOR mode;

Reviewed by:	adrian
Differential Revision:	https://reviews.freebsd.org/D5472
2016-04-21 05:47:47 +00:00
Andriy Voskoboinyk
1d47c76c8c net80211: copy MAC address into iv_myaddr[] instead of aliasing it.
Since IF_LLADDR() returns a non-constant pointer to the MAC address
preserve a copy of it in iv_myaddr.

PR:		208505
2016-04-05 21:29:11 +00:00
Andriy Voskoboinyk
c6427be92b net80211: remove redundant locking.
All callers of ieee80211_promisc()/ieee80211_allmulti()
(ieee80211_vap_detach(), ieee80211_ioctl(), ap_start() and ap_end())
already hold the com_lock while calling them.

Tested with RTL8188EU, STA mode.

Approved by:	adrian (mentor)
Differential Revision:	https://reviews.freebsd.org/D5475
2016-02-28 23:48:34 +00:00
Andriy Voskoboinyk
f09a089ee6 net80211: fix 'uma_zalloc_arg: zone "32" with non-sleepable locks held'
when 'sysctl net.wlan.devices' is executed.

PR:		207497
Submitted by:	glebius
Approved by:	adrian (mentor)
2016-02-26 20:47:08 +00:00
Gleb Smirnoff
8ec07310fa These files were getting sys/malloc.h and vm/uma.h with header pollution
via sys/mbuf.h
2016-02-01 17:41:21 +00:00
Andriy Voskoboinyk
4061c639f0 net80211: add ieee80211_restart_all() call.
This call may be used when device cannot continue to operate normally
(e.g., throws firmware error, watchdog timer expires)
and need to be restarted.

Approved by:	adrian (mentor)
Differential Revision:	https://reviews.freebsd.org/D3998
2015-10-27 20:40:57 +00:00
Gleb Smirnoff
7a79cebfba Replay r286410. Change KPI of how device drivers that provide wireless
connectivity interact with the net80211 stack.

Historical background: originally wireless devices created an interface,
just like Ethernet devices do. Name of an interface matched the name of
the driver that created. Later, wlan(4) layer was introduced, and the
wlanX interfaces become the actual interface, leaving original ones as
"a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer
and a driver became a mix of methods that pass a pointer to struct ifnet
as identifier and methods that pass pointer to struct ieee80211com. From
user point of view, the parent interface just hangs on in the ifconfig
list, and user can't do anything useful with it.

Now, the struct ifnet goes away. The struct ieee80211com is the only
KPI between a device driver and net80211. Details:

- The struct ieee80211com is embedded into drivers softc.
- Packets are sent via new ic_transmit method, which is very much like
  the previous if_transmit.
- Bringing parent up/down is done via new ic_parent method, which notifies
  driver about any changes: number of wlan(4) interfaces, number of them
  in promisc or allmulti state.
- Device specific ioctls (if any) are received on new ic_ioctl method.
- Packets/errors accounting are done by the stack. In certain cases, when
  driver experiences errors and can not attribute them to any specific
  interface, driver updates ic_oerrors or ic_ierrors counters.

Details on interface configuration with new world order:
- A sequence of commands needed to bring up wireless DOESN"T change.
- /etc/rc.conf parameters DON'T change.
- List of devices that can be used to create wlan(4) interfaces is
  now provided by net.wlan.devices sysctl.

Most drivers in this change were converted by me, except of wpi(4),
that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing
changes to at least 8 drivers. Thanks to pluknet@, Oliver Hartmann,
Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in
testing.

Reviewed by:	adrian
Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2015-08-27 08:56:39 +00:00
Adrian Chadd
ba2c1fbc03 Revert the wifi ifnet changes until things are more baked and tested.
* 286410
* 286413
* 286416

The initial commit broke a variety of debug and features that aren't
in the GENERIC kernels but are enabled in other platforms.
2015-08-08 01:10:17 +00:00
Gleb Smirnoff
79d2c5e857 Change KPI of how device drivers that provide wireless connectivity interact
with the net80211 stack.

Historical background: originally wireless devices created an interface,
just like Ethernet devices do. Name of an interface matched the name of
the driver that created. Later, wlan(4) layer was introduced, and the
wlanX interfaces become the actual interface, leaving original ones as
"a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer
and a driver became a mix of methods that pass a pointer to struct ifnet
as identifier and methods that pass pointer to struct ieee80211com. From
user point of view, the parent interface just hangs on in the ifconfig
list, and user can't do anything useful with it.

Now, the struct ifnet goes away. The struct ieee80211com is the only
KPI between a device driver and net80211. Details:

- The struct ieee80211com is embedded into drivers softc.
- Packets are sent via new ic_transmit method, which is very much like
  the previous if_transmit.
- Bringing parent up/down is done via new ic_parent method, which notifies
  driver about any changes: number of wlan(4) interfaces, number of them
  in promisc or allmulti state.
- Device specific ioctls (if any) are received on new ic_ioctl method.
- Packets/errors accounting are done by the stack. In certain cases, when
  driver experiences errors and can not attribute them to any specific
  interface, driver updates ic_oerrors or ic_ierrors counters.

Details on interface configuration with new world order:
- A sequence of commands needed to bring up wireless DOESN"T change.
- /etc/rc.conf parameters DON'T change.
- List of devices that can be used to create wlan(4) interfaces is
  now provided by net.wlan.devices sysctl.

Most drivers in this change were converted by me, except of wpi(4),
that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing
changes to at least 8 drivers. Thanks to Olivier Cochard, gjb@, mmoll@,
op@ and lev@, who also participated in testing. Details here:

https://wiki.freebsd.org/projects/ifnet/net80211

Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not
tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances
of problems are low. The wtap wasn't compilable even before this change.
But the ndis driver is complex, and it is likely to be broken with this
commit. Help with testing and debugging it is appreciated.

Differential Revision:	D2655, D2740
Sponsored by:	Nginx, Inc.
Sponsored by:	Netflix
2015-08-07 11:43:14 +00:00
Adrian Chadd
2108f2a8e7 For now, just default to presenting "found" channels as 11g, not 11b.
The intel 7260 driver under development requires this - the scans come
in as normal frames but with the frequency provided.  The correct method
is to have the driver provide flags (so we can determine if it's 11b
or 11g); this will have to do in the meantime.

Without this, the channel found is 11b, and no ERP (ie "11g") bits
are negotiated with the AP.

This allows the 7260 in 2ghz mode to operate in 11bg, rather than
just 11b.

Tested:

* intel 7260 driver, 11bg channels
2015-06-05 06:49:08 +00:00
Gleb Smirnoff
28da1b56ea Provide ieee80211_get_counter() that sums up ieee802com
errors to the errors of this vap interface.

Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2015-05-26 13:19:05 +00:00
Gleb Smirnoff
92002144c0 Make ieee80211broadcastaddr global, so that drivers or other
code may use it and not paste.
2015-05-26 12:40:27 +00:00
Gleb Smirnoff
7fc10b6b41 Reduce diff before functional changes:
- Use ic_name instead of if_xname.
- Formatting cleanup.
2015-05-26 12:06:36 +00:00
Gleb Smirnoff
e14a2a4cf4 Cleanup compat shims for FreeBSD versions that predate 10.0-RELEASE.
There are no plans to merge anything save a trivial bugfix to stable/9.

Discussed with:	adrian
2015-05-25 20:06:49 +00:00
Gleb Smirnoff
272f6ade9b Change three methods in struct ieee80211com, namely ic_updateslot,
ic_update_mcast and ic_update_promisc, to pass pointer to the ieee80211com,
not to the ifnet.

Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2015-05-25 19:53:29 +00:00
Adrian Chadd
c79f192c09 Begin plumbing ieee80211_rx_stats through the receive path.
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.
2015-05-25 16:37:41 +00:00
Gleb Smirnoff
c8f5794e0a Use name from ieee80211com instead of parent ifnet, in debugging printfs.
Sponsored by:	Netflix
Sponsored by:	Nginx, Inc.
2015-05-25 14:30:44 +00:00
Adrian Chadd
a1cbd04334 Global-ify channel_type() - this fixes non-debug net80211 builds. 2015-01-06 18:25:10 +00:00
Gleb Smirnoff
dea4512157 Mechanically convert to if_inc_counter(). 2014-09-19 09:20:55 +00:00
Adrian Chadd
31f92dec23 Undo r195846 for now - allow raw frame transmit in monitor mode.
The original commit was supposed to stop the ability to do raw frame
injection in monitor mode to arbitrary channels (whether supported
by regulatory or not) however it doesn't seem to have been followed
by any useful way of doing it.

Apparently AHDEMO is supposed to be that way, but it seems to require
too much fiddly things (disable scanning, set a garbage SSID, etc)
for it to actually be useful for spoofing things.

So for now let's just disable it and instead look to filter transmit
in the output path if the channel isn't allowed by regulatory.
That way monitor RX works fine but TX will be blocked.

I don't plan on MFC'ing this to -10 until the regulatory enforcement
bits are written.
2014-08-10 08:35:42 +00:00
Adrian Chadd
9f098ac76f Allow the state of the interface to be "up" if the VAP is in SLEEP state.
Without this, the carrier will drop when the NIC transitions to SLEEP
and nothing will ever transmit.
2014-04-23 22:43:39 +00:00
Gleb Smirnoff
76039bc84f The r48589 promised to remove implicit inclusion of if_var.h soon. Prepare
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.
2013-10-26 17:58:36 +00:00
Rui Paulo
a3e08d6f4c Replace the homegrown implementation of nitems() with calls to nitems()
(param.h).

Operating systems that don't have nitems() can easily define it on their own
net80211 OS-specific header file.

Discussed with:		adrian
2013-08-14 04:24:25 +00:00
Adrian Chadd
e7495198d5 Convert net80211 over to using if_transmit for the dispatch from the
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
2013-08-08 05:09:35 +00:00
Adrian Chadd
cc80eae5cf Allow net80211 to compile on stable/9 and stable/8. 2013-08-07 22:01:43 +00:00
Gleb Smirnoff
47e8d432d5 Add const qualifier to the dst parameter of the ifnet if_output method. 2013-04-26 12:50:32 +00:00
Adrian Chadd
5cda6006e4 Bring over my initial work from the net80211 TX locking branch.
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.
2013-03-08 20:23:55 +00:00
Adrian Chadd
30e4856a81 Fix up some initial issues with creation and deletion of hotplugged
net80211 devices and vaps.

* vnet sets vnet0 during kldload and device probe/attach, but not for
  the hotplug event.  Thus, plugging in a NIC causes things to panic.
  So, add a CURVNET_SET(vnet0) for now during the attach phase, until
  the hotplug code is taught to set CURVNET_SET(vnet0).

* there's also no implied detach vnet context - so teach the detach
  path about ifp->if_vnet.

* When creating/deleting vaps, also set the vnet context appropriately.
  These can be done at any time.

Now, the problems!

* ieee80211.c is supposed to be OS-portable code, with no OS-specific stuff
  like vnet. That should be fixed.

* When the device hotplug code gets taught about CURVNET_SET(vnet0), the
  device vnet set can go away; but the VAP vnet set still needs to be there.

* .. and there still is the question about potentially adding an implied
  CURVNET_SET(ifp->if_vnet) on if_free(), since any/all devices may end up
  being detached by a hotplug event in today's world.  That's going to be
  a topic of a subsequent commit.
2012-10-26 16:56:55 +00:00
Adrian Chadd
b94299c437 Create a new task to handle 802.11n channel width changes.
Currently, a channel width change updates the 802.11n HT info data in
net80211 but it doesn't trigger any device changes.  So the device
driver may decide that HT40 frames can be transmitted but the last
device channel set only had HT20 set.

Now, a task is scheduled so a hardware reset or change isn't done
during any active ongoing RX. It also means that it's serialised
with the other task operations (eg channel change.)

This isn't the final incantation of this work, see below.

For now, any unmodified drivers will simply receive a channel
change log entry.  A subsequent patch to ath(4) will introduce
some basic channel change handling (by resetting the NIC.)
Other NICs may need to update their rate control information.

TODO:

* There's still a small window at the present moment where the
  channel width has been updated but the task hasn't been fired.
  The final version of this should likely pass in a channel width
  field to the driver and let the driver atomically do whatever
  it needs to before changing the channel.

PR:		kern/166286
2012-03-25 03:11:57 +00:00
Adrian Chadd
7b2b15eb98 Mark the taskqueue as the _net80211_ taskqueue.
This makes it much easier to determine whether an event occurs in the
net80211 taskqueue (which was called "ath0 taskq") or the ath driver
taskqueue (which is also called "ath0 taskq".)
2012-01-22 05:30:29 +00:00
Bernhard Schmidt
fcd9500f91 Fix some net80211 enum nits:
- ic_vap_create() uses an ieee80211_opmode argument
- ieee80211_rate2media() takes an ieee80211_phymode argument
- ieee80211_plcp2rate() takes an ieee80211_phytype argument
- cast to enum ieee80211_protmode and ieee80211_roamingmode to silence
  compiler warnings

Submitted by:	arundel@
2011-12-17 10:23:17 +00:00
Bernhard Schmidt
6f897ba9dd While determining the maxrate for ieee80211_media_setup() honor
the device capabilities.
2011-03-13 11:47:43 +00:00
Bernhard Schmidt
fbbe47a9ea First step on removing the harcoded RX/TX stream and MCS0-15 assumptions.
Initialize ic_rxstream/ic_txstream with 2, for compatibility reasons.
Introduce 4 new HTC flags, which are used in addition to ic_rxstream
and ic_txstream to compute the hc_mcsset content and also for initializing
ni_htrates. The number of spatial streams is enough to determine support
for MCS0-31 but not for MCS32-76 as well as some TX parameters in the
hc_mcsset field.
2011-03-13 11:40:18 +00:00
Bernhard Schmidt
f136f45f39 Complete the MCS rate table based on the final 802.11n std. While here
adjust the IEEE80211_HTRATE_MAXSIZE constant, only MCS0 - 76 are valid
the other bits in the mcsset IE (77 - 127) are either reserved or used
for TX parameters.
2011-03-10 18:17:24 +00:00
Bernhard Schmidt
a7c6aabdc3 Instead of using the AMRR ratectl algo as default for drivers which have
the IEEE80211_C_RATECTL flag set, default to NONE for all drivers. Only if
a driver calls ieee80211_ratectl_init() check if the NONE algo is still
selected and try to use AMRR in that case. Drivers are still free to use
any other algo by calling ieee80211_ratectl_set() prior to the
ieee80211_ratectl_init() call.

After this change it is now safe to assume that a ratectl algo is always
available and selected, which renders the IEEE80211_C_RATECTL flag pretty
much useless. Therefore revert r211314 and 211546.

Reviewed by:	rpaulo
MFC after:	2 weeks
2010-11-06 18:17:20 +00:00