1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
<table class="head">
<tr>
<td class="head-ltitle">IEEE80211_VAP(9)</td>
<td class="head-vol">Kernel Developer's Manual</td>
<td class="head-rtitle">IEEE80211_VAP(9)</td>
</tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">net80211_vap</code> —
<span class="Nd">802.11 network layer virtual radio support</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
<<a class="In">net80211/ieee80211_var.h</a>></code></p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">ieee80211_vap_setup</code>(<var class="Fa">struct
ieee80211com *</var>, <var class="Fa">struct ieee80211vap *</var>,
<var class="Fa">const char name[IFNAMSIZ]</var>, <var class="Fa">int
unit</var>, <var class="Fa">int opmode</var>, <var class="Fa">int
flags</var>, <var class="Fa">const uint8_t bssid[IEEE80211_ADDR_LEN]</var>,
<var class="Fa">const uint8_t macaddr[IEEE80211_ADDR_LEN]</var>);</p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">ieee80211_vap_attach</code>(<var class="Fa">struct
ieee80211vap *</var>, <var class="Fa">ifm_change_cb_t media_change</var>,
<var class="Fa">ifm_stat_cb_t media_stat</var>);</p>
<p class="Pp"><var class="Ft">void</var>
<br/>
<code class="Fn">ieee80211_vap_detach</code>(<var class="Fa" style="white-space: nowrap;">struct
ieee80211vap *</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">The <code class="Nm">net80211</code> software layer provides a
support framework for drivers that includes a virtual radio API that is
exported to users through network interfaces (aka vaps) that are cloned from
the underlying device. These interfaces have an operating mode (station,
adhoc, hostap, wds, monitor, etc.) that is fixed for the lifetime of the
interface. Devices that can support multiple concurrent interfaces allow
multiple vaps to be cloned.</p>
<p class="Pp">The virtual radio interface defined by the
<code class="Nm">net80211</code> layer means that drivers must be structured
to follow specific rules. Drivers that support only a single interface at
any time must still follow these rules.</p>
<p class="Pp">The virtual radio architecture splits state between a single
per-device <var class="Vt">ieee80211com</var> structure and one or more
<var class="Vt">ieee80211vap</var> structures. Vaps are created with the
<code class="Dv">SIOCIFCREATE2</code> request. This results in a call into
the driver's <var class="Vt">ic_vap_create</var> method where the driver can
decide if the request should be accepted.</p>
<p class="Pp" id="ieee80211_vap_setup">The vap creation process is done in three
steps. First the driver allocates the data structure with
<a class="Xr">malloc(9)</a>. This data structure must have an
<var class="Vt">ieee80211vap</var> structure at the front but is usually
extended with driver-private state. Next the vap is setup with a call to
<a class="permalink" href="#ieee80211_vap_setup"><code class="Fn">ieee80211_vap_setup</code></a>().
This request initializes <code class="Nm">net80211</code> state but does not
activate the interface. The driver can then override methods setup by
<code class="Nm">net80211</code> and setup driver resources before finally
calling
<a class="permalink" href="#ieee80211_vap_attach"><code class="Fn" id="ieee80211_vap_attach">ieee80211_vap_attach</code></a>()
to complete the process. Both these calls must be done without holding any
driver locks as work may require the process block/sleep.</p>
<p class="Pp" id="ieee80211_vap_detach">A vap is deleted when an
<code class="Dv">SIOCIFDESTROY</code> ioctl request is made or when the
device detaches (causing all associated vaps to automatically be deleted).
Delete requests cause the <var class="Vt">ic_vap_delete</var> method to be
called. Drivers must quiesce the device before calling
<a class="permalink" href="#ieee80211_vap_detach"><code class="Fn">ieee80211_vap_detach</code></a>()
to deactivate the vap and isolate it from activities such as requests from
user applications. The driver can then reclaim resources held by the vap and
re-enable device operation. The exact procedure for quiescing a device is
unspecified but typically it involves blocking interrupts and stopping
transmit and receive processing.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="MULTI-VAP_OPERATION"><a class="permalink" href="#MULTI-VAP_OPERATION">MULTI-VAP
OPERATION</a></h1>
<p class="Pp">Drivers are responsible for deciding if multiple vaps can be
created and how to manage them. Whether or not multiple concurrent vaps can
be supported depends on a device's capabilities. For example, multiple
hostap vaps can usually be supported but many devices do not support
assigning each vap a unique BSSID. If a device supports hostap operation it
can usually support concurrent station mode vaps but possibly with
limitations such as losing support for hardware beacon miss support. Devices
that are capable of hostap operation and can send and receive 4-address
frames should be able to support WDS vaps together with an ap vap. But in
contrast some devices cannot support WDS vaps without at least one ap vap
(this however can be finessed by forcing the ap vap to not transmit beacon
frames). All devices should support the creation of any number of monitor
mode vaps concurrent with other vaps but it is the responsibility of the
driver to allow this.</p>
<p class="Pp">An important consequence of supporting multiple concurrent vaps is
that a driver's <var class="Vt">iv_newstate</var> method must be written to
handle being called for each vap. Where necessary, drivers must track
private state for all vaps and not just the one whose state is being changed
(e.g. for handling beacon timers the driver may need to know if all vaps
that beacon are stopped before stopping the hardware timers).</p>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
ALSO</a></h1>
<p class="Pp"><a class="Xr">ieee80211(9)</a>, <a class="Xr">ifnet(9)</a>,
<a class="Xr">malloc(9)</a></p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">August 4, 2009</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|