1 /*-
2 * Copyright (c) 2020-2025 The FreeBSD Foundation
3 * Copyright (c) 2020-2025 Bjoern A. Zeeb
4 *
5 * This software was developed by Björn Zeeb under sponsorship from
6 * the FreeBSD Foundation.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * Public functions are called linuxkpi_*().
32 * Internal (static) functions are called lkpi_*().
33 *
34 * The internal structures holding metadata over public structures are also
35 * called lkpi_xxx (usually with a member at the end called xxx).
36 * Note: we do not replicate the structure names but the general variable names
37 * for these (e.g., struct hw -> struct lkpi_hw, struct sta -> struct lkpi_sta).
38 * There are macros to access one from the other.
39 * We call the internal versions lxxx (e.g., hw -> lhw, sta -> lsta).
40 */
41
42 /*
43 * TODO:
44 * - lots :)
45 * - HW_CRYPTO: we need a "keystore" and an ordered list for suspend/resume.
46 */
47
48 #include <sys/param.h>
49 #include <sys/types.h>
50 #include <sys/kernel.h>
51 #include <sys/errno.h>
52 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/mutex.h>
55 #include <sys/sbuf.h>
56 #include <sys/socket.h>
57 #include <sys/sysctl.h>
58 #include <sys/queue.h>
59 #include <sys/taskqueue.h>
60 #include <sys/libkern.h>
61
62 #include <net/if.h>
63 #include <net/if_var.h>
64 #include <net/if_media.h>
65 #include <net/ethernet.h>
66
67 #include <net80211/ieee80211_var.h>
68 #include <net80211/ieee80211_proto.h>
69 #include <net80211/ieee80211_ratectl.h>
70 #include <net80211/ieee80211_radiotap.h>
71 #include <net80211/ieee80211_vht.h>
72
73 #define LINUXKPI_NET80211
74 #include <net/mac80211.h>
75
76 #include <linux/workqueue.h>
77 #include <linux/rculist.h>
78 #include "linux_80211.h"
79
80 #define LKPI_80211_WME
81 #define LKPI_80211_HW_CRYPTO
82 #define LKPI_80211_HT
83 #define LKPI_80211_VHT
84
85 #if defined(LKPI_80211_VHT) && !defined(LKPI_80211_HT)
86 #define LKPI_80211_HT
87 #endif
88 #if defined(LKPI_80211_HT) && !defined(LKPI_80211_HW_CRYPTO)
89 #define LKPI_80211_HW_CRYPTO
90 #endif
91
92 static MALLOC_DEFINE(M_LKPI80211, "lkpi80211", "LinuxKPI 80211 compat");
93
94 /* XXX-BZ really want this and others in queue.h */
95 #define TAILQ_ELEM_INIT(elm, field) do { \
96 (elm)->field.tqe_next = NULL; \
97 (elm)->field.tqe_prev = NULL; \
98 } while (0)
99
100 /* -------------------------------------------------------------------------- */
101
102 SYSCTL_DECL(_compat_linuxkpi);
103 SYSCTL_NODE(_compat_linuxkpi, OID_AUTO, 80211, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
104 "LinuxKPI 802.11 compatibility layer");
105
106 #if defined(LKPI_80211_HW_CRYPTO)
107 static bool lkpi_hwcrypto = false;
108 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, hw_crypto, CTLFLAG_RDTUN,
109 &lkpi_hwcrypto, 0, "Enable LinuxKPI 802.11 hardware crypto offload");
110
111 static bool lkpi_hwcrypto_tkip = false;
112 SYSCTL_BOOL(_compat_linuxkpi_80211, OID_AUTO, tkip, CTLFLAG_RDTUN,
113 &lkpi_hwcrypto_tkip, 0, "Enable LinuxKPI 802.11 TKIP crypto offload");
114 #endif
115
116 /* Keep public for as long as header files are using it too. */
117 int linuxkpi_debug_80211;
118
119 #ifdef LINUXKPI_DEBUG_80211
120 SYSCTL_INT(_compat_linuxkpi_80211, OID_AUTO, debug, CTLFLAG_RWTUN,
121 &linuxkpi_debug_80211, 0, "LinuxKPI 802.11 debug level");
122
123 #define UNIMPLEMENTED if (linuxkpi_debug_80211 & D80211_TODO) \
124 printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__)
125 #define TRACEOK() if (linuxkpi_debug_80211 & D80211_TRACEOK) \
126 printf("XXX-TODO %s:%d: TRACEPOINT\n", __func__, __LINE__)
127 #else
128 #define UNIMPLEMENTED do { } while (0)
129 #define TRACEOK() do { } while (0)
130 #endif
131
132 /* #define PREP_TX_INFO_DURATION (IEEE80211_TRANS_WAIT * 1000) */
133 #ifndef PREP_TX_INFO_DURATION
134 #define PREP_TX_INFO_DURATION 0 /* Let the driver do its thing. */
135 #endif
136
137 /* This is DSAP | SSAP | CTRL | ProtoID/OrgCode{3}. */
138 const uint8_t rfc1042_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
139
140 /* IEEE 802.11-05/0257r1 */
141 const uint8_t bridge_tunnel_header[6] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
142
143 /* IEEE 802.11e Table 20i-UP-to-AC mappings. */
144 static const uint8_t ieee80211e_up_to_ac[] = {
145 IEEE80211_AC_BE,
146 IEEE80211_AC_BK,
147 IEEE80211_AC_BK,
148 IEEE80211_AC_BE,
149 IEEE80211_AC_VI,
150 IEEE80211_AC_VI,
151 IEEE80211_AC_VO,
152 IEEE80211_AC_VO,
153 #if 0
154 IEEE80211_AC_VO, /* We treat MGMT as TID 8, which is set as AC_VO */
155 #endif
156 };
157
158 const struct cfg80211_ops linuxkpi_mac80211cfgops = {
159 /*
160 * XXX TODO need a "glue layer" to link cfg80211 ops to
161 * mac80211 and to the driver or net80211.
162 * Can we pass some on 1:1? Need to compare the (*f)().
163 */
164 };
165
166 #if 0
167 static struct lkpi_sta *lkpi_find_lsta_by_ni(struct lkpi_vif *,
168 struct ieee80211_node *);
169 #endif
170 static void lkpi_80211_txq_tx_one(struct lkpi_sta *, struct mbuf *);
171 static void lkpi_80211_txq_task(void *, int);
172 static void lkpi_80211_lhw_rxq_task(void *, int);
173 static void lkpi_ieee80211_free_skb_mbuf(void *);
174 #ifdef LKPI_80211_WME
175 static int lkpi_wme_update(struct lkpi_hw *, struct ieee80211vap *, bool);
176 #endif
177 static void lkpi_ieee80211_wake_queues_locked(struct ieee80211_hw *);
178
179 static const char *
lkpi_rate_info_bw_to_str(enum rate_info_bw bw)180 lkpi_rate_info_bw_to_str(enum rate_info_bw bw)
181 {
182
183 switch (bw) {
184
185 case RATE_INFO_BW_20:
186 return ("20");
187 break;
188 case RATE_INFO_BW_5:
189 return ("5");
190 break;
191 case RATE_INFO_BW_10:
192 return ("10");
193 break;
194 case RATE_INFO_BW_40:
195 return ("40");
196 break;
197 case RATE_INFO_BW_80:
198 return ("80");
199 break;
200 case RATE_INFO_BW_160:
201 return ("160");
202 break;
203 case RATE_INFO_BW_HE_RU:
204 IMPROVE("nl80211_he_ru_alloc");
205 return ("HE_RU");
206 break;
207 case RATE_INFO_BW_320:
208 return ("320");
209 break;
210 case RATE_INFO_BW_EHT_RU:
211 IMPROVE("nl80211_eht_ru_alloc");
212 return ("EHT_RU");
213 break;
214 default:
215 return ("?");
216 break;
217 }
218 }
219
220 static void
lkpi_nl80211_sta_info_to_str(struct sbuf * s,const char * prefix,const uint64_t flags)221 lkpi_nl80211_sta_info_to_str(struct sbuf *s, const char *prefix,
222 const uint64_t flags)
223 {
224 int bit, i;
225
226 sbuf_printf(s, "%s %#010jx", prefix, flags);
227
228 i = 0;
229 for (bit = 0; bit < BITS_PER_TYPE(flags); bit++) {
230
231 if ((flags & BIT_ULL(bit)) == 0)
232 continue;
233
234 #define EXPAND_CASE(_flag) \
235 case NL80211_STA_INFO_ ## _flag: \
236 sbuf_printf(s, "%c%s", (i == 0) ? '<' : ',', #_flag); \
237 i++; \
238 break;
239
240 switch (bit) {
241 EXPAND_CASE(BEACON_RX)
242 EXPAND_CASE(BEACON_SIGNAL_AVG)
243 EXPAND_CASE(BSS_PARAM)
244 EXPAND_CASE(CHAIN_SIGNAL)
245 EXPAND_CASE(CHAIN_SIGNAL_AVG)
246 EXPAND_CASE(CONNECTED_TIME)
247 EXPAND_CASE(INACTIVE_TIME)
248 EXPAND_CASE(SIGNAL)
249 EXPAND_CASE(SIGNAL_AVG)
250 EXPAND_CASE(STA_FLAGS)
251 EXPAND_CASE(RX_BITRATE)
252 EXPAND_CASE(RX_PACKETS)
253 EXPAND_CASE(RX_BYTES)
254 EXPAND_CASE(RX_DROP_MISC)
255 EXPAND_CASE(TX_BITRATE)
256 EXPAND_CASE(TX_PACKETS)
257 EXPAND_CASE(TX_BYTES)
258 EXPAND_CASE(TX_BYTES64)
259 EXPAND_CASE(RX_BYTES64)
260 EXPAND_CASE(TX_FAILED)
261 EXPAND_CASE(TX_RETRIES)
262 EXPAND_CASE(RX_DURATION)
263 EXPAND_CASE(TX_DURATION)
264 EXPAND_CASE(ACK_SIGNAL)
265 EXPAND_CASE(ACK_SIGNAL_AVG)
266 default:
267 sbuf_printf(s, "%c?%d", (i == 0) ? '<' : ',', bit);
268 break;
269 }
270 }
271 #undef EXPAND_CASE
272 if (i > 0)
273 sbuf_printf(s, ">");
274 sbuf_printf(s, "\n");
275 }
276
277 static int
lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)278 lkpi_80211_dump_stas(SYSCTL_HANDLER_ARGS)
279 {
280 struct lkpi_hw *lhw;
281 struct ieee80211_hw *hw;
282 struct ieee80211vap *vap;
283 struct lkpi_vif *lvif;
284 struct ieee80211_vif *vif;
285 struct lkpi_sta *lsta;
286 struct ieee80211_sta *sta;
287 struct station_info sinfo;
288 struct sbuf s;
289 int error;
290
291 if (req->newptr)
292 return (EPERM);
293
294 lvif = (struct lkpi_vif *)arg1;
295 vif = LVIF_TO_VIF(lvif);
296 vap = LVIF_TO_VAP(lvif);
297 lhw = vap->iv_ic->ic_softc;
298 hw = LHW_TO_HW(lhw);
299
300 sbuf_new_for_sysctl(&s, NULL, 1024, req);
301
302 wiphy_lock(hw->wiphy);
303 list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
304 sta = LSTA_TO_STA(lsta);
305
306 sbuf_putc(&s, '\n');
307 sbuf_printf(&s, "lsta %p sta %p added_to_drv %d\n", lsta, sta, lsta->added_to_drv);
308
309 memset(&sinfo, 0, sizeof(sinfo));
310 error = lkpi_80211_mo_sta_statistics(hw, vif, sta, &sinfo);
311 if (error == EEXIST) /* Not added to driver. */
312 continue;
313 if (error == ENOTSUPP) {
314 sbuf_printf(&s, " sta_statistics not supported\n");
315 continue;
316 }
317 if (error != 0) {
318 sbuf_printf(&s, " sta_statistics failed: %d\n", error);
319 continue;
320 }
321
322 /* If no RX_BITRATE is reported, try to fill it in from the lsta sinfo. */
323 if ((sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) == 0 &&
324 (lsta->sinfo.filled & BIT_ULL(NL80211_STA_INFO_RX_BITRATE)) != 0) {
325 memcpy(&sinfo.rxrate, &lsta->sinfo.rxrate, sizeof(sinfo.rxrate));
326 sinfo.filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
327 }
328
329 lkpi_nl80211_sta_info_to_str(&s, " nl80211_sta_info (valid fields)", sinfo.filled);
330 sbuf_printf(&s, " connected_time %u inactive_time %u\n",
331 sinfo.connected_time, sinfo.inactive_time);
332 sbuf_printf(&s, " rx_bytes %ju rx_packets %u rx_dropped_misc %u\n",
333 (uintmax_t)sinfo.rx_bytes, sinfo.rx_packets, sinfo.rx_dropped_misc);
334 sbuf_printf(&s, " rx_duration %ju rx_beacon %u rx_beacon_signal_avg %d\n",
335 (uintmax_t)sinfo.rx_duration, sinfo.rx_beacon, (int8_t)sinfo.rx_beacon_signal_avg);
336
337 sbuf_printf(&s, " tx_bytes %ju tx_packets %u tx_failed %u\n",
338 (uintmax_t)sinfo.tx_bytes, sinfo.tx_packets, sinfo.tx_failed);
339 sbuf_printf(&s, " tx_duration %ju tx_retries %u\n",
340 (uintmax_t)sinfo.tx_duration, sinfo.tx_retries);
341
342 sbuf_printf(&s, " signal %d signal_avg %d ack_signal %d avg_ack_signal %d\n",
343 sinfo.signal, sinfo.signal_avg, sinfo.ack_signal, sinfo.avg_ack_signal);
344
345 sbuf_printf(&s, " generation %d assoc_req_ies_len %zu chains %d\n",
346 sinfo.generation, sinfo.assoc_req_ies_len, sinfo.chains);
347
348 for (int i = 0; i < sinfo.chains && i < IEEE80211_MAX_CHAINS; i++) {
349 sbuf_printf(&s, " chain[%d] signal %d signal_avg %d\n",
350 i, (int8_t)sinfo.chain_signal[i], (int8_t)sinfo.chain_signal_avg[i]);
351 }
352
353 /* assoc_req_ies, bss_param, sta_flags */
354
355 sbuf_printf(&s, " rxrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
356 sinfo.rxrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
357 sinfo.rxrate.bw, lkpi_rate_info_bw_to_str(sinfo.rxrate.bw),
358 sinfo.rxrate.legacy * 100,
359 sinfo.rxrate.mcs, sinfo.rxrate.nss);
360 sbuf_printf(&s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
361 sinfo.rxrate.he_dcm, sinfo.rxrate.he_gi, sinfo.rxrate.he_ru_alloc,
362 sinfo.rxrate.eht_gi);
363 sbuf_printf(&s, " txrate: flags %b bw %u(%s) legacy %u kbit/s mcs %u nss %u\n",
364 sinfo.txrate.flags, CFG80211_RATE_INFO_FLAGS_BITS,
365 sinfo.txrate.bw, lkpi_rate_info_bw_to_str(sinfo.txrate.bw),
366 sinfo.txrate.legacy * 100,
367 sinfo.txrate.mcs, sinfo.txrate.nss);
368 sbuf_printf(&s, " he_dcm %u he_gi %u he_ru_alloc %u eht_gi %u\n",
369 sinfo.txrate.he_dcm, sinfo.txrate.he_gi, sinfo.txrate.he_ru_alloc,
370 sinfo.txrate.eht_gi);
371 }
372 wiphy_unlock(hw->wiphy);
373
374 sbuf_finish(&s);
375 sbuf_delete(&s);
376
377 return (0);
378 }
379
380 static enum ieee80211_sta_rx_bw
lkpi_cw_to_rx_bw(enum nl80211_chan_width cw)381 lkpi_cw_to_rx_bw(enum nl80211_chan_width cw)
382 {
383 switch (cw) {
384 case NL80211_CHAN_WIDTH_320:
385 return (IEEE80211_STA_RX_BW_320);
386 case NL80211_CHAN_WIDTH_160:
387 case NL80211_CHAN_WIDTH_80P80:
388 return (IEEE80211_STA_RX_BW_160);
389 case NL80211_CHAN_WIDTH_80:
390 return (IEEE80211_STA_RX_BW_80);
391 case NL80211_CHAN_WIDTH_40:
392 return (IEEE80211_STA_RX_BW_40);
393 case NL80211_CHAN_WIDTH_20:
394 case NL80211_CHAN_WIDTH_20_NOHT:
395 return (IEEE80211_STA_RX_BW_20);
396 case NL80211_CHAN_WIDTH_5:
397 case NL80211_CHAN_WIDTH_10:
398 /* Unsupported input. */
399 return (IEEE80211_STA_RX_BW_20);
400 }
401 }
402
403 static enum nl80211_chan_width
lkpi_rx_bw_to_cw(enum ieee80211_sta_rx_bw rx_bw)404 lkpi_rx_bw_to_cw(enum ieee80211_sta_rx_bw rx_bw)
405 {
406 switch (rx_bw) {
407 case IEEE80211_STA_RX_BW_20:
408 return (NL80211_CHAN_WIDTH_20); /* _NOHT */
409 case IEEE80211_STA_RX_BW_40:
410 return (NL80211_CHAN_WIDTH_40);
411 case IEEE80211_STA_RX_BW_80:
412 return (NL80211_CHAN_WIDTH_80);
413 case IEEE80211_STA_RX_BW_160:
414 return (NL80211_CHAN_WIDTH_160); /* 80P80 */
415 case IEEE80211_STA_RX_BW_320:
416 return (NL80211_CHAN_WIDTH_320);
417 }
418 }
419
420 static void
lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta)421 lkpi_sync_chanctx_cw_from_rx_bw(struct ieee80211_hw *hw,
422 struct ieee80211_vif *vif, struct ieee80211_sta *sta)
423 {
424 struct ieee80211_chanctx_conf *chanctx_conf;
425 enum ieee80211_sta_rx_bw old_bw;
426 uint32_t changed;
427
428 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
429 lockdep_is_held(&hw->wiphy->mtx));
430 if (chanctx_conf == NULL)
431 return;
432
433 old_bw = lkpi_cw_to_rx_bw(chanctx_conf->def.width);
434 if (old_bw == sta->deflink.bandwidth)
435 return;
436
437 chanctx_conf->def.width = lkpi_rx_bw_to_cw(sta->deflink.bandwidth);
438 if (chanctx_conf->def.width == NL80211_CHAN_WIDTH_20 &&
439 !sta->deflink.ht_cap.ht_supported)
440 chanctx_conf->def.width = NL80211_CHAN_WIDTH_20_NOHT;
441
442 chanctx_conf->min_def = chanctx_conf->def;
443
444 vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width;
445
446 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
447 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
448 lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
449 }
450
451 #if defined(LKPI_80211_HT)
452 static void
lkpi_sta_sync_ht_from_ni(struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni)453 lkpi_sta_sync_ht_from_ni(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
454 struct ieee80211_node *ni)
455 {
456 struct ieee80211vap *vap;
457 uint8_t *ie;
458 struct ieee80211_ht_cap *htcap;
459 int i, rx_nss;
460
461 if ((ni->ni_flags & IEEE80211_NODE_HT) == 0) {
462 sta->deflink.ht_cap.ht_supported = false;
463 return;
464 }
465
466 sta->deflink.ht_cap.ht_supported = true;
467
468 /* htcap->ampdu_params_info */
469 vap = ni->ni_vap;
470 sta->deflink.ht_cap.ampdu_density = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MPDUDENSITY);
471 if (sta->deflink.ht_cap.ampdu_density > vap->iv_ampdu_density)
472 sta->deflink.ht_cap.ampdu_density = vap->iv_ampdu_density;
473 sta->deflink.ht_cap.ampdu_factor = _IEEE80211_MASKSHIFT(ni->ni_htparam, IEEE80211_HTCAP_MAXRXAMPDU);
474 if (sta->deflink.ht_cap.ampdu_factor > vap->iv_ampdu_rxmax)
475 sta->deflink.ht_cap.ampdu_factor = vap->iv_ampdu_rxmax;
476
477 ie = ni->ni_ies.htcap_ie;
478 KASSERT(ie != NULL, ("%s: HT but no htcap_ie on ni %p\n", __func__, ni));
479 if (ie[0] == IEEE80211_ELEMID_VENDOR)
480 ie += 4;
481 ie += 2;
482 htcap = (struct ieee80211_ht_cap *)ie;
483 sta->deflink.ht_cap.cap = htcap->cap_info;
484 sta->deflink.ht_cap.mcs = htcap->mcs;
485
486 /*
487 * 802.11n-2009 20.6 Parameters for HT MCSs gives the mandatory/
488 * optional MCS for Nss=1..4. We need to check the first four
489 * MCS sets from the Rx MCS Bitmask; then there is MCS 32 and
490 * MCS33.. is UEQM.
491 */
492 rx_nss = 0;
493 for (i = 0; i < 4; i++) {
494 if (htcap->mcs.rx_mask[i] != 0)
495 rx_nss++;
496 }
497 if (rx_nss > 0) {
498 sta->deflink.rx_nss = rx_nss;
499 } else {
500 sta->deflink.ht_cap.ht_supported = false;
501 return;
502 }
503
504 if ((sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) != 0 &&
505 IEEE80211_IS_CHAN_HT40(ni->ni_chan))
506 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_40;
507 else
508 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20;
509
510 IMPROVE("sta->wme");
511
512 if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_MAX_AMSDU)
513 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_7935;
514 else
515 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_3839;
516 sta->deflink.agg.max_rc_amsdu_len = IEEE80211_MAX_MPDU_LEN_HT_BA;
517 #ifdef __handled_by_driver__ /* iwlwifi only? actually unused? */
518 for (i = 0; i < nitems(sta.deflink.agg.max_tid_amsdu_len); i++) {
519 sta->deflink.agg.max_tid_amsdu_len[j] = ;
520 }
521 #endif
522 }
523 #endif
524
525 #if defined(LKPI_80211_VHT)
526 static void
lkpi_sta_sync_vht_from_ni(struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni)527 lkpi_sta_sync_vht_from_ni(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
528 struct ieee80211_node *ni)
529 {
530 enum ieee80211_sta_rx_bw bw;
531 uint32_t width;
532 int rx_nss;
533 uint16_t rx_mcs_map;
534 uint8_t mcs;
535
536 if ((ni->ni_flags & IEEE80211_NODE_VHT) == 0 ||
537 !IEEE80211_IS_CHAN_VHT_5GHZ(ni->ni_chan)) {
538 sta->deflink.vht_cap.vht_supported = false;
539 return;
540 }
541
542 sta->deflink.vht_cap.vht_supported = true;
543
544 sta->deflink.vht_cap.cap = ni->ni_vhtcap;
545 sta->deflink.vht_cap.vht_mcs = ni->ni_vht_mcsinfo;
546
547 /*
548 * If VHT20/40 are selected do not update the bandwidth
549 * from HT but stya on VHT.
550 */
551 if (ni->ni_vht_chanwidth == IEEE80211_VHT_CHANWIDTH_USE_HT)
552 goto skip_bw;
553
554 bw = sta->deflink.bandwidth;
555 width = (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK);
556 switch (width) {
557 /* Deprecated. */
558 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ:
559 case IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ:
560 bw = IEEE80211_STA_RX_BW_160;
561 break;
562 default:
563 /* Check if we do support 160Mhz somehow after all. */
564 if ((sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) != 0)
565 bw = IEEE80211_STA_RX_BW_160;
566 else
567 bw = IEEE80211_STA_RX_BW_80;
568 }
569 /*
570 * While we can set what is possibly supported we also need to be
571 * on a channel which supports that bandwidth; e.g., we can support
572 * VHT160 but the AP only does VHT80.
573 * Further ni_chan will also have filtered out what we disabled
574 * by configuration.
575 * Once net80211 channel selection is fixed for 802.11-2020 and
576 * VHT160 we can possibly spare ourselves the above.
577 */
578 if (bw == IEEE80211_STA_RX_BW_160 &&
579 !IEEE80211_IS_CHAN_VHT160(ni->ni_chan) &&
580 !IEEE80211_IS_CHAN_VHT80P80(ni->ni_chan))
581 bw = IEEE80211_STA_RX_BW_80;
582 if (bw == IEEE80211_STA_RX_BW_80 &&
583 !IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
584 bw = sta->deflink.bandwidth;
585 sta->deflink.bandwidth = bw;
586 skip_bw:
587
588 rx_nss = 0;
589 rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
590 for (int i = 7; i >= 0; i--) {
591 mcs = rx_mcs_map >> (2 * i);
592 mcs &= 0x3;
593 if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
594 rx_nss = i + 1;
595 break;
596 }
597 }
598 if (rx_nss > 0)
599 sta->deflink.rx_nss = rx_nss;
600
601 switch (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
602 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
603 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
604 break;
605 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991:
606 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_7991;
607 break;
608 case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895:
609 default:
610 sta->deflink.agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_3895;
611 break;
612 }
613 }
614 #endif
615
616 static void
lkpi_sta_sync_from_ni(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_node * ni,bool updchnctx)617 lkpi_sta_sync_from_ni(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
618 struct ieee80211_sta *sta, struct ieee80211_node *ni, bool updchnctx)
619 {
620
621 #if defined(LKPI_80211_HT)
622 lkpi_sta_sync_ht_from_ni(vif, sta, ni);
623 #endif
624 #if defined(LKPI_80211_VHT)
625 lkpi_sta_sync_vht_from_ni(vif, sta, ni);
626 #endif
627
628 /*
629 * Ensure rx_nss is at least 1 as otherwise drivers run into
630 * unexpected problems.
631 */
632 sta->deflink.rx_nss = MAX(1, sta->deflink.rx_nss);
633
634 /*
635 * We are also called from node allocation which net80211
636 * can do even on `ifconfig down`; in that case the chanctx
637 * may still be valid and we get a discrepancy between
638 * sta and chanctx. Thus do not try to update the chanctx
639 * when called from lkpi_lsta_alloc().
640 */
641 if (updchnctx)
642 lkpi_sync_chanctx_cw_from_rx_bw(hw, vif, sta);
643 }
644
645 static uint8_t
lkpi_get_max_rx_chains(struct ieee80211_node * ni)646 lkpi_get_max_rx_chains(struct ieee80211_node *ni)
647 {
648 uint8_t chains;
649 #if defined(LKPI_80211_HT) || defined(LKPI_80211_VHT)
650 struct lkpi_sta *lsta;
651 struct ieee80211_sta *sta;
652
653 lsta = ni->ni_drv_data;
654 sta = LSTA_TO_STA(lsta);
655 #endif
656
657 chains = 1;
658 #if defined(LKPI_80211_HT)
659 IMPROVE("We should factor counting MCS/NSS out for sync and here");
660 if (sta->deflink.ht_cap.ht_supported)
661 chains = MAX(chains, sta->deflink.rx_nss);
662 #endif
663
664 #if defined(LKPI_80211_VHT)
665 if (sta->deflink.vht_cap.vht_supported)
666 chains = MAX(chains, sta->deflink.rx_nss);
667 #endif
668
669 return (chains);
670 }
671
672 static void
lkpi_lsta_dump(struct lkpi_sta * lsta,struct ieee80211_node * ni,const char * _f,int _l)673 lkpi_lsta_dump(struct lkpi_sta *lsta, struct ieee80211_node *ni,
674 const char *_f, int _l)
675 {
676
677 #ifdef LINUXKPI_DEBUG_80211
678 if ((linuxkpi_debug_80211 & D80211_TRACE_STA) == 0)
679 return;
680 if (lsta == NULL)
681 return;
682
683 printf("%s:%d lsta %p ni %p sta %p\n",
684 _f, _l, lsta, ni, &lsta->sta);
685 if (ni != NULL)
686 ieee80211_dump_node(NULL, ni);
687 printf("\ttxq_task txq len %d mtx\n", mbufq_len(&lsta->txq));
688 printf("\tkc %p state %d added_to_drv %d in_mgd %d\n",
689 &lsta->kc[0], lsta->state, lsta->added_to_drv, lsta->in_mgd);
690 #endif
691 }
692
693 static void
lkpi_lsta_remove(struct lkpi_sta * lsta,struct lkpi_vif * lvif)694 lkpi_lsta_remove(struct lkpi_sta *lsta, struct lkpi_vif *lvif)
695 {
696
697 lockdep_assert_wiphy(lsta->hw->wiphy);
698
699 KASSERT(!list_empty(&lsta->lsta_list),
700 ("%s: lsta %p ni %p\n", __func__, lsta, lsta->ni));
701 list_del_init(&lsta->lsta_list);
702 }
703
704 static struct lkpi_sta *
lkpi_lsta_alloc(struct ieee80211vap * vap,const uint8_t mac[IEEE80211_ADDR_LEN],struct ieee80211_hw * hw,struct ieee80211_node * ni)705 lkpi_lsta_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN],
706 struct ieee80211_hw *hw, struct ieee80211_node *ni)
707 {
708 struct lkpi_sta *lsta;
709 struct lkpi_vif *lvif;
710 struct ieee80211_vif *vif;
711 struct ieee80211_sta *sta;
712 int band, i, tid;
713
714 lsta = malloc(sizeof(*lsta) + hw->sta_data_size, M_LKPI80211,
715 M_NOWAIT | M_ZERO);
716 if (lsta == NULL)
717 return (NULL);
718
719 lsta->hw = hw;
720 lsta->added_to_drv = false;
721 lsta->state = IEEE80211_STA_NOTEXIST;
722 /*
723 * Link the ni to the lsta here without taking a reference.
724 * For one we would have to take the reference in node_init()
725 * as ieee80211_alloc_node() will initialise the refcount after us.
726 * For the other a ni and an lsta are 1:1 mapped and always together
727 * from [ic_]node_alloc() to [ic_]node_free() so we are essentally
728 * using the ni references for the lsta as well despite it being
729 * two separate allocations.
730 */
731 lsta->ni = ni;
732 /* The back-pointer "drv_data" to net80211_node let's us get lsta. */
733 ni->ni_drv_data = lsta;
734
735 lvif = VAP_TO_LVIF(vap);
736 vif = LVIF_TO_VIF(lvif);
737 sta = LSTA_TO_STA(lsta);
738
739 IEEE80211_ADDR_COPY(sta->addr, mac);
740
741 /* TXQ */
742 for (tid = 0; tid < nitems(sta->txq); tid++) {
743 struct lkpi_txq *ltxq;
744
745 /* We are not limiting ourselves to hw.queues here. */
746 ltxq = malloc(sizeof(*ltxq) + hw->txq_data_size,
747 M_LKPI80211, M_NOWAIT | M_ZERO);
748 if (ltxq == NULL)
749 goto cleanup;
750 /* iwlwifi//mvm/sta.c::tid_to_mac80211_ac[] */
751 if (tid == IEEE80211_NUM_TIDS) {
752 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ)) {
753 free(ltxq, M_LKPI80211);
754 continue;
755 }
756 IMPROVE("AP/if we support non-STA here too");
757 ltxq->txq.ac = IEEE80211_AC_VO;
758 } else {
759 ltxq->txq.ac = ieee80211e_up_to_ac[tid & 7];
760 }
761 ltxq->seen_dequeue = false;
762 ltxq->stopped = false;
763 ltxq->txq.vif = vif;
764 ltxq->txq.tid = tid;
765 ltxq->txq.sta = sta;
766 TAILQ_ELEM_INIT(ltxq, txq_entry);
767 skb_queue_head_init(<xq->skbq);
768 LKPI_80211_LTXQ_LOCK_INIT(ltxq);
769 sta->txq[tid] = <xq->txq;
770 }
771
772 /* Deflink information. */
773 for (band = 0; band < NUM_NL80211_BANDS; band++) {
774 struct ieee80211_supported_band *supband;
775
776 supband = hw->wiphy->bands[band];
777 if (supband == NULL)
778 continue;
779
780 for (i = 0; i < supband->n_bitrates; i++) {
781 switch (band) {
782 case NL80211_BAND_2GHZ:
783 switch (supband->bitrates[i].bitrate) {
784 case 240: /* 11g only */
785 case 120: /* 11g only */
786 case 110:
787 case 60: /* 11g only */
788 case 55:
789 case 20:
790 case 10:
791 sta->deflink.supp_rates[band] |= BIT(i);
792 break;
793 }
794 break;
795 case NL80211_BAND_5GHZ:
796 switch (supband->bitrates[i].bitrate) {
797 case 240:
798 case 120:
799 case 60:
800 sta->deflink.supp_rates[band] |= BIT(i);
801 break;
802 }
803 break;
804 }
805 }
806 }
807
808 sta->deflink.smps_mode = IEEE80211_SMPS_OFF;
809 sta->deflink.bandwidth = IEEE80211_STA_RX_BW_20;
810 sta->deflink.rx_nss = 1;
811
812 lkpi_sta_sync_from_ni(hw, vif, sta, ni, false);
813
814 IMPROVE("he, eht, bw_320, ... smps_mode, ..");
815
816 /* Link configuration. */
817 IEEE80211_ADDR_COPY(sta->deflink.addr, sta->addr);
818 sta->link[0] = &sta->deflink;
819 for (i = 1; i < nitems(sta->link); i++) {
820 IMPROVE("more links; only link[0] = deflink currently.");
821 }
822 IMPROVE("11be");
823 sta->mlo = false;
824
825 /* Deferred TX path. */
826 LKPI_80211_LSTA_TXQ_LOCK_INIT(lsta);
827 TASK_INIT(&lsta->txq_task, 0, lkpi_80211_txq_task, lsta);
828 mbufq_init(&lsta->txq, 32 * NAPI_POLL_WEIGHT);
829 lsta->txq_ready = true;
830
831 return (lsta);
832
833 cleanup:
834 for (; tid >= 0; tid--) {
835 struct lkpi_txq *ltxq;
836
837 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
838 LKPI_80211_LTXQ_LOCK_DESTROY(ltxq);
839 free(sta->txq[tid], M_LKPI80211);
840 }
841 free(lsta, M_LKPI80211);
842 return (NULL);
843 }
844
845 static void
lkpi_lsta_free(struct lkpi_sta * lsta,struct ieee80211_node * ni)846 lkpi_lsta_free(struct lkpi_sta *lsta, struct ieee80211_node *ni)
847 {
848 struct mbuf *m;
849
850 if (lsta->added_to_drv)
851 panic("%s: Trying to free an lsta still known to firmware: "
852 "lsta %p ni %p added_to_drv %d\n",
853 __func__, lsta, ni, lsta->added_to_drv);
854
855 /* XXX-BZ free resources, ... */
856 IMPROVE();
857
858 /* Drain sta->txq[] */
859
860 LKPI_80211_LSTA_TXQ_LOCK(lsta);
861 lsta->txq_ready = false;
862 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
863
864 /* Drain taskq, won't be restarted until added_to_drv is set again. */
865 while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
866 taskqueue_drain(taskqueue_thread, &lsta->txq_task);
867
868 /* Flush mbufq (make sure to release ni refs!). */
869 m = mbufq_dequeue(&lsta->txq);
870 while (m != NULL) {
871 struct ieee80211_node *nim;
872
873 nim = (struct ieee80211_node *)m->m_pkthdr.rcvif;
874 if (nim != NULL)
875 ieee80211_free_node(nim);
876 m_freem(m);
877 m = mbufq_dequeue(&lsta->txq);
878 }
879 KASSERT(mbufq_empty(&lsta->txq), ("%s: lsta %p has txq len %d != 0\n",
880 __func__, lsta, mbufq_len(&lsta->txq)));
881 LKPI_80211_LSTA_TXQ_LOCK_DESTROY(lsta);
882
883 /* Remove lsta from vif; that is done by the state machine. Should assert it? */
884
885 IMPROVE("Make sure everything is cleaned up.");
886
887 /* Free lsta. */
888 lsta->ni = NULL;
889 ni->ni_drv_data = NULL;
890 free(lsta, M_LKPI80211);
891 }
892
893
894 static enum nl80211_band
lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel * c)895 lkpi_net80211_chan_to_nl80211_band(struct ieee80211_channel *c)
896 {
897
898 if (IEEE80211_IS_CHAN_2GHZ(c))
899 return (NL80211_BAND_2GHZ);
900 else if (IEEE80211_IS_CHAN_5GHZ(c))
901 return (NL80211_BAND_5GHZ);
902 #ifdef __notyet__
903 else if ()
904 return (NL80211_BAND_6GHZ);
905 else if ()
906 return (NL80211_BAND_60GHZ);
907 else if (IEEE80211_IS_CHAN_GSM(c))
908 return (NL80211_BAND_XXX);
909 #endif
910 else
911 panic("%s: unsupported band. c %p flags %#x\n",
912 __func__, c, c->ic_flags);
913 }
914
915 static uint32_t
lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)916 lkpi_nl80211_band_to_net80211_band(enum nl80211_band band)
917 {
918
919 /* XXX-BZ this is just silly; net80211 is too convoluted. */
920 /* IEEE80211_CHAN_A / _G / .. doesn't really work either. */
921 switch (band) {
922 case NL80211_BAND_2GHZ:
923 return (IEEE80211_CHAN_2GHZ);
924 break;
925 case NL80211_BAND_5GHZ:
926 return (IEEE80211_CHAN_5GHZ);
927 break;
928 case NL80211_BAND_60GHZ:
929 break;
930 case NL80211_BAND_6GHZ:
931 break;
932 default:
933 panic("%s: unsupported band %u\n", __func__, band);
934 break;
935 }
936
937 IMPROVE();
938 return (0x00);
939 }
940
941 #if 0
942 static enum ieee80211_ac_numbers
943 lkpi_ac_net_to_l80211(int ac)
944 {
945
946 switch (ac) {
947 case WME_AC_VO:
948 return (IEEE80211_AC_VO);
949 case WME_AC_VI:
950 return (IEEE80211_AC_VI);
951 case WME_AC_BE:
952 return (IEEE80211_AC_BE);
953 case WME_AC_BK:
954 return (IEEE80211_AC_BK);
955 default:
956 printf("%s: invalid WME_AC_* input: ac = %d\n", __func__, ac);
957 return (IEEE80211_AC_BE);
958 }
959 }
960 #endif
961
962 static enum nl80211_iftype
lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)963 lkpi_opmode_to_vif_type(enum ieee80211_opmode opmode)
964 {
965
966 switch (opmode) {
967 case IEEE80211_M_IBSS:
968 return (NL80211_IFTYPE_ADHOC);
969 break;
970 case IEEE80211_M_STA:
971 return (NL80211_IFTYPE_STATION);
972 break;
973 case IEEE80211_M_WDS:
974 return (NL80211_IFTYPE_WDS);
975 break;
976 case IEEE80211_M_HOSTAP:
977 return (NL80211_IFTYPE_AP);
978 break;
979 case IEEE80211_M_MONITOR:
980 return (NL80211_IFTYPE_MONITOR);
981 break;
982 case IEEE80211_M_MBSS:
983 return (NL80211_IFTYPE_MESH_POINT);
984 break;
985 case IEEE80211_M_AHDEMO:
986 /* FALLTHROUGH */
987 default:
988 printf("ERROR: %s: unsupported opmode %d\n", __func__, opmode);
989 /* FALLTHROUGH */
990 }
991 return (NL80211_IFTYPE_UNSPECIFIED);
992 }
993
994 #ifdef LKPI_80211_HW_CRYPTO
995 static const char *
lkpi_cipher_suite_to_name(uint32_t wlan_cipher_suite)996 lkpi_cipher_suite_to_name(uint32_t wlan_cipher_suite)
997 {
998 switch (wlan_cipher_suite) {
999 case WLAN_CIPHER_SUITE_WEP40:
1000 return ("WEP40");
1001 case WLAN_CIPHER_SUITE_WEP104:
1002 return ("WEP104");
1003 case WLAN_CIPHER_SUITE_TKIP:
1004 return ("TKIP");
1005 case WLAN_CIPHER_SUITE_CCMP:
1006 return ("CCMP");
1007 case WLAN_CIPHER_SUITE_CCMP_256:
1008 return ("CCMP_256");
1009 case WLAN_CIPHER_SUITE_GCMP:
1010 return ("GCMP");
1011 case WLAN_CIPHER_SUITE_GCMP_256:
1012 return ("GCMP_256");
1013 case WLAN_CIPHER_SUITE_AES_CMAC:
1014 return ("AES_CMAC");
1015 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1016 return ("BIP_CMAC_256");
1017 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1018 return ("BIP_GMAC_128");
1019 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1020 return ("BIP_GMAC_256");
1021 default:
1022 return ("??");
1023 }
1024 }
1025
1026 static uint32_t
lkpi_l80211_to_net80211_cyphers(struct ieee80211com * ic,uint32_t wlan_cipher_suite)1027 lkpi_l80211_to_net80211_cyphers(struct ieee80211com *ic,
1028 uint32_t wlan_cipher_suite)
1029 {
1030 switch (wlan_cipher_suite) {
1031 case WLAN_CIPHER_SUITE_WEP40:
1032 return (IEEE80211_CRYPTO_WEP);
1033 case WLAN_CIPHER_SUITE_WEP104:
1034 return (IEEE80211_CRYPTO_WEP);
1035 case WLAN_CIPHER_SUITE_TKIP:
1036 return (IEEE80211_CRYPTO_TKIP);
1037 case WLAN_CIPHER_SUITE_CCMP:
1038 return (IEEE80211_CRYPTO_AES_CCM);
1039 case WLAN_CIPHER_SUITE_CCMP_256:
1040 return (IEEE80211_CRYPTO_AES_CCM_256);
1041 case WLAN_CIPHER_SUITE_GCMP:
1042 return (IEEE80211_CRYPTO_AES_GCM_128);
1043 case WLAN_CIPHER_SUITE_GCMP_256:
1044 return (IEEE80211_CRYPTO_AES_GCM_256);
1045 case WLAN_CIPHER_SUITE_AES_CMAC:
1046 return (IEEE80211_CRYPTO_BIP_CMAC_128);
1047 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
1048 return (IEEE80211_CRYPTO_BIP_CMAC_256);
1049 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
1050 return (IEEE80211_CRYPTO_BIP_GMAC_128);
1051 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
1052 return (IEEE80211_CRYPTO_BIP_GMAC_256);
1053 default:
1054 ic_printf(ic, "%s: unknown WLAN Cipher Suite %#08x | %u (%s)\n",
1055 __func__,
1056 wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff,
1057 lkpi_cipher_suite_to_name(wlan_cipher_suite));
1058 return (0);
1059 }
1060 }
1061
1062 static uint32_t
lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher,uint8_t keylen)1063 lkpi_net80211_to_l80211_cipher_suite(uint32_t cipher, uint8_t keylen)
1064 {
1065
1066 switch (cipher) {
1067 case IEEE80211_CIPHER_WEP:
1068 if (keylen == (40/NBBY))
1069 return (WLAN_CIPHER_SUITE_WEP40);
1070 else if (keylen == (104/NBBY))
1071 return (WLAN_CIPHER_SUITE_WEP104);
1072 else {
1073 printf("%s: WEP with unsupported keylen %d\n",
1074 __func__, keylen * NBBY);
1075 return (0);
1076 }
1077 break;
1078 case IEEE80211_CIPHER_TKIP:
1079 return (WLAN_CIPHER_SUITE_TKIP);
1080 case IEEE80211_CIPHER_AES_CCM:
1081 return (WLAN_CIPHER_SUITE_CCMP);
1082 case IEEE80211_CIPHER_AES_CCM_256:
1083 return (WLAN_CIPHER_SUITE_CCMP_256);
1084 case IEEE80211_CIPHER_AES_GCM_128:
1085 return (WLAN_CIPHER_SUITE_GCMP);
1086 case IEEE80211_CIPHER_AES_GCM_256:
1087 return (WLAN_CIPHER_SUITE_GCMP_256);
1088 case IEEE80211_CIPHER_BIP_CMAC_128:
1089 return (WLAN_CIPHER_SUITE_AES_CMAC);
1090 case IEEE80211_CIPHER_BIP_CMAC_256:
1091 return (WLAN_CIPHER_SUITE_BIP_CMAC_256);
1092 case IEEE80211_CIPHER_BIP_GMAC_128:
1093 return (WLAN_CIPHER_SUITE_BIP_GMAC_128);
1094 case IEEE80211_CIPHER_BIP_GMAC_256:
1095 return (WLAN_CIPHER_SUITE_BIP_GMAC_256);
1096
1097 case IEEE80211_CIPHER_AES_OCB:
1098 case IEEE80211_CIPHER_TKIPMIC:
1099 /*
1100 * TKIP w/ hw MIC support
1101 * (gone wrong; should really be a crypto flag in net80211).
1102 */
1103 case IEEE80211_CIPHER_CKIP:
1104 case IEEE80211_CIPHER_NONE:
1105 printf("%s: unsupported cipher %#010x\n", __func__, cipher);
1106 break;
1107 default:
1108 printf("%s: unknown cipher %#010x\n", __func__, cipher);
1109 };
1110 return (0);
1111 }
1112 #endif
1113
1114 #ifdef __notyet__
1115 static enum ieee80211_sta_state
lkpi_net80211_state_to_sta_state(enum ieee80211_state state)1116 lkpi_net80211_state_to_sta_state(enum ieee80211_state state)
1117 {
1118
1119 /*
1120 * XXX-BZ The net80211 states are "try to ..", the lkpi8011 states are
1121 * "done". Also ASSOC/AUTHORIZED are both "RUN" then?
1122 */
1123 switch (state) {
1124 case IEEE80211_S_INIT:
1125 return (IEEE80211_STA_NOTEXIST);
1126 case IEEE80211_S_SCAN:
1127 return (IEEE80211_STA_NONE);
1128 case IEEE80211_S_AUTH:
1129 return (IEEE80211_STA_AUTH);
1130 case IEEE80211_S_ASSOC:
1131 return (IEEE80211_STA_ASSOC);
1132 case IEEE80211_S_RUN:
1133 return (IEEE80211_STA_AUTHORIZED);
1134 case IEEE80211_S_CAC:
1135 case IEEE80211_S_CSA:
1136 case IEEE80211_S_SLEEP:
1137 default:
1138 UNIMPLEMENTED;
1139 };
1140
1141 return (IEEE80211_STA_NOTEXIST);
1142 }
1143 #endif
1144
1145 static struct linuxkpi_ieee80211_channel *
lkpi_find_lkpi80211_chan(struct lkpi_hw * lhw,struct ieee80211_channel * c)1146 lkpi_find_lkpi80211_chan(struct lkpi_hw *lhw,
1147 struct ieee80211_channel *c)
1148 {
1149 struct ieee80211_hw *hw;
1150 struct linuxkpi_ieee80211_channel *channels;
1151 enum nl80211_band band;
1152 int i, nchans;
1153
1154 hw = LHW_TO_HW(lhw);
1155 band = lkpi_net80211_chan_to_nl80211_band(c);
1156 if (hw->wiphy->bands[band] == NULL)
1157 return (NULL);
1158
1159 nchans = hw->wiphy->bands[band]->n_channels;
1160 if (nchans <= 0)
1161 return (NULL);
1162
1163 channels = hw->wiphy->bands[band]->channels;
1164 for (i = 0; i < nchans; i++) {
1165 if (channels[i].hw_value == c->ic_ieee)
1166 return (&channels[i]);
1167 }
1168
1169 return (NULL);
1170 }
1171
1172 #if 0
1173 static struct linuxkpi_ieee80211_channel *
1174 lkpi_get_lkpi80211_chan(struct ieee80211com *ic, struct ieee80211_node *ni)
1175 {
1176 struct linuxkpi_ieee80211_channel *chan;
1177 struct ieee80211_channel *c;
1178 struct lkpi_hw *lhw;
1179
1180 chan = NULL;
1181 if (ni != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC)
1182 c = ni->ni_chan;
1183 else if (ic->ic_bsschan != IEEE80211_CHAN_ANYC)
1184 c = ic->ic_bsschan;
1185 else if (ic->ic_curchan != IEEE80211_CHAN_ANYC)
1186 c = ic->ic_curchan;
1187 else
1188 c = NULL;
1189
1190 if (c != NULL && c != IEEE80211_CHAN_ANYC) {
1191 lhw = ic->ic_softc;
1192 chan = lkpi_find_lkpi80211_chan(lhw, c);
1193 }
1194
1195 return (chan);
1196 }
1197 #endif
1198
1199 struct linuxkpi_ieee80211_channel *
linuxkpi_ieee80211_get_channel(struct wiphy * wiphy,uint32_t freq)1200 linuxkpi_ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq)
1201 {
1202 enum nl80211_band band;
1203
1204 for (band = 0; band < NUM_NL80211_BANDS; band++) {
1205 struct ieee80211_supported_band *supband;
1206 struct linuxkpi_ieee80211_channel *channels;
1207 int i;
1208
1209 supband = wiphy->bands[band];
1210 if (supband == NULL || supband->n_channels == 0)
1211 continue;
1212
1213 channels = supband->channels;
1214 for (i = 0; i < supband->n_channels; i++) {
1215 if (channels[i].center_freq == freq)
1216 return (&channels[i]);
1217 }
1218 }
1219
1220 return (NULL);
1221 }
1222
1223 #ifdef LKPI_80211_HW_CRYPTO
1224 static int
lkpi_sta_del_keys(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct lkpi_sta * lsta)1225 lkpi_sta_del_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1226 struct lkpi_sta *lsta)
1227 {
1228 int error;
1229
1230 if (!lkpi_hwcrypto)
1231 return (0);
1232
1233 lockdep_assert_wiphy(hw->wiphy);
1234 ieee80211_ref_node(lsta->ni);
1235
1236 error = 0;
1237 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc); keyix++) {
1238 struct ieee80211_key_conf *kc;
1239 int err;
1240
1241 if (lsta->kc[keyix] == NULL)
1242 continue;
1243 kc = lsta->kc[keyix];
1244
1245 #ifdef LINUXKPI_DEBUG_80211
1246 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1247 ic_printf(lsta->ni->ni_ic, "%d %lu %s: running set_key cmd %d(%s) for "
1248 "sta %6D: keyidx %u hw_key_idx %u flags %b\n",
1249 curthread->td_tid, jiffies, __func__,
1250 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":",
1251 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1252 #endif
1253
1254 err = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif,
1255 LSTA_TO_STA(lsta), kc);
1256 if (err != 0) {
1257 ic_printf(lsta->ni->ni_ic, "%d %lu %s: set_key cmd %d(%s) for "
1258 "sta %6D failed: %d\n", curthread->td_tid, jiffies, __func__,
1259 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":", err);
1260 error++;
1261
1262 /*
1263 * If we free the key here we will never be able to get it
1264 * removed from the driver/fw which will likely make us
1265 * crash (firmware).
1266 */
1267 continue;
1268 }
1269 #ifdef LINUXKPI_DEBUG_80211
1270 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1271 ic_printf(lsta->ni->ni_ic, "%d %lu %s: set_key cmd %d(%s) for "
1272 "sta %6D succeeded: keyidx %u hw_key_idx %u flags %b\n",
1273 curthread->td_tid, jiffies, __func__,
1274 DISABLE_KEY, "DISABLE", lsta->sta.addr, ":",
1275 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1276 #endif
1277
1278 lsta->kc[keyix] = NULL;
1279 free(kc, M_LKPI80211);
1280 }
1281 ieee80211_free_node(lsta->ni);
1282 return (error);
1283 }
1284
1285 /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */
1286 /* See also lkpi_sta_del_keys() these days. */
1287 static int
lkpi_iv_key_delete(struct ieee80211vap * vap,const struct ieee80211_key * k)1288 lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
1289 {
1290 struct ieee80211com *ic;
1291 struct lkpi_hw *lhw;
1292 struct ieee80211_hw *hw;
1293 struct lkpi_vif *lvif;
1294 struct lkpi_sta *lsta;
1295 struct ieee80211_vif *vif;
1296 struct ieee80211_sta *sta;
1297 struct ieee80211_node *ni;
1298 struct ieee80211_key_conf *kc;
1299 int error;
1300
1301 ic = vap->iv_ic;
1302 lhw = ic->ic_softc;
1303 hw = LHW_TO_HW(lhw);
1304 lvif = VAP_TO_LVIF(vap);
1305
1306 /*
1307 * Make sure we do not make it here without going through
1308 * lkpi_iv_key_update_begin() first.
1309 */
1310 lockdep_assert_wiphy(hw->wiphy);
1311
1312 if (IEEE80211_KEY_UNDEFINED(k)) {
1313 ic_printf(ic, "%s: vap %p key %p is undefined: %p %u\n",
1314 __func__, vap, k, k->wk_cipher, k->wk_keyix);
1315 return (0);
1316 }
1317
1318 if (vap->iv_bss == NULL) {
1319 ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1320 __func__, vap->iv_bss, vap);
1321 return (0);
1322 }
1323
1324 ni = ieee80211_ref_node(vap->iv_bss);
1325 lsta = ni->ni_drv_data;
1326 if (lsta == NULL) {
1327 ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1328 __func__, ni, ni->ni_bssid, ":");
1329 ieee80211_free_node(ni);
1330 return (0);
1331 }
1332 sta = LSTA_TO_STA(lsta);
1333
1334 if (lsta->kc[k->wk_keyix] == NULL) {
1335 #ifdef LINUXKPI_DEBUG_80211
1336 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1337 ic_printf(ic, "%d %lu %s: sta %6D and no key information, "
1338 "keyidx %u wk_macaddr %6D; returning success\n",
1339 curthread->td_tid, jiffies, __func__, sta->addr, ":",
1340 k->wk_keyix, k->wk_macaddr, ":");
1341 #endif
1342 ieee80211_free_node(ni);
1343 return (1);
1344 }
1345 kc = lsta->kc[k->wk_keyix];
1346
1347 #ifdef LINUXKPI_DEBUG_80211
1348 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1349 ic_printf(ic, "%d %lu %s: running set_key cmd %d(%s) for sta %6D: "
1350 "keyidx %u hw_key_idx %u flags %b\n",
1351 curthread->td_tid, jiffies, __func__,
1352 DISABLE_KEY, "DISABLE", sta->addr, ":",
1353 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1354 #endif
1355
1356 vif = LVIF_TO_VIF(lvif);
1357 error = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif, sta, kc);
1358 if (error != 0) {
1359 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1360 curthread->td_tid, jiffies, __func__,
1361 DISABLE_KEY, "DISABLE", sta->addr, ":", error);
1362 error = 0;
1363 goto out;
1364 }
1365
1366 #ifdef LINUXKPI_DEBUG_80211
1367 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1368 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D succeeded: "
1369 "keyidx %u hw_key_idx %u flags %b\n",
1370 curthread->td_tid, jiffies, __func__,
1371 DISABLE_KEY, "DISABLE", sta->addr, ":",
1372 kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1373 #endif
1374 lsta->kc[k->wk_keyix] = NULL;
1375 free(kc, M_LKPI80211);
1376 error = 1;
1377 out:
1378 ieee80211_free_node(ni);
1379 return (error);
1380 }
1381
1382 static int
lkpi_iv_key_set(struct ieee80211vap * vap,const struct ieee80211_key * k)1383 lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
1384 {
1385 struct ieee80211com *ic;
1386 struct lkpi_hw *lhw;
1387 struct ieee80211_hw *hw;
1388 struct lkpi_vif *lvif;
1389 struct lkpi_sta *lsta;
1390 struct ieee80211_vif *vif;
1391 struct ieee80211_sta *sta;
1392 struct ieee80211_node *ni;
1393 struct ieee80211_key_conf *kc;
1394 uint32_t lcipher;
1395 uint16_t exp_flags;
1396 uint8_t keylen;
1397 int error;
1398
1399 ic = vap->iv_ic;
1400 lhw = ic->ic_softc;
1401 hw = LHW_TO_HW(lhw);
1402
1403 /*
1404 * Make sure we do not make it here without going through
1405 * lkpi_iv_key_update_begin() first.
1406 */
1407 lockdep_assert_wiphy(hw->wiphy);
1408
1409 if (IEEE80211_KEY_UNDEFINED(k)) {
1410 ic_printf(ic, "%s: vap %p key %p is undefined: %p %u\n",
1411 __func__, vap, k, k->wk_cipher, k->wk_keyix);
1412 return (0);
1413 }
1414
1415 if (vap->iv_bss == NULL) {
1416 ic_printf(ic, "%s: iv_bss %p for vap %p is NULL\n",
1417 __func__, vap->iv_bss, vap);
1418 return (0);
1419 }
1420 ni = ieee80211_ref_node(vap->iv_bss);
1421 lsta = ni->ni_drv_data;
1422 if (lsta == NULL) {
1423 ic_printf(ic, "%s: ni %p (%6D) with lsta NULL\n",
1424 __func__, ni, ni->ni_bssid, ":");
1425 ieee80211_free_node(ni);
1426 return (0);
1427 }
1428 sta = LSTA_TO_STA(lsta);
1429
1430 keylen = k->wk_keylen;
1431 lcipher = lkpi_net80211_to_l80211_cipher_suite(
1432 k->wk_cipher->ic_cipher, k->wk_keylen);
1433 switch (lcipher) {
1434 case WLAN_CIPHER_SUITE_TKIP:
1435 keylen += 2 * k->wk_cipher->ic_miclen;
1436 break;
1437 case WLAN_CIPHER_SUITE_CCMP:
1438 case WLAN_CIPHER_SUITE_GCMP:
1439 break;
1440 default:
1441 ic_printf(ic, "%s: CIPHER SUITE %#x (%s) not supported\n",
1442 __func__, lcipher, lkpi_cipher_suite_to_name(lcipher));
1443 IMPROVE();
1444 ieee80211_free_node(ni);
1445 return (0);
1446 }
1447
1448 if (lsta->kc[k->wk_keyix] != NULL) {
1449 IMPROVE("Still in firmware? Del first. Can we assert this cannot happen?");
1450 ic_printf(ic, "%s: sta %6D found with key information\n",
1451 __func__, sta->addr, ":");
1452 kc = lsta->kc[k->wk_keyix];
1453 lsta->kc[k->wk_keyix] = NULL;
1454 free(kc, M_LKPI80211);
1455 kc = NULL; /* safeguard */
1456 }
1457
1458 kc = malloc(sizeof(*kc) + keylen, M_LKPI80211, M_WAITOK | M_ZERO);
1459 kc->_k = k; /* Save the pointer to net80211. */
1460 kc->cipher = lcipher;
1461 kc->keyidx = k->wk_keyix;
1462 #if 0
1463 kc->hw_key_idx = /* set by hw and needs to be passed for TX */;
1464 #endif
1465 atomic64_set(&kc->tx_pn, k->wk_keytsc);
1466 kc->keylen = k->wk_keylen;
1467 memcpy(kc->key, k->wk_key, k->wk_keylen);
1468
1469 if (k->wk_flags & (IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV))
1470 kc->flags |= IEEE80211_KEY_FLAG_PAIRWISE;
1471 if (k->wk_flags & IEEE80211_KEY_GROUP)
1472 kc->flags &= ~IEEE80211_KEY_FLAG_PAIRWISE;
1473
1474 kc->iv_len = k->wk_cipher->ic_header;
1475 kc->icv_len = k->wk_cipher->ic_trailer;
1476
1477 switch (kc->cipher) {
1478 case WLAN_CIPHER_SUITE_TKIP:
1479 memcpy(kc->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY, k->wk_txmic, k->wk_cipher->ic_miclen);
1480 memcpy(kc->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY, k->wk_rxmic, k->wk_cipher->ic_miclen);
1481 break;
1482 case WLAN_CIPHER_SUITE_CCMP:
1483 case WLAN_CIPHER_SUITE_GCMP:
1484 break;
1485 default:
1486 /* currently UNREACH */
1487 IMPROVE();
1488 break;
1489 };
1490 lsta->kc[k->wk_keyix] = kc;
1491
1492 #ifdef LINUXKPI_DEBUG_80211
1493 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1494 ic_printf(ic, "%d %lu %s: running set_key cmd %d(%s) for sta %6D: "
1495 "kc %p keyidx %u hw_key_idx %u keylen %u flags %b\n",
1496 curthread->td_tid, jiffies, __func__,
1497 SET_KEY, "SET", sta->addr, ":", kc, kc->keyidx, kc->hw_key_idx,
1498 kc->keylen, kc->flags, IEEE80211_KEY_FLAG_BITS);
1499 #endif
1500
1501 lvif = VAP_TO_LVIF(vap);
1502 vif = LVIF_TO_VIF(lvif);
1503 error = lkpi_80211_mo_set_key(hw, SET_KEY, vif, sta, kc);
1504 if (error != 0) {
1505 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D failed: %d\n",
1506 curthread->td_tid, jiffies, __func__,
1507 SET_KEY, "SET", sta->addr, ":", error);
1508 lsta->kc[k->wk_keyix] = NULL;
1509 free(kc, M_LKPI80211);
1510 ieee80211_free_node(ni);
1511 return (0);
1512 }
1513
1514 #ifdef LINUXKPI_DEBUG_80211
1515 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1516 ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D succeeded: "
1517 "kc %p keyidx %u hw_key_idx %u flags %b\n",
1518 curthread->td_tid, jiffies, __func__,
1519 SET_KEY, "SET", sta->addr, ":",
1520 kc, kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
1521 #endif
1522
1523 exp_flags = 0;
1524 switch (kc->cipher) {
1525 case WLAN_CIPHER_SUITE_TKIP:
1526 exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
1527 IEEE80211_KEY_FLAG_PUT_IV_SPACE |
1528 IEEE80211_KEY_FLAG_GENERATE_MMIC |
1529 IEEE80211_KEY_FLAG_PUT_MIC_SPACE);
1530 #define TKIP_INVAL_COMBINATION \
1531 (IEEE80211_KEY_FLAG_PUT_MIC_SPACE|IEEE80211_KEY_FLAG_GENERATE_MMIC)
1532 if ((kc->flags & TKIP_INVAL_COMBINATION) == TKIP_INVAL_COMBINATION) {
1533 ic_printf(ic, "%s: SET_KEY for %s returned invalid "
1534 "combination %b\n", __func__,
1535 lkpi_cipher_suite_to_name(kc->cipher),
1536 kc->flags, IEEE80211_KEY_FLAG_BITS);
1537 }
1538 #undef TKIP_INVAL_COMBINATION
1539 #ifdef __notyet__
1540 /* Do flags surgery; special see linuxkpi_ieee80211_ifattach(). */
1541 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) != 0) {
1542 k->wk_flags &= ~(IEEE80211_KEY_NOMICMGT|IEEE80211_KEY_NOMIC);
1543 k->wk_flags |= IEEE80211_KEY_SWMIC;
1544 ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC
1545 }
1546 #endif
1547 break;
1548 case WLAN_CIPHER_SUITE_CCMP:
1549 case WLAN_CIPHER_SUITE_GCMP:
1550 exp_flags = (IEEE80211_KEY_FLAG_PAIRWISE |
1551 IEEE80211_KEY_FLAG_PUT_IV_SPACE |
1552 IEEE80211_KEY_FLAG_GENERATE_IV |
1553 IEEE80211_KEY_FLAG_GENERATE_IV_MGMT | /* Only needs IV geeration for MGMT frames. */
1554 IEEE80211_KEY_FLAG_SW_MGMT_TX); /* MFP in software */
1555 break;
1556 }
1557 if ((kc->flags & ~exp_flags) != 0)
1558 ic_printf(ic, "%s: SET_KEY for %s returned unexpected key flags: "
1559 " %#06x & ~%#06x = %b\n", __func__,
1560 lkpi_cipher_suite_to_name(kc->cipher), kc->flags, exp_flags,
1561 (kc->flags & ~exp_flags), IEEE80211_KEY_FLAG_BITS);
1562
1563 #ifdef __notyet__
1564 /* Do flags surgery. */
1565 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) == 0)
1566 k->wk_flags |= IEEE80211_KEY_NOIVMGT;
1567 if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
1568 k->wk_flags |= IEEE80211_KEY_NOIV;
1569 #endif
1570
1571 ieee80211_free_node(ni);
1572 return (1);
1573 }
1574
1575 static void
lkpi_iv_key_update_begin(struct ieee80211vap * vap)1576 lkpi_iv_key_update_begin(struct ieee80211vap *vap)
1577 {
1578 struct ieee80211_node_table *nt;
1579 struct ieee80211com *ic;
1580 struct lkpi_hw *lhw;
1581 struct ieee80211_hw *hw;
1582 struct lkpi_vif *lvif;
1583 struct ieee80211_node *ni;
1584 bool icislocked, ntislocked;
1585
1586 ic = vap->iv_ic;
1587 lhw = ic->ic_softc;
1588 hw = LHW_TO_HW(lhw);
1589 lvif = VAP_TO_LVIF(vap);
1590 nt = &ic->ic_sta;
1591
1592 icislocked = IEEE80211_IS_LOCKED(ic);
1593 ntislocked = IEEE80211_NODE_IS_LOCKED(nt);
1594
1595 #ifdef LINUXKPI_DEBUG_80211
1596 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1597 ic_printf(ic, "%d %lu %s: vap %p ic %p %slocked nt %p %slocked "
1598 "lvif ic_unlocked %d nt_unlocked %d\n",
1599 curthread->td_tid, jiffies, __func__, vap,
1600 ic, icislocked ? "" : "un", nt, ntislocked ? "" : "un",
1601 lvif->ic_unlocked, lvif->nt_unlocked);
1602 #endif
1603
1604 /*
1605 * This is inconsistent net80211 locking to be fixed one day.
1606 */
1607 /* Try to make sure the node does not go away while possibly unlocked. */
1608 ni = NULL;
1609 if (icislocked || ntislocked) {
1610 if (vap->iv_bss != NULL)
1611 ni = ieee80211_ref_node(vap->iv_bss);
1612 }
1613
1614 if (icislocked)
1615 IEEE80211_UNLOCK(ic);
1616 if (ntislocked)
1617 IEEE80211_NODE_UNLOCK(nt);
1618
1619 wiphy_lock(hw->wiphy);
1620
1621 KASSERT(lvif->key_update_iv_bss == NULL, ("%s: key_update_iv_bss not NULL %p",
1622 __func__, lvif->key_update_iv_bss));
1623 lvif->key_update_iv_bss = ni;
1624
1625 /*
1626 * ic/nt_unlocked could be a bool given we are under the lock and there
1627 * must only be a single thread.
1628 * In case anything in the future disturbs the order the refcnt will
1629 * help us catching problems a lot easier.
1630 */
1631 if (icislocked)
1632 refcount_acquire(&lvif->ic_unlocked);
1633 if (ntislocked)
1634 refcount_acquire(&lvif->nt_unlocked);
1635
1636 /*
1637 * Stop the queues while doing key updates.
1638 */
1639 ieee80211_stop_queues(hw);
1640 }
1641
1642 static void
lkpi_iv_key_update_end(struct ieee80211vap * vap)1643 lkpi_iv_key_update_end(struct ieee80211vap *vap)
1644 {
1645 struct ieee80211_node_table *nt;
1646 struct ieee80211com *ic;
1647 struct lkpi_hw *lhw;
1648 struct ieee80211_hw *hw;
1649 struct lkpi_vif *lvif;
1650 bool icislocked, ntislocked;
1651
1652 ic = vap->iv_ic;
1653 lhw = ic->ic_softc;
1654 hw = LHW_TO_HW(lhw);
1655 lvif = VAP_TO_LVIF(vap);
1656 nt = &ic->ic_sta;
1657
1658 /*
1659 * Re-enabled the queues after the key update.
1660 */
1661 lkpi_ieee80211_wake_queues_locked(hw);
1662
1663 icislocked = IEEE80211_IS_LOCKED(ic);
1664 MPASS(!icislocked);
1665 ntislocked = IEEE80211_NODE_IS_LOCKED(nt);
1666 MPASS(!ntislocked);
1667
1668 #ifdef LINUXKPI_DEBUG_80211
1669 if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO)
1670 ic_printf(ic, "%d %lu %s: vap %p ic %p %slocked nt %p %slocked "
1671 "lvif ic_unlocked %d nt_unlocked %d\n",
1672 curthread->td_tid, jiffies, __func__, vap,
1673 ic, icislocked ? "" : "un", nt, ntislocked ? "" : "un",
1674 lvif->ic_unlocked, lvif->nt_unlocked);
1675 #endif
1676
1677 /*
1678 * Check under lock; see comment in lkpi_iv_key_update_begin().
1679 * In case the refcnt gets out of sync locking in net80211 will
1680 * quickly barf as well (trying to unlock a lock not held).
1681 */
1682 icislocked = refcount_release_if_last(&lvif->ic_unlocked);
1683 ntislocked = refcount_release_if_last(&lvif->nt_unlocked);
1684
1685 if (lvif->key_update_iv_bss != NULL) {
1686 ieee80211_free_node(lvif->key_update_iv_bss);
1687 lvif->key_update_iv_bss = NULL;
1688 }
1689
1690 wiphy_unlock(hw->wiphy);
1691
1692 /*
1693 * This is inconsistent net80211 locking to be fixed one day.
1694 * ic before nt to avoid a LOR.
1695 */
1696 if (icislocked)
1697 IEEE80211_LOCK(ic);
1698 if (ntislocked)
1699 IEEE80211_NODE_LOCK(nt);
1700 }
1701 #endif
1702
1703 static u_int
lkpi_ic_update_mcast_copy(void * arg,struct sockaddr_dl * sdl,u_int cnt)1704 lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt)
1705 {
1706 struct netdev_hw_addr_list *mc_list;
1707 struct netdev_hw_addr *addr;
1708
1709 KASSERT(arg != NULL && sdl != NULL, ("%s: arg %p sdl %p cnt %u\n",
1710 __func__, arg, sdl, cnt));
1711
1712 mc_list = arg;
1713 /* If it is on the list already skip it. */
1714 netdev_hw_addr_list_for_each(addr, mc_list) {
1715 if (!memcmp(addr->addr, LLADDR(sdl), sdl->sdl_alen))
1716 return (0);
1717 }
1718
1719 addr = malloc(sizeof(*addr), M_LKPI80211, M_NOWAIT | M_ZERO);
1720 if (addr == NULL)
1721 return (0);
1722
1723 INIT_LIST_HEAD(&addr->addr_list);
1724 memcpy(addr->addr, LLADDR(sdl), sdl->sdl_alen);
1725 /* XXX this should be a netdev function? */
1726 list_add(&addr->addr_list, &mc_list->addr_list);
1727 mc_list->count++;
1728
1729 #ifdef LINUXKPI_DEBUG_80211
1730 if (linuxkpi_debug_80211 & D80211_TRACE)
1731 printf("%s:%d: mc_list count %d: added %6D\n",
1732 __func__, __LINE__, mc_list->count, addr->addr, ":");
1733 #endif
1734
1735 return (1);
1736 }
1737
1738 static void
lkpi_update_mcast_filter(struct ieee80211com * ic,bool force)1739 lkpi_update_mcast_filter(struct ieee80211com *ic, bool force)
1740 {
1741 struct lkpi_hw *lhw;
1742 struct ieee80211_hw *hw;
1743 struct netdev_hw_addr_list mc_list;
1744 struct list_head *le, *next;
1745 struct netdev_hw_addr *addr;
1746 struct ieee80211vap *vap;
1747 u64 mc;
1748 unsigned int changed_flags, total_flags;
1749
1750 lhw = ic->ic_softc;
1751
1752 if (lhw->ops->prepare_multicast == NULL ||
1753 lhw->ops->configure_filter == NULL)
1754 return;
1755
1756 if (!lhw->update_mc && !force)
1757 return;
1758
1759 changed_flags = total_flags = 0;
1760 mc_list.count = 0;
1761 INIT_LIST_HEAD(&mc_list.addr_list);
1762 if (ic->ic_allmulti == 0) {
1763 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
1764 if_foreach_llmaddr(vap->iv_ifp,
1765 lkpi_ic_update_mcast_copy, &mc_list);
1766 } else {
1767 changed_flags |= FIF_ALLMULTI;
1768 }
1769
1770 hw = LHW_TO_HW(lhw);
1771 mc = lkpi_80211_mo_prepare_multicast(hw, &mc_list);
1772 /*
1773 * XXX-BZ make sure to get this sorted what is a change,
1774 * what gets all set; what was already set?
1775 */
1776 total_flags = changed_flags;
1777 lkpi_80211_mo_configure_filter(hw, changed_flags, &total_flags, mc);
1778
1779 #ifdef LINUXKPI_DEBUG_80211
1780 if (linuxkpi_debug_80211 & D80211_TRACE)
1781 printf("%s: changed_flags %#06x count %d total_flags %#010x\n",
1782 __func__, changed_flags, mc_list.count, total_flags);
1783 #endif
1784
1785 if (mc_list.count != 0) {
1786 list_for_each_safe(le, next, &mc_list.addr_list) {
1787 addr = list_entry(le, struct netdev_hw_addr, addr_list);
1788 free(addr, M_LKPI80211);
1789 mc_list.count--;
1790 }
1791 }
1792 KASSERT(mc_list.count == 0, ("%s: mc_list %p count %d != 0\n",
1793 __func__, &mc_list, mc_list.count));
1794 }
1795
1796 static enum ieee80211_bss_changed
lkpi_update_dtim_tsf(struct ieee80211_vif * vif,struct ieee80211_node * ni,struct ieee80211vap * vap,const char * _f,int _l)1797 lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct ieee80211_node *ni,
1798 struct ieee80211vap *vap, const char *_f, int _l)
1799 {
1800 enum ieee80211_bss_changed bss_changed;
1801
1802 bss_changed = 0;
1803
1804 #ifdef LINUXKPI_DEBUG_80211
1805 if (linuxkpi_debug_80211 & D80211_TRACE)
1806 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
1807 "dtim_period %u sync_dtim_count %u sync_tsf %ju "
1808 "sync_device_ts %u bss_changed %#010jx\n",
1809 __func__, __LINE__, _f, _l,
1810 vif->cfg.assoc, vif->cfg.aid,
1811 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
1812 vif->bss_conf.sync_dtim_count,
1813 (uintmax_t)vif->bss_conf.sync_tsf,
1814 vif->bss_conf.sync_device_ts,
1815 (uintmax_t)bss_changed);
1816 #endif
1817
1818 if (vif->bss_conf.beacon_int != ni->ni_intval) {
1819 vif->bss_conf.beacon_int = ni->ni_intval;
1820 /* iwlwifi FW bug workaround; iwl_mvm_mac_sta_state. */
1821 if (vif->bss_conf.beacon_int < 16)
1822 vif->bss_conf.beacon_int = 16;
1823 bss_changed |= BSS_CHANGED_BEACON_INT;
1824 }
1825 if (vif->bss_conf.dtim_period != vap->iv_dtim_period &&
1826 vap->iv_dtim_period > 0) {
1827 vif->bss_conf.dtim_period = vap->iv_dtim_period;
1828 bss_changed |= BSS_CHANGED_BEACON_INFO;
1829 }
1830
1831 vif->bss_conf.sync_dtim_count = vap->iv_dtim_count;
1832 vif->bss_conf.sync_tsf = le64toh(ni->ni_tstamp.tsf);
1833 /* vif->bss_conf.sync_device_ts = set in linuxkpi_ieee80211_rx. */
1834
1835 #ifdef LINUXKPI_DEBUG_80211
1836 if (linuxkpi_debug_80211 & D80211_TRACE)
1837 printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
1838 "dtim_period %u sync_dtim_count %u sync_tsf %ju "
1839 "sync_device_ts %u bss_changed %#010jx\n",
1840 __func__, __LINE__, _f, _l,
1841 vif->cfg.assoc, vif->cfg.aid,
1842 vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
1843 vif->bss_conf.sync_dtim_count,
1844 (uintmax_t)vif->bss_conf.sync_tsf,
1845 vif->bss_conf.sync_device_ts,
1846 (uintmax_t)bss_changed);
1847 #endif
1848
1849 return (bss_changed);
1850 }
1851
1852 static void
lkpi_stop_hw_scan(struct lkpi_hw * lhw,struct ieee80211_vif * vif)1853 lkpi_stop_hw_scan(struct lkpi_hw *lhw, struct ieee80211_vif *vif)
1854 {
1855 struct ieee80211_hw *hw;
1856 int error;
1857 bool cancel;
1858
1859 LKPI_80211_LHW_SCAN_LOCK(lhw);
1860 cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
1861 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
1862 if (!cancel)
1863 return;
1864
1865 hw = LHW_TO_HW(lhw);
1866
1867 IEEE80211_UNLOCK(lhw->ic);
1868 wiphy_lock(hw->wiphy);
1869 /* Need to cancel the scan. */
1870 lkpi_80211_mo_cancel_hw_scan(hw, vif);
1871 wiphy_unlock(hw->wiphy);
1872
1873 /* Need to make sure we see ieee80211_scan_completed. */
1874 LKPI_80211_LHW_SCAN_LOCK(lhw);
1875 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0)
1876 error = msleep(lhw, &lhw->scan_mtx, 0, "lhwscanstop", hz/2);
1877 cancel = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
1878 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
1879
1880 IEEE80211_LOCK(lhw->ic);
1881
1882 if (cancel)
1883 ic_printf(lhw->ic, "%s: failed to cancel scan: %d (%p, %p)\n",
1884 __func__, error, lhw, vif);
1885 }
1886
1887 static void
lkpi_hw_conf_idle(struct ieee80211_hw * hw,bool new)1888 lkpi_hw_conf_idle(struct ieee80211_hw *hw, bool new)
1889 {
1890 struct lkpi_hw *lhw;
1891 int error;
1892 bool old;
1893
1894 old = hw->conf.flags & IEEE80211_CONF_IDLE;
1895 if (old == new)
1896 return;
1897
1898 hw->conf.flags ^= IEEE80211_CONF_IDLE;
1899 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_IDLE);
1900 if (error != 0 && error != EOPNOTSUPP) {
1901 lhw = HW_TO_LHW(hw);
1902 ic_printf(lhw->ic, "ERROR: %s: config %#0x returned %d\n",
1903 __func__, IEEE80211_CONF_CHANGE_IDLE, error);
1904 }
1905 }
1906
1907 static enum ieee80211_bss_changed
lkpi_disassoc(struct ieee80211_sta * sta,struct ieee80211_vif * vif,struct lkpi_hw * lhw)1908 lkpi_disassoc(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
1909 struct lkpi_hw *lhw)
1910 {
1911 enum ieee80211_bss_changed changed;
1912
1913 changed = 0;
1914 sta->aid = 0;
1915 if (vif->cfg.assoc) {
1916
1917 lhw->update_mc = true;
1918 lkpi_update_mcast_filter(lhw->ic, true);
1919
1920 vif->cfg.assoc = false;
1921 vif->cfg.aid = 0;
1922 changed |= BSS_CHANGED_ASSOC;
1923 IMPROVE();
1924
1925 /*
1926 * Executing the bss_info_changed(BSS_CHANGED_ASSOC) with
1927 * assoc = false right away here will remove the sta from
1928 * firmware for iwlwifi.
1929 * We no longer do this but only return the BSS_CHNAGED value.
1930 * The caller is responsible for removing the sta gong to
1931 * IEEE80211_STA_NOTEXIST and then executing the
1932 * bss_info_changed() update.
1933 * See lkpi_sta_run_to_init() for more detailed comment.
1934 */
1935 }
1936
1937 return (changed);
1938 }
1939
1940 static void
lkpi_wake_tx_queues(struct ieee80211_hw * hw,struct ieee80211_sta * sta,bool dequeue_seen,bool no_emptyq)1941 lkpi_wake_tx_queues(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
1942 bool dequeue_seen, bool no_emptyq)
1943 {
1944 struct lkpi_txq *ltxq;
1945 int tid;
1946 bool ltxq_empty;
1947
1948 /* Wake up all queues to know they are allocated in the driver. */
1949 for (tid = 0; tid < nitems(sta->txq); tid++) {
1950
1951 if (tid == IEEE80211_NUM_TIDS) {
1952 IMPROVE("station specific?");
1953 if (!ieee80211_hw_check(hw, STA_MMPDU_TXQ))
1954 continue;
1955 } else if (tid >= hw->queues)
1956 continue;
1957
1958 if (sta->txq[tid] == NULL)
1959 continue;
1960
1961 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
1962 if (dequeue_seen && !ltxq->seen_dequeue)
1963 continue;
1964
1965 LKPI_80211_LTXQ_LOCK(ltxq);
1966 ltxq_empty = skb_queue_empty(<xq->skbq);
1967 LKPI_80211_LTXQ_UNLOCK(ltxq);
1968 if (no_emptyq && ltxq_empty)
1969 continue;
1970
1971 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]);
1972 }
1973 }
1974
1975 /*
1976 * On the way down from RUN -> ASSOC -> AUTH we may send a DISASSOC or DEAUTH
1977 * packet. The problem is that the state machine functions tend to hold the
1978 * LHW lock which will prevent lkpi_80211_txq_tx_one() from sending the packet.
1979 * We call this after dropping the ic lock and before acquiring the LHW lock.
1980 * we make sure no further packets are queued and if they are queued the task
1981 * will finish or be cancelled. At the end if a packet is left we manually
1982 * send it. scan_to_auth() would re-enable sending if the lsta would be
1983 * re-used.
1984 */
1985 static void
lkpi_80211_flush_tx(struct lkpi_hw * lhw,struct lkpi_sta * lsta)1986 lkpi_80211_flush_tx(struct lkpi_hw *lhw, struct lkpi_sta *lsta)
1987 {
1988 struct ieee80211_hw *hw;
1989 struct mbufq mq;
1990 struct mbuf *m;
1991 int len;
1992
1993 /* There is no lockdep_assert_not_held_wiphy(). */
1994 hw = LHW_TO_HW(lhw);
1995 lockdep_assert_not_held(&hw->wiphy->mtx);
1996
1997 /* Do not accept any new packets until scan_to_auth or lsta_free(). */
1998 LKPI_80211_LSTA_TXQ_LOCK(lsta);
1999 lsta->txq_ready = false;
2000 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2001
2002 while (taskqueue_cancel(taskqueue_thread, &lsta->txq_task, NULL) != 0)
2003 taskqueue_drain(taskqueue_thread, &lsta->txq_task);
2004
2005 LKPI_80211_LSTA_TXQ_LOCK(lsta);
2006 len = mbufq_len(&lsta->txq);
2007 if (len <= 0) {
2008 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2009 return;
2010 }
2011
2012 mbufq_init(&mq, IFQ_MAXLEN);
2013 mbufq_concat(&mq, &lsta->txq);
2014 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2015
2016 m = mbufq_dequeue(&mq);
2017 while (m != NULL) {
2018 lkpi_80211_txq_tx_one(lsta, m);
2019 m = mbufq_dequeue(&mq);
2020 }
2021 }
2022
2023
2024 static void
lkpi_remove_chanctx(struct ieee80211_hw * hw,struct ieee80211_vif * vif)2025 lkpi_remove_chanctx(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2026 {
2027 struct ieee80211_chanctx_conf *chanctx_conf;
2028 struct lkpi_chanctx *lchanctx;
2029
2030 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
2031 lockdep_is_held(&hw->wiphy->mtx));
2032
2033 if (chanctx_conf == NULL)
2034 return;
2035
2036 /* Remove vif context. */
2037 lkpi_80211_mo_unassign_vif_chanctx(hw, vif, &vif->bss_conf, chanctx_conf);
2038
2039 lkpi_hw_conf_idle(hw, true);
2040
2041 /* Remove chan ctx. */
2042 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2043
2044 /* Cleanup. */
2045 rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL);
2046 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2047 list_del(&lchanctx->entry);
2048 free(lchanctx, M_LKPI80211);
2049 }
2050
2051
2052 /* -------------------------------------------------------------------------- */
2053
2054 static int
lkpi_sta_state_do_nada(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2055 lkpi_sta_state_do_nada(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2056 {
2057
2058 return (0);
2059 }
2060
2061 /* lkpi_iv_newstate() handles the stop scan case generally. */
2062 #define lkpi_sta_scan_to_init(_v, _n, _a) lkpi_sta_state_do_nada(_v, _n, _a)
2063
2064 static int
lkpi_sta_scan_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2065 lkpi_sta_scan_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2066 {
2067 struct linuxkpi_ieee80211_channel *chan;
2068 struct lkpi_chanctx *lchanctx;
2069 struct ieee80211_chanctx_conf *chanctx_conf;
2070 struct lkpi_hw *lhw;
2071 struct ieee80211_hw *hw;
2072 struct lkpi_vif *lvif;
2073 struct ieee80211_vif *vif;
2074 struct ieee80211_node *ni;
2075 struct lkpi_sta *lsta;
2076 enum ieee80211_bss_changed bss_changed;
2077 struct ieee80211_prep_tx_info prep_tx_info;
2078 uint32_t changed;
2079 int error;
2080 bool synched;
2081
2082 /*
2083 * In here we use vap->iv_bss until lvif->lvif_bss is set.
2084 * For all later (STATE >= AUTH) functions we need to use the lvif
2085 * cache which will be tracked even through (*iv_update_bss)().
2086 */
2087
2088 if (vap->iv_bss == NULL) {
2089 ic_printf(vap->iv_ic, "%s: no iv_bss for vap %p\n", __func__, vap);
2090 return (EINVAL);
2091 }
2092 /*
2093 * Keep the ni alive locally. In theory (and practice) iv_bss can change
2094 * once we unlock here. This is due to net80211 allowing state changes
2095 * and new join1() despite having an active node as well as due to
2096 * the fact that the iv_bss can be swapped under the hood in (*iv_update_bss).
2097 */
2098 ni = ieee80211_ref_node(vap->iv_bss);
2099 if (ni->ni_chan == NULL || ni->ni_chan == IEEE80211_CHAN_ANYC) {
2100 ic_printf(vap->iv_ic, "%s: no channel set for iv_bss ni %p "
2101 "on vap %p\n", __func__, ni, vap);
2102 ieee80211_free_node(ni); /* Error handling for the local ni. */
2103 return (EINVAL);
2104 }
2105
2106 lhw = vap->iv_ic->ic_softc;
2107 chan = lkpi_find_lkpi80211_chan(lhw, ni->ni_chan);
2108 if (chan == NULL) {
2109 ic_printf(vap->iv_ic, "%s: failed to get LKPI channel from "
2110 "iv_bss ni %p on vap %p\n", __func__, ni, vap);
2111 ieee80211_free_node(ni); /* Error handling for the local ni. */
2112 return (ESRCH);
2113 }
2114
2115 hw = LHW_TO_HW(lhw);
2116 lvif = VAP_TO_LVIF(vap);
2117 vif = LVIF_TO_VIF(lvif);
2118
2119 LKPI_80211_LVIF_LOCK(lvif);
2120 /* XXX-BZ KASSERT later? */
2121 if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL) {
2122 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2123 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2124 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2125 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2126 lvif->lvif_bss_synched);
2127 LKPI_80211_LVIF_UNLOCK(lvif);
2128 ieee80211_free_node(ni); /* Error handling for the local ni. */
2129 return (EBUSY);
2130 }
2131 LKPI_80211_LVIF_UNLOCK(lvif);
2132
2133 IEEE80211_UNLOCK(vap->iv_ic);
2134 wiphy_lock(hw->wiphy);
2135
2136 /* Add chanctx (or if exists, change it). */
2137 chanctx_conf = rcu_dereference_protected(vif->bss_conf.chanctx_conf,
2138 lockdep_is_held(&hw->wiphy->mtx));
2139 if (chanctx_conf != NULL) {
2140 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2141 IMPROVE("diff changes for changed, working on live copy, rcu");
2142 } else {
2143 /* Keep separate alloc as in Linux this is rcu managed? */
2144 lchanctx = malloc(sizeof(*lchanctx) + hw->chanctx_data_size,
2145 M_LKPI80211, M_WAITOK | M_ZERO);
2146 chanctx_conf = &lchanctx->chanctx_conf;
2147 }
2148
2149 chanctx_conf->rx_chains_static = 1;
2150 chanctx_conf->rx_chains_dynamic = 1;
2151 chanctx_conf->radar_enabled =
2152 (chan->flags & IEEE80211_CHAN_RADAR) ? true : false;
2153 chanctx_conf->def.chan = chan;
2154 chanctx_conf->def.width = NL80211_CHAN_WIDTH_20_NOHT;
2155 chanctx_conf->def.center_freq1 = ieee80211_get_channel_center_freq1(ni->ni_chan);
2156 chanctx_conf->def.center_freq2 = ieee80211_get_channel_center_freq2(ni->ni_chan);
2157 IMPROVE("Check vht_cap from band not just chan?");
2158 KASSERT(ni->ni_chan != NULL && ni->ni_chan != IEEE80211_CHAN_ANYC,
2159 ("%s:%d: ni %p ni_chan %p\n", __func__, __LINE__, ni, ni->ni_chan));
2160
2161 #ifdef LKPI_80211_HT
2162 if (IEEE80211_IS_CHAN_HT(ni->ni_chan)) {
2163 if (IEEE80211_IS_CHAN_HT40(ni->ni_chan))
2164 chanctx_conf->def.width = NL80211_CHAN_WIDTH_40;
2165 else
2166 chanctx_conf->def.width = NL80211_CHAN_WIDTH_20;
2167 }
2168 #endif
2169 #ifdef LKPI_80211_VHT
2170 if (IEEE80211_IS_CHAN_VHT_5GHZ(ni->ni_chan)) {
2171 if (IEEE80211_IS_CHAN_VHT80P80(ni->ni_chan))
2172 chanctx_conf->def.width = NL80211_CHAN_WIDTH_80P80;
2173 else if (IEEE80211_IS_CHAN_VHT160(ni->ni_chan))
2174 chanctx_conf->def.width = NL80211_CHAN_WIDTH_160;
2175 else if (IEEE80211_IS_CHAN_VHT80(ni->ni_chan))
2176 chanctx_conf->def.width = NL80211_CHAN_WIDTH_80;
2177 }
2178 #endif
2179 chanctx_conf->rx_chains_dynamic = lkpi_get_max_rx_chains(ni);
2180 /* Responder ... */
2181 #if 0
2182 chanctx_conf->min_def.chan = chanctx_conf->def.chan;
2183 chanctx_conf->min_def.width = NL80211_CHAN_WIDTH_20_NOHT;
2184 #ifdef LKPI_80211_HT
2185 if (IEEE80211_IS_CHAN_HT(ni->ni_chan) || IEEE80211_IS_CHAN_VHT(ni->ni_chan))
2186 chanctx_conf->min_def.width = NL80211_CHAN_WIDTH_20;
2187 #endif
2188 chanctx_conf->min_def.center_freq1 = chanctx_conf->def.center_freq1;
2189 chanctx_conf->min_def.center_freq2 = chanctx_conf->def.center_freq2;
2190 #else
2191 chanctx_conf->min_def = chanctx_conf->def;
2192 #endif
2193
2194 /* Set bss info (bss_info_changed). */
2195 bss_changed = 0;
2196 vif->bss_conf.bssid = ni->ni_bssid;
2197 bss_changed |= BSS_CHANGED_BSSID;
2198 vif->bss_conf.txpower = ni->ni_txpower;
2199 bss_changed |= BSS_CHANGED_TXPOWER;
2200 vif->cfg.idle = false;
2201 bss_changed |= BSS_CHANGED_IDLE;
2202
2203 /* vif->bss_conf.basic_rates ? Where exactly? */
2204
2205 /* Should almost assert it is this. */
2206 vif->cfg.assoc = false;
2207 vif->cfg.aid = 0;
2208
2209 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2210
2211 error = 0;
2212 if (vif->bss_conf.chanctx_conf == chanctx_conf) {
2213 changed = IEEE80211_CHANCTX_CHANGE_MIN_WIDTH;
2214 changed |= IEEE80211_CHANCTX_CHANGE_RADAR;
2215 changed |= IEEE80211_CHANCTX_CHANGE_RX_CHAINS;
2216 changed |= IEEE80211_CHANCTX_CHANGE_WIDTH;
2217 lkpi_80211_mo_change_chanctx(hw, chanctx_conf, changed);
2218 } else {
2219 error = lkpi_80211_mo_add_chanctx(hw, chanctx_conf);
2220 if (error == 0 || error == EOPNOTSUPP) {
2221 vif->bss_conf.chanreq.oper.chan = chanctx_conf->def.chan;
2222 vif->bss_conf.chanreq.oper.width = chanctx_conf->def.width;
2223 vif->bss_conf.chanreq.oper.center_freq1 =
2224 chanctx_conf->def.center_freq1;
2225 vif->bss_conf.chanreq.oper.center_freq2 =
2226 chanctx_conf->def.center_freq2;
2227 } else {
2228 ic_printf(vap->iv_ic, "%s:%d: mo_add_chanctx "
2229 "failed: %d\n", __func__, __LINE__, error);
2230 goto out;
2231 }
2232
2233 list_add_rcu(&lchanctx->entry, &lhw->lchanctx_list);
2234 rcu_assign_pointer(vif->bss_conf.chanctx_conf, chanctx_conf);
2235
2236 /* Assign vif chanctx. */
2237 if (error == 0)
2238 error = lkpi_80211_mo_assign_vif_chanctx(hw, vif,
2239 &vif->bss_conf, chanctx_conf);
2240 if (error == EOPNOTSUPP)
2241 error = 0;
2242 if (error != 0) {
2243 ic_printf(vap->iv_ic, "%s:%d: mo_assign_vif_chanctx "
2244 "failed: %d\n", __func__, __LINE__, error);
2245 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
2246 rcu_assign_pointer(vif->bss_conf.chanctx_conf, NULL);
2247 lchanctx = CHANCTX_CONF_TO_LCHANCTX(chanctx_conf);
2248 list_del(&lchanctx->entry);
2249 free(lchanctx, M_LKPI80211);
2250 goto out;
2251 }
2252 }
2253 IMPROVE("update radiotap chan fields too");
2254
2255 /* RATES */
2256 IMPROVE("bss info: not all needs to come now and rates are missing");
2257 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2258
2259 /*
2260 * Given ni and lsta are 1:1 from alloc to free we can assert that
2261 * ni always has lsta data attach despite net80211 node swapping
2262 * under the hoods.
2263 */
2264 KASSERT(ni->ni_drv_data != NULL, ("%s: ni %p ni_drv_data %p\n",
2265 __func__, ni, ni->ni_drv_data));
2266 lsta = ni->ni_drv_data;
2267
2268 /* Insert the [l]sta into the list of known stations. */
2269 list_add_tail(&lsta->lsta_list, &lvif->lsta_list);
2270
2271 /* Add (or adjust) sta and change state (from NOTEXIST) to NONE. */
2272 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2273 KASSERT(lsta->state == IEEE80211_STA_NOTEXIST, ("%s: lsta %p state not "
2274 "NOTEXIST: %#x\n", __func__, lsta, lsta->state));
2275 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
2276 if (error != 0) {
2277 IMPROVE("do we need to undo the chan ctx?");
2278 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
2279 "failed: %d\n", __func__, __LINE__, error);
2280 goto out;
2281 }
2282 #if 0
2283 lsta->added_to_drv = true; /* mo manages. */
2284 #endif
2285
2286 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2287
2288 #if 0
2289 /*
2290 * Wakeup all queues now that sta is there so we have as much time to
2291 * possibly prepare the queue in the driver to be ready for the 1st
2292 * packet; lkpi_80211_txq_tx_one() still has a workaround as there
2293 * is no guarantee or way to check.
2294 * XXX-BZ and by now we know that this does not work on all drivers
2295 * for all queues.
2296 */
2297 lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, false);
2298 #endif
2299
2300 /* Start mgd_prepare_tx. */
2301 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2302 prep_tx_info.duration = PREP_TX_INFO_DURATION;
2303 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2304 lsta->in_mgd = true;
2305
2306 /*
2307 * What is going to happen next:
2308 * - <twiddle> .. we should end up in "auth_to_assoc"
2309 * - event_callback
2310 * - update sta_state (NONE to AUTH)
2311 * - mgd_complete_tx
2312 * (ideally we'd do that on a callback for something else ...)
2313 */
2314
2315 wiphy_unlock(hw->wiphy);
2316 IEEE80211_LOCK(vap->iv_ic);
2317
2318 LKPI_80211_LVIF_LOCK(lvif);
2319 /* Re-check given (*iv_update_bss) could have happened while we were unlocked. */
2320 if (lvif->lvif_bss_synched || lvif->lvif_bss != NULL ||
2321 lsta->ni != vap->iv_bss)
2322 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2323 "lvif_bss->ni %p synched %d, ni %p lsta %p\n", __func__, __LINE__,
2324 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2325 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2326 lvif->lvif_bss_synched, ni, lsta);
2327
2328 /*
2329 * Reference the "ni" for caching the lsta/ni in lvif->lvif_bss.
2330 * Given we cache lsta we use lsta->ni instead of ni here (even though
2331 * lsta->ni == ni) to be distinct from the rest of the code where we do
2332 * assume that ni == vap->iv_bss which it may or may not be.
2333 * So do NOT use iv_bss here anymore as that may have diverged from our
2334 * function local ni already while ic was unlocked and would lead to
2335 * inconsistencies. Go and see if we lost a race and do not update
2336 * lvif_bss_synched in that case.
2337 */
2338 ieee80211_ref_node(lsta->ni);
2339 lvif->lvif_bss = lsta;
2340 if (lsta->ni == vap->iv_bss) {
2341 lvif->lvif_bss_synched = synched = true;
2342 } else {
2343 /* Set to un-synched no matter what. */
2344 lvif->lvif_bss_synched = synched = false;
2345 /*
2346 * We do not error as someone has to take us down.
2347 * If we are followed by a 2nd, new net80211::join1() going to
2348 * AUTH lkpi_sta_a_to_a() will error, lkpi_sta_auth_to_{scan,init}()
2349 * will take the lvif->lvif_bss node down eventually.
2350 * What happens with the vap->iv_bss node will entirely be up
2351 * to net80211 as we never used the node beyond alloc()/free()
2352 * and we do not hold an extra reference for that anymore given
2353 * ni : lsta == 1:1.
2354 * Problem is if we do not error a MGMT/AUTH frame will be
2355 * sent from net80211::sta_newstate(); disable lsta queue below.
2356 */
2357 }
2358 LKPI_80211_LVIF_UNLOCK(lvif);
2359 /*
2360 * Make sure in case the sta did not change and we re-added it,
2361 * that we can tx again but only if the vif/iv_bss are in sync.
2362 * Otherwise this should prevent the MGMT/AUTH frame from being
2363 * sent triggering a warning in iwlwifi.
2364 */
2365 LKPI_80211_LSTA_TXQ_LOCK(lsta);
2366 lsta->txq_ready = synched;
2367 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
2368 goto out_relocked;
2369
2370 out:
2371 wiphy_unlock(hw->wiphy);
2372 IEEE80211_LOCK(vap->iv_ic);
2373 out_relocked:
2374 /*
2375 * Release the reference that kept the ni stable locally
2376 * during the work of this function.
2377 */
2378 if (ni != NULL)
2379 ieee80211_free_node(ni);
2380 return (error);
2381 }
2382
2383 static int
lkpi_sta_auth_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2384 lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2385 {
2386 struct lkpi_hw *lhw;
2387 struct ieee80211_hw *hw;
2388 struct lkpi_vif *lvif;
2389 struct ieee80211_vif *vif;
2390 struct ieee80211_node *ni;
2391 struct lkpi_sta *lsta;
2392 struct ieee80211_sta *sta;
2393 struct ieee80211_prep_tx_info prep_tx_info;
2394 int error;
2395
2396 lhw = vap->iv_ic->ic_softc;
2397 hw = LHW_TO_HW(lhw);
2398 lvif = VAP_TO_LVIF(vap);
2399 vif = LVIF_TO_VIF(lvif);
2400
2401 LKPI_80211_LVIF_LOCK(lvif);
2402 #ifdef LINUXKPI_DEBUG_80211
2403 /* XXX-BZ KASSERT later; state going down so no action. */
2404 if (lvif->lvif_bss == NULL)
2405 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2406 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2407 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2408 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2409 lvif->lvif_bss_synched);
2410 #endif
2411
2412 lsta = lvif->lvif_bss;
2413 LKPI_80211_LVIF_UNLOCK(lvif);
2414 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2415 "lvif %p vap %p\n", __func__,
2416 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2417 ni = lsta->ni; /* Reference held for lvif_bss. */
2418 sta = LSTA_TO_STA(lsta);
2419
2420 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2421
2422 IEEE80211_UNLOCK(vap->iv_ic);
2423 wiphy_lock(hw->wiphy);
2424
2425 /* flush, drop. */
2426 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
2427
2428 /* Wake tx queues to get packet(s) out. */
2429 lkpi_wake_tx_queues(hw, sta, false, true);
2430
2431 /* flush, no drop */
2432 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
2433
2434 /* End mgd_complete_tx. */
2435 if (lsta->in_mgd) {
2436 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2437 prep_tx_info.success = false;
2438 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2439 lsta->in_mgd = false;
2440 }
2441
2442 /* sync_rx_queues */
2443 lkpi_80211_mo_sync_rx_queues(hw);
2444
2445 /* sta_pre_rcu_remove */
2446 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
2447
2448 /* Take the station down. */
2449
2450 /* Adjust sta and change state (from NONE) to NOTEXIST. */
2451 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2452 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2453 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
2454 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
2455 if (error != 0) {
2456 IMPROVE("do we need to undo the chan ctx?");
2457 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
2458 "failed: %d\n", __func__, __LINE__, error);
2459 goto out;
2460 }
2461 #if 0
2462 lsta->added_to_drv = false; /* mo manages. */
2463 #endif
2464
2465 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2466
2467 LKPI_80211_LVIF_LOCK(lvif);
2468 /* Remove ni reference for this cache of lsta. */
2469 lvif->lvif_bss = NULL;
2470 lvif->lvif_bss_synched = false;
2471 LKPI_80211_LVIF_UNLOCK(lvif);
2472 lkpi_lsta_remove(lsta, lvif);
2473 /*
2474 * The very last release the reference on the ni for the ni/lsta on
2475 * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
2476 * and potentially freed.
2477 */
2478 ieee80211_free_node(ni);
2479
2480 /* conf_tx */
2481
2482 lkpi_remove_chanctx(hw, vif);
2483
2484 out:
2485 wiphy_unlock(hw->wiphy);
2486 IEEE80211_LOCK(vap->iv_ic);
2487 return (error);
2488 }
2489
2490 static int
lkpi_sta_auth_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2491 lkpi_sta_auth_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2492 {
2493 int error;
2494
2495 error = lkpi_sta_auth_to_scan(vap, nstate, arg);
2496 if (error == 0)
2497 error = lkpi_sta_scan_to_init(vap, nstate, arg);
2498 return (error);
2499 }
2500
2501 static int
lkpi_sta_auth_to_assoc(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2502 lkpi_sta_auth_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2503 {
2504 struct lkpi_hw *lhw;
2505 struct ieee80211_hw *hw;
2506 struct lkpi_vif *lvif;
2507 struct ieee80211_vif *vif;
2508 struct lkpi_sta *lsta;
2509 struct ieee80211_prep_tx_info prep_tx_info;
2510 int error;
2511
2512 lhw = vap->iv_ic->ic_softc;
2513 hw = LHW_TO_HW(lhw);
2514 lvif = VAP_TO_LVIF(vap);
2515 vif = LVIF_TO_VIF(lvif);
2516
2517 IEEE80211_UNLOCK(vap->iv_ic);
2518 wiphy_lock(hw->wiphy);
2519
2520 LKPI_80211_LVIF_LOCK(lvif);
2521 /* XXX-BZ KASSERT later? */
2522 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2523 #ifdef LINUXKPI_DEBUG_80211
2524 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2525 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2526 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2527 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2528 lvif->lvif_bss_synched);
2529 #endif
2530 error = ENOTRECOVERABLE;
2531 LKPI_80211_LVIF_UNLOCK(lvif);
2532 goto out;
2533 }
2534 lsta = lvif->lvif_bss;
2535 LKPI_80211_LVIF_UNLOCK(lvif);
2536
2537 KASSERT(lsta != NULL, ("%s: lsta %p\n", __func__, lsta));
2538
2539 /* Finish auth. */
2540 IMPROVE("event callback");
2541
2542 /* Update sta_state (NONE to AUTH). */
2543 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2544 "NONE: %#x\n", __func__, lsta, lsta->state));
2545 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
2546 if (error != 0) {
2547 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
2548 "failed: %d\n", __func__, __LINE__, error);
2549 goto out;
2550 }
2551
2552 /* End mgd_complete_tx. */
2553 if (lsta->in_mgd) {
2554 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2555 prep_tx_info.success = true;
2556 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2557 lsta->in_mgd = false;
2558 }
2559
2560 /* Now start assoc. */
2561
2562 /* Start mgd_prepare_tx. */
2563 if (!lsta->in_mgd) {
2564 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2565 prep_tx_info.duration = PREP_TX_INFO_DURATION;
2566 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2567 lsta->in_mgd = true;
2568 }
2569
2570 /* Wake tx queue to get packet out. */
2571 lkpi_wake_tx_queues(hw, LSTA_TO_STA(lsta), false, true);
2572
2573 /*
2574 * <twiddle> .. we end up in "assoc_to_run"
2575 * - update sta_state (AUTH to ASSOC)
2576 * - conf_tx [all]
2577 * - bss_info_changed (assoc, aid, ssid, ..)
2578 * - change_chanctx (if needed)
2579 * - event_callback
2580 * - mgd_complete_tx
2581 */
2582
2583 out:
2584 wiphy_unlock(hw->wiphy);
2585 IEEE80211_LOCK(vap->iv_ic);
2586 return (error);
2587 }
2588
2589 /* auth_to_auth, assoc_to_assoc. */
2590 static int
lkpi_sta_a_to_a(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2591 lkpi_sta_a_to_a(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2592 {
2593 struct lkpi_hw *lhw;
2594 struct ieee80211_hw *hw;
2595 struct lkpi_vif *lvif;
2596 struct ieee80211_vif *vif;
2597 struct lkpi_sta *lsta;
2598 struct ieee80211_prep_tx_info prep_tx_info;
2599 int error;
2600
2601 lhw = vap->iv_ic->ic_softc;
2602 hw = LHW_TO_HW(lhw);
2603 lvif = VAP_TO_LVIF(vap);
2604 vif = LVIF_TO_VIF(lvif);
2605
2606 IEEE80211_UNLOCK(vap->iv_ic);
2607 wiphy_lock(hw->wiphy);
2608
2609 LKPI_80211_LVIF_LOCK(lvif);
2610 /* XXX-BZ KASSERT later? */
2611 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2612 #ifdef LINUXKPI_DEBUG_80211
2613 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2614 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2615 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2616 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2617 lvif->lvif_bss_synched);
2618 #endif
2619 LKPI_80211_LVIF_UNLOCK(lvif);
2620 error = ENOTRECOVERABLE;
2621 goto out;
2622 }
2623 lsta = lvif->lvif_bss;
2624 LKPI_80211_LVIF_UNLOCK(lvif);
2625
2626 KASSERT(lsta != NULL, ("%s: lsta %p! lvif %p vap %p\n", __func__,
2627 lsta, lvif, vap));
2628
2629 IMPROVE("event callback?");
2630
2631 /* End mgd_complete_tx. */
2632 if (lsta->in_mgd) {
2633 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2634 prep_tx_info.success = false;
2635 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2636 lsta->in_mgd = false;
2637 }
2638
2639 /* Now start assoc. */
2640
2641 /* Start mgd_prepare_tx. */
2642 if (!lsta->in_mgd) {
2643 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2644 prep_tx_info.duration = PREP_TX_INFO_DURATION;
2645 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2646 lsta->in_mgd = true;
2647 }
2648
2649 error = 0;
2650 out:
2651 wiphy_unlock(hw->wiphy);
2652 IEEE80211_LOCK(vap->iv_ic);
2653
2654 return (error);
2655 }
2656
2657 static int
_lkpi_sta_assoc_to_down(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2658 _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2659 {
2660 struct lkpi_hw *lhw;
2661 struct ieee80211_hw *hw;
2662 struct lkpi_vif *lvif;
2663 struct ieee80211_vif *vif;
2664 struct ieee80211_node *ni;
2665 struct lkpi_sta *lsta;
2666 struct ieee80211_sta *sta;
2667 struct ieee80211_prep_tx_info prep_tx_info;
2668 enum ieee80211_bss_changed bss_changed;
2669 int error;
2670
2671 lhw = vap->iv_ic->ic_softc;
2672 hw = LHW_TO_HW(lhw);
2673 lvif = VAP_TO_LVIF(vap);
2674 vif = LVIF_TO_VIF(lvif);
2675
2676 IEEE80211_UNLOCK(vap->iv_ic);
2677 wiphy_lock(hw->wiphy);
2678
2679 LKPI_80211_LVIF_LOCK(lvif);
2680 #ifdef LINUXKPI_DEBUG_80211
2681 /* XXX-BZ KASSERT later; state going down so no action. */
2682 if (lvif->lvif_bss == NULL)
2683 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2684 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2685 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2686 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2687 lvif->lvif_bss_synched);
2688 #endif
2689 lsta = lvif->lvif_bss;
2690 LKPI_80211_LVIF_UNLOCK(lvif);
2691 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2692 "lvif %p vap %p\n", __func__,
2693 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2694
2695 ni = lsta->ni; /* Reference held for lvif_bss. */
2696 sta = LSTA_TO_STA(lsta);
2697
2698 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2699
2700 /* flush, drop. */
2701 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
2702
2703 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
2704 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
2705 !lsta->in_mgd) {
2706 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2707 prep_tx_info.duration = PREP_TX_INFO_DURATION;
2708 prep_tx_info.was_assoc = true;
2709 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
2710 lsta->in_mgd = true;
2711 }
2712
2713 wiphy_unlock(hw->wiphy);
2714 IEEE80211_LOCK(vap->iv_ic);
2715
2716 /* Call iv_newstate first so we get potential DEAUTH packet out. */
2717 error = lvif->iv_newstate(vap, nstate, arg);
2718 if (error != 0) {
2719 ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
2720 "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
2721 goto outni;
2722 }
2723
2724 IEEE80211_UNLOCK(vap->iv_ic);
2725
2726 /* Ensure the packets get out. */
2727 lkpi_80211_flush_tx(lhw, lsta);
2728
2729 wiphy_lock(hw->wiphy);
2730
2731 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2732
2733 /* Wake tx queues to get packet(s) out. */
2734 lkpi_wake_tx_queues(hw, sta, false, true);
2735
2736 /* flush, no drop */
2737 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
2738
2739 /* End mgd_complete_tx. */
2740 if (lsta->in_mgd) {
2741 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2742 prep_tx_info.success = false;
2743 prep_tx_info.was_assoc = true;
2744 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2745 lsta->in_mgd = false;
2746 }
2747
2748 /* sync_rx_queues */
2749 lkpi_80211_mo_sync_rx_queues(hw);
2750
2751 /* sta_pre_rcu_remove */
2752 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
2753
2754 /* Take the station down. */
2755
2756 /* Update sta and change state (from AUTH) to NONE. */
2757 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2758 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2759 "AUTH: %#x\n", __func__, lsta, lsta->state));
2760 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
2761 if (error != 0) {
2762 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
2763 "failed: %d\n", __func__, __LINE__, error);
2764 goto out;
2765 }
2766
2767 /* See comment in lkpi_sta_run_to_init(). */
2768 bss_changed = 0;
2769 bss_changed |= lkpi_disassoc(sta, vif, lhw);
2770
2771 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
2772
2773 /* Adjust sta and change state (from NONE) to NOTEXIST. */
2774 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2775 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
2776 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
2777 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
2778 if (error != 0) {
2779 IMPROVE("do we need to undo the chan ctx?");
2780 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
2781 "failed: %d\n", __func__, __LINE__, error);
2782 goto out;
2783 }
2784
2785 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); /* sta no longer save to use. */
2786
2787 IMPROVE("Any bss_info changes to announce?");
2788 vif->bss_conf.qos = 0;
2789 bss_changed |= BSS_CHANGED_QOS;
2790 vif->cfg.ssid_len = 0;
2791 memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
2792 bss_changed |= BSS_CHANGED_BSSID;
2793 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2794
2795 LKPI_80211_LVIF_LOCK(lvif);
2796 /* Remove ni reference for this cache of lsta. */
2797 lvif->lvif_bss = NULL;
2798 lvif->lvif_bss_synched = false;
2799 LKPI_80211_LVIF_UNLOCK(lvif);
2800 lkpi_lsta_remove(lsta, lvif);
2801 /*
2802 * The very last release the reference on the ni for the ni/lsta on
2803 * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
2804 * and potentially freed.
2805 */
2806 ieee80211_free_node(ni);
2807
2808 /* conf_tx */
2809
2810 lkpi_remove_chanctx(hw, vif);
2811
2812 error = EALREADY;
2813 out:
2814 wiphy_unlock(hw->wiphy);
2815 IEEE80211_LOCK(vap->iv_ic);
2816 outni:
2817 return (error);
2818 }
2819
2820 static int
lkpi_sta_assoc_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2821 lkpi_sta_assoc_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2822 {
2823 int error;
2824
2825 error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2826 if (error != 0 && error != EALREADY)
2827 return (error);
2828
2829 /* At this point iv_bss is long a new node! */
2830
2831 error |= lkpi_sta_scan_to_auth(vap, nstate, 0);
2832 return (error);
2833 }
2834
2835 static int
lkpi_sta_assoc_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2836 lkpi_sta_assoc_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2837 {
2838 int error;
2839
2840 error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2841 return (error);
2842 }
2843
2844 static int
lkpi_sta_assoc_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2845 lkpi_sta_assoc_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2846 {
2847 int error;
2848
2849 error = _lkpi_sta_assoc_to_down(vap, nstate, arg);
2850 return (error);
2851 }
2852
2853 static int
lkpi_sta_assoc_to_run(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)2854 lkpi_sta_assoc_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
2855 {
2856 struct lkpi_hw *lhw;
2857 struct ieee80211_hw *hw;
2858 struct lkpi_vif *lvif;
2859 struct ieee80211_vif *vif;
2860 struct ieee80211_node *ni;
2861 struct lkpi_sta *lsta;
2862 struct ieee80211_sta *sta;
2863 struct ieee80211_prep_tx_info prep_tx_info;
2864 enum ieee80211_bss_changed bss_changed;
2865 int error;
2866
2867 lhw = vap->iv_ic->ic_softc;
2868 hw = LHW_TO_HW(lhw);
2869 lvif = VAP_TO_LVIF(vap);
2870 vif = LVIF_TO_VIF(lvif);
2871
2872 IEEE80211_UNLOCK(vap->iv_ic);
2873 wiphy_lock(hw->wiphy);
2874
2875 LKPI_80211_LVIF_LOCK(lvif);
2876 /* XXX-BZ KASSERT later? */
2877 if (!lvif->lvif_bss_synched || lvif->lvif_bss == NULL) {
2878 #ifdef LINUXKPI_DEBUG_80211
2879 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
2880 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
2881 lvif, vap, vap->iv_bss, lvif->lvif_bss,
2882 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
2883 lvif->lvif_bss_synched);
2884 #endif
2885 LKPI_80211_LVIF_UNLOCK(lvif);
2886 error = ENOTRECOVERABLE;
2887 goto out;
2888 }
2889 lsta = lvif->lvif_bss;
2890 LKPI_80211_LVIF_UNLOCK(lvif);
2891 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
2892 "lvif %p vap %p\n", __func__,
2893 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
2894
2895 ni = lsta->ni; /* Reference held for lvif_bss. */
2896
2897 IMPROVE("ponder some of this moved to ic_newassoc, scan_assoc_success, "
2898 "and to lesser extend ieee80211_notify_node_join");
2899
2900 /* Finish assoc. */
2901 /* Update sta_state (AUTH to ASSOC) and set aid. */
2902 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
2903 "AUTH: %#x\n", __func__, lsta, lsta->state));
2904 sta = LSTA_TO_STA(lsta);
2905 sta->aid = IEEE80211_NODE_AID(ni);
2906 #ifdef LKPI_80211_WME
2907 if (vap->iv_flags & IEEE80211_F_WME)
2908 sta->wme = true;
2909 #endif
2910 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
2911 if (error != 0) {
2912 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
2913 "failed: %d\n", __func__, __LINE__, error);
2914 goto out;
2915 }
2916
2917 IMPROVE("wme / conf_tx [all]");
2918
2919 /* Update bss info (bss_info_changed) (assoc, aid, ..). */
2920 bss_changed = 0;
2921 #ifdef LKPI_80211_WME
2922 bss_changed |= lkpi_wme_update(lhw, vap, true);
2923 #endif
2924 if (!vif->cfg.assoc || vif->cfg.aid != IEEE80211_NODE_AID(ni)) {
2925 vif->cfg.assoc = true;
2926 vif->cfg.aid = IEEE80211_NODE_AID(ni);
2927 bss_changed |= BSS_CHANGED_ASSOC;
2928 }
2929 /* We set SSID but this is not BSSID! */
2930 vif->cfg.ssid_len = ni->ni_esslen;
2931 memcpy(vif->cfg.ssid, ni->ni_essid, ni->ni_esslen);
2932 if ((vap->iv_flags & IEEE80211_F_SHPREAMBLE) !=
2933 vif->bss_conf.use_short_preamble) {
2934 vif->bss_conf.use_short_preamble ^= 1;
2935 /* bss_changed |= BSS_CHANGED_??? */
2936 }
2937 if ((vap->iv_flags & IEEE80211_F_SHSLOT) !=
2938 vif->bss_conf.use_short_slot) {
2939 vif->bss_conf.use_short_slot ^= 1;
2940 /* bss_changed |= BSS_CHANGED_??? */
2941 }
2942 if ((ni->ni_flags & IEEE80211_NODE_QOS) !=
2943 vif->bss_conf.qos) {
2944 vif->bss_conf.qos ^= 1;
2945 bss_changed |= BSS_CHANGED_QOS;
2946 }
2947
2948 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
2949 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
2950
2951 /* - change_chanctx (if needed)
2952 * - event_callback
2953 */
2954
2955 /* End mgd_complete_tx. */
2956 if (lsta->in_mgd) {
2957 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
2958 prep_tx_info.success = true;
2959 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
2960 lsta->in_mgd = false;
2961 }
2962
2963 lkpi_hw_conf_idle(hw, false);
2964
2965 /*
2966 * And then:
2967 * - (more packets)?
2968 * - set_key
2969 * - set_default_unicast_key
2970 * - set_key (?)
2971 * - ipv6_addr_change (?)
2972 */
2973 /* Prepare_multicast && configure_filter. */
2974 lhw->update_mc = true;
2975 lkpi_update_mcast_filter(vap->iv_ic, true);
2976
2977 if (!ieee80211_node_is_authorized(ni)) {
2978 IMPROVE("net80211 does not consider node authorized");
2979 }
2980
2981 IMPROVE("Is this the right spot, has net80211 done all updates already?");
2982 lkpi_sta_sync_from_ni(hw, vif, sta, ni, true);
2983
2984 /* Update thresholds. */
2985 hw->wiphy->frag_threshold = vap->iv_fragthreshold;
2986 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold);
2987 hw->wiphy->rts_threshold = vap->iv_rtsthreshold;
2988 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold);
2989
2990 /* Update sta_state (ASSOC to AUTHORIZED). */
2991 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
2992 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
2993 "ASSOC: %#x\n", __func__, lsta, lsta->state));
2994 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTHORIZED);
2995 if (error != 0) {
2996 IMPROVE("undo some changes?");
2997 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTHORIZED) "
2998 "failed: %d\n", __func__, __LINE__, error);
2999 goto out;
3000 }
3001
3002 /* - drv_config (?)
3003 * - bss_info_changed
3004 * - set_rekey_data (?)
3005 *
3006 * And now we should be passing packets.
3007 */
3008 IMPROVE("Need that bssid setting, and the keys");
3009
3010 bss_changed = 0;
3011 bss_changed |= lkpi_update_dtim_tsf(vif, ni, vap, __func__, __LINE__);
3012 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
3013
3014 out:
3015 wiphy_unlock(hw->wiphy);
3016 IEEE80211_LOCK(vap->iv_ic);
3017 return (error);
3018 }
3019
3020 static int
lkpi_sta_auth_to_run(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3021 lkpi_sta_auth_to_run(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3022 {
3023 int error;
3024
3025 error = lkpi_sta_auth_to_assoc(vap, nstate, arg);
3026 if (error == 0)
3027 error = lkpi_sta_assoc_to_run(vap, nstate, arg);
3028 return (error);
3029 }
3030
3031 static int
lkpi_sta_run_to_assoc(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3032 lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3033 {
3034 struct lkpi_hw *lhw;
3035 struct ieee80211_hw *hw;
3036 struct lkpi_vif *lvif;
3037 struct ieee80211_vif *vif;
3038 struct ieee80211_node *ni;
3039 struct lkpi_sta *lsta;
3040 struct ieee80211_sta *sta;
3041 struct ieee80211_prep_tx_info prep_tx_info;
3042 #if 0
3043 enum ieee80211_bss_changed bss_changed;
3044 #endif
3045 int error;
3046
3047 lhw = vap->iv_ic->ic_softc;
3048 hw = LHW_TO_HW(lhw);
3049 lvif = VAP_TO_LVIF(vap);
3050 vif = LVIF_TO_VIF(lvif);
3051
3052 LKPI_80211_LVIF_LOCK(lvif);
3053 #ifdef LINUXKPI_DEBUG_80211
3054 /* XXX-BZ KASSERT later; state going down so no action. */
3055 if (lvif->lvif_bss == NULL)
3056 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
3057 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
3058 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3059 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3060 lvif->lvif_bss_synched);
3061 #endif
3062 lsta = lvif->lvif_bss;
3063 LKPI_80211_LVIF_UNLOCK(lvif);
3064 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
3065 "lvif %p vap %p\n", __func__,
3066 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
3067
3068 ni = lsta->ni; /* Reference held for lvif_bss. */
3069 sta = LSTA_TO_STA(lsta);
3070
3071 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3072
3073 IEEE80211_UNLOCK(vap->iv_ic);
3074 wiphy_lock(hw->wiphy);
3075
3076 /* flush, drop. */
3077 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
3078
3079 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
3080 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
3081 !lsta->in_mgd) {
3082 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3083 prep_tx_info.duration = PREP_TX_INFO_DURATION;
3084 prep_tx_info.was_assoc = true;
3085 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
3086 lsta->in_mgd = true;
3087 }
3088
3089 wiphy_unlock(hw->wiphy);
3090 IEEE80211_LOCK(vap->iv_ic);
3091
3092 /* Call iv_newstate first so we get potential DISASSOC packet out. */
3093 error = lvif->iv_newstate(vap, nstate, arg);
3094 if (error != 0) {
3095 ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
3096 "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
3097 goto outni;
3098 }
3099
3100 IEEE80211_UNLOCK(vap->iv_ic);
3101
3102 /* Ensure the packets get out. */
3103 lkpi_80211_flush_tx(lhw, lsta);
3104
3105 wiphy_lock(hw->wiphy);
3106
3107 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3108
3109 /* Wake tx queues to get packet(s) out. */
3110 lkpi_wake_tx_queues(hw, sta, false, true);
3111
3112 /* flush, no drop */
3113 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
3114
3115 /* End mgd_complete_tx. */
3116 if (lsta->in_mgd) {
3117 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3118 prep_tx_info.success = false;
3119 prep_tx_info.was_assoc = true;
3120 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3121 lsta->in_mgd = false;
3122 }
3123
3124 #if 0
3125 /* sync_rx_queues */
3126 lkpi_80211_mo_sync_rx_queues(hw);
3127
3128 /* sta_pre_rcu_remove */
3129 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
3130 #endif
3131
3132 /* Take the station down. */
3133
3134 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */
3135 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3136 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not "
3137 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state));
3138 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
3139 if (error != 0) {
3140 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
3141 "failed: %d\n", __func__, __LINE__, error);
3142 goto out;
3143 }
3144
3145 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3146
3147 #ifdef LKPI_80211_HW_CRYPTO
3148 if (lkpi_hwcrypto) {
3149 error = lkpi_sta_del_keys(hw, vif, lsta);
3150 if (error != 0) {
3151 ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
3152 "failed: %d\n", __func__, __LINE__, error);
3153 /*
3154 * Either drv/fw will crash or cleanup itself,
3155 * otherwise net80211 will delete the keys (at a
3156 * less appropriate time).
3157 */
3158 /* goto out; */
3159 }
3160 }
3161 #endif
3162
3163 /* Update sta_state (ASSOC to AUTH). */
3164 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3165 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
3166 "ASSOC: %#x\n", __func__, lsta, lsta->state));
3167 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
3168 if (error != 0) {
3169 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
3170 "failed: %d\n", __func__, __LINE__, error);
3171 goto out;
3172 }
3173
3174 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3175
3176 #if 0
3177 /* Update bss info (bss_info_changed) (assoc, aid, ..). */
3178 lkpi_disassoc(sta, vif, lhw);
3179 #endif
3180
3181 error = EALREADY;
3182 out:
3183 wiphy_unlock(hw->wiphy);
3184 IEEE80211_LOCK(vap->iv_ic);
3185 outni:
3186 return (error);
3187 }
3188
3189 static int
lkpi_sta_run_to_init(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3190 lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3191 {
3192 struct lkpi_hw *lhw;
3193 struct ieee80211_hw *hw;
3194 struct lkpi_vif *lvif;
3195 struct ieee80211_vif *vif;
3196 struct ieee80211_node *ni;
3197 struct lkpi_sta *lsta;
3198 struct ieee80211_sta *sta;
3199 struct ieee80211_prep_tx_info prep_tx_info;
3200 enum ieee80211_bss_changed bss_changed;
3201 int error;
3202
3203 lhw = vap->iv_ic->ic_softc;
3204 hw = LHW_TO_HW(lhw);
3205 lvif = VAP_TO_LVIF(vap);
3206 vif = LVIF_TO_VIF(lvif);
3207
3208 IEEE80211_UNLOCK(vap->iv_ic);
3209 wiphy_lock(hw->wiphy);
3210
3211 LKPI_80211_LVIF_LOCK(lvif);
3212 #ifdef LINUXKPI_DEBUG_80211
3213 /* XXX-BZ KASSERT later; state going down so no action. */
3214 if (lvif->lvif_bss == NULL)
3215 ic_printf(vap->iv_ic, "%s:%d: lvif %p vap %p iv_bss %p lvif_bss %p "
3216 "lvif_bss->ni %p synched %d\n", __func__, __LINE__,
3217 lvif, vap, vap->iv_bss, lvif->lvif_bss,
3218 (lvif->lvif_bss != NULL) ? lvif->lvif_bss->ni : NULL,
3219 lvif->lvif_bss_synched);
3220 #endif
3221 lsta = lvif->lvif_bss;
3222 LKPI_80211_LVIF_UNLOCK(lvif);
3223 KASSERT(lsta != NULL && lsta->ni != NULL, ("%s: lsta %p ni %p "
3224 "lvif %p vap %p\n", __func__,
3225 lsta, (lsta != NULL) ? lsta->ni : NULL, lvif, vap));
3226
3227 ni = lsta->ni; /* Reference held for lvif_bss. */
3228 sta = LSTA_TO_STA(lsta);
3229
3230 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3231
3232 /* flush, drop. */
3233 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), true);
3234
3235 IMPROVE("What are the proper conditions for DEAUTH_NEED_MGD_TX_PREP?");
3236 if (ieee80211_hw_check(hw, DEAUTH_NEED_MGD_TX_PREP) &&
3237 !lsta->in_mgd) {
3238 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3239 prep_tx_info.duration = PREP_TX_INFO_DURATION;
3240 prep_tx_info.was_assoc = true;
3241 lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
3242 lsta->in_mgd = true;
3243 }
3244
3245 wiphy_unlock(hw->wiphy);
3246 IEEE80211_LOCK(vap->iv_ic);
3247
3248 /* Call iv_newstate first so we get potential DISASSOC packet out. */
3249 error = lvif->iv_newstate(vap, nstate, arg);
3250 if (error != 0) {
3251 ic_printf(vap->iv_ic, "%s:%d: iv_newstate(%p, %d, %d) "
3252 "failed: %d\n", __func__, __LINE__, vap, nstate, arg, error);
3253 goto outni;
3254 }
3255
3256 IEEE80211_UNLOCK(vap->iv_ic);
3257
3258 /* Ensure the packets get out. */
3259 lkpi_80211_flush_tx(lhw, lsta);
3260
3261 wiphy_lock(hw->wiphy);
3262
3263 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3264
3265 /* Wake tx queues to get packet(s) out. */
3266 lkpi_wake_tx_queues(hw, sta, false, true);
3267
3268 /* flush, no drop */
3269 lkpi_80211_mo_flush(hw, vif, nitems(sta->txq), false);
3270
3271 /* End mgd_complete_tx. */
3272 if (lsta->in_mgd) {
3273 memset(&prep_tx_info, 0, sizeof(prep_tx_info));
3274 prep_tx_info.success = false;
3275 prep_tx_info.was_assoc = true;
3276 lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
3277 lsta->in_mgd = false;
3278 }
3279
3280 /* sync_rx_queues */
3281 lkpi_80211_mo_sync_rx_queues(hw);
3282
3283 /* sta_pre_rcu_remove */
3284 lkpi_80211_mo_sta_pre_rcu_remove(hw, vif, sta);
3285
3286 /* Take the station down. */
3287
3288 /* Adjust sta and change state (from AUTHORIZED) to ASSOC. */
3289 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3290 KASSERT(lsta->state == IEEE80211_STA_AUTHORIZED, ("%s: lsta %p state not "
3291 "AUTHORIZED: %#x\n", __func__, lsta, lsta->state));
3292 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_ASSOC);
3293 if (error != 0) {
3294 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(ASSOC) "
3295 "failed: %d\n", __func__, __LINE__, error);
3296 goto out;
3297 }
3298
3299 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3300
3301 #ifdef LKPI_80211_HW_CRYPTO
3302 if (lkpi_hwcrypto) {
3303 error = lkpi_sta_del_keys(hw, vif, lsta);
3304 if (error != 0) {
3305 ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys "
3306 "failed: %d\n", __func__, __LINE__, error);
3307 /*
3308 * Either drv/fw will crash or cleanup itself,
3309 * otherwise net80211 will delete the keys (at a
3310 * less appropriate time).
3311 */
3312 /* goto out; */
3313 }
3314 }
3315 #endif
3316
3317 /* Update sta_state (ASSOC to AUTH). */
3318 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3319 KASSERT(lsta->state == IEEE80211_STA_ASSOC, ("%s: lsta %p state not "
3320 "ASSOC: %#x\n", __func__, lsta, lsta->state));
3321 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_AUTH);
3322 if (error != 0) {
3323 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(AUTH) "
3324 "failed: %d\n", __func__, __LINE__, error);
3325 goto out;
3326 }
3327
3328 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3329
3330 /* Update sta and change state (from AUTH) to NONE. */
3331 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3332 KASSERT(lsta->state == IEEE80211_STA_AUTH, ("%s: lsta %p state not "
3333 "AUTH: %#x\n", __func__, lsta, lsta->state));
3334 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NONE);
3335 if (error != 0) {
3336 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NONE) "
3337 "failed: %d\n", __func__, __LINE__, error);
3338 goto out;
3339 }
3340
3341 bss_changed = 0;
3342 /*
3343 * Start updating bss info (bss_info_changed) (assoc, aid, ..).
3344 *
3345 * One would expect this to happen when going off AUTHORIZED.
3346 * See comment there; removes the sta from fw if not careful
3347 * (bss_info_changed() change is executed right away).
3348 *
3349 * We need to do this now, before sta changes to IEEE80211_STA_NOTEXIST
3350 * as otherwise drivers (iwlwifi at least) will silently not remove
3351 * the sta from the firmware and when we will add a new one trigger
3352 * a fw assert.
3353 *
3354 * The order which works best so far avoiding early removal or silent
3355 * non-removal seems to be (for iwlwifi::mld-mac80211.c cases;
3356 * the iwlwifi:mac80211.c case still to be tested):
3357 * 1) lkpi_disassoc(): set vif->cfg.assoc = false (aid=0 side effect here)
3358 * 2) call the last sta_state update -> IEEE80211_STA_NOTEXIST
3359 * (removes the sta given assoc is false)
3360 * 3) add the remaining BSS_CHANGED changes and call bss_info_changed()
3361 * 4) call unassign_vif_chanctx
3362 * 5) call lkpi_hw_conf_idle
3363 * 6) call remove_chanctx
3364 */
3365 bss_changed |= lkpi_disassoc(sta, vif, lhw);
3366
3367 lkpi_lsta_dump(lsta, ni, __func__, __LINE__);
3368
3369 /* Adjust sta and change state (from NONE) to NOTEXIST. */
3370 KASSERT(lsta != NULL, ("%s: ni %p lsta is NULL\n", __func__, ni));
3371 KASSERT(lsta->state == IEEE80211_STA_NONE, ("%s: lsta %p state not "
3372 "NONE: %#x, nstate %d arg %d\n", __func__, lsta, lsta->state, nstate, arg));
3373 error = lkpi_80211_mo_sta_state(hw, vif, lsta, IEEE80211_STA_NOTEXIST);
3374 if (error != 0) {
3375 IMPROVE("do we need to undo the chan ctx?");
3376 ic_printf(vap->iv_ic, "%s:%d: mo_sta_state(NOTEXIST) "
3377 "failed: %d\n", __func__, __LINE__, error);
3378 goto out;
3379 }
3380
3381 lkpi_lsta_remove(lsta, lvif);
3382
3383 lkpi_lsta_dump(lsta, ni, __func__, __LINE__); /* sta no longer save to use. */
3384
3385 IMPROVE("Any bss_info changes to announce?");
3386 vif->bss_conf.qos = 0;
3387 bss_changed |= BSS_CHANGED_QOS;
3388 vif->cfg.ssid_len = 0;
3389 memset(vif->cfg.ssid, '\0', sizeof(vif->cfg.ssid));
3390 bss_changed |= BSS_CHANGED_BSSID;
3391 vif->bss_conf.use_short_preamble = false;
3392 vif->bss_conf.qos = false;
3393 /* XXX BSS_CHANGED_???? */
3394 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, bss_changed);
3395
3396 LKPI_80211_LVIF_LOCK(lvif);
3397 /* Remove ni reference for this cache of lsta. */
3398 lvif->lvif_bss = NULL;
3399 lvif->lvif_bss_synched = false;
3400 LKPI_80211_LVIF_UNLOCK(lvif);
3401 /*
3402 * The very last release the reference on the ni for the ni/lsta on
3403 * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
3404 * and potentially freed.
3405 */
3406 ieee80211_free_node(ni);
3407
3408 /* conf_tx */
3409
3410 lkpi_remove_chanctx(hw, vif);
3411
3412 error = EALREADY;
3413 out:
3414 wiphy_unlock(hw->wiphy);
3415 IEEE80211_LOCK(vap->iv_ic);
3416 outni:
3417 return (error);
3418 }
3419
3420 static int
lkpi_sta_run_to_scan(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3421 lkpi_sta_run_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3422 {
3423
3424 return (lkpi_sta_run_to_init(vap, nstate, arg));
3425 }
3426
3427 static int
lkpi_sta_run_to_auth(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3428 lkpi_sta_run_to_auth(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3429 {
3430 int error;
3431
3432 error = lkpi_sta_run_to_init(vap, nstate, arg);
3433 if (error != 0 && error != EALREADY)
3434 return (error);
3435
3436 /* At this point iv_bss is long a new node! */
3437
3438 error |= lkpi_sta_scan_to_auth(vap, nstate, 0);
3439 return (error);
3440 }
3441
3442 /* -------------------------------------------------------------------------- */
3443
3444 /*
3445 * The matches the documented state changes in net80211::sta_newstate().
3446 * XXX (1) without CSA and SLEEP yet, * XXX (2) not all unhandled cases
3447 * there are "invalid" (so there is a room for failure here).
3448 */
3449 struct fsm_state {
3450 /* INIT, SCAN, AUTH, ASSOC, CAC, RUN, CSA, SLEEP */
3451 enum ieee80211_state ostate;
3452 enum ieee80211_state nstate;
3453 int (*handler)(struct ieee80211vap *, enum ieee80211_state, int);
3454 } sta_state_fsm[] = {
3455 { IEEE80211_S_INIT, IEEE80211_S_INIT, lkpi_sta_state_do_nada },
3456 { IEEE80211_S_SCAN, IEEE80211_S_INIT, lkpi_sta_state_do_nada }, /* scan_to_init */
3457 { IEEE80211_S_AUTH, IEEE80211_S_INIT, lkpi_sta_auth_to_init }, /* not explicitly in sta_newstate() */
3458 { IEEE80211_S_ASSOC, IEEE80211_S_INIT, lkpi_sta_assoc_to_init }, /* Send DEAUTH. */
3459 { IEEE80211_S_RUN, IEEE80211_S_INIT, lkpi_sta_run_to_init }, /* Send DISASSOC. */
3460
3461 { IEEE80211_S_INIT, IEEE80211_S_SCAN, lkpi_sta_state_do_nada },
3462 { IEEE80211_S_SCAN, IEEE80211_S_SCAN, lkpi_sta_state_do_nada },
3463 { IEEE80211_S_AUTH, IEEE80211_S_SCAN, lkpi_sta_auth_to_scan },
3464 { IEEE80211_S_ASSOC, IEEE80211_S_SCAN, lkpi_sta_assoc_to_scan },
3465 { IEEE80211_S_RUN, IEEE80211_S_SCAN, lkpi_sta_run_to_scan }, /* Beacon miss. */
3466
3467 { IEEE80211_S_INIT, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* Send AUTH. */
3468 { IEEE80211_S_SCAN, IEEE80211_S_AUTH, lkpi_sta_scan_to_auth }, /* Send AUTH. */
3469 { IEEE80211_S_AUTH, IEEE80211_S_AUTH, lkpi_sta_a_to_a }, /* Send ?AUTH. */
3470 { IEEE80211_S_ASSOC, IEEE80211_S_AUTH, lkpi_sta_assoc_to_auth }, /* Send ?AUTH. */
3471 { IEEE80211_S_RUN, IEEE80211_S_AUTH, lkpi_sta_run_to_auth }, /* Send ?AUTH. */
3472
3473 { IEEE80211_S_AUTH, IEEE80211_S_ASSOC, lkpi_sta_auth_to_assoc }, /* Send ASSOCREQ. */
3474 { IEEE80211_S_ASSOC, IEEE80211_S_ASSOC, lkpi_sta_a_to_a }, /* Send ASSOCREQ. */
3475 { IEEE80211_S_RUN, IEEE80211_S_ASSOC, lkpi_sta_run_to_assoc }, /* Send ASSOCREQ/REASSOCREQ. */
3476
3477 { IEEE80211_S_AUTH, IEEE80211_S_RUN, lkpi_sta_auth_to_run },
3478 { IEEE80211_S_ASSOC, IEEE80211_S_RUN, lkpi_sta_assoc_to_run },
3479 { IEEE80211_S_RUN, IEEE80211_S_RUN, lkpi_sta_state_do_nada },
3480
3481 /* Dummy at the end without handler. */
3482 { IEEE80211_S_INIT, IEEE80211_S_INIT, NULL },
3483 };
3484
3485 static int
lkpi_iv_newstate(struct ieee80211vap * vap,enum ieee80211_state nstate,int arg)3486 lkpi_iv_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg)
3487 {
3488 struct ieee80211com *ic;
3489 struct lkpi_hw *lhw;
3490 struct lkpi_vif *lvif;
3491 struct ieee80211_vif *vif;
3492 struct fsm_state *s;
3493 enum ieee80211_state ostate;
3494 int error;
3495
3496 ic = vap->iv_ic;
3497 IEEE80211_LOCK_ASSERT(ic);
3498 ostate = vap->iv_state;
3499
3500 #ifdef LINUXKPI_DEBUG_80211
3501 if (linuxkpi_debug_80211 & D80211_TRACE)
3502 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x\n",
3503 __func__, __LINE__, vap, nstate, arg);
3504 #endif
3505
3506 if (vap->iv_opmode == IEEE80211_M_STA) {
3507
3508 lhw = ic->ic_softc;
3509 lvif = VAP_TO_LVIF(vap);
3510 vif = LVIF_TO_VIF(lvif);
3511
3512 /* No need to replicate this in most state handlers. */
3513 if (ostate == IEEE80211_S_SCAN && nstate != IEEE80211_S_SCAN)
3514 lkpi_stop_hw_scan(lhw, vif);
3515
3516 s = sta_state_fsm;
3517
3518 } else {
3519 ic_printf(vap->iv_ic, "%s: only station mode currently supported: "
3520 "cap %p iv_opmode %d\n", __func__, vap, vap->iv_opmode);
3521 return (ENOSYS);
3522 }
3523
3524 error = 0;
3525 for (; s->handler != NULL; s++) {
3526 if (ostate == s->ostate && nstate == s->nstate) {
3527 #ifdef LINUXKPI_DEBUG_80211
3528 if (linuxkpi_debug_80211 & D80211_TRACE)
3529 ic_printf(vap->iv_ic, "%s: new state %d (%s) ->"
3530 " %d (%s): arg %d.\n", __func__,
3531 ostate, ieee80211_state_name[ostate],
3532 nstate, ieee80211_state_name[nstate], arg);
3533 #endif
3534 error = s->handler(vap, nstate, arg);
3535 break;
3536 }
3537 }
3538 IEEE80211_LOCK_ASSERT(vap->iv_ic);
3539
3540 if (s->handler == NULL) {
3541 IMPROVE("turn this into a KASSERT\n");
3542 ic_printf(vap->iv_ic, "%s: unsupported state transition "
3543 "%d (%s) -> %d (%s)\n", __func__,
3544 ostate, ieee80211_state_name[ostate],
3545 nstate, ieee80211_state_name[nstate]);
3546 return (ENOSYS);
3547 }
3548
3549 if (error == EALREADY) {
3550 #ifdef LINUXKPI_DEBUG_80211
3551 if (linuxkpi_debug_80211 & D80211_TRACE)
3552 ic_printf(vap->iv_ic, "%s: state transition %d (%s) -> "
3553 "%d (%s): iv_newstate already handled: %d.\n",
3554 __func__, ostate, ieee80211_state_name[ostate],
3555 nstate, ieee80211_state_name[nstate], error);
3556 #endif
3557 return (0);
3558 }
3559
3560 if (error != 0) {
3561 ic_printf(vap->iv_ic, "%s: error %d during state transition "
3562 "%d (%s) -> %d (%s)\n", __func__, error,
3563 ostate, ieee80211_state_name[ostate],
3564 nstate, ieee80211_state_name[nstate]);
3565 return (error);
3566 }
3567
3568 #ifdef LINUXKPI_DEBUG_80211
3569 if (linuxkpi_debug_80211 & D80211_TRACE)
3570 ic_printf(vap->iv_ic, "%s:%d: vap %p nstate %#x arg %#x "
3571 "calling net80211 parent\n",
3572 __func__, __LINE__, vap, nstate, arg);
3573 #endif
3574
3575 return (lvif->iv_newstate(vap, nstate, arg));
3576 }
3577
3578 /* -------------------------------------------------------------------------- */
3579
3580 /*
3581 * We overload (*iv_update_bss) as otherwise we have cases in, e.g.,
3582 * net80211::ieee80211_sta_join1() where vap->iv_bss gets replaced by a
3583 * new node without us knowing and thus our ni/lsta are out of sync.
3584 */
3585 static struct ieee80211_node *
lkpi_iv_update_bss(struct ieee80211vap * vap,struct ieee80211_node * ni)3586 lkpi_iv_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
3587 {
3588 struct lkpi_vif *lvif;
3589 struct ieee80211_node *rni;
3590
3591 IEEE80211_LOCK_ASSERT(vap->iv_ic);
3592
3593 lvif = VAP_TO_LVIF(vap);
3594
3595 LKPI_80211_LVIF_LOCK(lvif);
3596 lvif->lvif_bss_synched = false;
3597 LKPI_80211_LVIF_UNLOCK(lvif);
3598
3599 rni = lvif->iv_update_bss(vap, ni);
3600 return (rni);
3601 }
3602
3603 #ifdef LKPI_80211_WME
3604 static int
lkpi_wme_update(struct lkpi_hw * lhw,struct ieee80211vap * vap,bool planned)3605 lkpi_wme_update(struct lkpi_hw *lhw, struct ieee80211vap *vap, bool planned)
3606 {
3607 struct ieee80211com *ic;
3608 struct ieee80211_hw *hw;
3609 struct lkpi_vif *lvif;
3610 struct ieee80211_vif *vif;
3611 struct chanAccParams chp;
3612 struct wmeParams wmeparr[WME_NUM_AC];
3613 struct ieee80211_tx_queue_params txqp;
3614 enum ieee80211_bss_changed changed;
3615 int error;
3616 uint16_t ac;
3617
3618 hw = LHW_TO_HW(lhw);
3619 lockdep_assert_wiphy(hw->wiphy);
3620
3621 IMPROVE();
3622 KASSERT(WME_NUM_AC == IEEE80211_NUM_ACS, ("%s: WME_NUM_AC %d != "
3623 "IEEE80211_NUM_ACS %d\n", __func__, WME_NUM_AC, IEEE80211_NUM_ACS));
3624
3625 if (vap == NULL)
3626 return (0);
3627
3628 if ((vap->iv_flags & IEEE80211_F_WME) == 0)
3629 return (0);
3630
3631 if (lhw->ops->conf_tx == NULL)
3632 return (0);
3633
3634 if (!planned && (vap->iv_state != IEEE80211_S_RUN)) {
3635 lhw->update_wme = true;
3636 return (0);
3637 }
3638 lhw->update_wme = false;
3639
3640 ic = lhw->ic;
3641 ieee80211_wme_ic_getparams(ic, &chp);
3642 IEEE80211_LOCK(ic);
3643 for (ac = 0; ac < WME_NUM_AC; ac++)
3644 wmeparr[ac] = chp.cap_wmeParams[ac];
3645 IEEE80211_UNLOCK(ic);
3646
3647 lvif = VAP_TO_LVIF(vap);
3648 vif = LVIF_TO_VIF(lvif);
3649
3650 /* Configure tx queues (conf_tx) & send BSS_CHANGED_QOS. */
3651 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3652 struct wmeParams *wmep;
3653
3654 wmep = &wmeparr[ac];
3655 bzero(&txqp, sizeof(txqp));
3656 txqp.cw_min = wmep->wmep_logcwmin;
3657 txqp.cw_max = wmep->wmep_logcwmax;
3658 txqp.txop = wmep->wmep_txopLimit;
3659 txqp.aifs = wmep->wmep_aifsn;
3660 error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
3661 if (error != 0)
3662 ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
3663 __func__, ac, error);
3664 }
3665 changed = BSS_CHANGED_QOS;
3666 if (!planned)
3667 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3668
3669 return (changed);
3670 }
3671 #endif
3672
3673 static int
lkpi_ic_wme_update(struct ieee80211com * ic)3674 lkpi_ic_wme_update(struct ieee80211com *ic)
3675 {
3676 #ifdef LKPI_80211_WME
3677 struct ieee80211vap *vap;
3678 struct lkpi_hw *lhw;
3679 struct ieee80211_hw *hw;
3680
3681 IMPROVE("Use the per-VAP callback in net80211.");
3682 vap = TAILQ_FIRST(&ic->ic_vaps);
3683 if (vap == NULL)
3684 return (0);
3685
3686 lhw = ic->ic_softc;
3687 hw = LHW_TO_HW(lhw);
3688
3689 wiphy_lock(hw->wiphy);
3690 lkpi_wme_update(lhw, vap, false);
3691 wiphy_unlock(hw->wiphy);
3692 #endif
3693 return (0); /* unused */
3694 }
3695
3696 /*
3697 * Change link-layer address on the vif (if the vap is not started/"UP").
3698 * This can happen if a user changes 'ether' using ifconfig.
3699 * The code is based on net80211/ieee80211_freebsd.c::wlan_iflladdr() but
3700 * we do use a per-[l]vif event handler to be sure we exist as we
3701 * cannot assume that from every vap derives a vif and we have a hard
3702 * time checking based on net80211 information.
3703 * Should this ever become a real problem we could add a callback function
3704 * to wlan_iflladdr() to be set optionally but that would be for a
3705 * single-consumer (or needs a list) -- was just too complicated for an
3706 * otherwise perfect mechanism FreeBSD already provides.
3707 */
3708 static void
lkpi_vif_iflladdr(void * arg,struct ifnet * ifp)3709 lkpi_vif_iflladdr(void *arg, struct ifnet *ifp)
3710 {
3711 struct epoch_tracker et;
3712 struct ieee80211_vif *vif;
3713
3714 NET_EPOCH_ENTER(et);
3715 /* NB: identify vap's by if_transmit; left as an extra check. */
3716 if (if_gettransmitfn(ifp) != ieee80211_vap_transmit ||
3717 (if_getflags(ifp) & IFF_UP) != 0) {
3718 NET_EPOCH_EXIT(et);
3719 return;
3720 }
3721
3722 vif = arg;
3723 IEEE80211_ADDR_COPY(vif->bss_conf.addr, if_getlladdr(ifp));
3724 NET_EPOCH_EXIT(et);
3725 }
3726
3727 static struct ieee80211vap *
lkpi_ic_vap_create(struct ieee80211com * ic,const char name[IFNAMSIZ],int unit,enum ieee80211_opmode opmode,int flags,const uint8_t bssid[IEEE80211_ADDR_LEN],const uint8_t mac[IEEE80211_ADDR_LEN])3728 lkpi_ic_vap_create(struct ieee80211com *ic, const char name[IFNAMSIZ],
3729 int unit, enum ieee80211_opmode opmode, int flags,
3730 const uint8_t bssid[IEEE80211_ADDR_LEN],
3731 const uint8_t mac[IEEE80211_ADDR_LEN])
3732 {
3733 struct lkpi_hw *lhw;
3734 struct ieee80211_hw *hw;
3735 struct lkpi_vif *lvif;
3736 struct ieee80211vap *vap;
3737 struct ieee80211_vif *vif;
3738 struct ieee80211_tx_queue_params txqp;
3739 enum ieee80211_bss_changed changed;
3740 struct sysctl_oid *node;
3741 size_t len;
3742 int error, i;
3743 uint16_t ac;
3744
3745 if (!TAILQ_EMPTY(&ic->ic_vaps)) /* 1 so far. Add <n> once this works. */
3746 return (NULL);
3747
3748 lhw = ic->ic_softc;
3749 hw = LHW_TO_HW(lhw);
3750
3751 len = sizeof(*lvif);
3752 len += hw->vif_data_size; /* vif->drv_priv */
3753
3754 lvif = malloc(len, M_80211_VAP, M_WAITOK | M_ZERO);
3755 mtx_init(&lvif->mtx, "lvif", NULL, MTX_DEF);
3756 INIT_LIST_HEAD(&lvif->lsta_list);
3757 lvif->lvif_bss = NULL;
3758 refcount_init(&lvif->nt_unlocked, 0);
3759 lvif->lvif_bss_synched = false;
3760 vap = LVIF_TO_VAP(lvif);
3761
3762 vif = LVIF_TO_VIF(lvif);
3763 memcpy(vif->addr, mac, IEEE80211_ADDR_LEN);
3764 vif->p2p = false;
3765 vif->probe_req_reg = false;
3766 vif->type = lkpi_opmode_to_vif_type(opmode);
3767 lvif->wdev.iftype = vif->type;
3768 /* Need to fill in other fields as well. */
3769 IMPROVE();
3770
3771 /* XXX-BZ hardcoded for now! */
3772 #if 1
3773 RCU_INIT_POINTER(vif->bss_conf.chanctx_conf, NULL);
3774 vif->bss_conf.vif = vif;
3775 /* vap->iv_myaddr is not set until net80211::vap_setup or vap_attach. */
3776 IEEE80211_ADDR_COPY(vif->bss_conf.addr, mac);
3777 lvif->lvif_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event,
3778 lkpi_vif_iflladdr, vif, EVENTHANDLER_PRI_ANY);
3779 vif->bss_conf.link_id = 0; /* Non-MLO operation. */
3780 vif->bss_conf.chanreq.oper.width = NL80211_CHAN_WIDTH_20_NOHT;
3781 vif->bss_conf.use_short_preamble = false; /* vap->iv_flags IEEE80211_F_SHPREAMBLE */
3782 vif->bss_conf.use_short_slot = false; /* vap->iv_flags IEEE80211_F_SHSLOT */
3783 vif->bss_conf.qos = false;
3784 vif->bss_conf.use_cts_prot = false; /* vap->iv_protmode */
3785 vif->bss_conf.ht_operation_mode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
3786 vif->cfg.aid = 0;
3787 vif->cfg.assoc = false;
3788 vif->cfg.idle = true;
3789 vif->cfg.ps = false;
3790 IMPROVE("Check other fields and then figure out whats is left elsewhere of them");
3791 /*
3792 * We need to initialize it to something as the bss_info_changed call
3793 * will try to copy from it in iwlwifi and NULL is a panic.
3794 * We will set the proper one in scan_to_auth() before being assoc.
3795 */
3796 vif->bss_conf.bssid = ieee80211broadcastaddr;
3797 #endif
3798 #if 0
3799 vif->bss_conf.dtim_period = 0; /* IEEE80211_DTIM_DEFAULT ; must stay 0. */
3800 IEEE80211_ADDR_COPY(vif->bss_conf.bssid, bssid);
3801 vif->bss_conf.beacon_int = ic->ic_bintval;
3802 /* iwlwifi bug. */
3803 if (vif->bss_conf.beacon_int < 16)
3804 vif->bss_conf.beacon_int = 16;
3805 #endif
3806
3807 /* Link Config */
3808 vif->link_conf[0] = &vif->bss_conf;
3809 for (i = 0; i < nitems(vif->link_conf); i++) {
3810 IMPROVE("more than 1 link one day");
3811 }
3812
3813 /* Setup queue defaults; driver may override in (*add_interface). */
3814 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
3815 if (ieee80211_hw_check(hw, QUEUE_CONTROL))
3816 vif->hw_queue[i] = IEEE80211_INVAL_HW_QUEUE;
3817 else if (hw->queues >= IEEE80211_NUM_ACS)
3818 vif->hw_queue[i] = i;
3819 else
3820 vif->hw_queue[i] = 0;
3821
3822 /* Initialize the queue to running. Stopped? */
3823 lvif->hw_queue_stopped[i] = false;
3824 }
3825 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
3826
3827 IMPROVE();
3828
3829 error = lkpi_80211_mo_start(hw);
3830 if (error != 0) {
3831 ic_printf(ic, "%s: failed to start hw: %d\n", __func__, error);
3832 mtx_destroy(&lvif->mtx);
3833 free(lvif, M_80211_VAP);
3834 return (NULL);
3835 }
3836
3837 error = lkpi_80211_mo_add_interface(hw, vif);
3838 if (error != 0) {
3839 IMPROVE(); /* XXX-BZ mo_stop()? */
3840 ic_printf(ic, "%s: failed to add interface: %d\n", __func__, error);
3841 mtx_destroy(&lvif->mtx);
3842 free(lvif, M_80211_VAP);
3843 return (NULL);
3844 }
3845
3846 LKPI_80211_LHW_LVIF_LOCK(lhw);
3847 TAILQ_INSERT_TAIL(&lhw->lvif_head, lvif, lvif_entry);
3848 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
3849
3850 /* Set bss_info. */
3851 changed = 0;
3852 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3853
3854 /* Configure tx queues (conf_tx), default WME & send BSS_CHANGED_QOS. */
3855 IMPROVE("Hardcoded values; to fix see 802.11-2016, 9.4.2.29 EDCA Parameter Set element");
3856 wiphy_lock(hw->wiphy);
3857 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
3858
3859 bzero(&txqp, sizeof(txqp));
3860 txqp.cw_min = 15;
3861 txqp.cw_max = 1023;
3862 txqp.txop = 0;
3863 txqp.aifs = 2;
3864 error = lkpi_80211_mo_conf_tx(hw, vif, /* link_id */0, ac, &txqp);
3865 if (error != 0)
3866 ic_printf(ic, "%s: conf_tx ac %u failed %d\n",
3867 __func__, ac, error);
3868 }
3869 wiphy_unlock(hw->wiphy);
3870 changed = BSS_CHANGED_QOS;
3871 lkpi_80211_mo_bss_info_changed(hw, vif, &vif->bss_conf, changed);
3872
3873 /* Force MC init. */
3874 lkpi_update_mcast_filter(ic, true);
3875
3876 IMPROVE();
3877
3878 ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid);
3879
3880 /* Override with LinuxKPI method so we can drive mac80211/cfg80211. */
3881 lvif->iv_newstate = vap->iv_newstate;
3882 vap->iv_newstate = lkpi_iv_newstate;
3883 lvif->iv_update_bss = vap->iv_update_bss;
3884 vap->iv_update_bss = lkpi_iv_update_bss;
3885
3886 #ifdef LKPI_80211_HW_CRYPTO
3887 /* Key management. */
3888 if (lkpi_hwcrypto && lhw->ops->set_key != NULL) {
3889 vap->iv_key_set = lkpi_iv_key_set;
3890 vap->iv_key_delete = lkpi_iv_key_delete;
3891 vap->iv_key_update_begin = lkpi_iv_key_update_begin;
3892 vap->iv_key_update_end = lkpi_iv_key_update_end;
3893 }
3894 #endif
3895
3896 #ifdef LKPI_80211_HT
3897 /* Stay with the iv_ampdu_rxmax,limit / iv_ampdu_density defaults until later. */
3898 #endif
3899
3900 ieee80211_ratectl_init(vap);
3901
3902 /* Complete setup. */
3903 ieee80211_vap_attach(vap, ieee80211_media_change,
3904 ieee80211_media_status, mac);
3905
3906 #ifdef LKPI_80211_HT
3907 /*
3908 * Modern chipset/fw/drv will do A-MPDU in drv/fw and fail
3909 * to do so if they cannot do the crypto too.
3910 */
3911 if (!lkpi_hwcrypto && ieee80211_hw_check(hw, AMPDU_AGGREGATION))
3912 vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_RX;
3913 #endif
3914 #if defined(LKPI_80211_HT)
3915 /* 20250125-BZ Keep A-MPDU TX cleared until we sorted out AddBA for all drivers. */
3916 vap->iv_flags_ht &= ~IEEE80211_FHT_AMPDU_TX;
3917 #endif
3918
3919 if (hw->max_listen_interval == 0)
3920 hw->max_listen_interval = 7 * (ic->ic_lintval / ic->ic_bintval);
3921 hw->conf.listen_interval = hw->max_listen_interval;
3922 ic->ic_set_channel(ic);
3923
3924 /* XXX-BZ do we need to be able to update these? */
3925 hw->wiphy->frag_threshold = vap->iv_fragthreshold;
3926 lkpi_80211_mo_set_frag_threshold(hw, vap->iv_fragthreshold);
3927 hw->wiphy->rts_threshold = vap->iv_rtsthreshold;
3928 lkpi_80211_mo_set_rts_threshold(hw, vap->iv_rtsthreshold);
3929 /* any others? */
3930
3931 /* Add per-VIF/VAP sysctls. */
3932 sysctl_ctx_init(&lvif->sysctl_ctx);
3933
3934 node = SYSCTL_ADD_NODE(&lvif->sysctl_ctx,
3935 SYSCTL_CHILDREN(&sysctl___compat_linuxkpi_80211),
3936 OID_AUTO, if_name(vap->iv_ifp),
3937 CTLFLAG_RD | CTLFLAG_SKIP | CTLFLAG_MPSAFE, NULL, "VIF Information");
3938
3939 SYSCTL_ADD_PROC(&lvif->sysctl_ctx,
3940 SYSCTL_CHILDREN(node), OID_AUTO, "dump_stas",
3941 CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, lvif, 0,
3942 lkpi_80211_dump_stas, "A", "Dump sta statistics of this vif");
3943
3944 IMPROVE();
3945
3946 return (vap);
3947 }
3948
3949 void
linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw * hw)3950 linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw *hw)
3951 {
3952
3953 wiphy_unregister(hw->wiphy);
3954 linuxkpi_ieee80211_ifdetach(hw);
3955
3956 IMPROVE();
3957 }
3958
3959 void
linuxkpi_ieee80211_restart_hw(struct ieee80211_hw * hw)3960 linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *hw)
3961 {
3962
3963 TODO();
3964 }
3965
3966 static void
lkpi_ic_vap_delete(struct ieee80211vap * vap)3967 lkpi_ic_vap_delete(struct ieee80211vap *vap)
3968 {
3969 struct ieee80211com *ic;
3970 struct lkpi_hw *lhw;
3971 struct ieee80211_hw *hw;
3972 struct lkpi_vif *lvif;
3973 struct ieee80211_vif *vif;
3974
3975 lvif = VAP_TO_LVIF(vap);
3976 vif = LVIF_TO_VIF(lvif);
3977 ic = vap->iv_ic;
3978 lhw = ic->ic_softc;
3979 hw = LHW_TO_HW(lhw);
3980
3981 EVENTHANDLER_DEREGISTER(iflladdr_event, lvif->lvif_ifllevent);
3982
3983 /* Clear up per-VIF/VAP sysctls. */
3984 sysctl_ctx_free(&lvif->sysctl_ctx);
3985
3986 LKPI_80211_LHW_LVIF_LOCK(lhw);
3987 TAILQ_REMOVE(&lhw->lvif_head, lvif, lvif_entry);
3988 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
3989
3990 ieee80211_ratectl_deinit(vap);
3991 ieee80211_vap_detach(vap);
3992
3993 IMPROVE("clear up other bits in this state");
3994
3995 lkpi_80211_mo_remove_interface(hw, vif);
3996
3997 /* Single VAP, so we can do this here. */
3998 lkpi_80211_mo_stop(hw, false); /* XXX SUSPEND */
3999
4000 mtx_destroy(&lvif->mtx);
4001 free(lvif, M_80211_VAP);
4002 }
4003
4004 static void
lkpi_ic_update_mcast(struct ieee80211com * ic)4005 lkpi_ic_update_mcast(struct ieee80211com *ic)
4006 {
4007
4008 lkpi_update_mcast_filter(ic, false);
4009 TRACEOK();
4010 }
4011
4012 static void
lkpi_ic_update_promisc(struct ieee80211com * ic)4013 lkpi_ic_update_promisc(struct ieee80211com *ic)
4014 {
4015
4016 UNIMPLEMENTED;
4017 }
4018
4019 static void
lkpi_ic_update_chw(struct ieee80211com * ic)4020 lkpi_ic_update_chw(struct ieee80211com *ic)
4021 {
4022
4023 UNIMPLEMENTED;
4024 }
4025
4026 /* Start / stop device. */
4027 static void
lkpi_ic_parent(struct ieee80211com * ic)4028 lkpi_ic_parent(struct ieee80211com *ic)
4029 {
4030 struct lkpi_hw *lhw;
4031 struct ieee80211_hw *hw;
4032 #ifdef HW_START_STOP
4033 int error;
4034 #endif
4035 bool start_all;
4036
4037 IMPROVE();
4038
4039 lhw = ic->ic_softc;
4040 hw = LHW_TO_HW(lhw);
4041 start_all = false;
4042
4043 /* IEEE80211_UNLOCK(ic); */
4044 wiphy_lock(hw->wiphy);
4045 if (ic->ic_nrunning > 0) {
4046 #ifdef HW_START_STOP
4047 error = lkpi_80211_mo_start(hw);
4048 if (error == 0)
4049 #endif
4050 start_all = true;
4051 } else {
4052 #ifdef HW_START_STOP
4053 lkpi_80211_mo_stop(hw, false); /* XXX SUSPEND */
4054 #endif
4055 }
4056 wiphy_unlock(hw->wiphy);
4057 /* IEEE80211_LOCK(ic); */
4058
4059 if (start_all)
4060 ieee80211_start_all(ic);
4061 }
4062
4063 bool
linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie,const u8 * ie_ids,size_t ie_ids_len)4064 linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8 ie, const u8 *ie_ids,
4065 size_t ie_ids_len)
4066 {
4067 int i;
4068
4069 for (i = 0; i < ie_ids_len; i++) {
4070 if (ie == *ie_ids)
4071 return (true);
4072 }
4073
4074 return (false);
4075 }
4076
4077 /* Return true if skipped; false if error. */
4078 bool
linuxkpi_ieee80211_ie_advance(size_t * xp,const u8 * ies,size_t ies_len)4079 linuxkpi_ieee80211_ie_advance(size_t *xp, const u8 *ies, size_t ies_len)
4080 {
4081 size_t x;
4082 uint8_t l;
4083
4084 x = *xp;
4085
4086 KASSERT(x < ies_len, ("%s: x %zu ies_len %zu ies %p\n",
4087 __func__, x, ies_len, ies));
4088 l = ies[x + 1];
4089 x += 2 + l;
4090
4091 if (x > ies_len)
4092 return (false);
4093
4094 *xp = x;
4095 return (true);
4096 }
4097
4098 static uint8_t *
lkpi_scan_ies_add(uint8_t * p,struct ieee80211_scan_ies * scan_ies,uint32_t band_mask,struct ieee80211vap * vap,struct ieee80211_hw * hw)4099 lkpi_scan_ies_add(uint8_t *p, struct ieee80211_scan_ies *scan_ies,
4100 uint32_t band_mask, struct ieee80211vap *vap, struct ieee80211_hw *hw)
4101 {
4102 struct ieee80211_supported_band *supband;
4103 struct linuxkpi_ieee80211_channel *channels;
4104 struct ieee80211com *ic;
4105 const struct ieee80211_channel *chan;
4106 const struct ieee80211_rateset *rs;
4107 uint8_t *pb;
4108 int band, i;
4109
4110 ic = vap->iv_ic;
4111 for (band = 0; band < NUM_NL80211_BANDS; band++) {
4112 if ((band_mask & (1 << band)) == 0)
4113 continue;
4114
4115 supband = hw->wiphy->bands[band];
4116 /*
4117 * This should not happen;
4118 * band_mask is a bitmask of valid bands to scan on.
4119 */
4120 if (supband == NULL || supband->n_channels == 0)
4121 continue;
4122
4123 /* Find a first channel to get the mode and rates from. */
4124 channels = supband->channels;
4125 chan = NULL;
4126 for (i = 0; i < supband->n_channels; i++) {
4127 uint32_t flags;
4128
4129 if (channels[i].flags & IEEE80211_CHAN_DISABLED)
4130 continue;
4131
4132 flags = 0;
4133 switch (band) {
4134 case NL80211_BAND_2GHZ:
4135 flags |= IEEE80211_CHAN_G;
4136 break;
4137 case NL80211_BAND_5GHZ:
4138 flags |= IEEE80211_CHAN_A;
4139 break;
4140 default:
4141 panic("%s:%d: unupported band %d\n",
4142 __func__, __LINE__, band);
4143 }
4144
4145 chan = ieee80211_find_channel(ic,
4146 channels[i].center_freq, flags);
4147 if (chan != NULL)
4148 break;
4149 }
4150
4151 /* This really should not happen. */
4152 if (chan == NULL)
4153 continue;
4154
4155 pb = p;
4156 rs = ieee80211_get_suprates(ic, chan); /* calls chan2mode */
4157 p = ieee80211_add_rates(p, rs);
4158 p = ieee80211_add_xrates(p, rs);
4159
4160 #if defined(LKPI_80211_HT)
4161 if ((vap->iv_flags_ht & IEEE80211_FHT_HT) != 0) {
4162 struct ieee80211_channel *c;
4163
4164 c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
4165 vap->iv_flags_ht);
4166 p = ieee80211_add_htcap_ch(p, vap, c);
4167 }
4168 #endif
4169 #if defined(LKPI_80211_VHT)
4170 if (band == NL80211_BAND_5GHZ &&
4171 (vap->iv_vht_flags & IEEE80211_FVHT_VHT) != 0) {
4172 struct ieee80211_channel *c;
4173
4174 c = ieee80211_ht_adjust_channel(ic, ic->ic_curchan,
4175 vap->iv_flags_ht);
4176 c = ieee80211_vht_adjust_channel(ic, c,
4177 vap->iv_vht_flags);
4178 p = ieee80211_add_vhtcap_ch(p, vap, c);
4179 }
4180 #endif
4181
4182 scan_ies->ies[band] = pb;
4183 scan_ies->len[band] = p - pb;
4184 }
4185
4186 /* Add common_ies */
4187 pb = p;
4188 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
4189 vap->iv_wpa_ie != NULL) {
4190 memcpy(p, vap->iv_wpa_ie, 2 + vap->iv_wpa_ie[1]);
4191 p += 2 + vap->iv_wpa_ie[1];
4192 }
4193 if (vap->iv_appie_probereq != NULL) {
4194 memcpy(p, vap->iv_appie_probereq->ie_data,
4195 vap->iv_appie_probereq->ie_len);
4196 p += vap->iv_appie_probereq->ie_len;
4197 }
4198 scan_ies->common_ies = pb;
4199 scan_ies->common_ie_len = p - pb;
4200
4201 return (p);
4202 }
4203
4204 static void
lkpi_ic_scan_start(struct ieee80211com * ic)4205 lkpi_ic_scan_start(struct ieee80211com *ic)
4206 {
4207 struct lkpi_hw *lhw;
4208 struct ieee80211_hw *hw;
4209 struct lkpi_vif *lvif;
4210 struct ieee80211_vif *vif;
4211 struct ieee80211_scan_state *ss;
4212 struct ieee80211vap *vap;
4213 int error;
4214 bool is_hw_scan;
4215
4216 lhw = ic->ic_softc;
4217 LKPI_80211_LHW_SCAN_LOCK(lhw);
4218 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
4219 /* A scan is still running. */
4220 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4221 return;
4222 }
4223 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4224 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4225
4226 ss = ic->ic_scan;
4227 vap = ss->ss_vap;
4228 if (vap->iv_state != IEEE80211_S_SCAN) {
4229 IMPROVE("We need to be able to scan if not in S_SCAN");
4230 return;
4231 }
4232
4233 hw = LHW_TO_HW(lhw);
4234 if (!is_hw_scan) {
4235 /* If hw_scan is cleared clear FEXT_SCAN_OFFLOAD too. */
4236 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD;
4237 sw_scan:
4238 lvif = VAP_TO_LVIF(vap);
4239 vif = LVIF_TO_VIF(lvif);
4240
4241 if (vap->iv_state == IEEE80211_S_SCAN)
4242 lkpi_hw_conf_idle(hw, false);
4243
4244 lkpi_80211_mo_sw_scan_start(hw, vif, vif->addr);
4245 /* net80211::scan_start() handled PS for us. */
4246 IMPROVE();
4247 /* XXX Also means it is too late to flush queues?
4248 * need to check iv_sta_ps or overload? */
4249 /* XXX want to adjust ss end time/ maxdwell? */
4250
4251 } else {
4252 struct ieee80211_scan_request *hw_req;
4253 struct linuxkpi_ieee80211_channel *lc, **cpp;
4254 struct cfg80211_ssid *ssids;
4255 struct cfg80211_scan_6ghz_params *s6gp;
4256 size_t chan_len, nchan, ssids_len, s6ghzlen;
4257 int band, i, ssid_count, common_ie_len;
4258 uint32_t band_mask;
4259 uint8_t *ie, *ieend;
4260 bool running;
4261
4262 ssid_count = min(ss->ss_nssid, hw->wiphy->max_scan_ssids);
4263 ssids_len = ssid_count * sizeof(*ssids);
4264 s6ghzlen = 0 * (sizeof(*s6gp)); /* XXX-BZ */
4265
4266 band_mask = 0;
4267 nchan = 0;
4268 if (ieee80211_hw_check(hw, SINGLE_SCAN_ON_ALL_BANDS)) {
4269 #if 0 /* Avoid net80211 scan lists until it has proper scan offload support. */
4270 for (i = ss->ss_next; i < ss->ss_last; i++) {
4271 nchan++;
4272 band = lkpi_net80211_chan_to_nl80211_band(
4273 ss->ss_chans[ss->ss_next + i]);
4274 band_mask |= (1 << band);
4275 }
4276 #else
4277 /* Instead we scan for all channels all the time. */
4278 for (band = 0; band < NUM_NL80211_BANDS; band++) {
4279 switch (band) {
4280 case NL80211_BAND_2GHZ:
4281 case NL80211_BAND_5GHZ:
4282 break;
4283 default:
4284 continue;
4285 }
4286 if (hw->wiphy->bands[band] != NULL) {
4287 nchan += hw->wiphy->bands[band]->n_channels;
4288 band_mask |= (1 << band);
4289 }
4290 }
4291 #endif
4292 } else {
4293 IMPROVE("individual band scans not yet supported, only scanning first band");
4294 /* In theory net80211 should drive this. */
4295 /* Probably we need to add local logic for now;
4296 * need to deal with scan_complete
4297 * and cancel_scan and keep local state.
4298 * Also cut the nchan down above.
4299 */
4300 /* XXX-BZ ath10k does not set this but still does it? &$%^ */
4301 }
4302
4303 chan_len = nchan * (sizeof(lc) + sizeof(*lc));
4304
4305 common_ie_len = 0;
4306 if ((vap->iv_flags & IEEE80211_F_WPA1) != 0 &&
4307 vap->iv_wpa_ie != NULL)
4308 common_ie_len += vap->iv_wpa_ie[1];
4309 if (vap->iv_appie_probereq != NULL)
4310 common_ie_len += vap->iv_appie_probereq->ie_len;
4311
4312 /* We would love to check this at an earlier stage... */
4313 if (common_ie_len > hw->wiphy->max_scan_ie_len) {
4314 ic_printf(ic, "WARNING: %s: common_ie_len %d > "
4315 "wiphy->max_scan_ie_len %d\n", __func__,
4316 common_ie_len, hw->wiphy->max_scan_ie_len);
4317 }
4318
4319 hw_req = malloc(sizeof(*hw_req) + ssids_len +
4320 s6ghzlen + chan_len + lhw->supbands * lhw->scan_ie_len +
4321 common_ie_len, M_LKPI80211, M_WAITOK | M_ZERO);
4322
4323 hw_req->req.flags = 0; /* XXX ??? */
4324 /* hw_req->req.wdev */
4325 hw_req->req.wiphy = hw->wiphy;
4326 hw_req->req.no_cck = false; /* XXX */
4327 #if 0
4328 /* This seems to pessimise default scanning behaviour. */
4329 hw_req->req.duration_mandatory = TICKS_2_USEC(ss->ss_mindwell);
4330 hw_req->req.duration = TICKS_2_USEC(ss->ss_maxdwell);
4331 #endif
4332 #ifdef __notyet__
4333 hw_req->req.flags |= NL80211_SCAN_FLAG_RANDOM_ADDR;
4334 memcpy(hw_req->req.mac_addr, xxx, IEEE80211_ADDR_LEN);
4335 memset(hw_req->req.mac_addr_mask, 0xxx, IEEE80211_ADDR_LEN);
4336 #endif
4337 eth_broadcast_addr(hw_req->req.bssid);
4338
4339 hw_req->req.n_channels = nchan;
4340 cpp = (struct linuxkpi_ieee80211_channel **)(hw_req + 1);
4341 lc = (struct linuxkpi_ieee80211_channel *)(cpp + nchan);
4342 for (i = 0; i < nchan; i++) {
4343 *(cpp + i) =
4344 (struct linuxkpi_ieee80211_channel *)(lc + i);
4345 }
4346 #if 0 /* Avoid net80211 scan lists until it has proper scan offload support. */
4347 for (i = 0; i < nchan; i++) {
4348 struct ieee80211_channel *c;
4349
4350 c = ss->ss_chans[ss->ss_next + i];
4351 lc->hw_value = c->ic_ieee;
4352 lc->center_freq = c->ic_freq; /* XXX */
4353 /* lc->flags */
4354 lc->band = lkpi_net80211_chan_to_nl80211_band(c);
4355 lc->max_power = c->ic_maxpower;
4356 /* lc-> ... */
4357 lc++;
4358 }
4359 #else
4360 for (band = 0; band < NUM_NL80211_BANDS; band++) {
4361 struct ieee80211_supported_band *supband;
4362 struct linuxkpi_ieee80211_channel *channels;
4363
4364 /* Band disabled for scanning? */
4365 if ((band_mask & (1 << band)) == 0)
4366 continue;
4367
4368 /* Nothing to scan in band? */
4369 supband = hw->wiphy->bands[band];
4370 if (supband == NULL || supband->n_channels == 0)
4371 continue;
4372
4373 channels = supband->channels;
4374 for (i = 0; i < supband->n_channels; i++) {
4375 *lc = channels[i];
4376 lc++;
4377 }
4378 }
4379 #endif
4380
4381 hw_req->req.n_ssids = ssid_count;
4382 if (hw_req->req.n_ssids > 0) {
4383 ssids = (struct cfg80211_ssid *)lc;
4384 hw_req->req.ssids = ssids;
4385 for (i = 0; i < ssid_count; i++) {
4386 ssids->ssid_len = ss->ss_ssid[i].len;
4387 memcpy(ssids->ssid, ss->ss_ssid[i].ssid,
4388 ss->ss_ssid[i].len);
4389 ssids++;
4390 }
4391 s6gp = (struct cfg80211_scan_6ghz_params *)ssids;
4392 } else {
4393 s6gp = (struct cfg80211_scan_6ghz_params *)lc;
4394 }
4395
4396 /* 6GHz one day. */
4397 hw_req->req.n_6ghz_params = 0;
4398 hw_req->req.scan_6ghz_params = NULL;
4399 hw_req->req.scan_6ghz = false; /* Weird boolean; not what you think. */
4400 /* s6gp->... */
4401
4402 ie = ieend = (uint8_t *)s6gp;
4403 /* Copy per-band IEs, copy common IEs */
4404 ieend = lkpi_scan_ies_add(ie, &hw_req->ies, band_mask, vap, hw);
4405 hw_req->req.ie = ie;
4406 hw_req->req.ie_len = ieend - ie;
4407
4408 lvif = VAP_TO_LVIF(vap);
4409 vif = LVIF_TO_VIF(lvif);
4410
4411 LKPI_80211_LHW_SCAN_LOCK(lhw);
4412 /* Re-check under lock. */
4413 running = (lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0;
4414 if (!running) {
4415 KASSERT(lhw->hw_req == NULL, ("%s: ic %p lhw %p hw_req %p "
4416 "!= NULL\n", __func__, ic, lhw, lhw->hw_req));
4417
4418 lhw->scan_flags |= LKPI_LHW_SCAN_RUNNING;
4419 lhw->hw_req = hw_req;
4420 }
4421 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4422 if (running) {
4423 free(hw_req, M_LKPI80211);
4424 return;
4425 }
4426
4427 error = lkpi_80211_mo_hw_scan(hw, vif, hw_req);
4428 if (error != 0) {
4429 ieee80211_cancel_scan(vap);
4430
4431 /*
4432 * ieee80211_scan_completed must be called in either
4433 * case of error or none. So let the free happen there
4434 * and only there.
4435 * That would be fine in theory but in practice drivers
4436 * behave differently:
4437 * ath10k does not return hw_scan until after scan_complete
4438 * and can then still return an error.
4439 * rtw88 can return 1 or -EBUSY without scan_complete
4440 * iwlwifi can return various errors before scan starts
4441 * ...
4442 * So we cannot rely on that behaviour and have to check
4443 * and balance between both code paths.
4444 */
4445 LKPI_80211_LHW_SCAN_LOCK(lhw);
4446 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) != 0) {
4447 free(lhw->hw_req, M_LKPI80211);
4448 lhw->hw_req = NULL;
4449 lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
4450 }
4451 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4452
4453 /*
4454 * XXX-SIGH magic number.
4455 * rtw88 has a magic "return 1" if offloading scan is
4456 * not possible. Fall back to sw scan in that case.
4457 */
4458 if (error == 1) {
4459 LKPI_80211_LHW_SCAN_LOCK(lhw);
4460 lhw->scan_flags &= ~LKPI_LHW_SCAN_HW;
4461 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4462 /*
4463 * XXX If we clear this now and later a driver
4464 * thinks it * can do a hw_scan again, we will
4465 * currently not re-enable it?
4466 */
4467 vap->iv_flags_ext &= ~IEEE80211_FEXT_SCAN_OFFLOAD;
4468 ieee80211_start_scan(vap,
4469 IEEE80211_SCAN_ACTIVE |
4470 IEEE80211_SCAN_NOPICK |
4471 IEEE80211_SCAN_ONCE,
4472 IEEE80211_SCAN_FOREVER,
4473 ss->ss_mindwell ? ss->ss_mindwell : msecs_to_ticks(20),
4474 ss->ss_maxdwell ? ss->ss_maxdwell : msecs_to_ticks(200),
4475 vap->iv_des_nssid, vap->iv_des_ssid);
4476 goto sw_scan;
4477 }
4478
4479 ic_printf(ic, "ERROR: %s: hw_scan returned %d\n",
4480 __func__, error);
4481 }
4482 }
4483 }
4484
4485 static void
lkpi_ic_scan_end(struct ieee80211com * ic)4486 lkpi_ic_scan_end(struct ieee80211com *ic)
4487 {
4488 struct lkpi_hw *lhw;
4489 bool is_hw_scan;
4490
4491 lhw = ic->ic_softc;
4492 LKPI_80211_LHW_SCAN_LOCK(lhw);
4493 if ((lhw->scan_flags & LKPI_LHW_SCAN_RUNNING) == 0) {
4494 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4495 return;
4496 }
4497 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4498 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4499
4500 if (!is_hw_scan) {
4501 struct ieee80211_scan_state *ss;
4502 struct ieee80211vap *vap;
4503 struct ieee80211_hw *hw;
4504 struct lkpi_vif *lvif;
4505 struct ieee80211_vif *vif;
4506
4507 ss = ic->ic_scan;
4508 vap = ss->ss_vap;
4509 hw = LHW_TO_HW(lhw);
4510 lvif = VAP_TO_LVIF(vap);
4511 vif = LVIF_TO_VIF(lvif);
4512
4513 lkpi_80211_mo_sw_scan_complete(hw, vif);
4514
4515 /* Send PS to stop buffering if n80211 does not for us? */
4516
4517 if (vap->iv_state == IEEE80211_S_SCAN)
4518 lkpi_hw_conf_idle(hw, true);
4519 }
4520 }
4521
4522 static void
lkpi_ic_scan_curchan(struct ieee80211_scan_state * ss,unsigned long maxdwell)4523 lkpi_ic_scan_curchan(struct ieee80211_scan_state *ss,
4524 unsigned long maxdwell)
4525 {
4526 struct lkpi_hw *lhw;
4527 bool is_hw_scan;
4528
4529 lhw = ss->ss_ic->ic_softc;
4530 LKPI_80211_LHW_SCAN_LOCK(lhw);
4531 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4532 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4533 if (!is_hw_scan)
4534 lhw->ic_scan_curchan(ss, maxdwell);
4535 }
4536
4537 static void
lkpi_ic_scan_mindwell(struct ieee80211_scan_state * ss)4538 lkpi_ic_scan_mindwell(struct ieee80211_scan_state *ss)
4539 {
4540 struct lkpi_hw *lhw;
4541 bool is_hw_scan;
4542
4543 lhw = ss->ss_ic->ic_softc;
4544 LKPI_80211_LHW_SCAN_LOCK(lhw);
4545 is_hw_scan = (lhw->scan_flags & LKPI_LHW_SCAN_HW) != 0;
4546 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4547 if (!is_hw_scan)
4548 lhw->ic_scan_mindwell(ss);
4549 }
4550
4551 static void
lkpi_ic_set_channel(struct ieee80211com * ic)4552 lkpi_ic_set_channel(struct ieee80211com *ic)
4553 {
4554 struct lkpi_hw *lhw;
4555 struct ieee80211_hw *hw;
4556 struct ieee80211_channel *c;
4557 struct linuxkpi_ieee80211_channel *chan;
4558 int error;
4559 bool hw_scan_running;
4560
4561 lhw = ic->ic_softc;
4562
4563 /* If we do not support (*config)() save us the work. */
4564 if (lhw->ops->config == NULL)
4565 return;
4566
4567 /* If we have a hw_scan running do not switch channels. */
4568 LKPI_80211_LHW_SCAN_LOCK(lhw);
4569 hw_scan_running =
4570 (lhw->scan_flags & (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW)) ==
4571 (LKPI_LHW_SCAN_RUNNING|LKPI_LHW_SCAN_HW);
4572 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
4573 if (hw_scan_running)
4574 return;
4575
4576 c = ic->ic_curchan;
4577 if (c == NULL || c == IEEE80211_CHAN_ANYC) {
4578 ic_printf(ic, "%s: c %p ops->config %p\n", __func__,
4579 c, lhw->ops->config);
4580 return;
4581 }
4582
4583 chan = lkpi_find_lkpi80211_chan(lhw, c);
4584 if (chan == NULL) {
4585 ic_printf(ic, "%s: c %p chan %p\n", __func__,
4586 c, chan);
4587 return;
4588 }
4589
4590 /* XXX max power for scanning? */
4591 IMPROVE();
4592
4593 hw = LHW_TO_HW(lhw);
4594 cfg80211_chandef_create(&hw->conf.chandef, chan,
4595 #ifdef LKPI_80211_HT
4596 (ic->ic_flags_ht & IEEE80211_FHT_HT) ? NL80211_CHAN_HT20 :
4597 #endif
4598 NL80211_CHAN_NO_HT);
4599
4600 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_CHANNEL);
4601 if (error != 0 && error != EOPNOTSUPP) {
4602 ic_printf(ic, "ERROR: %s: config %#0x returned %d\n",
4603 __func__, IEEE80211_CONF_CHANGE_CHANNEL, error);
4604 /* XXX should we unroll to the previous chandef? */
4605 IMPROVE();
4606 } else {
4607 /* Update radiotap channels as well. */
4608 lhw->rtap_tx.wt_chan_freq = htole16(c->ic_freq);
4609 lhw->rtap_tx.wt_chan_flags = htole16(c->ic_flags);
4610 lhw->rtap_rx.wr_chan_freq = htole16(c->ic_freq);
4611 lhw->rtap_rx.wr_chan_flags = htole16(c->ic_flags);
4612 }
4613
4614 /* Currently PS is hard coded off! Not sure it belongs here. */
4615 IMPROVE();
4616 if (ieee80211_hw_check(hw, SUPPORTS_PS) &&
4617 (hw->conf.flags & IEEE80211_CONF_PS) != 0) {
4618 hw->conf.flags &= ~IEEE80211_CONF_PS;
4619 error = lkpi_80211_mo_config(hw, IEEE80211_CONF_CHANGE_PS);
4620 if (error != 0 && error != EOPNOTSUPP)
4621 ic_printf(ic, "ERROR: %s: config %#0x returned "
4622 "%d\n", __func__, IEEE80211_CONF_CHANGE_PS,
4623 error);
4624 }
4625 }
4626
4627 static struct ieee80211_node *
lkpi_ic_node_alloc(struct ieee80211vap * vap,const uint8_t mac[IEEE80211_ADDR_LEN])4628 lkpi_ic_node_alloc(struct ieee80211vap *vap,
4629 const uint8_t mac[IEEE80211_ADDR_LEN])
4630 {
4631 struct ieee80211com *ic;
4632 struct lkpi_hw *lhw;
4633 struct ieee80211_node *ni;
4634 struct ieee80211_hw *hw;
4635 struct lkpi_sta *lsta;
4636
4637 ic = vap->iv_ic;
4638 lhw = ic->ic_softc;
4639
4640 /* We keep allocations de-coupled so we can deal with the two worlds. */
4641 if (lhw->ic_node_alloc == NULL)
4642 return (NULL);
4643
4644 ni = lhw->ic_node_alloc(vap, mac);
4645 if (ni == NULL)
4646 return (NULL);
4647
4648 hw = LHW_TO_HW(lhw);
4649 lsta = lkpi_lsta_alloc(vap, mac, hw, ni);
4650 if (lsta == NULL) {
4651 if (lhw->ic_node_free != NULL)
4652 lhw->ic_node_free(ni);
4653 return (NULL);
4654 }
4655
4656 return (ni);
4657 }
4658
4659 static int
lkpi_ic_node_init(struct ieee80211_node * ni)4660 lkpi_ic_node_init(struct ieee80211_node *ni)
4661 {
4662 struct ieee80211com *ic;
4663 struct lkpi_hw *lhw;
4664 int error;
4665
4666 ic = ni->ni_ic;
4667 lhw = ic->ic_softc;
4668
4669 if (lhw->ic_node_init != NULL) {
4670 error = lhw->ic_node_init(ni);
4671 if (error != 0)
4672 return (error);
4673 }
4674
4675 /* XXX-BZ Sync other state over. */
4676 IMPROVE();
4677
4678 return (0);
4679 }
4680
4681 static void
lkpi_ic_node_cleanup(struct ieee80211_node * ni)4682 lkpi_ic_node_cleanup(struct ieee80211_node *ni)
4683 {
4684 struct ieee80211com *ic;
4685 struct lkpi_hw *lhw;
4686
4687 ic = ni->ni_ic;
4688 lhw = ic->ic_softc;
4689
4690 /* XXX-BZ remove from driver, ... */
4691 IMPROVE();
4692
4693 if (lhw->ic_node_cleanup != NULL)
4694 lhw->ic_node_cleanup(ni);
4695 }
4696
4697 static void
lkpi_ic_node_free(struct ieee80211_node * ni)4698 lkpi_ic_node_free(struct ieee80211_node *ni)
4699 {
4700 struct ieee80211com *ic;
4701 struct lkpi_hw *lhw;
4702 struct lkpi_sta *lsta;
4703
4704 ic = ni->ni_ic;
4705 lhw = ic->ic_softc;
4706 lsta = ni->ni_drv_data;
4707
4708 /* KASSERT lsta is not NULL here. Print ni/ni__refcnt. */
4709
4710 /*
4711 * Pass in the original ni just in case of error we could check that
4712 * it is the same as lsta->ni.
4713 */
4714 lkpi_lsta_free(lsta, ni);
4715
4716 if (lhw->ic_node_free != NULL)
4717 lhw->ic_node_free(ni);
4718 }
4719
4720 /*
4721 * lkpi_xmit() called from both the (*ic_raw_xmit) as well as the (*ic_transmit)
4722 * call path.
4723 * Unfortunately they have slightly different invariants. See
4724 * ieee80211_raw_output() and ieee80211_parent_xmitpkt().
4725 * Both take care of the ni reference in case of error, and otherwise during
4726 * the callback after transmit.
4727 * The difference is that in case of error (*ic_raw_xmit) needs us to release
4728 * the mbuf, while (*ic_transmit) will free the mbuf itself.
4729 */
4730 static int
lkpi_xmit(struct ieee80211_node * ni,struct mbuf * m,const struct ieee80211_bpf_params * params __unused,bool freem)4731 lkpi_xmit(struct ieee80211_node *ni, struct mbuf *m,
4732 const struct ieee80211_bpf_params *params __unused,
4733 bool freem)
4734 {
4735 struct lkpi_sta *lsta;
4736 int error;
4737
4738 lsta = ni->ni_drv_data;
4739 LKPI_80211_LSTA_TXQ_LOCK(lsta);
4740 #if 0
4741 if (!lsta->added_to_drv || !lsta->txq_ready) {
4742 #else
4743 /*
4744 * Backout this part of 886653492945f which breaks rtw88 or
4745 * in general drivers without (*sta_state)() but only the
4746 * legacy fallback to (*sta_add)().
4747 */
4748 if (!lsta->txq_ready) {
4749 #endif
4750 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4751 if (freem)
4752 m_free(m);
4753 return (ENETDOWN);
4754 }
4755
4756 /* Queue the packet and enqueue the task to handle it. */
4757 error = mbufq_enqueue(&lsta->txq, m);
4758 if (error != 0) {
4759 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4760 if (freem)
4761 m_free(m);
4762 #ifdef LINUXKPI_DEBUG_80211
4763 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4764 ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
4765 __func__, error);
4766 #endif
4767 return (ENETDOWN);
4768 }
4769 taskqueue_enqueue(taskqueue_thread, &lsta->txq_task);
4770 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
4771
4772 #ifdef LINUXKPI_DEBUG_80211
4773 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
4774 printf("%s:%d lsta %p ni %p %6D mbuf_qlen %d\n",
4775 __func__, __LINE__, lsta, ni, ni->ni_macaddr, ":",
4776 mbufq_len(&lsta->txq));
4777 #endif
4778
4779 return (0);
4780 }
4781
4782 static int
4783 lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
4784 const struct ieee80211_bpf_params *params __unused)
4785 {
4786 return (lkpi_xmit(ni, m, NULL, true));
4787 }
4788
4789 #ifdef LKPI_80211_HW_CRYPTO
4790 /*
4791 * This is a bit of a hack given we know we are operating on a
4792 * single frame and we know that hardware will deal with it.
4793 * But otherwise the enmic bit and the encrypt bit need to be
4794 * decoupled.
4795 */
4796 static int
4797 lkpi_hw_crypto_prepare_tkip(struct ieee80211_key *k,
4798 struct ieee80211_key_conf *kc, struct sk_buff *skb)
4799 {
4800 struct ieee80211_hdr *hdr;
4801 uint32_t hlen, hdrlen;
4802 uint8_t *p;
4803
4804 /*
4805 * TKIP only happens on data.
4806 */
4807 hdr = (void *)skb->data;
4808 if (!ieee80211_is_data_present(hdr->frame_control))
4809 return (0);
4810
4811 /*
4812 * "enmic" (though we do not do that).
4813 */
4814 /* any conditions to not apply this? */
4815 if (skb_tailroom(skb) < k->wk_cipher->ic_miclen)
4816 return (ENOBUFS);
4817
4818 p = skb_put(skb, k->wk_cipher->ic_miclen);
4819 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_MIC_SPACE) != 0)
4820 goto encrypt;
4821
4822 /*
4823 * (*enmic) which we hopefully do not have to do with hw accel.
4824 * That means if we make it here we have a problem.
4825 */
4826 TODO("(*enmic)");
4827 return (ENXIO);
4828
4829 encrypt:
4830 /*
4831 * "encrypt" (though we do not do that).
4832 */
4833 /*
4834 * Check if we have anything to do as requested by driver
4835 * or if we are done?
4836 */
4837 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
4838 (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
4839 return (0);
4840
4841 hlen = k->wk_cipher->ic_header;
4842 if (skb_headroom(skb) < hlen)
4843 return (ENOBUFS);
4844
4845 hdr = (void *)skb->data;
4846 hdrlen = ieee80211_hdrlen(hdr->frame_control);
4847 p = skb_push(skb, hlen);
4848 memmove(p, p + hlen, hdrlen);
4849
4850 /* If driver request space only we are done. */
4851 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
4852 return (0);
4853
4854 p += hdrlen;
4855 k->wk_cipher->ic_setiv(k, p);
4856
4857 /* If we make it hear we do sw encryption. */
4858 TODO("sw encrypt");
4859 return (ENXIO);
4860 }
4861
4862 static int
4863 lkpi_hw_crypto_prepare_ccmp(struct ieee80211_key *k,
4864 struct ieee80211_key_conf *kc, struct sk_buff *skb)
4865 {
4866 struct ieee80211_hdr *hdr;
4867 uint32_t hlen, hdrlen;
4868 uint8_t *p;
4869
4870 hdr = (void *)skb->data;
4871
4872 /*
4873 * Check if we have anythig to do as requested by driver
4874 * or if we are done?
4875 */
4876 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
4877 (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0 &&
4878 /* MFP */
4879 !((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) != 0 &&
4880 ieee80211_is_mgmt(hdr->frame_control)))
4881 return (0);
4882
4883 hlen = k->wk_cipher->ic_header;
4884 if (skb_headroom(skb) < hlen)
4885 return (ENOBUFS);
4886
4887 hdrlen = ieee80211_hdrlen(hdr->frame_control);
4888 p = skb_push(skb, hlen);
4889 memmove(p, p + hlen, hdrlen);
4890
4891 /* If driver request space only we are done. */
4892 if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
4893 return (0);
4894
4895 p += hdrlen;
4896 k->wk_cipher->ic_setiv(k, p);
4897
4898 return (0);
4899 }
4900
4901 static int
4902 lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
4903 struct sk_buff *skb)
4904 {
4905 struct ieee80211_tx_info *info;
4906 struct ieee80211_key_conf *kc;
4907
4908 KASSERT(lsta != NULL, ("%s: lsta is NULL", __func__));
4909 KASSERT(k != NULL, ("%s: key is NULL", __func__));
4910 KASSERT(skb != NULL, ("%s: skb is NULL", __func__));
4911
4912 kc = lsta->kc[k->wk_keyix];
4913
4914 info = IEEE80211_SKB_CB(skb);
4915 info->control.hw_key = kc;
4916
4917 /* MUST NOT happen. KASSERT? */
4918 if (kc == NULL) {
4919 ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p skb %p, "
4920 "kc is NULL on hw crypto offload\n", __func__, lsta, k, skb);
4921 return (ENXIO);
4922 }
4923
4924 switch (kc->cipher) {
4925 case WLAN_CIPHER_SUITE_TKIP:
4926 return (lkpi_hw_crypto_prepare_tkip(k, kc, skb));
4927 case WLAN_CIPHER_SUITE_CCMP:
4928 return (lkpi_hw_crypto_prepare_ccmp(k, kc, skb));
4929 case WLAN_CIPHER_SUITE_GCMP:
4930 return (lkpi_hw_crypto_prepare_ccmp(k, kc, skb));
4931 case WLAN_CIPHER_SUITE_WEP40:
4932 case WLAN_CIPHER_SUITE_WEP104:
4933 case WLAN_CIPHER_SUITE_CCMP_256:
4934 case WLAN_CIPHER_SUITE_GCMP_256:
4935 case WLAN_CIPHER_SUITE_AES_CMAC:
4936 case WLAN_CIPHER_SUITE_BIP_CMAC_256:
4937 case WLAN_CIPHER_SUITE_BIP_GMAC_128:
4938 case WLAN_CIPHER_SUITE_BIP_GMAC_256:
4939 default:
4940 ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p kc %p skb %p, "
4941 "unsupported cipher suite %u (%s)\n", __func__, lsta, k, kc,
4942 skb, kc->cipher, lkpi_cipher_suite_to_name(kc->cipher));
4943 return (EOPNOTSUPP);
4944 }
4945 }
4946
4947 static uint8_t
4948 lkpi_hw_crypto_tailroom(struct lkpi_sta *lsta, struct ieee80211_key *k)
4949 {
4950 struct ieee80211_key_conf *kc;
4951
4952 kc = lsta->kc[k->wk_keyix];
4953 if (kc == NULL)
4954 return (0);
4955
4956 IMPROVE("which other flags need tailroom?");
4957 if (kc->flags & (IEEE80211_KEY_FLAG_PUT_MIC_SPACE))
4958 return (32); /* Large enough to hold everything and pow2. */
4959
4960 return (0);
4961 }
4962 #endif
4963
4964 static void
4965 lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
4966 {
4967 struct ieee80211_node *ni;
4968 struct ieee80211_frame *wh;
4969 struct ieee80211_key *k;
4970 struct sk_buff *skb;
4971 struct ieee80211com *ic;
4972 struct lkpi_hw *lhw;
4973 struct ieee80211_hw *hw;
4974 struct lkpi_vif *lvif;
4975 struct ieee80211_vif *vif;
4976 struct ieee80211_channel *c;
4977 struct ieee80211_tx_control control;
4978 struct ieee80211_tx_info *info;
4979 struct ieee80211_sta *sta;
4980 struct ieee80211_hdr *hdr;
4981 struct lkpi_txq *ltxq;
4982 void *buf;
4983 ieee80211_keyix keyix;
4984 uint8_t ac, tid, tailroom;
4985
4986 M_ASSERTPKTHDR(m);
4987 #ifdef LINUXKPI_DEBUG_80211
4988 if (linuxkpi_debug_80211 & D80211_TRACE_TX_DUMP)
4989 hexdump(mtod(m, const void *), m->m_len, "RAW TX (plain) ", 0);
4990 #endif
4991
4992 ni = lsta->ni;
4993 k = NULL;
4994 keyix = IEEE80211_KEYIX_NONE;
4995 wh = mtod(m, struct ieee80211_frame *);
4996 if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
4997
4998 #ifdef LKPI_80211_HW_CRYPTO
4999 if (lkpi_hwcrypto) {
5000 k = ieee80211_crypto_get_txkey(ni, m);
5001 if (k != NULL && lsta->kc[k->wk_keyix] != NULL)
5002 keyix = k->wk_keyix;
5003 }
5004 #endif
5005
5006 /* Encrypt the frame if need be. */
5007 if (keyix == IEEE80211_KEYIX_NONE) {
5008 /* Retrieve key for TX && do software encryption. */
5009 k = ieee80211_crypto_encap(ni, m);
5010 if (k == NULL) {
5011 ieee80211_free_node(ni);
5012 m_freem(m);
5013 return;
5014 }
5015 }
5016 }
5017
5018 ic = ni->ni_ic;
5019 lhw = ic->ic_softc;
5020 hw = LHW_TO_HW(lhw);
5021 c = ni->ni_chan;
5022
5023 if (ieee80211_radiotap_active_vap(ni->ni_vap)) {
5024 struct lkpi_radiotap_tx_hdr *rtap;
5025
5026 rtap = &lhw->rtap_tx;
5027 rtap->wt_flags = 0;
5028 if (k != NULL)
5029 rtap->wt_flags |= IEEE80211_RADIOTAP_F_WEP;
5030 if (m->m_flags & M_FRAG)
5031 rtap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG;
5032 IMPROVE();
5033 rtap->wt_rate = 0;
5034 if (c != NULL && c != IEEE80211_CHAN_ANYC) {
5035 rtap->wt_chan_freq = htole16(c->ic_freq);
5036 rtap->wt_chan_flags = htole16(c->ic_flags);
5037 }
5038
5039 ieee80211_radiotap_tx(ni->ni_vap, m);
5040 }
5041
5042 #ifdef LKPI_80211_HW_CRYPTO
5043 if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE)
5044 tailroom = lkpi_hw_crypto_tailroom(lsta, k);
5045 else
5046 #endif
5047 tailroom = 0;
5048
5049 /*
5050 * net80211 should handle hw->extra_tx_headroom.
5051 * Though for as long as we are copying we don't mind.
5052 * XXX-BZ rtw88 asks for too much headroom for ipv6+tcp:
5053 * https://lists.freebsd.org/archives/freebsd-transport/2022-February/000012.html
5054 */
5055 skb = dev_alloc_skb(hw->extra_tx_headroom + tailroom + m->m_pkthdr.len);
5056 if (skb == NULL) {
5057 static uint8_t skb_alloc_failures = 0;
5058
5059 if (skb_alloc_failures++ == 0) {
5060 int tid;
5061
5062 sta = LSTA_TO_STA(lsta);
5063 ic_printf(ic, "ERROR %s: skb alloc failed %d + %d, lsta %p sta %p ni %p\n",
5064 __func__, hw->extra_tx_headroom, m->m_pkthdr.len, lsta, sta, ni);
5065 for (tid = 0; tid < nitems(sta->txq); tid++) {
5066 if (sta->txq[tid] == NULL)
5067 continue;
5068 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
5069 ic_printf(ic, " tid %d ltxq %p seen_dequeue %d stopped %d skb_queue_len %u\n",
5070 tid, ltxq, ltxq->seen_dequeue, ltxq->stopped, skb_queue_len(<xq->skbq));
5071 }
5072 }
5073 ieee80211_free_node(ni);
5074 m_freem(m);
5075 return;
5076 }
5077 skb_reserve(skb, hw->extra_tx_headroom);
5078
5079 /* XXX-BZ we need a SKB version understanding mbuf. */
5080 /* Save the mbuf for ieee80211_tx_complete(). */
5081 skb->m_free_func = lkpi_ieee80211_free_skb_mbuf;
5082 skb->m = m;
5083 #if 0
5084 skb_put_data(skb, m->m_data, m->m_pkthdr.len);
5085 #else
5086 buf = skb_put(skb, m->m_pkthdr.len);
5087 m_copydata(m, 0, m->m_pkthdr.len, buf);
5088 #endif
5089 /* Save the ni. */
5090 m->m_pkthdr.PH_loc.ptr = ni;
5091
5092 lvif = VAP_TO_LVIF(ni->ni_vap);
5093 vif = LVIF_TO_VIF(lvif);
5094
5095 hdr = (void *)skb->data;
5096 tid = linuxkpi_ieee80211_get_tid(hdr, true);
5097 if (tid == IEEE80211_NONQOS_TID) { /* == IEEE80211_NUM_TIDS */
5098 if (!ieee80211_is_data(hdr->frame_control)) {
5099 /* MGMT and CTRL frames go on TID 7/VO. */
5100 skb->priority = 7;
5101 ac = IEEE80211_AC_VO;
5102 } else {
5103 /* Other non-QOS traffic goes to BE. */
5104 /* Contrary to net80211 we MUST NOT promote M_EAPOL. */
5105 skb->priority = 0;
5106 ac = IEEE80211_AC_BE;
5107 }
5108 } else {
5109 skb->priority = tid & IEEE80211_QOS_CTL_TID_MASK;
5110 ac = ieee80211e_up_to_ac[tid & 7];
5111 }
5112 skb_set_queue_mapping(skb, ac);
5113
5114 info = IEEE80211_SKB_CB(skb);
5115 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
5116 /* Slight delay; probably only happens on scanning so fine? */
5117 if (c == NULL || c == IEEE80211_CHAN_ANYC)
5118 c = ic->ic_curchan;
5119 info->band = lkpi_net80211_chan_to_nl80211_band(c);
5120 info->hw_queue = vif->hw_queue[ac];
5121 if (m->m_flags & M_EAPOL)
5122 info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
5123 info->control.vif = vif;
5124 /* XXX-BZ info->control.rates */
5125 #ifdef __notyet__
5126 #ifdef LKPI_80211_HT
5127 info->control.rts_cts_rate_idx=
5128 info->control.use_rts= /* RTS */
5129 info->control.use_cts_prot= /* RTS/CTS*/
5130 #endif
5131 #endif
5132
5133 sta = LSTA_TO_STA(lsta);
5134 #ifdef LKPI_80211_HW_CRYPTO
5135 if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE) {
5136 int error;
5137
5138 error = lkpi_hw_crypto_prepare(lsta, k, skb);
5139 if (error != 0) {
5140 /*
5141 * We only have to free the skb which will free the
5142 * mbuf and release the reference on the ni.
5143 */
5144 dev_kfree_skb(skb);
5145 return;
5146 }
5147 }
5148 #endif
5149
5150 IMPROVE();
5151
5152 ltxq = NULL;
5153 if (!ieee80211_is_data_present(hdr->frame_control)) {
5154 if (vif->type == NL80211_IFTYPE_STATION &&
5155 lsta->added_to_drv &&
5156 sta->txq[IEEE80211_NUM_TIDS] != NULL)
5157 ltxq = TXQ_TO_LTXQ(sta->txq[IEEE80211_NUM_TIDS]);
5158 } else if (lsta->added_to_drv &&
5159 sta->txq[skb->priority] != NULL) {
5160 ltxq = TXQ_TO_LTXQ(sta->txq[skb->priority]);
5161 }
5162 if (ltxq == NULL)
5163 goto ops_tx;
5164
5165 KASSERT(ltxq != NULL, ("%s: lsta %p sta %p m %p skb %p "
5166 "ltxq %p != NULL\n", __func__, lsta, sta, m, skb, ltxq));
5167
5168 LKPI_80211_LTXQ_LOCK(ltxq);
5169 skb_queue_tail(<xq->skbq, skb);
5170 #ifdef LINUXKPI_DEBUG_80211
5171 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5172 printf("%s:%d mo_wake_tx_queue :: %d %lu lsta %p sta %p "
5173 "ni %p %6D skb %p lxtq %p { qlen %u, ac %d tid %u } "
5174 "WAKE_TX_Q ac %d prio %u qmap %u\n",
5175 __func__, __LINE__,
5176 curthread->td_tid, jiffies,
5177 lsta, sta, ni, ni->ni_macaddr, ":", skb, ltxq,
5178 skb_queue_len(<xq->skbq), ltxq->txq.ac,
5179 ltxq->txq.tid, ac, skb->priority, skb->qmap);
5180 #endif
5181 LKPI_80211_LTXQ_UNLOCK(ltxq);
5182 wiphy_lock(hw->wiphy);
5183 lkpi_80211_mo_wake_tx_queue(hw, <xq->txq);
5184 wiphy_unlock(hw->wiphy);
5185 return;
5186
5187 ops_tx:
5188 #ifdef LINUXKPI_DEBUG_80211
5189 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5190 printf("%s:%d mo_tx :: lsta %p sta %p ni %p %6D skb %p "
5191 "TX ac %d prio %u qmap %u\n",
5192 __func__, __LINE__, lsta, sta, ni, ni->ni_macaddr, ":",
5193 skb, ac, skb->priority, skb->qmap);
5194 #endif
5195 memset(&control, 0, sizeof(control));
5196 control.sta = sta;
5197 wiphy_lock(hw->wiphy);
5198 lkpi_80211_mo_tx(hw, &control, skb);
5199 wiphy_unlock(hw->wiphy);
5200 }
5201
5202 static void
5203 lkpi_80211_txq_task(void *ctx, int pending)
5204 {
5205 struct lkpi_sta *lsta;
5206 struct mbufq mq;
5207 struct mbuf *m;
5208 bool shall_tx;
5209
5210 lsta = ctx;
5211
5212 #ifdef LINUXKPI_DEBUG_80211
5213 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
5214 printf("%s:%d lsta %p ni %p %6D pending %d mbuf_qlen %d\n",
5215 __func__, __LINE__, lsta, lsta->ni, lsta->ni->ni_macaddr, ":",
5216 pending, mbufq_len(&lsta->txq));
5217 #endif
5218
5219 mbufq_init(&mq, IFQ_MAXLEN);
5220
5221 LKPI_80211_LSTA_TXQ_LOCK(lsta);
5222 /*
5223 * Do not re-check lsta->txq_ready here; we may have a pending
5224 * disassoc/deauth frame still. On the contrary if txq_ready is
5225 * false we do not have a valid sta anymore in the firmware so no
5226 * point to try to TX.
5227 * We also use txq_ready as a semaphore and will drain the txq manually
5228 * if needed on our way towards SCAN/INIT in the state machine.
5229 */
5230 #if 0
5231 shall_tx = lsta->added_to_drv && lsta->txq_ready;
5232 #else
5233 /*
5234 * Backout this part of 886653492945f which breaks rtw88 or
5235 * in general drivers without (*sta_state)() but only the
5236 * legacy fallback to (*sta_add)().
5237 */
5238 shall_tx = lsta->txq_ready;
5239 #endif
5240 if (__predict_true(shall_tx))
5241 mbufq_concat(&mq, &lsta->txq);
5242 /*
5243 * else a state change will push the packets out manually or
5244 * lkpi_lsta_free() will drain the lsta->txq and free the mbufs.
5245 */
5246 LKPI_80211_LSTA_TXQ_UNLOCK(lsta);
5247
5248 m = mbufq_dequeue(&mq);
5249 while (m != NULL) {
5250 lkpi_80211_txq_tx_one(lsta, m);
5251 m = mbufq_dequeue(&mq);
5252 }
5253 }
5254
5255 static int
5256 lkpi_ic_transmit(struct ieee80211com *ic, struct mbuf *m)
5257 {
5258
5259 /* XXX TODO */
5260 IMPROVE();
5261
5262 /* Quick and dirty cheating hack. */
5263 struct ieee80211_node *ni;
5264
5265 ni = (struct ieee80211_node *)m->m_pkthdr.rcvif;
5266 return (lkpi_xmit(ni, m, NULL, false));
5267 }
5268
5269 #ifdef LKPI_80211_HT
5270 static int
5271 lkpi_ic_recv_action(struct ieee80211_node *ni, const struct ieee80211_frame *wh,
5272 const uint8_t *frm, const uint8_t *efrm)
5273 {
5274 struct ieee80211com *ic;
5275 struct lkpi_hw *lhw;
5276
5277 ic = ni->ni_ic;
5278 lhw = ic->ic_softc;
5279
5280 IMPROVE_HT("recv_action called; nothing to do in lkpi; make debugging");
5281
5282 return (lhw->ic_recv_action(ni, wh, frm, efrm));
5283 }
5284
5285 static int
5286 lkpi_ic_send_action(struct ieee80211_node *ni, int category, int action, void *sa)
5287 {
5288 struct ieee80211com *ic;
5289 struct lkpi_hw *lhw;
5290
5291 ic = ni->ni_ic;
5292 lhw = ic->ic_softc;
5293
5294 IMPROVE_HT("send_action called; nothing to do in lkpi; make debugging");
5295
5296 return (lhw->ic_send_action(ni, category, action, sa));
5297 }
5298
5299
5300 static int
5301 lkpi_ic_ampdu_enable(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
5302 {
5303 struct ieee80211com *ic;
5304 struct lkpi_hw *lhw;
5305
5306 ic = ni->ni_ic;
5307 lhw = ic->ic_softc;
5308
5309 IMPROVE_HT("ieee80211_ampdu_enable called; nothing to do in lkpi for now; make debugging");
5310
5311 return (lhw->ic_ampdu_enable(ni, tap));
5312 }
5313
5314 /*
5315 * (*ic_addba_request)() is called by ieee80211_ampdu_request() before
5316 * calling send_action(CAT_BA, BA_ADDBA_REQUEST).
5317 *
5318 * NB: returns 0 on ERROR!
5319 */
5320 static int
5321 lkpi_ic_addba_request(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
5322 int dialogtoken, int baparamset, int batimeout)
5323 {
5324 struct ieee80211com *ic;
5325 struct lkpi_hw *lhw;
5326 struct ieee80211_hw *hw;
5327 struct ieee80211vap *vap;
5328 struct lkpi_vif *lvif;
5329 struct ieee80211_vif *vif;
5330 struct lkpi_sta *lsta;
5331 struct ieee80211_sta *sta;
5332 struct ieee80211_ampdu_params params = { };
5333 int error;
5334
5335 ic = ni->ni_ic;
5336 lhw = ic->ic_softc;
5337 hw = LHW_TO_HW(lhw);
5338 vap = ni->ni_vap;
5339 lvif = VAP_TO_LVIF(vap);
5340 vif = LVIF_TO_VIF(lvif);
5341 lsta = ni->ni_drv_data;
5342 sta = LSTA_TO_STA(lsta);
5343
5344 if (!lsta->added_to_drv) {
5345 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
5346 __func__, lsta, ni, sta);
5347 return (0);
5348 }
5349
5350 params.sta = sta;
5351 params.action = IEEE80211_AMPDU_TX_START;
5352 /* Keep 0 here! */
5353 params.buf_size = 0;
5354 params.timeout = 0;
5355 params.ssn = tap->txa_start & (IEEE80211_SEQ_RANGE-1);
5356 params.tid = tap->txa_tid;
5357 params.amsdu = false;
5358
5359 IEEE80211_UNLOCK(ic);
5360 wiphy_lock(hw->wiphy);
5361 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
5362 wiphy_unlock(hw->wiphy);
5363 IEEE80211_LOCK(ic);
5364 if (error != 0) {
5365 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
5366 __func__, error, ni, tap);
5367 return (0);
5368 }
5369
5370 return (lhw->ic_addba_request(ni, tap, dialogtoken, baparamset, batimeout));
5371 }
5372
5373 /*
5374 * (*ic_addba_response)() is called from ht_recv_action_ba_addba_response()
5375 * and calls the default ieee80211_addba_response() which always returns 1.
5376 *
5377 * NB: No error checking in net80211!
5378 * Staying with 0 is an error.
5379 */
5380 static int
5381 lkpi_ic_addba_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
5382 int status, int baparamset, int batimeout)
5383 {
5384 struct ieee80211com *ic;
5385 struct lkpi_hw *lhw;
5386 struct ieee80211_hw *hw;
5387 struct ieee80211vap *vap;
5388 struct lkpi_vif *lvif;
5389 struct ieee80211_vif *vif;
5390 struct lkpi_sta *lsta;
5391 struct ieee80211_sta *sta;
5392 struct ieee80211_ampdu_params params = { };
5393 int error;
5394
5395 ic = ni->ni_ic;
5396 lhw = ic->ic_softc;
5397 hw = LHW_TO_HW(lhw);
5398 vap = ni->ni_vap;
5399 lvif = VAP_TO_LVIF(vap);
5400 vif = LVIF_TO_VIF(lvif);
5401 lsta = ni->ni_drv_data;
5402 sta = LSTA_TO_STA(lsta);
5403
5404 if (!lsta->added_to_drv) {
5405 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
5406 __func__, lsta, ni, sta);
5407 return (0);
5408 }
5409
5410 if (status == IEEE80211_STATUS_SUCCESS) {
5411 params.sta = sta;
5412 params.action = IEEE80211_AMPDU_TX_OPERATIONAL;
5413 params.buf_size = tap->txa_wnd;
5414 params.timeout = 0;
5415 params.ssn = 0;
5416 params.tid = tap->txa_tid;
5417 if ((tap->txa_flags & IEEE80211_AGGR_AMSDU) != 0)
5418 params.amsdu = true;
5419 else
5420 params.amsdu = false;
5421 } else {
5422 /* We need to free the allocated resources. */
5423 params.sta = sta;
5424 switch (status) {
5425 /* params.action = FLUSH, FLUSH_CONT */
5426 default:
5427 params.action = IEEE80211_AMPDU_TX_STOP_CONT;
5428 break;
5429 }
5430 params.buf_size = 0;
5431 params.timeout = 0;
5432 params.ssn = 0;
5433 params.tid = tap->txa_tid;
5434 params.amsdu = false;
5435 }
5436
5437 IEEE80211_UNLOCK(ic);
5438 wiphy_lock(hw->wiphy);
5439 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
5440 wiphy_unlock(hw->wiphy);
5441 IEEE80211_LOCK(ic);
5442 if (error != 0) {
5443 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
5444 __func__, error, ni, tap);
5445 return (0);
5446 }
5447
5448 IMPROVE_HT("who unleashes the TXQ? and when?, do we need to ni->ni_txseqs[tid] = tap->txa_start & 0xfff;");
5449
5450 return (lhw->ic_addba_response(ni, tap, status, baparamset, batimeout));
5451 }
5452
5453 /*
5454 * (*ic_addba_stop)() is called from ampdu_tx_stop(), ht_recv_action_ba_delba(),
5455 * and ieee80211_ampdu_stop() and calls the default ieee80211_addba_stop().
5456 */
5457 static void
5458 lkpi_ic_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
5459 {
5460 struct ieee80211com *ic;
5461 struct lkpi_hw *lhw;
5462 struct ieee80211_hw *hw;
5463 struct ieee80211vap *vap;
5464 struct lkpi_vif *lvif;
5465 struct ieee80211_vif *vif;
5466 struct lkpi_sta *lsta;
5467 struct ieee80211_sta *sta;
5468 struct ieee80211_ampdu_params params = { };
5469 int error;
5470
5471 ic = ni->ni_ic;
5472 lhw = ic->ic_softc;
5473 hw = LHW_TO_HW(lhw);
5474 vap = ni->ni_vap;
5475 lvif = VAP_TO_LVIF(vap);
5476 vif = LVIF_TO_VIF(lvif);
5477 lsta = ni->ni_drv_data;
5478 sta = LSTA_TO_STA(lsta);
5479
5480 if (!lsta->added_to_drv) {
5481 ic_printf(ic, "%s: lsta %p ni %p, sta %p not added to firmware\n",
5482 __func__, lsta, ni, sta);
5483 goto n80211;
5484 }
5485
5486 /* We need to free the allocated resources. */
5487 params.sta = sta;
5488 IMPROVE("net80211 does not provide a reason to us");
5489 params.action = IEEE80211_AMPDU_TX_STOP_CONT; /* params.action = FLUSH, FLUSH_CONT */
5490 params.buf_size = 0;
5491 params.timeout = 0;
5492 params.ssn = 0;
5493 params.tid = tap->txa_tid;
5494 params.amsdu = false;
5495
5496 IEEE80211_UNLOCK(ic);
5497 wiphy_lock(hw->wiphy);
5498 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
5499 wiphy_unlock(hw->wiphy);
5500 IEEE80211_LOCK(ic);
5501 if (error != 0) {
5502 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p tap %p\n",
5503 __func__, error, ni, tap);
5504 goto n80211;
5505 }
5506
5507 IMPROVE_HT("anyting else?");
5508
5509 n80211:
5510 lhw->ic_addba_stop(ni, tap);
5511 }
5512
5513 static void
5514 lkpi_ic_addba_response_timeout(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap)
5515 {
5516 struct ieee80211com *ic;
5517 struct lkpi_hw *lhw;
5518
5519 ic = ni->ni_ic;
5520 lhw = ic->ic_softc;
5521
5522 IMPROVE_HT();
5523
5524 lhw->ic_addba_response_timeout(ni, tap);
5525 }
5526
5527 static void
5528 lkpi_ic_bar_response(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap,
5529 int status)
5530 {
5531 struct ieee80211com *ic;
5532 struct lkpi_hw *lhw;
5533
5534 ic = ni->ni_ic;
5535 lhw = ic->ic_softc;
5536
5537 IMPROVE_HT();
5538
5539 lhw->ic_bar_response(ni, tap, status);
5540 }
5541
5542 static int
5543 lkpi_ic_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
5544 int baparamset, int batimeout, int baseqctl)
5545 {
5546 struct ieee80211com *ic;
5547 struct lkpi_hw *lhw;
5548 struct ieee80211_hw *hw;
5549 struct ieee80211vap *vap;
5550 struct lkpi_vif *lvif;
5551 struct ieee80211_vif *vif;
5552 struct lkpi_sta *lsta;
5553 struct ieee80211_sta *sta;
5554 struct ieee80211_ampdu_params params = { };
5555 int error;
5556
5557 ic = ni->ni_ic;
5558 lhw = ic->ic_softc;
5559 hw = LHW_TO_HW(lhw);
5560 vap = ni->ni_vap;
5561 lvif = VAP_TO_LVIF(vap);
5562 vif = LVIF_TO_VIF(lvif);
5563 lsta = ni->ni_drv_data;
5564 sta = LSTA_TO_STA(lsta);
5565
5566 IEEE80211_UNLOCK_ASSERT(ic);
5567
5568 if (!lsta->added_to_drv) {
5569 ic_printf(ic, "%s: lsta %p ni %p vap %p, sta %p not added to firmware\n",
5570 __func__, lsta, ni, vap, sta);
5571 return (-ENXIO);
5572 }
5573
5574 params.sta = sta;
5575 params.action = IEEE80211_AMPDU_RX_START;
5576 params.buf_size = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_BUFSIZ);
5577 if (params.buf_size == 0)
5578 params.buf_size = IEEE80211_MAX_AMPDU_BUF_HT;
5579 else
5580 params.buf_size = min(params.buf_size, IEEE80211_MAX_AMPDU_BUF_HT);
5581 if (hw->max_rx_aggregation_subframes > 0 &&
5582 params.buf_size > hw->max_rx_aggregation_subframes)
5583 params.buf_size = hw->max_rx_aggregation_subframes;
5584 params.timeout = le16toh(batimeout);
5585 params.ssn = _IEEE80211_MASKSHIFT(le16toh(baseqctl), IEEE80211_BASEQ_START);
5586 params.tid = _IEEE80211_MASKSHIFT(le16toh(baparamset), IEEE80211_BAPS_TID);
5587
5588 /* Based on net80211::ampdu_rx_start(). */
5589 if ((vap->iv_htcaps & IEEE80211_HTC_RX_AMSDU_AMPDU) &&
5590 (_IEEE80211_MASKSHIFT(baparamset, IEEE80211_BAPS_AMSDU)))
5591 params.amsdu = true;
5592 else
5593 params.amsdu = false;
5594
5595 wiphy_lock(hw->wiphy);
5596 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
5597 wiphy_unlock(hw->wiphy);
5598 if (error != 0) {
5599 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
5600 __func__, error, ni, rap);
5601 return (error);
5602 }
5603
5604 if (!ieee80211_hw_check(hw, SUPPORTS_REORDERING_BUFFER)) {
5605 IMPROVE("%s: TODO: SUPPORTS_REORDERING_BUFFER not set; check net80211\n", __func__);
5606 }
5607
5608 IMPROVE_HT("net80211 is missing the error check on return and assumes success");
5609
5610 error = lhw->ic_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
5611 return (error);
5612 }
5613
5614 static void
5615 lkpi_ic_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
5616 {
5617 struct ieee80211com *ic;
5618 struct lkpi_hw *lhw;
5619 struct ieee80211_hw *hw;
5620 struct ieee80211vap *vap;
5621 struct lkpi_vif *lvif;
5622 struct ieee80211_vif *vif;
5623 struct lkpi_sta *lsta;
5624 struct ieee80211_sta *sta;
5625 struct ieee80211_ampdu_params params = { };
5626 int error;
5627 uint8_t tid;
5628 bool ic_locked;
5629
5630 ic = ni->ni_ic;
5631 lhw = ic->ic_softc;
5632
5633 /*
5634 * We should not (cannot) call into mac80211 ops with AMPDU_RX_STOP if
5635 * we did not START. Some drivers pass it down to firmware which will
5636 * simply barf and net80211 calls ieee80211_ht_node_cleanup() from
5637 * ieee80211_ht_node_init() amongst others which will iterate over all
5638 * tid and call ic_ampdu_rx_stop() unconditionally.
5639 * XXX net80211 should probably be more "gentle" in these cases and
5640 * track some state itself.
5641 */
5642 if ((rap->rxa_flags & IEEE80211_AGGR_RUNNING) == 0)
5643 goto net80211_only;
5644
5645 hw = LHW_TO_HW(lhw);
5646 vap = ni->ni_vap;
5647 lvif = VAP_TO_LVIF(vap);
5648 vif = LVIF_TO_VIF(lvif);
5649 lsta = ni->ni_drv_data;
5650 sta = LSTA_TO_STA(lsta);
5651
5652 IMPROVE_HT("This really should be passed from ht_recv_action_ba_delba.");
5653 for (tid = 0; tid < WME_NUM_TID; tid++) {
5654 if (&ni->ni_rx_ampdu[tid] == rap)
5655 break;
5656 }
5657
5658 params.sta = sta;
5659 params.action = IEEE80211_AMPDU_RX_STOP;
5660 params.buf_size = 0;
5661 params.timeout = 0;
5662 params.ssn = 0;
5663 params.tid = tid;
5664 params.amsdu = false;
5665
5666 ic_locked = IEEE80211_IS_LOCKED(ic);
5667 if (ic_locked)
5668 IEEE80211_UNLOCK(ic);
5669 wiphy_lock(hw->wiphy);
5670 error = lkpi_80211_mo_ampdu_action(hw, vif, ¶ms);
5671 wiphy_unlock(hw->wiphy);
5672 if (ic_locked)
5673 IEEE80211_LOCK(ic);
5674 if (error != 0)
5675 ic_printf(ic, "%s: mo_ampdu_action returned %d. ni %p rap %p\n",
5676 __func__, error, ni, rap);
5677
5678 net80211_only:
5679 lhw->ic_ampdu_rx_stop(ni, rap);
5680 }
5681 #endif
5682
5683 static void
5684 lkpi_ic_getradiocaps_ht(struct ieee80211com *ic, struct ieee80211_hw *hw,
5685 uint8_t *bands, int *chan_flags, enum nl80211_band band)
5686 {
5687 #ifdef LKPI_80211_HT
5688 struct ieee80211_sta_ht_cap *ht_cap;
5689
5690 ht_cap = &hw->wiphy->bands[band]->ht_cap;
5691 if (!ht_cap->ht_supported)
5692 return;
5693
5694 switch (band) {
5695 case NL80211_BAND_2GHZ:
5696 setbit(bands, IEEE80211_MODE_11NG);
5697 break;
5698 case NL80211_BAND_5GHZ:
5699 setbit(bands, IEEE80211_MODE_11NA);
5700 break;
5701 default:
5702 IMPROVE("Unsupported band %d", band);
5703 return;
5704 }
5705
5706 ic->ic_htcaps = IEEE80211_HTC_HT; /* HT operation */
5707
5708 /*
5709 * Rather than manually checking each flag and
5710 * translating IEEE80211_HT_CAP_ to IEEE80211_HTCAP_,
5711 * simply copy the 16bits.
5712 */
5713 ic->ic_htcaps |= ht_cap->cap;
5714
5715 /* Then deal with the other flags. */
5716 if (ieee80211_hw_check(hw, AMPDU_AGGREGATION))
5717 ic->ic_htcaps |= IEEE80211_HTC_AMPDU;
5718 #ifdef __notyet__
5719 if (ieee80211_hw_check(hw, TX_AMSDU))
5720 ic->ic_htcaps |= IEEE80211_HTC_AMSDU;
5721 if (ieee80211_hw_check(hw, SUPPORTS_AMSDU_IN_AMPDU))
5722 ic->ic_htcaps |= (IEEE80211_HTC_RX_AMSDU_AMPDU |
5723 IEEE80211_HTC_TX_AMSDU_AMPDU);
5724 #endif
5725
5726 IMPROVE("PS, ampdu_*, ht_cap.mcs.tx_params, ...");
5727 ic->ic_htcaps |= IEEE80211_HTCAP_SMPS_OFF;
5728
5729 /* Only add HT40 channels if supported. */
5730 if ((ic->ic_htcaps & IEEE80211_HTCAP_CHWIDTH40) != 0 &&
5731 chan_flags != NULL)
5732 *chan_flags |= NET80211_CBW_FLAG_HT40;
5733 #endif
5734 }
5735
5736 static void
5737 lkpi_ic_getradiocaps(struct ieee80211com *ic, int maxchan,
5738 int *n, struct ieee80211_channel *c)
5739 {
5740 struct lkpi_hw *lhw;
5741 struct ieee80211_hw *hw;
5742 struct linuxkpi_ieee80211_channel *channels;
5743 uint8_t bands[IEEE80211_MODE_BYTES];
5744 int chan_flags, error, i, nchans;
5745
5746 /* Channels */
5747 lhw = ic->ic_softc;
5748 hw = LHW_TO_HW(lhw);
5749
5750 /* NL80211_BAND_2GHZ */
5751 nchans = 0;
5752 if (hw->wiphy->bands[NL80211_BAND_2GHZ] != NULL)
5753 nchans = hw->wiphy->bands[NL80211_BAND_2GHZ]->n_channels;
5754 if (nchans > 0) {
5755 memset(bands, 0, sizeof(bands));
5756 chan_flags = 0;
5757 setbit(bands, IEEE80211_MODE_11B);
5758 /* XXX-BZ unclear how to check for 11g. */
5759
5760 IMPROVE("the bitrates may have flags?");
5761 setbit(bands, IEEE80211_MODE_11G);
5762
5763 lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
5764 NL80211_BAND_2GHZ);
5765
5766 channels = hw->wiphy->bands[NL80211_BAND_2GHZ]->channels;
5767 for (i = 0; i < nchans && *n < maxchan; i++) {
5768 uint32_t nflags = 0;
5769 int cflags = chan_flags;
5770
5771 if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
5772 ic_printf(ic, "%s: Skipping disabled chan "
5773 "[%u/%u/%#x]\n", __func__,
5774 channels[i].hw_value,
5775 channels[i].center_freq, channels[i].flags);
5776 continue;
5777 }
5778 if (channels[i].flags & IEEE80211_CHAN_NO_IR)
5779 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
5780 if (channels[i].flags & IEEE80211_CHAN_RADAR)
5781 nflags |= IEEE80211_CHAN_DFS;
5782 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
5783 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
5784 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
5785 cflags &= ~NET80211_CBW_FLAG_VHT80;
5786 /* XXX how to map the remaining enum ieee80211_channel_flags? */
5787 if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
5788 cflags &= ~NET80211_CBW_FLAG_HT40;
5789
5790 error = ieee80211_add_channel_cbw(c, maxchan, n,
5791 channels[i].hw_value, channels[i].center_freq,
5792 channels[i].max_power,
5793 nflags, bands, cflags);
5794 /* net80211::ENOBUFS: *n >= maxchans */
5795 if (error != 0 && error != ENOBUFS)
5796 ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
5797 "returned error %d\n",
5798 __func__, channels[i].hw_value,
5799 channels[i].center_freq, channels[i].flags,
5800 nflags, chan_flags, cflags, error);
5801 if (error != 0)
5802 break;
5803 }
5804 }
5805
5806 /* NL80211_BAND_5GHZ */
5807 nchans = 0;
5808 if (hw->wiphy->bands[NL80211_BAND_5GHZ] != NULL)
5809 nchans = hw->wiphy->bands[NL80211_BAND_5GHZ]->n_channels;
5810 if (nchans > 0) {
5811 memset(bands, 0, sizeof(bands));
5812 chan_flags = 0;
5813 setbit(bands, IEEE80211_MODE_11A);
5814
5815 lkpi_ic_getradiocaps_ht(ic, hw, bands, &chan_flags,
5816 NL80211_BAND_5GHZ);
5817
5818 #ifdef LKPI_80211_VHT
5819 if (hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_supported) {
5820
5821 ic->ic_flags_ext |= IEEE80211_FEXT_VHT;
5822 ic->ic_vht_cap.vht_cap_info =
5823 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.cap;
5824 ic->ic_vht_cap.supp_mcs =
5825 hw->wiphy->bands[NL80211_BAND_5GHZ]->vht_cap.vht_mcs;
5826
5827 setbit(bands, IEEE80211_MODE_VHT_5GHZ);
5828 chan_flags |= NET80211_CBW_FLAG_VHT80;
5829 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160MHZ(
5830 ic->ic_vht_cap.vht_cap_info))
5831 chan_flags |= NET80211_CBW_FLAG_VHT160;
5832 if (IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_IS_160_80P80MHZ(
5833 ic->ic_vht_cap.vht_cap_info))
5834 chan_flags |= NET80211_CBW_FLAG_VHT80P80;
5835 }
5836 #endif
5837
5838 channels = hw->wiphy->bands[NL80211_BAND_5GHZ]->channels;
5839 for (i = 0; i < nchans && *n < maxchan; i++) {
5840 uint32_t nflags = 0;
5841 int cflags = chan_flags;
5842
5843 if (channels[i].flags & IEEE80211_CHAN_DISABLED) {
5844 ic_printf(ic, "%s: Skipping disabled chan "
5845 "[%u/%u/%#x]\n", __func__,
5846 channels[i].hw_value,
5847 channels[i].center_freq, channels[i].flags);
5848 continue;
5849 }
5850 if (channels[i].flags & IEEE80211_CHAN_NO_IR)
5851 nflags |= (IEEE80211_CHAN_NOADHOC|IEEE80211_CHAN_PASSIVE);
5852 if (channels[i].flags & IEEE80211_CHAN_RADAR)
5853 nflags |= IEEE80211_CHAN_DFS;
5854 if (channels[i].flags & IEEE80211_CHAN_NO_160MHZ)
5855 cflags &= ~(NET80211_CBW_FLAG_VHT160|NET80211_CBW_FLAG_VHT80P80);
5856 if (channels[i].flags & IEEE80211_CHAN_NO_80MHZ)
5857 cflags &= ~NET80211_CBW_FLAG_VHT80;
5858 /* XXX hwo to map the remaining enum ieee80211_channel_flags? */
5859 if (channels[i].flags & IEEE80211_CHAN_NO_HT40)
5860 cflags &= ~NET80211_CBW_FLAG_HT40;
5861
5862 error = ieee80211_add_channel_cbw(c, maxchan, n,
5863 channels[i].hw_value, channels[i].center_freq,
5864 channels[i].max_power,
5865 nflags, bands, cflags);
5866 /* net80211::ENOBUFS: *n >= maxchans */
5867 if (error != 0 && error != ENOBUFS)
5868 ic_printf(ic, "%s: Adding chan %u/%u/%#x/%#x/%#x/%#x "
5869 "returned error %d\n",
5870 __func__, channels[i].hw_value,
5871 channels[i].center_freq, channels[i].flags,
5872 nflags, chan_flags, cflags, error);
5873 if (error != 0)
5874 break;
5875 }
5876 }
5877 }
5878
5879 static void *
5880 lkpi_ieee80211_ifalloc(void)
5881 {
5882 struct ieee80211com *ic;
5883
5884 ic = malloc(sizeof(*ic), M_LKPI80211, M_WAITOK | M_ZERO);
5885
5886 /* Setting these happens later when we have device information. */
5887 ic->ic_softc = NULL;
5888 ic->ic_name = "linuxkpi";
5889
5890 return (ic);
5891 }
5892
5893 struct ieee80211_hw *
5894 linuxkpi_ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops)
5895 {
5896 struct ieee80211_hw *hw;
5897 struct lkpi_hw *lhw;
5898 struct wiphy *wiphy;
5899 int ac;
5900
5901 /* Get us and the driver data also allocated. */
5902 wiphy = wiphy_new(&linuxkpi_mac80211cfgops, sizeof(*lhw) + priv_len);
5903 if (wiphy == NULL)
5904 return (NULL);
5905
5906 lhw = wiphy_priv(wiphy);
5907 lhw->ops = ops;
5908
5909 LKPI_80211_LHW_SCAN_LOCK_INIT(lhw);
5910 LKPI_80211_LHW_TXQ_LOCK_INIT(lhw);
5911 sx_init_flags(&lhw->lvif_sx, "lhw-lvif", SX_RECURSE | SX_DUPOK);
5912 TAILQ_INIT(&lhw->lvif_head);
5913 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
5914 lhw->txq_generation[ac] = 1;
5915 TAILQ_INIT(&lhw->scheduled_txqs[ac]);
5916 }
5917
5918 /* Chanctx_conf */
5919 INIT_LIST_HEAD(&lhw->lchanctx_list);
5920
5921 /* Deferred RX path. */
5922 LKPI_80211_LHW_RXQ_LOCK_INIT(lhw);
5923 TASK_INIT(&lhw->rxq_task, 0, lkpi_80211_lhw_rxq_task, lhw);
5924 mbufq_init(&lhw->rxq, 32 * NAPI_POLL_WEIGHT);
5925 lhw->rxq_stopped = false;
5926
5927 /*
5928 * XXX-BZ TODO make sure there is a "_null" function to all ops
5929 * not initialized.
5930 */
5931 hw = LHW_TO_HW(lhw);
5932 hw->wiphy = wiphy;
5933 hw->conf.flags |= IEEE80211_CONF_IDLE;
5934 hw->priv = (void *)(lhw + 1);
5935
5936 /* BSD Specific. */
5937 lhw->ic = lkpi_ieee80211_ifalloc();
5938
5939 IMPROVE();
5940
5941 return (hw);
5942 }
5943
5944 void
5945 linuxkpi_ieee80211_iffree(struct ieee80211_hw *hw)
5946 {
5947 struct lkpi_hw *lhw;
5948 struct mbuf *m;
5949
5950 lhw = HW_TO_LHW(hw);
5951 free(lhw->ic, M_LKPI80211);
5952 lhw->ic = NULL;
5953
5954 /*
5955 * Drain the deferred RX path.
5956 */
5957 LKPI_80211_LHW_RXQ_LOCK(lhw);
5958 lhw->rxq_stopped = true;
5959 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
5960
5961 /* Drain taskq, won't be restarted due to rxq_stopped being set. */
5962 while (taskqueue_cancel(taskqueue_thread, &lhw->rxq_task, NULL) != 0)
5963 taskqueue_drain(taskqueue_thread, &lhw->rxq_task);
5964
5965 /* Flush mbufq (make sure to release ni refs!). */
5966 m = mbufq_dequeue(&lhw->rxq);
5967 while (m != NULL) {
5968 #ifdef LKPI_80211_USE_MTAG
5969 struct m_tag *mtag;
5970
5971 mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
5972 if (mtag != NULL) {
5973 struct lkpi_80211_tag_rxni *rxni;
5974
5975 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
5976 ieee80211_free_node(rxni->ni);
5977 }
5978 #else
5979 if (m->m_pkthdr.PH_loc.ptr != NULL) {
5980 struct ieee80211_node *ni;
5981
5982 ni = m->m_pkthdr.PH_loc.ptr;
5983 ieee80211_free_node(ni);
5984 }
5985 #endif
5986 m_freem(m);
5987 m = mbufq_dequeue(&lhw->rxq);
5988 }
5989 KASSERT(mbufq_empty(&lhw->rxq), ("%s: lhw %p has rxq len %d != 0\n",
5990 __func__, lhw, mbufq_len(&lhw->rxq)));
5991 LKPI_80211_LHW_RXQ_LOCK_DESTROY(lhw);
5992
5993 /* Chanctx_conf. */
5994 if (!list_empty_careful(&lhw->lchanctx_list)) {
5995 struct lkpi_chanctx *lchanctx, *next;
5996 struct ieee80211_chanctx_conf *chanctx_conf;
5997
5998 list_for_each_entry_safe(lchanctx, next, &lhw->lchanctx_list, entry) {
5999 if (lchanctx->added_to_drv) {
6000 /* In reality we should panic? */
6001 chanctx_conf = &lchanctx->chanctx_conf;
6002 lkpi_80211_mo_remove_chanctx(hw, chanctx_conf);
6003 }
6004 list_del(&lchanctx->entry);
6005 free(lchanctx, M_LKPI80211);
6006 }
6007 }
6008
6009 /* Cleanup more of lhw here or in wiphy_free()? */
6010 LKPI_80211_LHW_TXQ_LOCK_DESTROY(lhw);
6011 LKPI_80211_LHW_SCAN_LOCK_DESTROY(lhw);
6012 sx_destroy(&lhw->lvif_sx);
6013 IMPROVE();
6014 }
6015
6016 void
6017 linuxkpi_set_ieee80211_dev(struct ieee80211_hw *hw, char *name)
6018 {
6019 struct lkpi_hw *lhw;
6020 struct ieee80211com *ic;
6021
6022 lhw = HW_TO_LHW(hw);
6023 ic = lhw->ic;
6024
6025 /* Now set a proper name before ieee80211_ifattach(). */
6026 ic->ic_softc = lhw;
6027 ic->ic_name = name;
6028
6029 /* XXX-BZ do we also need to set wiphy name? */
6030 }
6031
6032 struct ieee80211_hw *
6033 linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *wiphy)
6034 {
6035 struct lkpi_hw *lhw;
6036
6037 lhw = wiphy_priv(wiphy);
6038 return (LHW_TO_HW(lhw));
6039 }
6040
6041 static void
6042 lkpi_radiotap_attach(struct lkpi_hw *lhw)
6043 {
6044 struct ieee80211com *ic;
6045
6046 ic = lhw->ic;
6047 ieee80211_radiotap_attach(ic,
6048 &lhw->rtap_tx.wt_ihdr, sizeof(lhw->rtap_tx),
6049 LKPI_RTAP_TX_FLAGS_PRESENT,
6050 &lhw->rtap_rx.wr_ihdr, sizeof(lhw->rtap_rx),
6051 LKPI_RTAP_RX_FLAGS_PRESENT);
6052 }
6053
6054 int
6055 linuxkpi_ieee80211_ifattach(struct ieee80211_hw *hw)
6056 {
6057 struct ieee80211com *ic;
6058 struct lkpi_hw *lhw;
6059 int band, i;
6060
6061 lhw = HW_TO_LHW(hw);
6062 ic = lhw->ic;
6063
6064 /* We do it this late as wiphy->dev should be set for the name. */
6065 lhw->workq = alloc_ordered_workqueue(wiphy_name(hw->wiphy), 0);
6066 if (lhw->workq == NULL)
6067 return (-EAGAIN);
6068
6069 /* XXX-BZ figure this out how they count his... */
6070 if (!is_zero_ether_addr(hw->wiphy->perm_addr)) {
6071 IEEE80211_ADDR_COPY(ic->ic_macaddr,
6072 hw->wiphy->perm_addr);
6073 } else if (hw->wiphy->n_addresses > 0) {
6074 /* We take the first one. */
6075 IEEE80211_ADDR_COPY(ic->ic_macaddr,
6076 hw->wiphy->addresses[0].addr);
6077 } else {
6078 ic_printf(ic, "%s: warning, no hardware address!\n", __func__);
6079 }
6080
6081 #ifdef __not_yet__
6082 /* See comment in lkpi_80211_txq_tx_one(). */
6083 ic->ic_headroom = hw->extra_tx_headroom;
6084 #endif
6085
6086 ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
6087 ic->ic_opmode = IEEE80211_M_STA;
6088
6089 /* Set device capabilities. */
6090 /* XXX-BZ we need to get these from linux80211/drivers and convert. */
6091 ic->ic_caps =
6092 IEEE80211_C_STA |
6093 IEEE80211_C_MONITOR |
6094 IEEE80211_C_WPA | /* WPA/RSN */
6095 #ifdef LKPI_80211_WME
6096 IEEE80211_C_WME |
6097 #endif
6098 #if 0
6099 IEEE80211_C_PMGT |
6100 #endif
6101 IEEE80211_C_SHSLOT | /* short slot time supported */
6102 IEEE80211_C_SHPREAMBLE /* short preamble supported */
6103 ;
6104 #if 0
6105 /* Scanning is a different kind of beast to re-work. */
6106 ic->ic_caps |= IEEE80211_C_BGSCAN;
6107 #endif
6108 if (lhw->ops->hw_scan) {
6109 /*
6110 * Advertise full-offload scanning.
6111 *
6112 * Not limiting to SINGLE_SCAN_ON_ALL_BANDS here as otherwise
6113 * we essentially disable hw_scan for all drivers not setting
6114 * the flag.
6115 */
6116 ic->ic_flags_ext |= IEEE80211_FEXT_SCAN_OFFLOAD;
6117 lhw->scan_flags |= LKPI_LHW_SCAN_HW;
6118 }
6119
6120 /* Does HW support Fragmentation offload? */
6121 if (ieee80211_hw_check(hw, SUPPORTS_TX_FRAG))
6122 ic->ic_flags_ext |= IEEE80211_FEXT_FRAG_OFFLOAD;
6123
6124 /*
6125 * The wiphy variables report bitmasks of avail antennas.
6126 * (*get_antenna) get the current bitmask sets which can be
6127 * altered by (*set_antenna) for some drivers.
6128 * XXX-BZ will the count alone do us much good long-term in net80211?
6129 */
6130 if (hw->wiphy->available_antennas_rx ||
6131 hw->wiphy->available_antennas_tx) {
6132 uint32_t rxs, txs;
6133
6134 if (lkpi_80211_mo_get_antenna(hw, &txs, &rxs) == 0) {
6135 ic->ic_rxstream = bitcount32(rxs);
6136 ic->ic_txstream = bitcount32(txs);
6137 }
6138 }
6139
6140 ic->ic_cryptocaps = 0;
6141 #ifdef LKPI_80211_HW_CRYPTO
6142 if (lkpi_hwcrypto && hw->wiphy->n_cipher_suites > 0) {
6143 uint32_t hwciphers;
6144
6145 hwciphers = 0;
6146 for (i = 0; i < hw->wiphy->n_cipher_suites; i++) {
6147 uint32_t cs;
6148
6149 cs = lkpi_l80211_to_net80211_cyphers(
6150 ic, hw->wiphy->cipher_suites[i]);
6151 if (cs == IEEE80211_CRYPTO_TKIP) {
6152 /*
6153 * We do set this here. We will only find out
6154 * when doing a SET_KEY operation depending on
6155 * what the driver returns.
6156 * net80211::ieee80211_crypto_newkey()
6157 * checks this so we will have to do flags
6158 * surgery later.
6159 */
6160 cs |= IEEE80211_CRYPTO_TKIPMIC;
6161 }
6162 hwciphers |= cs;
6163 }
6164 /*
6165 * (20250415) nothing anywhere in the path checks we actually
6166 * support all these in net80211.
6167 * net80211 supports _256 variants but the ioctl does not.
6168 */
6169 IMPROVE("as net80211 grows more support, enable them");
6170 hwciphers &= (IEEE80211_CRYPTO_WEP |
6171 IEEE80211_CRYPTO_TKIP | IEEE80211_CRYPTO_TKIPMIC |
6172 IEEE80211_CRYPTO_AES_CCM | IEEE80211_CRYPTO_AES_GCM_128);
6173 /*
6174 * We only support CCMP here, so further filter.
6175 * Also permit TKIP if turned on.
6176 */
6177 hwciphers &= (IEEE80211_CRYPTO_AES_CCM |
6178 IEEE80211_CRYPTO_AES_GCM_128 |
6179 (lkpi_hwcrypto_tkip ? (IEEE80211_CRYPTO_TKIP |
6180 IEEE80211_CRYPTO_TKIPMIC) : 0));
6181 ieee80211_set_hardware_ciphers(ic, hwciphers);
6182 }
6183 #endif
6184
6185 lkpi_ic_getradiocaps(ic, IEEE80211_CHAN_MAX, &ic->ic_nchans,
6186 ic->ic_channels);
6187
6188 ieee80211_ifattach(ic);
6189
6190 ic->ic_update_mcast = lkpi_ic_update_mcast;
6191 ic->ic_update_promisc = lkpi_ic_update_promisc;
6192 ic->ic_update_chw = lkpi_ic_update_chw;
6193 ic->ic_parent = lkpi_ic_parent;
6194 ic->ic_scan_start = lkpi_ic_scan_start;
6195 ic->ic_scan_end = lkpi_ic_scan_end;
6196 ic->ic_set_channel = lkpi_ic_set_channel;
6197 ic->ic_transmit = lkpi_ic_transmit;
6198 ic->ic_raw_xmit = lkpi_ic_raw_xmit;
6199 ic->ic_vap_create = lkpi_ic_vap_create;
6200 ic->ic_vap_delete = lkpi_ic_vap_delete;
6201 ic->ic_getradiocaps = lkpi_ic_getradiocaps;
6202 ic->ic_wme.wme_update = lkpi_ic_wme_update;
6203
6204 lhw->ic_scan_curchan = ic->ic_scan_curchan;
6205 ic->ic_scan_curchan = lkpi_ic_scan_curchan;
6206 lhw->ic_scan_mindwell = ic->ic_scan_mindwell;
6207 ic->ic_scan_mindwell = lkpi_ic_scan_mindwell;
6208
6209 lhw->ic_node_alloc = ic->ic_node_alloc;
6210 ic->ic_node_alloc = lkpi_ic_node_alloc;
6211 lhw->ic_node_init = ic->ic_node_init;
6212 ic->ic_node_init = lkpi_ic_node_init;
6213 lhw->ic_node_cleanup = ic->ic_node_cleanup;
6214 ic->ic_node_cleanup = lkpi_ic_node_cleanup;
6215 lhw->ic_node_free = ic->ic_node_free;
6216 ic->ic_node_free = lkpi_ic_node_free;
6217
6218 #ifdef LKPI_80211_HT
6219 /*
6220 * Only attach if the driver/firmware supports (*ampdu_action)().
6221 * Otherwise it is in the hands of net80211.
6222 */
6223 if (lhw->ops->ampdu_action != NULL) {
6224 lhw->ic_recv_action = ic->ic_recv_action;
6225 ic->ic_recv_action = lkpi_ic_recv_action;
6226 lhw->ic_send_action = ic->ic_send_action;
6227 ic->ic_send_action = lkpi_ic_send_action;
6228
6229 lhw->ic_ampdu_enable = ic->ic_ampdu_enable;
6230 ic->ic_ampdu_enable = lkpi_ic_ampdu_enable;
6231
6232 lhw->ic_addba_request = ic->ic_addba_request;
6233 ic->ic_addba_request = lkpi_ic_addba_request;
6234 lhw->ic_addba_response = ic->ic_addba_response;
6235 ic->ic_addba_response = lkpi_ic_addba_response;
6236 lhw->ic_addba_stop = ic->ic_addba_stop;
6237 ic->ic_addba_stop = lkpi_ic_addba_stop;
6238 lhw->ic_addba_response_timeout = ic->ic_addba_response_timeout;
6239 ic->ic_addba_response_timeout = lkpi_ic_addba_response_timeout;
6240
6241 lhw->ic_bar_response = ic->ic_bar_response;
6242 ic->ic_bar_response = lkpi_ic_bar_response;
6243
6244 lhw->ic_ampdu_rx_start = ic->ic_ampdu_rx_start;
6245 ic->ic_ampdu_rx_start = lkpi_ic_ampdu_rx_start;
6246 lhw->ic_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
6247 ic->ic_ampdu_rx_stop = lkpi_ic_ampdu_rx_stop;
6248 }
6249 #endif
6250
6251 lkpi_radiotap_attach(lhw);
6252
6253 /*
6254 * Assign the first possible channel for now; seems Realtek drivers
6255 * expect one.
6256 * Also remember the amount of bands we support and the most rates
6257 * in any band so we can scale [(ext) sup rates] IE(s) accordingly.
6258 */
6259 lhw->supbands = lhw->max_rates = 0;
6260 for (band = 0; band < NUM_NL80211_BANDS; band++) {
6261 struct ieee80211_supported_band *supband;
6262 struct linuxkpi_ieee80211_channel *channels;
6263
6264 supband = hw->wiphy->bands[band];
6265 if (supband == NULL || supband->n_channels == 0)
6266 continue;
6267
6268 lhw->supbands++;
6269 lhw->max_rates = max(lhw->max_rates, supband->n_bitrates);
6270
6271 /* If we have a channel, we need to keep counting supbands. */
6272 if (hw->conf.chandef.chan != NULL)
6273 continue;
6274
6275 channels = supband->channels;
6276 for (i = 0; i < supband->n_channels; i++) {
6277
6278 if (channels[i].flags & IEEE80211_CHAN_DISABLED)
6279 continue;
6280
6281 cfg80211_chandef_create(&hw->conf.chandef, &channels[i],
6282 #ifdef LKPI_80211_HT
6283 (ic->ic_flags_ht & IEEE80211_FHT_HT) ? NL80211_CHAN_HT20 :
6284 #endif
6285 NL80211_CHAN_NO_HT);
6286 break;
6287 }
6288 }
6289
6290 IMPROVE("see net80211::ieee80211_chan_init vs. wiphy->bands[].bitrates possibly in lkpi_ic_getradiocaps?");
6291
6292 /* Make sure we do not support more than net80211 is willing to take. */
6293 if (lhw->max_rates > IEEE80211_RATE_MAXSIZE) {
6294 ic_printf(ic, "%s: limiting max_rates %d to %d!\n", __func__,
6295 lhw->max_rates, IEEE80211_RATE_MAXSIZE);
6296 lhw->max_rates = IEEE80211_RATE_MAXSIZE;
6297 }
6298
6299 /*
6300 * The maximum supported bitrates on any band + size for
6301 * DSSS Parameter Set give our per-band IE size.
6302 * SSID is the responsibility of the driver and goes on the side.
6303 * The user specified bits coming from the vap go into the
6304 * "common ies" fields.
6305 */
6306 lhw->scan_ie_len = 2 + IEEE80211_RATE_SIZE;
6307 if (lhw->max_rates > IEEE80211_RATE_SIZE)
6308 lhw->scan_ie_len += 2 + (lhw->max_rates - IEEE80211_RATE_SIZE);
6309
6310 if (hw->wiphy->features & NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) {
6311 /*
6312 * net80211 does not seem to support the DSSS Parameter Set but
6313 * some of the drivers insert it so calculate the extra fixed
6314 * space in.
6315 */
6316 lhw->scan_ie_len += 2 + 1;
6317 }
6318
6319 #if defined(LKPI_80211_HT)
6320 if ((ic->ic_htcaps & IEEE80211_HTC_HT) != 0)
6321 lhw->scan_ie_len += sizeof(struct ieee80211_ie_htcap);
6322 #endif
6323 #if defined(LKPI_80211_VHT)
6324 if (IEEE80211_CONF_VHT(ic))
6325 lhw->scan_ie_len += 2 + sizeof(struct ieee80211_vht_cap);
6326 #endif
6327
6328 /* Reduce the max_scan_ie_len "left" by the amount we consume already. */
6329 if (hw->wiphy->max_scan_ie_len > 0) {
6330 if (lhw->scan_ie_len > hw->wiphy->max_scan_ie_len)
6331 goto err;
6332 hw->wiphy->max_scan_ie_len -= lhw->scan_ie_len;
6333 }
6334
6335 if (bootverbose)
6336 ieee80211_announce(ic);
6337
6338 return (0);
6339 err:
6340 IMPROVE("TODO FIXME CLEANUP");
6341 return (-EAGAIN);
6342 }
6343
6344 void
6345 linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *hw)
6346 {
6347 struct lkpi_hw *lhw;
6348 struct ieee80211com *ic;
6349
6350 lhw = HW_TO_LHW(hw);
6351 ic = lhw->ic;
6352 ieee80211_ifdetach(ic);
6353 }
6354
6355 void
6356 linuxkpi_ieee80211_iterate_interfaces(struct ieee80211_hw *hw,
6357 enum ieee80211_iface_iter flags,
6358 void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
6359 void *arg)
6360 {
6361 struct lkpi_hw *lhw;
6362 struct lkpi_vif *lvif;
6363 struct ieee80211_vif *vif;
6364 bool active, atomic, nin_drv;
6365
6366 lhw = HW_TO_LHW(hw);
6367
6368 if (flags & ~(IEEE80211_IFACE_ITER_NORMAL|
6369 IEEE80211_IFACE_ITER_RESUME_ALL|
6370 IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER|
6371 IEEE80211_IFACE_ITER_ACTIVE|IEEE80211_IFACE_ITER__ATOMIC)) {
6372 ic_printf(lhw->ic, "XXX TODO %s flags(%#x) not yet supported.\n",
6373 __func__, flags);
6374 }
6375
6376 active = (flags & IEEE80211_IFACE_ITER_ACTIVE) != 0;
6377 atomic = (flags & IEEE80211_IFACE_ITER__ATOMIC) != 0;
6378 nin_drv = (flags & IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER) != 0;
6379
6380 if (atomic)
6381 LKPI_80211_LHW_LVIF_LOCK(lhw);
6382 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
6383 struct ieee80211vap *vap;
6384
6385 vif = LVIF_TO_VIF(lvif);
6386
6387 /*
6388 * If we want "active" interfaces, we need to distinguish on
6389 * whether the driver knows about them or not to be able to
6390 * handle the "resume" case correctly. Skip the ones the
6391 * driver does not know about.
6392 */
6393 if (active && !lvif->added_to_drv &&
6394 (flags & IEEE80211_IFACE_ITER_RESUME_ALL) != 0)
6395 continue;
6396
6397 /*
6398 * If we shall skip interfaces not added to the driver do so
6399 * if we haven't yet.
6400 */
6401 if (nin_drv && !lvif->added_to_drv)
6402 continue;
6403
6404 /*
6405 * Run the iterator function if we are either not asking
6406 * asking for active only or if the VAP is "running".
6407 */
6408 /* XXX-BZ probably should have state in the lvif as well. */
6409 vap = LVIF_TO_VAP(lvif);
6410 if (!active || (vap->iv_state != IEEE80211_S_INIT))
6411 iterfunc(arg, vif->addr, vif);
6412 }
6413 if (atomic)
6414 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
6415 }
6416
6417 static void
6418 lkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
6419 ieee80211_keyix keyix, struct lkpi_sta *lsta,
6420 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
6421 struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
6422 void *arg)
6423 {
6424 if (!lsta->added_to_drv)
6425 return;
6426
6427 if (lsta->kc[keyix] == NULL)
6428 return;
6429
6430 iterfunc(hw, vif, LSTA_TO_STA(lsta), lsta->kc[keyix], arg);
6431 }
6432
6433 void
6434 linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *hw,
6435 struct ieee80211_vif *vif,
6436 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
6437 struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
6438 void *arg, bool rcu)
6439 {
6440 struct lkpi_sta *lsta;
6441 struct lkpi_vif *lvif;
6442
6443 lvif = VIF_TO_LVIF(vif);
6444
6445 if (rcu) {
6446 rcu_read_lock_held(); /* XXX-BZ is this correct? */
6447
6448 if (vif == NULL) {
6449 TODO();
6450 } else {
6451 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
6452 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
6453 keyix++)
6454 lkpi_ieee80211_iterate_keys(hw, vif,
6455 keyix, lsta, iterfunc, arg);
6456 }
6457 }
6458 } else {
6459 TODO("Used by suspend/resume; order of keys as installed to "
6460 "firmware is important; we'll need to rewrite some code for that");
6461 lockdep_assert_wiphy(hw->wiphy);
6462
6463 if (vif == NULL) {
6464 TODO();
6465 } else {
6466 list_for_each_entry(lsta, &lvif->lsta_list, lsta_list) {
6467 for (ieee80211_keyix keyix = 0; keyix < nitems(lsta->kc);
6468 keyix++)
6469 lkpi_ieee80211_iterate_keys(hw, vif,
6470 keyix, lsta, iterfunc, arg);
6471 }
6472 }
6473 }
6474 }
6475
6476 void
6477 linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *hw,
6478 void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *,
6479 void *),
6480 void *arg)
6481 {
6482 struct lkpi_hw *lhw;
6483 struct lkpi_chanctx *lchanctx;
6484
6485 KASSERT(hw != NULL && iterfunc != NULL,
6486 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
6487
6488 lhw = HW_TO_LHW(hw);
6489
6490 rcu_read_lock();
6491 list_for_each_entry_rcu(lchanctx, &lhw->lchanctx_list, entry) {
6492 if (!lchanctx->added_to_drv)
6493 continue;
6494 iterfunc(hw, &lchanctx->chanctx_conf, arg);
6495 }
6496 rcu_read_unlock();
6497 }
6498
6499 void
6500 linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
6501 void (*iterfunc)(void *, struct ieee80211_sta *), void *arg)
6502 {
6503 struct lkpi_hw *lhw;
6504 struct lkpi_vif *lvif;
6505 struct lkpi_sta *lsta;
6506 struct ieee80211_sta *sta;
6507
6508 KASSERT(hw != NULL && iterfunc != NULL,
6509 ("%s: hw %p iterfunc %p arg %p\n", __func__, hw, iterfunc, arg));
6510
6511 lhw = HW_TO_LHW(hw);
6512
6513 LKPI_80211_LHW_LVIF_LOCK(lhw);
6514 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
6515
6516 rcu_read_lock();
6517 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
6518 if (!lsta->added_to_drv)
6519 continue;
6520 sta = LSTA_TO_STA(lsta);
6521 iterfunc(arg, sta);
6522 }
6523 rcu_read_unlock();
6524 }
6525 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
6526 }
6527
6528 struct linuxkpi_ieee80211_regdomain *
6529 lkpi_get_linuxkpi_ieee80211_regdomain(size_t n)
6530 {
6531 struct linuxkpi_ieee80211_regdomain *regd;
6532
6533 regd = kzalloc(sizeof(*regd) + n * sizeof(struct ieee80211_reg_rule),
6534 GFP_KERNEL);
6535 return (regd);
6536 }
6537
6538 int
6539 linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
6540 struct linuxkpi_ieee80211_regdomain *regd)
6541 {
6542 struct lkpi_hw *lhw;
6543 struct ieee80211com *ic;
6544 struct ieee80211_regdomain *rd;
6545
6546 lhw = wiphy_priv(wiphy);
6547 ic = lhw->ic;
6548
6549 rd = &ic->ic_regdomain;
6550 if (rd->isocc[0] == '\0') {
6551 rd->isocc[0] = regd->alpha2[0];
6552 rd->isocc[1] = regd->alpha2[1];
6553 }
6554
6555 TODO();
6556 /* XXX-BZ finish the rest. */
6557
6558 return (0);
6559 }
6560
6561 void
6562 linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *hw,
6563 struct cfg80211_scan_info *info)
6564 {
6565 struct lkpi_hw *lhw;
6566 struct ieee80211com *ic;
6567 struct ieee80211_scan_state *ss;
6568
6569 lhw = wiphy_priv(hw->wiphy);
6570 ic = lhw->ic;
6571 ss = ic->ic_scan;
6572
6573 ieee80211_scan_done(ss->ss_vap);
6574
6575 LKPI_80211_LHW_SCAN_LOCK(lhw);
6576 free(lhw->hw_req, M_LKPI80211);
6577 lhw->hw_req = NULL;
6578 lhw->scan_flags &= ~LKPI_LHW_SCAN_RUNNING;
6579 wakeup(lhw);
6580 LKPI_80211_LHW_SCAN_UNLOCK(lhw);
6581
6582 return;
6583 }
6584
6585 static void
6586 lkpi_80211_lhw_rxq_rx_one(struct lkpi_hw *lhw, struct mbuf *m)
6587 {
6588 struct ieee80211_node *ni;
6589 #ifdef LKPI_80211_USE_MTAG
6590 struct m_tag *mtag;
6591 #endif
6592 int ok;
6593
6594 ni = NULL;
6595 #ifdef LKPI_80211_USE_MTAG
6596 mtag = m_tag_locate(m, MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI, NULL);
6597 if (mtag != NULL) {
6598 struct lkpi_80211_tag_rxni *rxni;
6599
6600 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
6601 ni = rxni->ni;
6602 }
6603 #else
6604 if (m->m_pkthdr.PH_loc.ptr != NULL) {
6605 ni = m->m_pkthdr.PH_loc.ptr;
6606 m->m_pkthdr.PH_loc.ptr = NULL;
6607 }
6608 #endif
6609
6610 if (ni != NULL) {
6611 ok = ieee80211_input_mimo(ni, m);
6612 ieee80211_free_node(ni); /* Release the reference. */
6613 if (ok < 0)
6614 m_freem(m);
6615 } else {
6616 ok = ieee80211_input_mimo_all(lhw->ic, m);
6617 /* mbuf got consumed. */
6618 }
6619
6620 #ifdef LINUXKPI_DEBUG_80211
6621 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6622 printf("TRACE-RX: %s: handled frame type %#0x\n", __func__, ok);
6623 #endif
6624 }
6625
6626 static void
6627 lkpi_80211_lhw_rxq_task(void *ctx, int pending)
6628 {
6629 struct lkpi_hw *lhw;
6630 struct mbufq mq;
6631 struct mbuf *m;
6632
6633 lhw = ctx;
6634
6635 #ifdef LINUXKPI_DEBUG_80211
6636 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6637 printf("TRACE-RX: %s: lhw %p pending %d mbuf_qlen %d\n",
6638 __func__, lhw, pending, mbufq_len(&lhw->rxq));
6639 #endif
6640
6641 mbufq_init(&mq, IFQ_MAXLEN);
6642
6643 LKPI_80211_LHW_RXQ_LOCK(lhw);
6644 mbufq_concat(&mq, &lhw->rxq);
6645 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
6646
6647 m = mbufq_dequeue(&mq);
6648 while (m != NULL) {
6649 lkpi_80211_lhw_rxq_rx_one(lhw, m);
6650 m = mbufq_dequeue(&mq);
6651 }
6652 }
6653
6654 static void
6655 lkpi_convert_rx_status(struct ieee80211_hw *hw, struct lkpi_sta *lsta,
6656 struct ieee80211_rx_status *rx_status,
6657 struct ieee80211_rx_stats *rx_stats,
6658 uint8_t *rssip)
6659 {
6660 struct ieee80211_supported_band *supband;
6661 struct rate_info rxrate;
6662 int i;
6663 uint8_t rssi;
6664
6665 memset(&rxrate, 0, sizeof(rxrate));
6666 memset(rx_stats, 0, sizeof(*rx_stats));
6667 rx_stats->r_flags = IEEE80211_R_NF | IEEE80211_R_RSSI;
6668 /* XXX-BZ correct hardcoded noise floor, survey data? */
6669 rx_stats->c_nf = -96;
6670 if (ieee80211_hw_check(hw, SIGNAL_DBM) &&
6671 !(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
6672 rssi = rx_status->signal;
6673 else
6674 rssi = rx_stats->c_nf;
6675 /*
6676 * net80211 signal strength data are in .5 dBm units relative to
6677 * the current noise floor (see comment in ieee80211_node.h).
6678 */
6679 rssi -= rx_stats->c_nf;
6680 if (rssip != NULL)
6681 *rssip = rssi;
6682 rx_stats->c_rssi = rssi * 2;
6683 rx_stats->r_flags |= IEEE80211_R_BAND;
6684 rx_stats->c_band =
6685 lkpi_nl80211_band_to_net80211_band(rx_status->band);
6686 rx_stats->r_flags |= IEEE80211_R_FREQ | IEEE80211_R_IEEE;
6687 rx_stats->c_freq = rx_status->freq;
6688 rx_stats->c_ieee = ieee80211_mhz2ieee(rx_stats->c_freq, rx_stats->c_band);
6689
6690 rx_stats->c_rx_tsf = rx_status->mactime;
6691
6692 /* XXX RX_FLAG_MACTIME_IS_RTAP_TS64 ? */
6693 if ((rx_status->flag & RX_FLAG_MACTIME) ==
6694 (RX_FLAG_MACTIME_START|RX_FLAG_MACTIME_END)) {
6695 rx_stats->r_flags |= IEEE80211_R_TSF64;
6696 /* XXX RX_FLAG_MACTIME_PLCP_START ? */
6697 if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_START)
6698 rx_stats->r_flags |= IEEE80211_R_TSF_START;
6699 if ((rx_status->flag & RX_FLAG_MACTIME) == RX_FLAG_MACTIME_END)
6700 rx_stats->r_flags |= IEEE80211_R_TSF_END;
6701 /* XXX-BZ if TSF_END will net80211 do the unwind of time? */
6702 }
6703
6704 if (rx_status->chains != 0) {
6705 int cc;
6706 int8_t crssi;
6707
6708 rx_stats->c_chain = rx_status->chains;
6709 rx_stats->r_flags |= IEEE80211_R_C_CHAIN;
6710
6711 cc = 0;
6712 for (i = 0; i < nitems(rx_status->chain_signal); i++) {
6713 if (!(rx_status->chains & BIT(i)))
6714 continue;
6715 crssi = rx_status->chain_signal[i];
6716 crssi -= rx_stats->c_nf;
6717 rx_stats->c_rssi_ctl[i] = crssi * 2;
6718 rx_stats->c_rssi_ext[i] = crssi * 2; /* XXX _ext ??? ATH thing? */
6719 /* We currently only have the global noise floor value. */
6720 rx_stats->c_nf_ctl[i] = rx_stats->c_nf;
6721 rx_stats->c_nf_ext[i] = rx_stats->c_nf;
6722 cc++;
6723 }
6724 if (cc > 0)
6725 rx_stats->r_flags |= (IEEE80211_R_C_NF | IEEE80211_R_C_RSSI);
6726 }
6727
6728 /* XXX-NET80211 We are not going to populate c_phytype! */
6729
6730 switch (rx_status->encoding) {
6731 case RX_ENC_LEGACY:
6732 {
6733 uint32_t legacy = 0;
6734
6735 supband = hw->wiphy->bands[rx_status->band];
6736 if (supband != NULL)
6737 legacy = supband->bitrates[rx_status->rate_idx].bitrate;
6738 rx_stats->c_rate = legacy;
6739 rxrate.legacy = legacy;
6740 /* Is there a LinuxKPI way of reporting IEEE80211_RX_F_CCK / _OFDM? */
6741 break;
6742 }
6743 case RX_ENC_HT:
6744 rx_stats->c_pktflags |= IEEE80211_RX_F_HT;
6745 rx_stats->c_rate = rx_status->rate_idx; /* mcs */
6746 rxrate.flags |= RATE_INFO_FLAGS_MCS;
6747 rxrate.mcs = rx_status->rate_idx;
6748 if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0) {
6749 rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
6750 rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6751 }
6752 break;
6753 case RX_ENC_VHT:
6754 rx_stats->c_pktflags |= IEEE80211_RX_F_VHT;
6755 rx_stats->c_rate = rx_status->rate_idx; /* mcs */
6756 rx_stats->c_vhtnss = rx_status->nss;
6757 rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
6758 rxrate.mcs = rx_status->rate_idx;
6759 rxrate.nss = rx_status->nss;
6760 if ((rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI) != 0) {
6761 rx_stats->c_pktflags |= IEEE80211_RX_F_SHORTGI;
6762 rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
6763 }
6764 break;
6765 case RX_ENC_HE:
6766 rxrate.flags |= RATE_INFO_FLAGS_HE_MCS;
6767 rxrate.mcs = rx_status->rate_idx;
6768 rxrate.nss = rx_status->nss;
6769 /* XXX TODO */
6770 TODO("net80211 has not matching encoding for %u", rx_status->encoding);
6771 break;
6772 case RX_ENC_EHT:
6773 rxrate.flags |= RATE_INFO_FLAGS_EHT_MCS;
6774 rxrate.mcs = rx_status->rate_idx;
6775 rxrate.nss = rx_status->nss;
6776 /* XXX TODO */
6777 TODO("net80211 has not matching encoding for %u", rx_status->encoding);
6778 break;
6779 }
6780
6781 rxrate.bw = rx_status->bw;
6782 switch (rx_status->bw) {
6783 case RATE_INFO_BW_20:
6784 rx_stats->c_width = IEEE80211_RX_FW_20MHZ;
6785 break;
6786 case RATE_INFO_BW_40:
6787 rx_stats->c_width = IEEE80211_RX_FW_40MHZ;
6788 break;
6789 case RATE_INFO_BW_80:
6790 rx_stats->c_width = IEEE80211_RX_FW_80MHZ;
6791 break;
6792 case RATE_INFO_BW_160:
6793 rx_stats->c_width = IEEE80211_RX_FW_160MHZ;
6794 break;
6795 case RATE_INFO_BW_320:
6796 case RATE_INFO_BW_HE_RU:
6797 case RATE_INFO_BW_EHT_RU:
6798 case RATE_INFO_BW_5:
6799 case RATE_INFO_BW_10:
6800 TODO("net80211 has not matching bandwidth for %u", rx_status->bw);
6801 break;
6802 }
6803
6804 if ((rx_status->enc_flags & RX_ENC_FLAG_LDPC) != 0)
6805 rx_stats->c_pktflags |= IEEE80211_RX_F_LDPC;
6806 if ((rx_status->enc_flags & RX_ENC_FLAG_STBC_MASK) != 0)
6807 rx_stats->c_pktflags |= IEEE80211_RX_F_STBC;
6808
6809 /*
6810 * We only need these for LKPI_80211_HW_CRYPTO in theory but in
6811 * case the hardware does something we do not expect always leave
6812 * these enabled. Leaving this commant as documentation for the || 1.
6813 */
6814 #if defined(LKPI_80211_HW_CRYPTO) || 1
6815 if (rx_status->flag & RX_FLAG_DECRYPTED) {
6816 rx_stats->c_pktflags |= IEEE80211_RX_F_DECRYPTED;
6817 /* Only valid if decrypted is set. */
6818 if (rx_status->flag & RX_FLAG_PN_VALIDATED)
6819 rx_stats->c_pktflags |= IEEE80211_RX_F_PN_VALIDATED;
6820 }
6821 if (rx_status->flag & RX_FLAG_IV_STRIPPED)
6822 rx_stats->c_pktflags |= IEEE80211_RX_F_IV_STRIP;
6823 if (rx_status->flag & RX_FLAG_ICV_STRIPPED)
6824 rx_stats->c_pktflags |= IEEE80211_RX_F_ICV_STRIP;
6825 if (rx_status->flag & RX_FLAG_MIC_STRIPPED)
6826 rx_stats->c_pktflags |= IEEE80211_RX_F_MIC_STRIP;
6827 if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
6828 rx_stats->c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
6829 if (rx_status->flag & RX_FLAG_MMIC_ERROR)
6830 rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_MMIC;
6831 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
6832 rx_stats->c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
6833 #endif
6834
6835 if (lsta != NULL) {
6836 memcpy(&lsta->sinfo.rxrate, &rxrate, sizeof(rxrate));
6837 lsta->sinfo.filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
6838 }
6839 }
6840
6841 /* For %list see comment towards the end of the function. */
6842 void
6843 linuxkpi_ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
6844 struct ieee80211_sta *sta, struct napi_struct *napi __unused,
6845 struct list_head *list __unused)
6846 {
6847 struct lkpi_hw *lhw;
6848 struct ieee80211com *ic;
6849 struct mbuf *m;
6850 struct skb_shared_info *shinfo;
6851 struct ieee80211_rx_status *rx_status;
6852 struct ieee80211_rx_stats rx_stats;
6853 struct ieee80211_node *ni;
6854 struct ieee80211vap *vap;
6855 struct ieee80211_hdr *hdr;
6856 struct lkpi_sta *lsta;
6857 int i, offset, ok, error;
6858 uint8_t rssi;
6859 bool is_beacon;
6860
6861 lhw = HW_TO_LHW(hw);
6862 ic = lhw->ic;
6863
6864 if (skb->len < 2) {
6865 /* Need 80211 stats here. */
6866 counter_u64_add(ic->ic_ierrors, 1);
6867 IMPROVE();
6868 goto err;
6869 }
6870
6871 /*
6872 * For now do the data copy; we can later improve things. Might even
6873 * have an mbuf backing the skb data then?
6874 */
6875 m = m_get3(skb->len, M_NOWAIT, MT_DATA, M_PKTHDR);
6876 if (m == NULL) {
6877 counter_u64_add(ic->ic_ierrors, 1);
6878 goto err;
6879 }
6880 m_copyback(m, 0, skb->tail - skb->data, skb->data);
6881
6882 shinfo = skb_shinfo(skb);
6883 offset = m->m_len;
6884 for (i = 0; i < shinfo->nr_frags; i++) {
6885 m_copyback(m, offset, shinfo->frags[i].size,
6886 (uint8_t *)linux_page_address(shinfo->frags[i].page) +
6887 shinfo->frags[i].offset);
6888 offset += shinfo->frags[i].size;
6889 }
6890
6891 rx_status = IEEE80211_SKB_RXCB(skb);
6892
6893 hdr = (void *)skb->data;
6894 is_beacon = ieee80211_is_beacon(hdr->frame_control);
6895
6896 #ifdef LINUXKPI_DEBUG_80211
6897 if (is_beacon && (linuxkpi_debug_80211 & D80211_TRACE_RX_BEACONS) == 0)
6898 goto no_trace_beacons;
6899
6900 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6901 printf("TRACE-RX: %s: skb %p l/d/t-len (%u/%u/%u) "
6902 "h %p d %p t %p e %p sh %p (%u) m %p plen %u len %u%s\n",
6903 __func__, skb, skb->len, skb->data_len,
6904 skb->truesize, skb->head, skb->data, skb->tail, skb->end,
6905 shinfo, shinfo->nr_frags,
6906 m, m->m_pkthdr.len, m->m_len, is_beacon ? " beacon" : "");
6907
6908 if (linuxkpi_debug_80211 & D80211_TRACE_RX_DUMP)
6909 hexdump(mtod(m, const void *), m->m_len, "RX (raw) ", 0);
6910
6911 /* Implement a dump_rxcb() !!! */
6912 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6913 printf("TRACE-RX: %s: RXCB: %ju %ju %u, %b, %u, %#0x, %#0x, "
6914 "%u band %u, %u { %d %d %d %d }, %d, %#x %#x %#x %#x %u %u %u\n",
6915 __func__,
6916 (uintmax_t)rx_status->boottime_ns,
6917 (uintmax_t)rx_status->mactime,
6918 rx_status->device_timestamp,
6919 rx_status->flag, IEEE80211_RX_STATUS_FLAGS_BITS,
6920 rx_status->freq,
6921 rx_status->bw,
6922 rx_status->encoding,
6923 rx_status->ampdu_reference,
6924 rx_status->band,
6925 rx_status->chains,
6926 rx_status->chain_signal[0],
6927 rx_status->chain_signal[1],
6928 rx_status->chain_signal[2],
6929 rx_status->chain_signal[3],
6930 rx_status->signal,
6931 rx_status->enc_flags,
6932 rx_status->he_dcm,
6933 rx_status->he_gi,
6934 rx_status->he_ru,
6935 rx_status->zero_length_psdu_type,
6936 rx_status->nss,
6937 rx_status->rate_idx);
6938 no_trace_beacons:
6939 #endif
6940
6941 lsta = NULL;
6942 if (sta != NULL) {
6943 lsta = STA_TO_LSTA(sta);
6944 ni = ieee80211_ref_node(lsta->ni);
6945 } else {
6946 struct ieee80211_frame_min *wh;
6947
6948 wh = mtod(m, struct ieee80211_frame_min *);
6949 ni = ieee80211_find_rxnode(ic, wh);
6950 if (ni != NULL)
6951 lsta = ni->ni_drv_data;
6952 }
6953
6954 rssi = 0;
6955 lkpi_convert_rx_status(hw, lsta, rx_status, &rx_stats, &rssi);
6956
6957 ok = ieee80211_add_rx_params(m, &rx_stats);
6958 if (ok == 0) {
6959 m_freem(m);
6960 counter_u64_add(ic->ic_ierrors, 1);
6961 goto err;
6962 }
6963
6964 if (ni != NULL)
6965 vap = ni->ni_vap;
6966 else
6967 /*
6968 * XXX-BZ can we improve this by looking at the frame hdr
6969 * or other meta-data passed up?
6970 */
6971 vap = TAILQ_FIRST(&ic->ic_vaps);
6972
6973 #ifdef LINUXKPI_DEBUG_80211
6974 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
6975 printf("TRACE-RX: %s: sta %p lsta %p state %d ni %p vap %p%s\n",
6976 __func__, sta, lsta, (lsta != NULL) ? lsta->state : -1,
6977 ni, vap, is_beacon ? " beacon" : "");
6978 #endif
6979
6980 if (ni != NULL && vap != NULL && is_beacon &&
6981 rx_status->device_timestamp > 0 &&
6982 m->m_pkthdr.len >= sizeof(struct ieee80211_frame)) {
6983 struct lkpi_vif *lvif;
6984 struct ieee80211_vif *vif;
6985 struct ieee80211_frame *wh;
6986
6987 wh = mtod(m, struct ieee80211_frame *);
6988 if (!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_bssid))
6989 goto skip_device_ts;
6990
6991 lvif = VAP_TO_LVIF(vap);
6992 vif = LVIF_TO_VIF(lvif);
6993
6994 IMPROVE("TIMING_BEACON_ONLY?");
6995 /* mac80211 specific (not net80211) so keep it here. */
6996 vif->bss_conf.sync_device_ts = rx_status->device_timestamp;
6997 /*
6998 * net80211 should take care of the other information (sync_tsf,
6999 * sync_dtim_count) as otherwise we need to parse the beacon.
7000 */
7001 skip_device_ts:
7002 ;
7003 }
7004
7005 if (vap != NULL && vap->iv_state > IEEE80211_S_INIT &&
7006 ieee80211_radiotap_active_vap(vap)) {
7007 struct lkpi_radiotap_rx_hdr *rtap;
7008
7009 rtap = &lhw->rtap_rx;
7010 rtap->wr_tsft = rx_status->device_timestamp;
7011 rtap->wr_flags = 0;
7012 if (rx_status->enc_flags & RX_ENC_FLAG_SHORTPRE)
7013 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7014 if (rx_status->enc_flags & RX_ENC_FLAG_SHORT_GI)
7015 rtap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTGI;
7016 #if 0 /* .. or it does not given we strip it below. */
7017 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
7018 rtap->wr_flags |= IEEE80211_RADIOTAP_F_FCS;
7019 #endif
7020 if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
7021 rtap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
7022 rtap->wr_rate = 0;
7023 IMPROVE();
7024 /* XXX TODO status->encoding / rate_index / bw */
7025 rtap->wr_chan_freq = htole16(rx_stats.c_freq);
7026 if (ic->ic_curchan->ic_ieee == rx_stats.c_ieee)
7027 rtap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
7028 rtap->wr_dbm_antsignal = rssi;
7029 rtap->wr_dbm_antnoise = rx_stats.c_nf;
7030 }
7031
7032 if (ieee80211_hw_check(hw, RX_INCLUDES_FCS))
7033 m_adj(m, -IEEE80211_CRC_LEN);
7034
7035 #if 0
7036 if (list != NULL) {
7037 /*
7038 * Normally this would be queued up and delivered by
7039 * netif_receive_skb_list(), napi_gro_receive(), or the like.
7040 * See mt76::mac80211.c as only current possible consumer.
7041 */
7042 IMPROVE("we simply pass the packet to net80211 to deal with.");
7043 }
7044 #endif
7045
7046 /* Attach meta-information to the mbuf for the deferred RX path. */
7047 if (ni != NULL) {
7048 #ifdef LKPI_80211_USE_MTAG
7049 struct m_tag *mtag;
7050 struct lkpi_80211_tag_rxni *rxni;
7051
7052 mtag = m_tag_alloc(MTAG_ABI_LKPI80211, LKPI80211_TAG_RXNI,
7053 sizeof(*rxni), IEEE80211_M_NOWAIT);
7054 if (mtag == NULL) {
7055 m_freem(m);
7056 counter_u64_add(ic->ic_ierrors, 1);
7057 goto err;
7058 }
7059 rxni = (struct lkpi_80211_tag_rxni *)(mtag + 1);
7060 rxni->ni = ni; /* We hold a reference. */
7061 m_tag_prepend(m, mtag);
7062 #else
7063 m->m_pkthdr.PH_loc.ptr = ni; /* We hold a reference. */
7064 #endif
7065 }
7066
7067 LKPI_80211_LHW_RXQ_LOCK(lhw);
7068 if (lhw->rxq_stopped) {
7069 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
7070 m_freem(m);
7071 counter_u64_add(ic->ic_ierrors, 1);
7072 goto err;
7073 }
7074
7075 error = mbufq_enqueue(&lhw->rxq, m);
7076 if (error != 0) {
7077 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
7078 m_freem(m);
7079 counter_u64_add(ic->ic_ierrors, 1);
7080 #ifdef LINUXKPI_DEBUG_80211
7081 if (linuxkpi_debug_80211 & D80211_TRACE_RX)
7082 ic_printf(ni->ni_ic, "%s: mbufq_enqueue failed: %d\n",
7083 __func__, error);
7084 #endif
7085 goto err;
7086 }
7087 taskqueue_enqueue(taskqueue_thread, &lhw->rxq_task);
7088 LKPI_80211_LHW_RXQ_UNLOCK(lhw);
7089
7090 IMPROVE();
7091
7092 err:
7093 /* The skb is ours so we can free it :-) */
7094 kfree_skb(skb);
7095 }
7096
7097 uint8_t
7098 linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr, bool nonqos_ok)
7099 {
7100 const struct ieee80211_frame *wh;
7101 uint8_t tid;
7102
7103 /* Linux seems to assume this is a QOS-Data-Frame */
7104 KASSERT(nonqos_ok || ieee80211_is_data_qos(hdr->frame_control),
7105 ("%s: hdr %p fc %#06x not qos_data\n", __func__, hdr,
7106 hdr->frame_control));
7107
7108 wh = (const struct ieee80211_frame *)hdr;
7109 tid = ieee80211_gettid(wh);
7110 KASSERT(nonqos_ok || tid == (tid & IEEE80211_QOS_TID), ("%s: tid %u "
7111 "not expected (%u?)\n", __func__, tid, IEEE80211_NONQOS_TID));
7112
7113 return (tid);
7114 }
7115
7116 /* -------------------------------------------------------------------------- */
7117
7118 static void
7119 lkpi_wiphy_work(struct work_struct *work)
7120 {
7121 struct lkpi_wiphy *lwiphy;
7122 struct wiphy *wiphy;
7123 struct wiphy_work *wk;
7124
7125 lwiphy = container_of(work, struct lkpi_wiphy, wwk);
7126 wiphy = LWIPHY_TO_WIPHY(lwiphy);
7127
7128 wiphy_lock(wiphy);
7129
7130 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
7131 wk = list_first_entry_or_null(&lwiphy->wwk_list, struct wiphy_work, entry);
7132 /* If there is nothing we do nothing. */
7133 if (wk == NULL) {
7134 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7135 wiphy_unlock(wiphy);
7136 return;
7137 }
7138 list_del_init(&wk->entry);
7139
7140 /* More work to do? */
7141 if (!list_empty(&lwiphy->wwk_list))
7142 schedule_work(work);
7143 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7144
7145 /* Finally call the (*wiphy_work_fn)() function. */
7146 wk->fn(wiphy, wk);
7147
7148 wiphy_unlock(wiphy);
7149 }
7150
7151 void
7152 linuxkpi_wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
7153 {
7154 struct lkpi_wiphy *lwiphy;
7155
7156 lwiphy = WIPHY_TO_LWIPHY(wiphy);
7157
7158 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
7159 /* Do not double-queue. */
7160 if (list_empty(&wwk->entry))
7161 list_add_tail(&wwk->entry, &lwiphy->wwk_list);
7162 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7163
7164 /*
7165 * See how ieee80211_queue_work() work continues in Linux or if things
7166 * migrate here over time?
7167 * Use a system queue from linux/workqueue.h for now.
7168 */
7169 queue_work(system_wq, &lwiphy->wwk);
7170 }
7171
7172 void
7173 linuxkpi_wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
7174 {
7175 struct lkpi_wiphy *lwiphy;
7176
7177 lwiphy = WIPHY_TO_LWIPHY(wiphy);
7178
7179 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
7180 /* Only cancel if queued. */
7181 if (!list_empty(&wwk->entry))
7182 list_del_init(&wwk->entry);
7183 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7184 }
7185
7186 void
7187 linuxkpi_wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
7188 {
7189 struct lkpi_wiphy *lwiphy;
7190 struct wiphy_work *wk;
7191
7192 lwiphy = WIPHY_TO_LWIPHY(wiphy);
7193 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
7194 /* If wwk is unset, flush everything; called when wiphy is shut down. */
7195 if (wwk != NULL && list_empty(&wwk->entry)) {
7196 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7197 return;
7198 }
7199
7200 while (!list_empty(&lwiphy->wwk_list)) {
7201
7202 wk = list_first_entry(&lwiphy->wwk_list, struct wiphy_work,
7203 entry);
7204 list_del_init(&wk->entry);
7205 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7206 wk->fn(wiphy, wk);
7207 LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
7208 if (wk == wwk)
7209 break;
7210 }
7211 LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
7212 }
7213
7214 void
7215 lkpi_wiphy_delayed_work_timer(struct timer_list *tl)
7216 {
7217 struct wiphy_delayed_work *wdwk;
7218
7219 wdwk = from_timer(wdwk, tl, timer);
7220 wiphy_work_queue(wdwk->wiphy, &wdwk->work);
7221 }
7222
7223 void
7224 linuxkpi_wiphy_delayed_work_queue(struct wiphy *wiphy,
7225 struct wiphy_delayed_work *wdwk, unsigned long delay)
7226 {
7227 if (delay == 0) {
7228 /* Run right away. */
7229 del_timer(&wdwk->timer);
7230 wiphy_work_queue(wiphy, &wdwk->work);
7231 } else {
7232 wdwk->wiphy = wiphy;
7233 mod_timer(&wdwk->timer, jiffies + delay);
7234 }
7235 }
7236
7237 void
7238 linuxkpi_wiphy_delayed_work_cancel(struct wiphy *wiphy,
7239 struct wiphy_delayed_work *wdwk)
7240 {
7241 del_timer_sync(&wdwk->timer);
7242 wiphy_work_cancel(wiphy, &wdwk->work);
7243 }
7244
7245 /* -------------------------------------------------------------------------- */
7246
7247 struct wiphy *
7248 linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len)
7249 {
7250 struct lkpi_wiphy *lwiphy;
7251 struct wiphy *wiphy;
7252
7253 lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL);
7254 if (lwiphy == NULL)
7255 return (NULL);
7256 lwiphy->ops = ops;
7257
7258 LKPI_80211_LWIPHY_WORK_LOCK_INIT(lwiphy);
7259 INIT_LIST_HEAD(&lwiphy->wwk_list);
7260 INIT_WORK(&lwiphy->wwk, lkpi_wiphy_work);
7261
7262 wiphy = LWIPHY_TO_WIPHY(lwiphy);
7263
7264 mutex_init(&wiphy->mtx);
7265 TODO();
7266
7267 return (wiphy);
7268 }
7269
7270 void
7271 linuxkpi_wiphy_free(struct wiphy *wiphy)
7272 {
7273 struct lkpi_wiphy *lwiphy;
7274
7275 if (wiphy == NULL)
7276 return;
7277
7278 linuxkpi_wiphy_work_flush(wiphy, NULL);
7279 mutex_destroy(&wiphy->mtx);
7280
7281 lwiphy = WIPHY_TO_LWIPHY(wiphy);
7282 LKPI_80211_LWIPHY_WORK_LOCK_DESTROY(lwiphy);
7283
7284 kfree(lwiphy);
7285 }
7286
7287 static uint32_t
7288 lkpi_cfg80211_calculate_bitrate_ht(struct rate_info *rate)
7289 {
7290 TODO("cfg80211_calculate_bitrate_ht");
7291 return (rate->legacy);
7292 }
7293
7294 static uint32_t
7295 lkpi_cfg80211_calculate_bitrate_vht(struct rate_info *rate)
7296 {
7297 TODO("cfg80211_calculate_bitrate_vht");
7298 return (rate->legacy);
7299 }
7300
7301 uint32_t
7302 linuxkpi_cfg80211_calculate_bitrate(struct rate_info *rate)
7303 {
7304
7305 /* Beware: order! */
7306 if (rate->flags & RATE_INFO_FLAGS_MCS)
7307 return (lkpi_cfg80211_calculate_bitrate_ht(rate));
7308
7309 if (rate->flags & RATE_INFO_FLAGS_VHT_MCS)
7310 return (lkpi_cfg80211_calculate_bitrate_vht(rate));
7311
7312 IMPROVE("HE/EHT/...");
7313
7314 return (rate->legacy);
7315 }
7316
7317 uint32_t
7318 linuxkpi_ieee80211_channel_to_frequency(uint32_t channel,
7319 enum nl80211_band band)
7320 {
7321
7322 switch (band) {
7323 case NL80211_BAND_2GHZ:
7324 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_2GHZ));
7325 break;
7326 case NL80211_BAND_5GHZ:
7327 return (ieee80211_ieee2mhz(channel, IEEE80211_CHAN_5GHZ));
7328 break;
7329 default:
7330 /* XXX abort, retry, error, panic? */
7331 break;
7332 }
7333
7334 return (0);
7335 }
7336
7337 uint32_t
7338 linuxkpi_ieee80211_frequency_to_channel(uint32_t freq, uint32_t flags __unused)
7339 {
7340
7341 return (ieee80211_mhz2ieee(freq, 0));
7342 }
7343
7344 #if 0
7345 static struct lkpi_sta *
7346 lkpi_find_lsta_by_ni(struct lkpi_vif *lvif, struct ieee80211_node *ni)
7347 {
7348 struct lkpi_sta *lsta, *temp;
7349
7350 rcu_read_lock();
7351 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7352 if (lsta->ni == ni) {
7353 rcu_read_unlock();
7354 return (lsta);
7355 }
7356 }
7357 rcu_read_unlock();
7358
7359 return (NULL);
7360 }
7361 #endif
7362
7363 struct ieee80211_sta *
7364 linuxkpi_ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer)
7365 {
7366 struct lkpi_vif *lvif;
7367 struct lkpi_sta *lsta;
7368 struct ieee80211_sta *sta;
7369
7370 lvif = VIF_TO_LVIF(vif);
7371
7372 rcu_read_lock();
7373 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7374 sta = LSTA_TO_STA(lsta);
7375 if (IEEE80211_ADDR_EQ(sta->addr, peer)) {
7376 rcu_read_unlock();
7377 return (sta);
7378 }
7379 }
7380 rcu_read_unlock();
7381 return (NULL);
7382 }
7383
7384 struct ieee80211_sta *
7385 linuxkpi_ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw,
7386 const uint8_t *addr, const uint8_t *ourvifaddr)
7387 {
7388 struct lkpi_hw *lhw;
7389 struct lkpi_vif *lvif;
7390 struct lkpi_sta *lsta;
7391 struct ieee80211_vif *vif;
7392 struct ieee80211_sta *sta;
7393
7394 lhw = wiphy_priv(hw->wiphy);
7395 sta = NULL;
7396
7397 LKPI_80211_LHW_LVIF_LOCK(lhw);
7398 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7399
7400 /* XXX-BZ check our address from the vif. */
7401
7402 vif = LVIF_TO_VIF(lvif);
7403 if (ourvifaddr != NULL &&
7404 !IEEE80211_ADDR_EQ(vif->addr, ourvifaddr))
7405 continue;
7406 sta = linuxkpi_ieee80211_find_sta(vif, addr);
7407 if (sta != NULL)
7408 break;
7409 }
7410 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7411
7412 if (sta != NULL) {
7413 lsta = STA_TO_LSTA(sta);
7414 if (!lsta->added_to_drv)
7415 return (NULL);
7416 }
7417
7418 return (sta);
7419 }
7420
7421 struct sk_buff *
7422 linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *hw,
7423 struct ieee80211_txq *txq)
7424 {
7425 struct lkpi_txq *ltxq;
7426 struct lkpi_vif *lvif;
7427 struct sk_buff *skb;
7428
7429 IMPROVE("wiphy_lock? or assert?");
7430 skb = NULL;
7431 ltxq = TXQ_TO_LTXQ(txq);
7432 ltxq->seen_dequeue = true;
7433
7434 if (ltxq->stopped)
7435 goto stopped;
7436
7437 lvif = VIF_TO_LVIF(ltxq->txq.vif);
7438 if (lvif->hw_queue_stopped[ltxq->txq.ac]) {
7439 ltxq->stopped = true;
7440 goto stopped;
7441 }
7442
7443 IMPROVE("hw(TX_FRAG_LIST)");
7444
7445 LKPI_80211_LTXQ_LOCK(ltxq);
7446 skb = skb_dequeue(<xq->skbq);
7447 LKPI_80211_LTXQ_UNLOCK(ltxq);
7448
7449 stopped:
7450 return (skb);
7451 }
7452
7453 void
7454 linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *txq,
7455 unsigned long *frame_cnt, unsigned long *byte_cnt)
7456 {
7457 struct lkpi_txq *ltxq;
7458 struct sk_buff *skb;
7459 unsigned long fc, bc;
7460
7461 ltxq = TXQ_TO_LTXQ(txq);
7462
7463 fc = bc = 0;
7464 LKPI_80211_LTXQ_LOCK(ltxq);
7465 skb_queue_walk(<xq->skbq, skb) {
7466 fc++;
7467 bc += skb->len;
7468 }
7469 LKPI_80211_LTXQ_UNLOCK(ltxq);
7470 if (frame_cnt)
7471 *frame_cnt = fc;
7472 if (byte_cnt)
7473 *byte_cnt = bc;
7474
7475 /* Validate that this is doing the correct thing. */
7476 /* Should we keep track on en/dequeue? */
7477 IMPROVE();
7478 }
7479
7480 /*
7481 * We are called from ieee80211_free_txskb() or ieee80211_tx_status().
7482 * The latter tries to derive the success status from the info flags
7483 * passed back from the driver. rawx_mit() saves the ni on the m and the
7484 * m on the skb for us to be able to give feedback to net80211.
7485 */
7486 static void
7487 _lkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
7488 int status)
7489 {
7490 struct ieee80211_node *ni;
7491 struct mbuf *m;
7492
7493 m = skb->m;
7494 skb->m = NULL;
7495
7496 if (m != NULL) {
7497 ni = m->m_pkthdr.PH_loc.ptr;
7498 /* Status: 0 is ok, != 0 is error. */
7499 ieee80211_tx_complete(ni, m, status);
7500 /* ni & mbuf were consumed. */
7501 }
7502 }
7503
7504 void
7505 linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb,
7506 int status)
7507 {
7508
7509 _lkpi_ieee80211_free_txskb(hw, skb, status);
7510 kfree_skb(skb);
7511 }
7512
7513 void
7514 linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *hw,
7515 struct ieee80211_tx_status *txstat)
7516 {
7517 struct sk_buff *skb;
7518 struct ieee80211_tx_info *info;
7519 struct ieee80211_ratectl_tx_status txs;
7520 struct ieee80211_node *ni;
7521 int status;
7522
7523 skb = txstat->skb;
7524 if (skb->m != NULL) {
7525 struct mbuf *m;
7526
7527 m = skb->m;
7528 ni = m->m_pkthdr.PH_loc.ptr;
7529 memset(&txs, 0, sizeof(txs));
7530 } else {
7531 ni = NULL;
7532 }
7533
7534 info = txstat->info;
7535 if (info->flags & IEEE80211_TX_STAT_ACK) {
7536 status = 0; /* No error. */
7537 txs.status = IEEE80211_RATECTL_TX_SUCCESS;
7538 } else {
7539 status = 1;
7540 txs.status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED;
7541 }
7542
7543 if (ni != NULL) {
7544 txs.pktlen = skb->len;
7545 txs.flags |= IEEE80211_RATECTL_STATUS_PKTLEN;
7546 if (info->status.rates[0].count > 1) {
7547 txs.long_retries = info->status.rates[0].count - 1; /* 1 + retries in drivers. */
7548 txs.flags |= IEEE80211_RATECTL_STATUS_LONG_RETRY;
7549 }
7550 #if 0 /* Unused in net80211 currently. */
7551 /* XXX-BZ convert check .flags for MCS/VHT/.. */
7552 txs.final_rate = info->status.rates[0].idx;
7553 txs.flags |= IEEE80211_RATECTL_STATUS_FINAL_RATE;
7554 #endif
7555 if (info->status.flags & IEEE80211_TX_STATUS_ACK_SIGNAL_VALID) {
7556 txs.rssi = info->status.ack_signal; /* XXX-BZ CONVERT? */
7557 txs.flags |= IEEE80211_RATECTL_STATUS_RSSI;
7558 }
7559
7560 IMPROVE("only update rate if needed but that requires us to get a proper rate from mo_sta_statistics");
7561 ieee80211_ratectl_tx_complete(ni, &txs);
7562 ieee80211_ratectl_rate(ni->ni_vap->iv_bss, NULL, 0);
7563
7564 #ifdef LINUXKPI_DEBUG_80211
7565 if (linuxkpi_debug_80211 & D80211_TRACE_TX) {
7566 printf("TX-RATE: %s: long_retries %d\n", __func__,
7567 txs.long_retries);
7568 }
7569 #endif
7570 }
7571
7572 #ifdef LINUXKPI_DEBUG_80211
7573 if (linuxkpi_debug_80211 & D80211_TRACE_TX)
7574 printf("TX-STATUS: %s: hw %p skb %p status %d : flags %#x "
7575 "band %u hw_queue %u tx_time_est %d : "
7576 "rates [ %u %u %#x, %u %u %#x, %u %u %#x, %u %u %#x ] "
7577 "ack_signal %u ampdu_ack_len %u ampdu_len %u antenna %u "
7578 "tx_time %u flags %#x "
7579 "status_driver_data [ %p %p ]\n",
7580 __func__, hw, skb, status, info->flags,
7581 info->band, info->hw_queue, info->tx_time_est,
7582 info->status.rates[0].idx, info->status.rates[0].count,
7583 info->status.rates[0].flags,
7584 info->status.rates[1].idx, info->status.rates[1].count,
7585 info->status.rates[1].flags,
7586 info->status.rates[2].idx, info->status.rates[2].count,
7587 info->status.rates[2].flags,
7588 info->status.rates[3].idx, info->status.rates[3].count,
7589 info->status.rates[3].flags,
7590 info->status.ack_signal, info->status.ampdu_ack_len,
7591 info->status.ampdu_len, info->status.antenna,
7592 info->status.tx_time, info->status.flags,
7593 info->status.status_driver_data[0],
7594 info->status.status_driver_data[1]);
7595 #endif
7596
7597 if (txstat->free_list) {
7598 _lkpi_ieee80211_free_txskb(hw, skb, status);
7599 list_add_tail(&skb->list, txstat->free_list);
7600 } else {
7601 linuxkpi_ieee80211_free_txskb(hw, skb, status);
7602 }
7603 }
7604
7605 void
7606 linuxkpi_ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
7607 {
7608 struct ieee80211_tx_status status;
7609
7610 memset(&status, 0, sizeof(status));
7611 status.info = IEEE80211_SKB_CB(skb);
7612 status.skb = skb;
7613 /* sta, n_rates, rates, free_list? */
7614
7615 ieee80211_tx_status_ext(hw, &status);
7616 }
7617
7618 /*
7619 * This is an internal bandaid for the moment for the way we glue
7620 * skbs and mbufs together for TX. Once we have skbs backed by
7621 * mbufs this should go away.
7622 * This is a public function but kept on the private KPI (lkpi_)
7623 * and is not exposed by a header file.
7624 */
7625 static void
7626 lkpi_ieee80211_free_skb_mbuf(void *p)
7627 {
7628 struct ieee80211_node *ni;
7629 struct mbuf *m;
7630
7631 if (p == NULL)
7632 return;
7633
7634 m = (struct mbuf *)p;
7635 M_ASSERTPKTHDR(m);
7636
7637 ni = m->m_pkthdr.PH_loc.ptr;
7638 m->m_pkthdr.PH_loc.ptr = NULL;
7639 if (ni != NULL)
7640 ieee80211_free_node(ni);
7641 m_freem(m);
7642 }
7643
7644 void
7645 linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
7646 struct delayed_work *w, int delay)
7647 {
7648 struct lkpi_hw *lhw;
7649
7650 /* Need to make sure hw is in a stable (non-suspended) state. */
7651 IMPROVE();
7652
7653 lhw = HW_TO_LHW(hw);
7654 queue_delayed_work(lhw->workq, w, delay);
7655 }
7656
7657 void
7658 linuxkpi_ieee80211_queue_work(struct ieee80211_hw *hw,
7659 struct work_struct *w)
7660 {
7661 struct lkpi_hw *lhw;
7662
7663 /* Need to make sure hw is in a stable (non-suspended) state. */
7664 IMPROVE();
7665
7666 lhw = HW_TO_LHW(hw);
7667 queue_work(lhw->workq, w);
7668 }
7669
7670 struct sk_buff *
7671 linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *hw, uint8_t *addr,
7672 uint8_t *ssid, size_t ssid_len, size_t tailroom)
7673 {
7674 struct sk_buff *skb;
7675 struct ieee80211_frame *wh;
7676 uint8_t *p;
7677 size_t len;
7678
7679 len = sizeof(*wh);
7680 len += 2 + ssid_len;
7681
7682 skb = dev_alloc_skb(hw->extra_tx_headroom + len + tailroom);
7683 if (skb == NULL)
7684 return (NULL);
7685
7686 skb_reserve(skb, hw->extra_tx_headroom);
7687
7688 wh = skb_put_zero(skb, sizeof(*wh));
7689 wh->i_fc[0] = IEEE80211_FC0_VERSION_0;
7690 wh->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT;
7691 IEEE80211_ADDR_COPY(wh->i_addr1, ieee80211broadcastaddr);
7692 IEEE80211_ADDR_COPY(wh->i_addr2, addr);
7693 IEEE80211_ADDR_COPY(wh->i_addr3, ieee80211broadcastaddr);
7694
7695 p = skb_put(skb, 2 + ssid_len);
7696 *p++ = IEEE80211_ELEMID_SSID;
7697 *p++ = ssid_len;
7698 if (ssid_len > 0)
7699 memcpy(p, ssid, ssid_len);
7700
7701 return (skb);
7702 }
7703
7704 struct sk_buff *
7705 linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *hw,
7706 struct ieee80211_vif *vif)
7707 {
7708 struct lkpi_vif *lvif;
7709 struct ieee80211vap *vap;
7710 struct sk_buff *skb;
7711 struct ieee80211_frame_pspoll *psp;
7712 uint16_t v;
7713
7714 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*psp));
7715 if (skb == NULL)
7716 return (NULL);
7717
7718 skb_reserve(skb, hw->extra_tx_headroom);
7719
7720 lvif = VIF_TO_LVIF(vif);
7721 vap = LVIF_TO_VAP(lvif);
7722
7723 psp = skb_put_zero(skb, sizeof(*psp));
7724 psp->i_fc[0] = IEEE80211_FC0_VERSION_0;
7725 psp->i_fc[0] |= IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL;
7726 v = htole16(vif->cfg.aid | 1<<15 | 1<<16);
7727 memcpy(&psp->i_aid, &v, sizeof(v));
7728 IEEE80211_ADDR_COPY(psp->i_bssid, vap->iv_bss->ni_macaddr);
7729 IEEE80211_ADDR_COPY(psp->i_ta, vif->addr);
7730
7731 return (skb);
7732 }
7733
7734 struct sk_buff *
7735 linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *hw,
7736 struct ieee80211_vif *vif, int linkid, bool qos)
7737 {
7738 struct lkpi_vif *lvif;
7739 struct ieee80211vap *vap;
7740 struct sk_buff *skb;
7741 struct ieee80211_frame *nullf;
7742
7743 IMPROVE("linkid");
7744
7745 skb = dev_alloc_skb(hw->extra_tx_headroom + sizeof(*nullf));
7746 if (skb == NULL)
7747 return (NULL);
7748
7749 skb_reserve(skb, hw->extra_tx_headroom);
7750
7751 lvif = VIF_TO_LVIF(vif);
7752 vap = LVIF_TO_VAP(lvif);
7753
7754 nullf = skb_put_zero(skb, sizeof(*nullf));
7755 nullf->i_fc[0] = IEEE80211_FC0_VERSION_0;
7756 nullf->i_fc[0] |= IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA;
7757 nullf->i_fc[1] = IEEE80211_FC1_DIR_TODS;
7758
7759 IEEE80211_ADDR_COPY(nullf->i_addr1, vap->iv_bss->ni_bssid);
7760 IEEE80211_ADDR_COPY(nullf->i_addr2, vif->addr);
7761 IEEE80211_ADDR_COPY(nullf->i_addr3, vap->iv_bss->ni_macaddr);
7762
7763 return (skb);
7764 }
7765
7766 struct wireless_dev *
7767 linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
7768 {
7769 struct lkpi_vif *lvif;
7770
7771 lvif = VIF_TO_LVIF(vif);
7772 return (&lvif->wdev);
7773 }
7774
7775 void
7776 linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *vif)
7777 {
7778 struct lkpi_vif *lvif;
7779 struct ieee80211vap *vap;
7780 enum ieee80211_state nstate;
7781 int arg;
7782
7783 lvif = VIF_TO_LVIF(vif);
7784 vap = LVIF_TO_VAP(lvif);
7785
7786 /*
7787 * Go to init; otherwise we need to elaborately check state and
7788 * handle accordingly, e.g., if in RUN we could call iv_bmiss.
7789 * Let the statemachine handle all neccessary changes.
7790 */
7791 nstate = IEEE80211_S_INIT;
7792 arg = 0; /* Not a valid reason. */
7793
7794 ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
7795 vif, vap, ieee80211_state_name[vap->iv_state]);
7796 ieee80211_new_state(vap, nstate, arg);
7797 }
7798
7799 void
7800 linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *vif)
7801 {
7802 struct lkpi_vif *lvif;
7803 struct ieee80211vap *vap;
7804
7805 lvif = VIF_TO_LVIF(vif);
7806 vap = LVIF_TO_VAP(lvif);
7807
7808 ic_printf(vap->iv_ic, "%s: vif %p vap %p state %s\n", __func__,
7809 vif, vap, ieee80211_state_name[vap->iv_state]);
7810 ieee80211_beacon_miss(vap->iv_ic);
7811 }
7812
7813 /* -------------------------------------------------------------------------- */
7814
7815 void
7816 linuxkpi_ieee80211_stop_queue(struct ieee80211_hw *hw, int qnum)
7817 {
7818 struct lkpi_hw *lhw;
7819 struct lkpi_vif *lvif;
7820 struct ieee80211_vif *vif;
7821 int ac_count, ac;
7822
7823 KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
7824 __func__, qnum, hw->queues, hw));
7825
7826 lhw = wiphy_priv(hw->wiphy);
7827
7828 /* See lkpi_ic_vap_create(). */
7829 if (hw->queues >= IEEE80211_NUM_ACS)
7830 ac_count = IEEE80211_NUM_ACS;
7831 else
7832 ac_count = 1;
7833
7834 LKPI_80211_LHW_LVIF_LOCK(lhw);
7835 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7836
7837 vif = LVIF_TO_VIF(lvif);
7838 for (ac = 0; ac < ac_count; ac++) {
7839 IMPROVE_TXQ("LOCKING");
7840 if (qnum == vif->hw_queue[ac]) {
7841 #ifdef LINUXKPI_DEBUG_80211
7842 /*
7843 * For now log this to better understand
7844 * how this is supposed to work.
7845 */
7846 if (lvif->hw_queue_stopped[ac] &&
7847 (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
7848 ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
7849 "lvif %p vif %p ac %d qnum %d already "
7850 "stopped\n", __func__, __LINE__,
7851 lhw, hw, lvif, vif, ac, qnum);
7852 #endif
7853 lvif->hw_queue_stopped[ac] = true;
7854 }
7855 }
7856 }
7857 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7858 }
7859
7860 void
7861 linuxkpi_ieee80211_stop_queues(struct ieee80211_hw *hw)
7862 {
7863 int i;
7864
7865 IMPROVE_TXQ("Locking; do we need further info?");
7866 for (i = 0; i < hw->queues; i++)
7867 linuxkpi_ieee80211_stop_queue(hw, i);
7868 }
7869
7870
7871 static void
7872 lkpi_ieee80211_wake_queues(struct ieee80211_hw *hw, int hwq)
7873 {
7874 struct lkpi_hw *lhw;
7875 struct lkpi_vif *lvif;
7876 struct lkpi_sta *lsta;
7877 int ac_count, ac, tid;
7878
7879 /* See lkpi_ic_vap_create(). */
7880 if (hw->queues >= IEEE80211_NUM_ACS)
7881 ac_count = IEEE80211_NUM_ACS;
7882 else
7883 ac_count = 1;
7884
7885 lhw = wiphy_priv(hw->wiphy);
7886
7887 IMPROVE_TXQ("Locking");
7888 LKPI_80211_LHW_LVIF_LOCK(lhw);
7889 TAILQ_FOREACH(lvif, &lhw->lvif_head, lvif_entry) {
7890 struct ieee80211_vif *vif;
7891
7892 vif = LVIF_TO_VIF(lvif);
7893 for (ac = 0; ac < ac_count; ac++) {
7894
7895 if (hwq == vif->hw_queue[ac]) {
7896
7897 /* XXX-BZ what about software scan? */
7898
7899 #ifdef LINUXKPI_DEBUG_80211
7900 /*
7901 * For now log this to better understand
7902 * how this is supposed to work.
7903 */
7904 if (!lvif->hw_queue_stopped[ac] &&
7905 (linuxkpi_debug_80211 & D80211_IMPROVE_TXQ) != 0)
7906 ic_printf(lhw->ic, "%s:%d: lhw %p hw %p "
7907 "lvif %p vif %p ac %d hw_q not stopped\n",
7908 __func__, __LINE__,
7909 lhw, hw, lvif, vif, ac);
7910 #endif
7911 lvif->hw_queue_stopped[ac] = false;
7912
7913 rcu_read_lock();
7914 list_for_each_entry_rcu(lsta, &lvif->lsta_list, lsta_list) {
7915 struct ieee80211_sta *sta;
7916
7917 sta = LSTA_TO_STA(lsta);
7918 for (tid = 0; tid < nitems(sta->txq); tid++) {
7919 struct lkpi_txq *ltxq;
7920
7921 if (sta->txq[tid] == NULL)
7922 continue;
7923
7924 if (sta->txq[tid]->ac != ac)
7925 continue;
7926
7927 ltxq = TXQ_TO_LTXQ(sta->txq[tid]);
7928 if (!ltxq->stopped)
7929 continue;
7930
7931 ltxq->stopped = false;
7932
7933 if (!skb_queue_empty(<xq->skbq))
7934 lkpi_80211_mo_wake_tx_queue(hw, sta->txq[tid]);
7935 }
7936 }
7937 rcu_read_unlock();
7938 }
7939 }
7940 }
7941 LKPI_80211_LHW_LVIF_UNLOCK(lhw);
7942 }
7943
7944 static void
7945 lkpi_ieee80211_wake_queues_locked(struct ieee80211_hw *hw)
7946 {
7947 int i;
7948
7949 IMPROVE_TXQ("Is this all/enough here?");
7950 for (i = 0; i < hw->queues; i++)
7951 lkpi_ieee80211_wake_queues(hw, i);
7952 }
7953
7954 void
7955 linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *hw)
7956 {
7957 wiphy_lock(hw->wiphy);
7958 lkpi_ieee80211_wake_queues_locked(hw);
7959 wiphy_unlock(hw->wiphy);
7960 }
7961
7962 void
7963 linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
7964 {
7965
7966 KASSERT(qnum < hw->queues, ("%s: qnum %d >= hw->queues %d, hw %p\n",
7967 __func__, qnum, hw->queues, hw));
7968
7969 wiphy_lock(hw->wiphy);
7970 lkpi_ieee80211_wake_queues(hw, qnum);
7971 wiphy_unlock(hw->wiphy);
7972 }
7973
7974 /* This is just hardware queues. */
7975 void
7976 linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint8_t ac)
7977 {
7978 struct lkpi_hw *lhw;
7979
7980 lhw = HW_TO_LHW(hw);
7981
7982 IMPROVE_TXQ("Are there reasons why we wouldn't schedule?");
7983 IMPROVE_TXQ("LOCKING");
7984 if (++lhw->txq_generation[ac] == 0)
7985 lhw->txq_generation[ac]++;
7986 }
7987
7988 struct ieee80211_txq *
7989 linuxkpi_ieee80211_next_txq(struct ieee80211_hw *hw, uint8_t ac)
7990 {
7991 struct lkpi_hw *lhw;
7992 struct ieee80211_txq *txq;
7993 struct lkpi_txq *ltxq;
7994
7995 lhw = HW_TO_LHW(hw);
7996 txq = NULL;
7997
7998 IMPROVE_TXQ("LOCKING");
7999
8000 /* Check that we are scheduled. */
8001 if (lhw->txq_generation[ac] == 0)
8002 goto out;
8003
8004 ltxq = TAILQ_FIRST(&lhw->scheduled_txqs[ac]);
8005 if (ltxq == NULL)
8006 goto out;
8007 if (ltxq->txq_generation == lhw->txq_generation[ac])
8008 goto out;
8009
8010 ltxq->txq_generation = lhw->txq_generation[ac];
8011 TAILQ_REMOVE(&lhw->scheduled_txqs[ac], ltxq, txq_entry);
8012 txq = <xq->txq;
8013 TAILQ_ELEM_INIT(ltxq, txq_entry);
8014
8015 out:
8016 return (txq);
8017 }
8018
8019 void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *hw,
8020 struct ieee80211_txq *txq, bool withoutpkts)
8021 {
8022 struct lkpi_hw *lhw;
8023 struct lkpi_txq *ltxq;
8024 bool ltxq_empty;
8025
8026 ltxq = TXQ_TO_LTXQ(txq);
8027
8028 IMPROVE_TXQ("LOCKING");
8029
8030 /* Only schedule if work to do or asked to anyway. */
8031 LKPI_80211_LTXQ_LOCK(ltxq);
8032 ltxq_empty = skb_queue_empty(<xq->skbq);
8033 LKPI_80211_LTXQ_UNLOCK(ltxq);
8034 if (!withoutpkts && ltxq_empty)
8035 goto out;
8036
8037 /*
8038 * Make sure we do not double-schedule. We do this by checking tqe_prev,
8039 * the previous entry in our tailq. tqe_prev is always valid if this entry
8040 * is queued, tqe_next may be NULL if this is the only element in the list.
8041 */
8042 if (ltxq->txq_entry.tqe_prev != NULL)
8043 goto out;
8044
8045 lhw = HW_TO_LHW(hw);
8046 TAILQ_INSERT_TAIL(&lhw->scheduled_txqs[txq->ac], ltxq, txq_entry);
8047 out:
8048 return;
8049 }
8050
8051 void
8052 linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
8053 struct ieee80211_txq *txq)
8054 {
8055 struct lkpi_hw *lhw;
8056 struct ieee80211_txq *ntxq;
8057 struct ieee80211_tx_control control;
8058 struct sk_buff *skb;
8059
8060 lhw = HW_TO_LHW(hw);
8061
8062 LKPI_80211_LHW_TXQ_LOCK(lhw);
8063 ieee80211_txq_schedule_start(hw, txq->ac);
8064 do {
8065 ntxq = ieee80211_next_txq(hw, txq->ac);
8066 if (ntxq == NULL)
8067 break;
8068
8069 memset(&control, 0, sizeof(control));
8070 control.sta = ntxq->sta;
8071 do {
8072 skb = linuxkpi_ieee80211_tx_dequeue(hw, ntxq);
8073 if (skb == NULL)
8074 break;
8075 lkpi_80211_mo_tx(hw, &control, skb);
8076 } while(1);
8077
8078 ieee80211_return_txq(hw, ntxq, false);
8079 } while (1);
8080 ieee80211_txq_schedule_end(hw, txq->ac);
8081 LKPI_80211_LHW_TXQ_UNLOCK(lhw);
8082 }
8083
8084 /* -------------------------------------------------------------------------- */
8085
8086 struct lkpi_cfg80211_bss {
8087 u_int refcnt;
8088 struct cfg80211_bss bss;
8089 };
8090
8091 struct lkpi_cfg80211_get_bss_iter_lookup {
8092 struct wiphy *wiphy;
8093 struct linuxkpi_ieee80211_channel *chan;
8094 const uint8_t *bssid;
8095 const uint8_t *ssid;
8096 size_t ssid_len;
8097 enum ieee80211_bss_type bss_type;
8098 enum ieee80211_privacy privacy;
8099
8100 /*
8101 * Something to store a copy of the result as the net80211 scan cache
8102 * is not refoucnted so a scan entry might go away any time.
8103 */
8104 bool match;
8105 struct cfg80211_bss *bss;
8106 };
8107
8108 static void
8109 lkpi_cfg80211_get_bss_iterf(void *arg, const struct ieee80211_scan_entry *se)
8110 {
8111 struct lkpi_cfg80211_get_bss_iter_lookup *lookup;
8112 size_t ielen;
8113
8114 lookup = arg;
8115
8116 /* Do not try to find another match. */
8117 if (lookup->match)
8118 return;
8119
8120 /* Nothing to store result. */
8121 if (lookup->bss == NULL)
8122 return;
8123
8124 if (lookup->privacy != IEEE80211_PRIVACY_ANY) {
8125 /* if (se->se_capinfo & IEEE80211_CAPINFO_PRIVACY) */
8126 /* We have no idea what to compare to as the drivers only request ANY */
8127 return;
8128 }
8129
8130 if (lookup->bss_type != IEEE80211_BSS_TYPE_ANY) {
8131 /* if (se->se_capinfo & (IEEE80211_CAPINFO_IBSS|IEEE80211_CAPINFO_ESS)) */
8132 /* We have no idea what to compare to as the drivers only request ANY */
8133 return;
8134 }
8135
8136 if (lookup->chan != NULL) {
8137 struct linuxkpi_ieee80211_channel *chan;
8138
8139 chan = linuxkpi_ieee80211_get_channel(lookup->wiphy,
8140 se->se_chan->ic_freq);
8141 if (chan == NULL || chan != lookup->chan)
8142 return;
8143 }
8144
8145 if (lookup->bssid && !IEEE80211_ADDR_EQ(lookup->bssid, se->se_bssid))
8146 return;
8147
8148 if (lookup->ssid) {
8149 if (lookup->ssid_len != se->se_ssid[1] ||
8150 se->se_ssid[1] == 0)
8151 return;
8152 if (memcmp(lookup->ssid, se->se_ssid+2, lookup->ssid_len) != 0)
8153 return;
8154 }
8155
8156 ielen = se->se_ies.len;
8157
8158 lookup->bss->ies = malloc(sizeof(*lookup->bss->ies) + ielen,
8159 M_LKPI80211, M_NOWAIT | M_ZERO);
8160 if (lookup->bss->ies == NULL)
8161 return;
8162
8163 lookup->bss->ies->data = (uint8_t *)lookup->bss->ies + sizeof(*lookup->bss->ies);
8164 lookup->bss->ies->len = ielen;
8165 if (ielen)
8166 memcpy(lookup->bss->ies->data, se->se_ies.data, ielen);
8167
8168 lookup->match = true;
8169 }
8170
8171 struct cfg80211_bss *
8172 linuxkpi_cfg80211_get_bss(struct wiphy *wiphy, struct linuxkpi_ieee80211_channel *chan,
8173 const uint8_t *bssid, const uint8_t *ssid, size_t ssid_len,
8174 enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy)
8175 {
8176 struct lkpi_cfg80211_bss *lbss;
8177 struct lkpi_cfg80211_get_bss_iter_lookup lookup;
8178 struct lkpi_hw *lhw;
8179 struct ieee80211vap *vap;
8180
8181 lhw = wiphy_priv(wiphy);
8182
8183 /* Let's hope we can alloc. */
8184 lbss = malloc(sizeof(*lbss), M_LKPI80211, M_NOWAIT | M_ZERO);
8185 if (lbss == NULL) {
8186 ic_printf(lhw->ic, "%s: alloc failed.\n", __func__);
8187 return (NULL);
8188 }
8189
8190 lookup.wiphy = wiphy;
8191 lookup.chan = chan;
8192 lookup.bssid = bssid;
8193 lookup.ssid = ssid;
8194 lookup.ssid_len = ssid_len;
8195 lookup.bss_type = bss_type;
8196 lookup.privacy = privacy;
8197 lookup.match = false;
8198 lookup.bss = &lbss->bss;
8199
8200 IMPROVE("Iterate over all VAPs comparing perm_addr and addresses?");
8201 vap = TAILQ_FIRST(&lhw->ic->ic_vaps);
8202 ieee80211_scan_iterate(vap, lkpi_cfg80211_get_bss_iterf, &lookup);
8203 if (!lookup.match) {
8204 free(lbss, M_LKPI80211);
8205 return (NULL);
8206 }
8207
8208 refcount_init(&lbss->refcnt, 1);
8209 return (&lbss->bss);
8210 }
8211
8212 void
8213 linuxkpi_cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss)
8214 {
8215 struct lkpi_cfg80211_bss *lbss;
8216
8217 lbss = container_of(bss, struct lkpi_cfg80211_bss, bss);
8218
8219 /* Free everything again on refcount ... */
8220 if (refcount_release(&lbss->refcnt)) {
8221 free(lbss->bss.ies, M_LKPI80211);
8222 free(lbss, M_LKPI80211);
8223 }
8224 }
8225
8226 void
8227 linuxkpi_cfg80211_bss_flush(struct wiphy *wiphy)
8228 {
8229 struct lkpi_hw *lhw;
8230 struct ieee80211com *ic;
8231 struct ieee80211vap *vap;
8232
8233 lhw = wiphy_priv(wiphy);
8234 ic = lhw->ic;
8235
8236 /*
8237 * If we haven't called ieee80211_ifattach() yet
8238 * or there is no VAP, there are no scans to flush.
8239 */
8240 if (ic == NULL ||
8241 (lhw->sc_flags & LKPI_MAC80211_DRV_STARTED) == 0)
8242 return;
8243
8244 /* Should only happen on the current one? Not seen it late enough. */
8245 IEEE80211_LOCK(ic);
8246 TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next)
8247 ieee80211_scan_flush(vap);
8248 IEEE80211_UNLOCK(ic);
8249 }
8250
8251 /* -------------------------------------------------------------------------- */
8252
8253 /*
8254 * hw->conf get initialized/set in various places for us:
8255 * - linuxkpi_ieee80211_alloc_hw(): flags
8256 * - linuxkpi_ieee80211_ifattach(): chandef
8257 * - lkpi_ic_vap_create(): listen_interval
8258 * - lkpi_ic_set_channel(): chandef, flags
8259 */
8260
8261 int lkpi_80211_update_chandef(struct ieee80211_hw *hw,
8262 struct ieee80211_chanctx_conf *new)
8263 {
8264 struct cfg80211_chan_def *cd;
8265 uint32_t changed;
8266 int error;
8267
8268 changed = 0;
8269 if (new == NULL || new->def.chan == NULL)
8270 cd = NULL;
8271 else
8272 cd = &new->def;
8273
8274 if (cd && cd->chan != hw->conf.chandef.chan) {
8275 /* Copy; the chan pointer is fine and will stay valid. */
8276 hw->conf.chandef = *cd;
8277 changed |= IEEE80211_CONF_CHANGE_CHANNEL;
8278 }
8279 IMPROVE("IEEE80211_CONF_CHANGE_PS, IEEE80211_CONF_CHANGE_POWER");
8280
8281 if (changed == 0)
8282 return (0);
8283
8284 error = lkpi_80211_mo_config(hw, changed);
8285 return (error);
8286 }
8287
8288 /* -------------------------------------------------------------------------- */
8289
8290 MODULE_VERSION(linuxkpi_wlan, 1);
8291 MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1);
8292 MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1);
8293