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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
<table class="head">
<tr>
<td class="head-ltitle">IEEE80211_OUTPUT(9)</td>
<td class="head-vol">Kernel Developer's Manual</td>
<td class="head-rtitle">IEEE80211_OUTPUT(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">ieee80211_output</code> —
<span class="Nd">software 802.11 stack output functions</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">M_WME_GETAC</code>(<var class="Fa" style="white-space: nowrap;">struct
mbuf *</var>);</p>
<p class="Pp"><var class="Ft">int</var>
<br/>
<code class="Fn">M_SEQNO_GET</code>(<var class="Fa" style="white-space: nowrap;">struct
mbuf *</var>);</p>
<p class="Pp"><var class="Ft">struct ieee80211_key *</var>
<br/>
<code class="Fn">ieee80211_crypto_encap</code>(<var class="Fa" style="white-space: nowrap;">struct
ieee80211_node *</var>, <var class="Fa" style="white-space: nowrap;">struct
mbuf *</var>);</p>
<p class="Pp"><var class="Ft">void</var>
<br/>
<code class="Fn">ieee80211_process_callback</code>(<var class="Fa">struct
ieee80211_node *</var>, <var class="Fa">struct mbuf *</var>,
<var class="Fa">int</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> layer that supports 802.11
device drivers handles most of the work required to transmit frames. Drivers
usually receive fully-encapsulated 802.11 frames that have been classified
and assigned a transmit priority; all that is left is to do crypto
encapsulation, prepare any hardware-specific state, and push the packet out
to the device. Outbound frames are either generated by the
<code class="Nm">net80211</code> layer (e.g. management frames) or are
passed down from upper layers through the <a class="Xr">ifnet(9)</a>
transmit queue. Data frames passed down for transmit flow through
<code class="Nm">net80211</code> which handles aggregation, 802.11
encapsulation, and then dispatches the frames to the driver through it's
transmit queue.</p>
<p class="Pp">There are two control paths by which frames reach a driver for
transmit. Data packets are queued to the device's
<var class="Vt">if_snd</var> queue and the driver's
<var class="Vt">if_start</var> method is called. Other frames are passed
down using the <var class="Vt">ic_raw_xmit</var> method without queueing
(unless done by the driver). The raw transmit path may include data frames
from user applications that inject them through <a class="Xr">bpf(4)</a> and
NullData frames generated by <code class="Nm">net80211</code> to probe for
idle stations (when operating as an access point).</p>
<p class="Pp"><code class="Nm">net80211</code> handles all state-related
bookkeeping and management for the handling of data frames. Data frames are
only transmit for a vap in the <code class="Dv">IEEE80211_S_RUN</code>
state; there is no need, for example, to check for frames sent down when CAC
or CSA is active. Similarly, <code class="Nm">net80211</code> handles
activities such as background scanning and power save mode, frames will not
be sent to a driver unless it is operating on the BSS channel with
“full power”.</p>
<p class="Pp" id="ieee80211_free_node">All frames passed to a driver for
transmit hold a reference to a node table entry in the
<var class="Vt">m_pkthdr.rcvif</var> field. The node is associated with the
frame destination. Typically it is the receiver's entry but in some
situations it may be a placeholder entry or the “next hop
station” (such as in a mesh network). In all cases the reference must
be reclaimed with
<a class="permalink" href="#ieee80211_free_node"><code class="Fn">ieee80211_free_node</code></a>()
when the transmit work is completed. The rule to remember is:
<code class="Nm">net80211</code> passes responsibility for the
<var class="Vt">mbuf</var> and “node reference” to the driver
with each frame it hands off for transmit.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="PACKET_CLASSIFICATION"><a class="permalink" href="#PACKET_CLASSIFICATION">PACKET
CLASSIFICATION</a></h1>
<p class="Pp">All frames passed by <code class="Nm">net80211</code> for transmit
are assigned a priority based on any vlan tag assigned to the receiving
station and/or any Diffserv setting in an IP or IPv6 header. If both vlan
and Diffserv priority are present the higher of the two is used. If WME/WMM
is being used then any ACM policy (in station mode) is also enforced. The
resulting AC is attached to the mbuf and may be read back using the
<a class="permalink" href="#M_WME_GETAC"><code class="Fn" id="M_WME_GETAC">M_WME_GETAC</code></a>()
macro.</p>
<p class="Pp">PAE/EAPOL frames are tagged with an
<code class="Dv">M_EAPOL</code> mbuf flag; drivers should transmit them with
care, usually by using the transmit rate for management frames.
Multicast/broadcast frames are marked with the
<code class="Dv">M_MCAST</code> mbuf flag. Frames coming out of a station's
power save queue and that have more frames immediately following are marked
with the <code class="Dv">M_MORE_DATA</code> mbuf flag. Such frames will be
queued consecutively in the driver's <var class="Vt">if_snd</var> queue and
drivers should preserve the ordering when passing them to the device.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="FRAGMENTED_FRAMES"><a class="permalink" href="#FRAGMENTED_FRAMES">FRAGMENTED
FRAMES</a></h1>
<p class="Pp">The <code class="Nm">net80211</code> layer will fragment data
frames according to the setting of <var class="Vt">iv_fragthreshold</var> if
a driver marks the <code class="Dv">IEEE80211_C_TXFRAG</code> capability.
Fragmented frames are placed in the devices transmit queue with the
fragments chained together with <var class="Vt">m_nextpkt</var>. Each frame
is marked with the <code class="Dv">M_FRAG</code> mbuf flag, and the first
and last are marked with <code class="Dv">M_FIRSTFRAG</code> and
<code class="Dv">M_LASTFRAG</code>, respectively. Drivers are expected to
process all fragments or none.</p>
</section>
<section class="Sh">
<h1 class="Sh" id="TRANSMIT_CALLBACKS"><a class="permalink" href="#TRANSMIT_CALLBACKS">TRANSMIT
CALLBACKS</a></h1>
<p class="Pp">Frames sent by <code class="Nm">net80211</code> may be tagged with
the <code class="Dv">M_TXCB</code> mbuf flag to indicate a callback should
be done when their transmission completes. The callback is done using
<a class="permalink" href="#ieee80211_process_callback"><code class="Fn" id="ieee80211_process_callback">ieee80211_process_callback</code></a>()
with the last parameter set to a non-zero value if an error occurred and
zero otherwise. Note <code class="Nm">net80211</code> understands that
drivers may be incapable of determining status; a device may not report if
an ACK frame is received and/or a device may queue transmit requests in its
hardware and only report status on whether the frame was successfully
queued.</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">bpf(4)</a>, <a class="Xr">ieee80211(9)</a>,
<a class="Xr">ifnet(9)</a></p>
</section>
</div>
<table class="foot">
<tr>
<td class="foot-date">March 29, 2010</td>
<td class="foot-os">FreeBSD 15.0</td>
</tr>
</table>
|