History

Merge tag 'mac80211-next-for-davem-2017-10-11' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next

Johannes Berg says: ==================== Work continues in various areas: * port authorized event for 4-way-HS offload (Avi) * enable MFP optional for such devices (Emmanuel) * Kees's timer setup patch for mac80211 mesh (the part that isn't trivially scripted) * improve VLAN vs. TXQ handling (myself) * load regulatory database as firmware file (myself) * with various other small improvements and cleanups I merged net-next once in the meantime to allow Kees's timer setup patch to go in. ====================

David S. Miller committed 9 years ago

Commit df2fd382 parents b822696 90a53e447 files · +1277 −898Browse files

Unified · Split

47 files
  1. Documentation/driver-api/80211/cfg80211.rst +0 −3
  2. Documentation/networking/regulatory.txt +10 −20
  3. MAINTAINERS +10 −3
  4. drivers/net/wireless/mac80211_hwsim.c +96 −96
  5. include/linux/ieee80211.h +1 −0
  6. include/net/cfg80211.h +21 −19
  7. include/net/fq.h +7 −0
  8. include/net/fq_impl.h +62 −10
  9. include/net/mac80211.h +7 −1
  10. include/uapi/linux/nl80211.h +65 −17
  11. net/mac80211/Makefile +1 −2
  12. net/mac80211/aead_api.c +20 −20
  13. net/mac80211/aead_api.h +27 −0
  14. net/mac80211/aes_ccm.h +31 −11
  15. net/mac80211/aes_gcm.c +0 −109
  16. net/mac80211/aes_gcm.h +30 −8
  17. net/mac80211/agg-rx.c +2 −2
  18. net/mac80211/ht.c +7 −5
  19. net/mac80211/ieee80211_i.h +2 −0
  20. net/mac80211/iface.c +6 −23
  21. net/mac80211/mesh.c +1 −2
  22. net/mac80211/mesh.h +1 −0
  23. net/mac80211/mesh_hwmp.c +4 −4
  24. net/mac80211/mesh_plink.c +5 −8
  25. net/mac80211/mlme.c +7 −12
  26. net/mac80211/scan.c +28 −9
  27. net/mac80211/sta_info.c +35 −26
  28. net/mac80211/sta_info.h +3 −1
  29. net/mac80211/tx.c +34 −0
  30. net/mac80211/util.c +11 −14
  31. net/mac80211/vht.c +10 −0
  32. net/mac80211/wpa.c +2 −2
  33. net/wireless/.gitignore +2 −1
  34. net/wireless/Kconfig +34 −24
  35. net/wireless/Makefile +20 −4
  36. net/wireless/certs/sforshee.x509 +0 −0
  37. net/wireless/core.c +1 −1
  38. net/wireless/core.h +5 −0
  39. net/wireless/db.txt +0 −17
  40. net/wireless/genregdb.awk +0 −158
  41. net/wireless/nl80211.c +136 −63
  42. net/wireless/nl80211.h +2 −0
  43. net/wireless/reg.c +411 −41
  44. net/wireless/reg.h +14 −0
  45. net/wireless/regdb.h +0 −23
  46. net/wireless/sme.c +44 −1
  47. net/wireless/util.c +63 −139
Documentation/driver-api/80211/cfg80211.rst+0−3
@@ -299,9 +299,6 @@ Data path helpers · 298 unmodified lines
299299 .. kernel-doc:: include/net/cfg80211.h
300300 :functions: ieee80211_data_to_8023
301301
302−.. kernel-doc:: include/net/cfg80211.h
303− :functions: ieee80211_data_from_8023
304−
305302 .. kernel-doc:: include/net/cfg80211.h
306303 :functions: ieee80211_amsdu_to_8023s
307304
Documentation/networking/regulatory.txt+10−20
@@ -19,6 +19,14 @@ core regulatory domain all wireless devices should adhere to. · 18 unmodified lines
1919 How to get regulatory domains to the kernel
2020 -------------------------------------------
2121
22+When the regulatory domain is first set up, the kernel will request a
23+database file (regulatory.db) containing all the regulatory rules. It
24+will then use that database when it needs to look up the rules for a
25+given country.
26+
27+How to get regulatory domains to the kernel (old CRDA solution)
28+---------------------------------------------------------------
29+
2230 Userspace gets a regulatory domain in the kernel by having
2331 a userspace agent build it and send it via nl80211. Only
2432 expected regulatory domains will be respected by the kernel.
@@ -192,23 +200,5 @@ Then in some part of your code after your wiphy has been registered: · 167 unmodified lines
192200 Statically compiled regulatory database
193201 ---------------------------------------
194202
195−In most situations the userland solution using CRDA as described
196−above is the preferred solution. However in some cases a set of
197−rules built into the kernel itself may be desirable. To account
198−for this situation, a configuration option has been provided
199−(i.e. CONFIG_CFG80211_INTERNAL_REGDB). With this option enabled,
200−the wireless database information contained in net/wireless/db.txt is
201−used to generate a data structure encoded in net/wireless/regdb.c.
202−That option also enables code in net/wireless/reg.c which queries
203−the data in regdb.c as an alternative to using CRDA.
204−
205−The file net/wireless/db.txt should be kept up-to-date with the db.txt
206−file available in the git repository here:
207−
208− git://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git
209−
210−Again, most users in most situations should be using the CRDA package
211−provided with their distribution, and in most other situations users
212−should be building and using CRDA on their own rather than using
213−this option. If you are not absolutely sure that you should be using
214−CONFIG_CFG80211_INTERNAL_REGDB then _DO_NOT_USE_IT_.
203+When a database should be fixed into the kernel, it can be provided as a
204+firmware file at build time that is then linked into the kernel.
MAINTAINERS+10−3
@@ -3329,17 +3329,22 @@ S: Maintained · 3328 unmodified lines
33293329 F: drivers/auxdisplay/cfag12864bfb.c
33303330 F: include/linux/cfag12864b.h
33313331
3332−CFG80211 and NL80211
3332+802.11 (including CFG80211/NL80211)
33333333 M: Johannes Berg <johannes@sipsolutions.net>
33343334 L: linux-wireless@vger.kernel.org
33353335 W: http://wireless.kernel.org/
33363336 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git
33373337 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
33383338 S: Maintained
3339+F: net/wireless/
33393340 F: include/uapi/linux/nl80211.h
3341+F: include/linux/ieee80211.h
3342+F: include/net/wext.h
33403343 F: include/net/cfg80211.h
3341−F: net/wireless/*
3342−X: net/wireless/wext*
3344+F: include/net/iw_handler.h
3345+F: include/net/ieee80211_radiotap.h
3346+F: Documentation/driver-api/80211/cfg80211.rst
3347+F: Documentation/networking/regulatory.txt
33433348
33443349 CHAR and MISC DRIVERS
33453350 M: Arnd Bergmann <arnd@arndb.de>
@@ -8208,6 +8213,7 @@ F: Documentation/networking/mac80211-injection.txt · 4862 unmodified lines
82088213 F: include/net/mac80211.h
82098214 F: net/mac80211/
82108215 F: drivers/net/wireless/mac80211_hwsim.[ch]
8216+F: Documentation/networking/mac80211_hwsim/README
82118217
82128218 MAILBOX API
82138219 M: Jassi Brar <jassisinghbrar@gmail.com>
@@ -11492,6 +11498,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211.git · 3278 unmodified lines
1149211498 T: git git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
1149311499 S: Maintained
1149411500 F: Documentation/rfkill.txt
11501+F: Documentation/ABI/stable/sysfs-class-rfkill
1149511502 F: net/rfkill/
1149611503
1149711504 RHASHTABLE
drivers/net/wireless/mac80211_hwsim.c+96−96
@@ -396,7 +396,7 @@ static int mac80211_hwsim_vendor_cmd_test(struct wiphy *wiphy, · 395 unmodified lines
396396 if (!tb[QCA_WLAN_VENDOR_ATTR_TEST])
397397 return -EINVAL;
398398 val = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_TEST]);
399− wiphy_debug(wiphy, "%s: test=%u\n", __func__, val);
399+ wiphy_dbg(wiphy, "%s: test=%u\n", __func__, val);
400400
401401 /* Send a vendor event as a test. Note that this would not normally be
402402 * done within a command handler, but rather, based on some other
@@ -643,9 +643,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) · 240 unmodified lines
643643 if (!vp->assoc)
644644 return;
645645
646− wiphy_debug(data->hw->wiphy,
647− "%s: send PS-Poll to %pM for aid %d\n",
648− __func__, vp->bssid, vp->aid);
646+ wiphy_dbg(data->hw->wiphy,
647+ "%s: send PS-Poll to %pM for aid %d\n",
648+ __func__, vp->bssid, vp->aid);
649649
650650 skb = dev_alloc_skb(sizeof(*pspoll));
651651 if (!skb)
@@ -674,9 +674,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, · 22 unmodified lines
674674 if (!vp->assoc)
675675 return;
676676
677− wiphy_debug(data->hw->wiphy,
678− "%s: send data::nullfunc to %pM ps=%d\n",
679− __func__, vp->bssid, ps);
677+ wiphy_dbg(data->hw->wiphy,
678+ "%s: send data::nullfunc to %pM ps=%d\n",
679+ __func__, vp->bssid, ps);
680680
681681 skb = dev_alloc_skb(sizeof(*hdr));
682682 if (!skb)
@@ -1034,7 +1034,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, · 351 unmodified lines
10341034 msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0,
10351035 HWSIM_CMD_FRAME);
10361036 if (msg_head == NULL) {
1037− printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n");
1037+ pr_debug("mac80211_hwsim: problem with msg_head\n");
10381038 goto nla_put_failure;
10391039 }
10401040
@@ -1093,7 +1093,7 @@ static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, · 52 unmodified lines
10931093 nla_put_failure:
10941094 nlmsg_free(skb);
10951095 err_free_txskb:
1096− printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
1096+ pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
10971097 ieee80211_free_txskb(hw, my_skb);
10981098 data->tx_failed++;
10991099 }
@@ -1347,7 +1347,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, · 247 unmodified lines
13471347 }
13481348
13491349 if (data->idle && !data->tmp_chan) {
1350− wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n");
1350+ wiphy_dbg(hw->wiphy, "Trying to TX when idle - reject\n");
13511351 ieee80211_free_txskb(hw, skb);
13521352 return;
13531353 }
@@ -1408,7 +1408,7 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, · 54 unmodified lines
14081408 static int mac80211_hwsim_start(struct ieee80211_hw *hw)
14091409 {
14101410 struct mac80211_hwsim_data *data = hw->priv;
1411− wiphy_debug(hw->wiphy, "%s\n", __func__);
1411+ wiphy_dbg(hw->wiphy, "%s\n", __func__);
14121412 data->started = true;
14131413 return 0;
14141414 }
@@ -1419,16 +1419,16 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw) · 4 unmodified lines
14191419 struct mac80211_hwsim_data *data = hw->priv;
14201420 data->started = false;
14211421 tasklet_hrtimer_cancel(&data->beacon_timer);
1422− wiphy_debug(hw->wiphy, "%s\n", __func__);
1422+ wiphy_dbg(hw->wiphy, "%s\n", __func__);
14231423 }
14241424
14251425
14261426 static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
14271427 struct ieee80211_vif *vif)
14281428 {
1429− wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1430− __func__, ieee80211_vif_type_p2p(vif),
1431− vif->addr);
1429+ wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1430+ __func__, ieee80211_vif_type_p2p(vif),
1431+ vif->addr);
14321432 hwsim_set_magic(vif);
14331433
14341434 vif->cab_queue = 0;
@@ -1447,9 +1447,9 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, · 12 unmodified lines
14471447 bool newp2p)
14481448 {
14491449 newtype = ieee80211_iftype_p2p(newtype, newp2p);
1450− wiphy_debug(hw->wiphy,
1451− "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
1452− __func__, ieee80211_vif_type_p2p(vif),
1450+ wiphy_dbg(hw->wiphy,
1451+ "%s (old type=%d, new type=%d, mac_addr=%pM)\n",
1452+ __func__, ieee80211_vif_type_p2p(vif),
14531453 newtype, vif->addr);
14541454 hwsim_check_magic(vif);
14551455
@@ -1465,9 +1465,9 @@ static int mac80211_hwsim_change_interface(struct ieee80211_hw *hw, · 9 unmodified lines
14651465 static void mac80211_hwsim_remove_interface(
14661466 struct ieee80211_hw *hw, struct ieee80211_vif *vif)
14671467 {
1468− wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1469− __func__, ieee80211_vif_type_p2p(vif),
1470− vif->addr);
1468+ wiphy_dbg(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
1469+ __func__, ieee80211_vif_type_p2p(vif),
1470+ vif->addr);
14711471 hwsim_check_magic(vif);
14721472 hwsim_clear_magic(vif);
14731473 }
@@ -1589,23 +1589,23 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed) · 115 unmodified lines
15891589 int idx;
15901590
15911591 if (conf->chandef.chan)
1592− wiphy_debug(hw->wiphy,
1593− "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
1594− __func__,
1595− conf->chandef.chan->center_freq,
1596− conf->chandef.center_freq1,
1597− conf->chandef.center_freq2,
1598− hwsim_chanwidths[conf->chandef.width],
1599− !!(conf->flags & IEEE80211_CONF_IDLE),
1600− !!(conf->flags & IEEE80211_CONF_PS),
1601− smps_modes[conf->smps_mode]);
1592+ wiphy_dbg(hw->wiphy,
1593+ "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
1594+ __func__,
1595+ conf->chandef.chan->center_freq,
1596+ conf->chandef.center_freq1,
1597+ conf->chandef.center_freq2,
1598+ hwsim_chanwidths[conf->chandef.width],
1599+ !!(conf->flags & IEEE80211_CONF_IDLE),
1600+ !!(conf->flags & IEEE80211_CONF_PS),
1601+ smps_modes[conf->smps_mode]);
16021602 else
1603− wiphy_debug(hw->wiphy,
1604− "%s (freq=0 idle=%d ps=%d smps=%s)\n",
1605− __func__,
1606− !!(conf->flags & IEEE80211_CONF_IDLE),
1607− !!(conf->flags & IEEE80211_CONF_PS),
1608− smps_modes[conf->smps_mode]);
1603+ wiphy_dbg(hw->wiphy,
1604+ "%s (freq=0 idle=%d ps=%d smps=%s)\n",
1605+ __func__,
1606+ !!(conf->flags & IEEE80211_CONF_IDLE),
1607+ !!(conf->flags & IEEE80211_CONF_PS),
1608+ smps_modes[conf->smps_mode]);
16091609
16101610 data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
16111611
@@ -1659,7 +1659,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw, · 47 unmodified lines
16591659 {
16601660 struct mac80211_hwsim_data *data = hw->priv;
16611661
1662− wiphy_debug(hw->wiphy, "%s\n", __func__);
1662+ wiphy_dbg(hw->wiphy, "%s\n", __func__);
16631663
16641664 data->rx_filter = 0;
16651665 if (*total_flags & FIF_ALLMULTI)
@@ -1688,25 +1688,25 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 22 unmodified lines
16881688
16891689 hwsim_check_magic(vif);
16901690
1691− wiphy_debug(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",
1692− __func__, changed, vif->addr);
1691+ wiphy_dbg(hw->wiphy, "%s(changed=0x%x vif->addr=%pM)\n",
1692+ __func__, changed, vif->addr);
16931693
16941694 if (changed & BSS_CHANGED_BSSID) {
1695− wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n",
1696− __func__, info->bssid);
1695+ wiphy_dbg(hw->wiphy, "%s: BSSID changed: %pM\n",
1696+ __func__, info->bssid);
16971697 memcpy(vp->bssid, info->bssid, ETH_ALEN);
16981698 }
16991699
17001700 if (changed & BSS_CHANGED_ASSOC) {
1701− wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n",
1702− info->assoc, info->aid);
1701+ wiphy_dbg(hw->wiphy, " ASSOC: assoc=%d aid=%d\n",
1702+ info->assoc, info->aid);
17031703 vp->assoc = info->assoc;
17041704 vp->aid = info->aid;
17051705 }
17061706
17071707 if (changed & BSS_CHANGED_BEACON_ENABLED) {
1708− wiphy_debug(hw->wiphy, " BCN EN: %d (BI=%u)\n",
1709− info->enable_beacon, info->beacon_int);
1708+ wiphy_dbg(hw->wiphy, " BCN EN: %d (BI=%u)\n",
1709+ info->enable_beacon, info->beacon_int);
17101710 vp->bcn_en = info->enable_beacon;
17111711 if (data->started &&
17121712 !hrtimer_is_queued(&data->beacon_timer.timer) &&
@@ -1725,8 +1725,8 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 12 unmodified lines
17251725 ieee80211_iterate_active_interfaces_atomic(
17261726 data->hw, IEEE80211_IFACE_ITER_NORMAL,
17271727 mac80211_hwsim_bcn_en_iter, &count);
1728− wiphy_debug(hw->wiphy, " beaconing vifs remaining: %u",
1729− count);
1728+ wiphy_dbg(hw->wiphy, " beaconing vifs remaining: %u",
1729+ count);
17301730 if (count == 0) {
17311731 tasklet_hrtimer_cancel(&data->beacon_timer);
17321732 data->beacon_int = 0;
@@ -1735,31 +1735,31 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw, · 2 unmodified lines
17351735 }
17361736
17371737 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
1738− wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n",
1739− info->use_cts_prot);
1738+ wiphy_dbg(hw->wiphy, " ERP_CTS_PROT: %d\n",
1739+ info->use_cts_prot);
17401740 }
17411741
17421742 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
1743− wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n",
1744− info->use_short_preamble);
1743+ wiphy_dbg(hw->wiphy, " ERP_PREAMBLE: %d\n",
1744+ info->use_short_preamble);
17451745 }
17461746
17471747 if (changed & BSS_CHANGED_ERP_SLOT) {
1748− wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot);
1748+ wiphy_dbg(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot);
17491749 }
17501750
17511751 if (changed & BSS_CHANGED_HT) {
1752− wiphy_debug(hw->wiphy, " HT: op_mode=0x%x\n",
1753− info->ht_operation_mode);
1752+ wiphy_dbg(hw->wiphy, " HT: op_mode=0x%x\n",
1753+ info->ht_operation_mode);
17541754 }
17551755
17561756 if (changed & BSS_CHANGED_BASIC_RATES) {
1757− wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n",
1758− (unsigned long long) info->basic_rates);
1757+ wiphy_dbg(hw->wiphy, " BASIC_RATES: 0x%llx\n",
1758+ (unsigned long long) info->basic_rates);
17591759 }
17601760
17611761 if (changed & BSS_CHANGED_TXPOWER)
1762− wiphy_debug(hw->wiphy, " TX Power: %d dBm\n", info->txpower);
1762+ wiphy_dbg(hw->wiphy, " TX Power: %d dBm\n", info->txpower);
17631763 }
17641764
17651765 static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,
@@ -1813,11 +1813,11 @@ static int mac80211_hwsim_conf_tx( · 47 unmodified lines
18131813 struct ieee80211_vif *vif, u16 queue,
18141814 const struct ieee80211_tx_queue_params *params)
18151815 {
1816− wiphy_debug(hw->wiphy,
1817− "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
1818− __func__, queue,
1819− params->txop, params->cw_min,
1820− params->cw_max, params->aifs);
1816+ wiphy_dbg(hw->wiphy,
1817+ "%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
1818+ __func__, queue,
1819+ params->txop, params->cw_min,
1820+ params->cw_max, params->aifs);
18211821 return 0;
18221822 }
18231823
@@ -1981,7 +1981,7 @@ static void hw_scan_work(struct work_struct *work) · 157 unmodified lines
19811981 .aborted = false,
19821982 };
19831983
1984− wiphy_debug(hwsim->hw->wiphy, "hw scan complete\n");
1984+ wiphy_dbg(hwsim->hw->wiphy, "hw scan complete\n");
19851985 ieee80211_scan_completed(hwsim->hw, &info);
19861986 hwsim->hw_scan_request = NULL;
19871987 hwsim->hw_scan_vif = NULL;
@@ -1990,8 +1990,8 @@ static void hw_scan_work(struct work_struct *work) · 2 unmodified lines
19901990 return;
19911991 }
19921992
1993− wiphy_debug(hwsim->hw->wiphy, "hw scan %d MHz\n",
1994− req->channels[hwsim->scan_chan_idx]->center_freq);
1993+ wiphy_dbg(hwsim->hw->wiphy, "hw scan %d MHz\n",
1994+ req->channels[hwsim->scan_chan_idx]->center_freq);
19951995
19961996 hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx];
19971997 if (hwsim->tmp_chan->flags & (IEEE80211_CHAN_NO_IR |
@@ -2060,7 +2060,7 @@ static int mac80211_hwsim_hw_scan(struct ieee80211_hw *hw, · 62 unmodified lines
20602060 memset(hwsim->survey_data, 0, sizeof(hwsim->survey_data));
20612061 mutex_unlock(&hwsim->mutex);
20622062
2063− wiphy_debug(hw->wiphy, "hwsim hw_scan request\n");
2063+ wiphy_dbg(hw->wiphy, "hwsim hw_scan request\n");
20642064
20652065 ieee80211_queue_delayed_work(hwsim->hw, &hwsim->hw_scan, 0);
20662066
@@ -2075,7 +2075,7 @@ static void mac80211_hwsim_cancel_hw_scan(struct ieee80211_hw *hw, · 8 unmodified lines
20752075 .aborted = true,
20762076 };
20772077
2078− wiphy_debug(hw->wiphy, "hwsim cancel_hw_scan\n");
2078+ wiphy_dbg(hw->wiphy, "hwsim cancel_hw_scan\n");
20792079
20802080 cancel_delayed_work_sync(&hwsim->hw_scan);
20812081
@@ -2096,11 +2096,11 @@ static void mac80211_hwsim_sw_scan(struct ieee80211_hw *hw, · 14 unmodified lines
20962096 mutex_lock(&hwsim->mutex);
20972097
20982098 if (hwsim->scanning) {
2099− printk(KERN_DEBUG "two hwsim sw_scans detected!\n");
2099+ pr_debug("two hwsim sw_scans detected!\n");
21002100 goto out;
21012101 }
21022102
2103− printk(KERN_DEBUG "hwsim sw_scan request, prepping stuff\n");
2103+ pr_debug("hwsim sw_scan request, prepping stuff\n");
21042104
21052105 memcpy(hwsim->scan_addr, mac_addr, ETH_ALEN);
21062106 hwsim->scanning = true;
@@ -2117,7 +2117,7 @@ static void mac80211_hwsim_sw_scan_complete(struct ieee80211_hw *hw, · 10 unmodified lines
21172117
21182118 mutex_lock(&hwsim->mutex);
21192119
2120− printk(KERN_DEBUG "hwsim sw_scan_complete\n");
2120+ pr_debug("hwsim sw_scan_complete\n");
21212121 hwsim->scanning = false;
21222122 eth_zero_addr(hwsim->scan_addr);
21232123
@@ -2131,7 +2131,7 @@ static void hw_roc_start(struct work_struct *work) · 7 unmodified lines
21312131
21322132 mutex_lock(&hwsim->mutex);
21332133
2134− wiphy_debug(hwsim->hw->wiphy, "hwsim ROC begins\n");
2134+ wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC begins\n");
21352135 hwsim->tmp_chan = hwsim->roc_chan;
21362136 ieee80211_ready_on_channel(hwsim->hw);
21372137
@@ -2151,7 +2151,7 @@ static void hw_roc_done(struct work_struct *work) · 13 unmodified lines
21512151 hwsim->tmp_chan = NULL;
21522152 mutex_unlock(&hwsim->mutex);
21532153
2154− wiphy_debug(hwsim->hw->wiphy, "hwsim ROC expired\n");
2154+ wiphy_dbg(hwsim->hw->wiphy, "hwsim ROC expired\n");
21552155 }
21562156
21572157 static int mac80211_hwsim_roc(struct ieee80211_hw *hw,
@@ -2172,8 +2172,8 @@ static int mac80211_hwsim_roc(struct ieee80211_hw *hw, · 14 unmodified lines
21722172 hwsim->roc_duration = duration;
21732173 mutex_unlock(&hwsim->mutex);
21742174
2175− wiphy_debug(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
2176− chan->center_freq, duration);
2175+ wiphy_dbg(hw->wiphy, "hwsim ROC (%d MHz, %d ms)\n",
2176+ chan->center_freq, duration);
21772177 ieee80211_queue_delayed_work(hw, &hwsim->roc_start, HZ/50);
21782178
21792179 return 0;
@@ -2190,7 +2190,7 @@ static int mac80211_hwsim_croc(struct ieee80211_hw *hw) · 10 unmodified lines
21902190 hwsim->tmp_chan = NULL;
21912191 mutex_unlock(&hwsim->mutex);
21922192
2193− wiphy_debug(hw->wiphy, "hwsim ROC canceled\n");
2193+ wiphy_dbg(hw->wiphy, "hwsim ROC canceled\n");
21942194
21952195 return 0;
21962196 }
@@ -2199,20 +2199,20 @@ static int mac80211_hwsim_add_chanctx(struct ieee80211_hw *hw, · 2 unmodified lines
21992199 struct ieee80211_chanctx_conf *ctx)
22002200 {
22012201 hwsim_set_chanctx_magic(ctx);
2202− wiphy_debug(hw->wiphy,
2203− "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2204− ctx->def.chan->center_freq, ctx->def.width,
2205− ctx->def.center_freq1, ctx->def.center_freq2);
2202+ wiphy_dbg(hw->wiphy,
2203+ "add channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2204+ ctx->def.chan->center_freq, ctx->def.width,
2205+ ctx->def.center_freq1, ctx->def.center_freq2);
22062206 return 0;
22072207 }
22082208
22092209 static void mac80211_hwsim_remove_chanctx(struct ieee80211_hw *hw,
22102210 struct ieee80211_chanctx_conf *ctx)
22112211 {
2212− wiphy_debug(hw->wiphy,
2213− "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2214− ctx->def.chan->center_freq, ctx->def.width,
2215− ctx->def.center_freq1, ctx->def.center_freq2);
2212+ wiphy_dbg(hw->wiphy,
2213+ "remove channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2214+ ctx->def.chan->center_freq, ctx->def.width,
2215+ ctx->def.center_freq1, ctx->def.center_freq2);
22162216 hwsim_check_chanctx_magic(ctx);
22172217 hwsim_clear_chanctx_magic(ctx);
22182218 }
@@ -2222,10 +2222,10 @@ static void mac80211_hwsim_change_chanctx(struct ieee80211_hw *hw, · 3 unmodified lines
22222222 u32 changed)
22232223 {
22242224 hwsim_check_chanctx_magic(ctx);
2225− wiphy_debug(hw->wiphy,
2226− "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2227− ctx->def.chan->center_freq, ctx->def.width,
2228− ctx->def.center_freq1, ctx->def.center_freq2);
2225+ wiphy_dbg(hw->wiphy,
2226+ "change channel context control: %d MHz/width: %d/cfreqs:%d/%d MHz\n",
2227+ ctx->def.chan->center_freq, ctx->def.width,
2228+ ctx->def.center_freq1, ctx->def.center_freq2);
22292229 }
22302230
22312231 static int mac80211_hwsim_assign_vif_chanctx(struct ieee80211_hw *hw,
@@ -2479,7 +2479,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 247 unmodified lines
24792479 ops = &mac80211_hwsim_mchan_ops;
24802480 hw = ieee80211_alloc_hw_nm(sizeof(*data), ops, param->hwname);
24812481 if (!hw) {
2482− printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw failed\n");
2482+ pr_debug("mac80211_hwsim: ieee80211_alloc_hw failed\n");
24832483 err = -ENOMEM;
24842484 goto failed;
24852485 }
@@ -2507,7 +2507,7 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 21 unmodified lines
25072507 data->dev->driver = &mac80211_hwsim_driver.driver;
25082508 err = device_bind_driver(data->dev);
25092509 if (err != 0) {
2510− printk(KERN_DEBUG "mac80211_hwsim: device_bind_driver failed (%d)\n",
2510+ pr_debug("mac80211_hwsim: device_bind_driver failed (%d)\n",
25112511 err);
25122512 goto failed_bind;
25132513 }
@@ -2698,12 +2698,12 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, · 184 unmodified lines
26982698
26992699 err = ieee80211_register_hw(hw);
27002700 if (err < 0) {
2701− printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
2701+ pr_debug("mac80211_hwsim: ieee80211_register_hw failed (%d)\n",
27022702 err);
27032703 goto failed_hw;
27042704 }
27052705
2706− wiphy_debug(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
2706+ wiphy_dbg(hw->wiphy, "hwaddr %pM registered\n", hw->wiphy->perm_addr);
27072707
27082708 if (param->reg_alpha2) {
27092709 data->alpha2[0] = param->reg_alpha2[0];
@@ -3067,7 +3067,7 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, · 357 unmodified lines
30673067
30683068 return 0;
30693069 err:
3070− printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
3070+ pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
30713071 out:
30723072 dev_kfree_skb(skb);
30733073 return -EINVAL;
@@ -3098,7 +3098,7 @@ static int hwsim_register_received_nl(struct sk_buff *skb_2, · 24 unmodified lines
30983098
30993099 hwsim_register_wmediumd(net, info->snd_portid);
31003100
3101− printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, "
3101+ pr_debug("mac80211_hwsim: received a REGISTER, "
31023102 "switching to wmediumd mode with pid %d\n", info->snd_portid);
31033103
31043104 return 0;
@@ -3387,7 +3387,7 @@ static int __init hwsim_init_netlink(void) · 282 unmodified lines
33873387 return 0;
33883388
33893389 failure:
3390− printk(KERN_DEBUG "mac80211_hwsim: error occurred in %s\n", __func__);
3390+ pr_debug("mac80211_hwsim: error occurred in %s\n", __func__);
33913391 return -EINVAL;
33923392 }
33933393
@@ -3578,7 +3578,7 @@ module_init(init_mac80211_hwsim); · 184 unmodified lines
35783578
35793579 static void __exit exit_mac80211_hwsim(void)
35803580 {
3581− printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n");
3581+ pr_debug("mac80211_hwsim: unregister radios\n");
35823582
35833583 hwsim_exit_netlink();
35843584
include/linux/ieee80211.h+1−0
@@ -2445,6 +2445,7 @@ enum ieee80211_sa_query_action { · 2444 unmodified lines
24452445 #define WLAN_OUI_TYPE_MICROSOFT_WPA 1
24462446 #define WLAN_OUI_TYPE_MICROSOFT_WMM 2
24472447 #define WLAN_OUI_TYPE_MICROSOFT_WPS 4
2448+#define WLAN_OUI_TYPE_MICROSOFT_TPC 8
24482449
24492450 /*
24502451 * WMM/802.11e Tspec Element
include/net/cfg80211.h+21−19
@@ -4346,19 +4346,6 @@ static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, · 4345 unmodified lines
43464346 return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype);
43474347 }
43484348
4349−/**
4350− * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11
4351− * @skb: the 802.3 frame
4352− * @addr: the device MAC address
4353− * @iftype: the virtual interface type
4354− * @bssid: the network bssid (used only for iftype STATION and ADHOC)
4355− * @qos: build 802.11 QoS data frame
4356− * Return: 0 on success, or a negative error code.
4357− */
4358−int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
4359− enum nl80211_iftype iftype, const u8 *bssid,
4360− bool qos);
4361−
43624349 /**
43634350 * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame
43644351 *
@@ -5441,9 +5428,6 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid, · 1076 unmodified lines
54415428 * @req_ie_len: association request IEs length
54425429 * @resp_ie: association response IEs (may be %NULL)
54435430 * @resp_ie_len: assoc response IEs length
5444− * @authorized: true if the 802.1X authentication was done by the driver or is
5445− * not needed (e.g., when Fast Transition protocol was used), false
5446− * otherwise. Ignored for networks that don't use 802.1X authentication.
54475431 */
54485432 struct cfg80211_roam_info {
54495433 struct ieee80211_channel *channel;
@@ -5453,7 +5437,6 @@ struct cfg80211_roam_info { · 3 unmodified lines
54535437 size_t req_ie_len;
54545438 const u8 *resp_ie;
54555439 size_t resp_ie_len;
5456− bool authorized;
54575440 };
54585441
54595442 /**
@@ -5477,6 +5460,23 @@ struct cfg80211_roam_info { · 17 unmodified lines
54775460 void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
54785461 gfp_t gfp);
54795462
5463+/**
5464+ * cfg80211_port_authorized - notify cfg80211 of successful security association
5465+ *
5466+ * @dev: network device
5467+ * @bssid: the BSSID of the AP
5468+ * @gfp: allocation flags
5469+ *
5470+ * This function should be called by a driver that supports 4 way handshake
5471+ * offload after a security association was successfully established (i.e.,
5472+ * the 4 way handshake was completed successfully). The call to this function
5473+ * should be preceded with a call to cfg80211_connect_result(),
5474+ * cfg80211_connect_done(), cfg80211_connect_bss() or cfg80211_roamed() to
5475+ * indicate the 802.11 association.
5476+ */
5477+void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
5478+ gfp_t gfp);
5479+
54805480 /**
54815481 * cfg80211_disconnected - notify cfg80211 that connection was dropped
54825482 *
@@ -5934,7 +5934,8 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, · 451 unmodified lines
59345934 * @ies: the IE buffer
59355935 * @ielen: the length of the IE buffer
59365936 * @ids: an array with element IDs that are allowed before
5937− * the split
5937+ * the split. A WLAN_EID_EXTENSION value means that the next
5938+ * EID in the list is a sub-element of the EXTENSION IE.
59385939 * @n_ids: the size of the element ID array
59395940 * @after_ric: array IE types that come after the RIC element
59405941 * @n_after_ric: size of the @after_ric array
@@ -5965,7 +5966,8 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, · 24 unmodified lines
59655966 * @ies: the IE buffer
59665967 * @ielen: the length of the IE buffer
59675968 * @ids: an array with element IDs that are allowed before
5968− * the split
5969+ * the split. A WLAN_EID_EXTENSION value means that the next
5970+ * EID in the list is a sub-element of the EXTENSION IE.
59695971 * @n_ids: the size of the element ID array
59705972 * @offset: offset where to start splitting in the buffer
59715973 *
include/net/fq.h+7−0
@@ -90,6 +90,13 @@ typedef void fq_skb_free_t(struct fq *, · 89 unmodified lines
9090 struct fq_flow *,
9191 struct sk_buff *);
9292
93+/* Return %true to filter (drop) the frame. */
94+typedef bool fq_skb_filter_t(struct fq *,
95+ struct fq_tin *,
96+ struct fq_flow *,
97+ struct sk_buff *,
98+ void *);
99+
93100 typedef struct fq_flow *fq_flow_get_default_t(struct fq *,
94101 struct fq_tin *,
95102 int idx,
include/net/fq_impl.h+62−10
@@ -12,24 +12,22 @@ · 11 unmodified lines
1212
1313 /* functions that are embedded into includer */
1414
15−static struct sk_buff *fq_flow_dequeue(struct fq *fq,
16− struct fq_flow *flow)
15+static void fq_adjust_removal(struct fq *fq,
16+ struct fq_flow *flow,
17+ struct sk_buff *skb)
1718 {
1819 struct fq_tin *tin = flow->tin;
19− struct fq_flow *i;
20− struct sk_buff *skb;
21−
22− lockdep_assert_held(&fq->lock);
23−
24− skb = __skb_dequeue(&flow->queue);
25− if (!skb)
26− return NULL;
2720
2821 tin->backlog_bytes -= skb->len;
2922 tin->backlog_packets--;
3023 flow->backlog -= skb->len;
3124 fq->backlog--;
3225 fq->memory_usage -= skb->truesize;
26+}
27+
28+static void fq_rejigger_backlog(struct fq *fq, struct fq_flow *flow)
29+{
30+ struct fq_flow *i;
3331
3432 if (flow->backlog == 0) {
3533 list_del_init(&flow->backlogchain);
@@ -43,6 +41,21 @@ static struct sk_buff *fq_flow_dequeue(struct fq *fq, · 7 unmodified lines
4341 list_move_tail(&flow->backlogchain,
4442 &i->backlogchain);
4543 }
44+}
45+
46+static struct sk_buff *fq_flow_dequeue(struct fq *fq,
47+ struct fq_flow *flow)
48+{
49+ struct sk_buff *skb;
50+
51+ lockdep_assert_held(&fq->lock);
52+
53+ skb = __skb_dequeue(&flow->queue);
54+ if (!skb)
55+ return NULL;
56+
57+ fq_adjust_removal(fq, flow, skb);
58+ fq_rejigger_backlog(fq, flow);
4659
4760 return skb;
4861 }
@@ -188,6 +201,45 @@ static void fq_tin_enqueue(struct fq *fq, · 139 unmodified lines
188201 }
189202 }
190203
204+static void fq_flow_filter(struct fq *fq,
205+ struct fq_flow *flow,
206+ fq_skb_filter_t filter_func,
207+ void *filter_data,
208+ fq_skb_free_t free_func)
209+{
210+ struct fq_tin *tin = flow->tin;
211+ struct sk_buff *skb, *tmp;
212+
213+ lockdep_assert_held(&fq->lock);
214+
215+ skb_queue_walk_safe(&flow->queue, skb, tmp) {
216+ if (!filter_func(fq, tin, flow, skb, filter_data))
217+ continue;
218+
219+ __skb_unlink(skb, &flow->queue);
220+ fq_adjust_removal(fq, flow, skb);
221+ free_func(fq, tin, flow, skb);
222+ }
223+
224+ fq_rejigger_backlog(fq, flow);
225+}
226+
227+static void fq_tin_filter(struct fq *fq,
228+ struct fq_tin *tin,
229+ fq_skb_filter_t filter_func,
230+ void *filter_data,
231+ fq_skb_free_t free_func)
232+{
233+ struct fq_flow *flow;
234+
235+ lockdep_assert_held(&fq->lock);
236+
237+ list_for_each_entry(flow, &tin->new_flows, flowchain)
238+ fq_flow_filter(fq, flow, filter_func, filter_data, free_func);
239+ list_for_each_entry(flow, &tin->old_flows, flowchain)
240+ fq_flow_filter(fq, flow, filter_func, filter_data, free_func);
241+}
242+
191243 static void fq_flow_reset(struct fq *fq,
192244 struct fq_flow *flow,
193245 fq_skb_free_t free_func)
include/net/mac80211.h+7−1
@@ -5441,8 +5441,14 @@ void ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *pubsta, u8 tid, · 5440 unmodified lines
54415441 */
54425442 void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn);
54435443
5444+/**
5445+ * ieee80211_manage_rx_ba_offl - helper to queue an RX BA work
5446+ * @vif: &struct ieee80211_vif pointer from the add_interface callback
5447+ * @addr: station mac address
5448+ * @tid: the rx tid
5449+ */
54445450 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, const u8 *addr,
5445− unsigned int bit);
5451+ unsigned int tid);
54465452
54475453 /**
54485454 * ieee80211_start_rx_ba_session_offl - start a Rx BA session
include/uapi/linux/nl80211.h+65−17
@@ -569,13 +569,14 @@ · 568 unmodified lines
569569 * authentication/association or not receiving a response from the AP.
570570 * Non-zero %NL80211_ATTR_STATUS_CODE value is indicated in that case as
571571 * well to remain backwards compatible.
572− * @NL80211_CMD_ROAM: notifcation indicating the card/driver roamed by itself.
573− * When the driver roamed in a network that requires 802.1X authentication,
574− * %NL80211_ATTR_PORT_AUTHORIZED should be set if the 802.1X authentication
575− * was done by the driver or if roaming was done using Fast Transition
576− * protocol (in which case 802.1X authentication is not needed). If
577− * %NL80211_ATTR_PORT_AUTHORIZED is not set, user space is responsible for
578− * the 802.1X authentication.
572+ * When establishing a security association, drivers that support 4 way
573+ * handshake offload should send %NL80211_CMD_PORT_AUTHORIZED event when
574+ * the 4 way handshake is completed successfully.
575+ * @NL80211_CMD_ROAM: Notification indicating the card/driver roamed by itself.
576+ * When a security association was established with the new AP (e.g. if
577+ * the FT protocol was used for roaming or the driver completed the 4 way
578+ * handshake), this event should be followed by an
579+ * %NL80211_CMD_PORT_AUTHORIZED event.
579580 * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify
580581 * userspace that a connection was dropped by the AP or due to other
581582 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
@@ -982,6 +983,14 @@ · 400 unmodified lines
982983 * @NL80211_CMD_DEL_PMK: For offloaded 4-Way handshake, delete the previously
983984 * configured PMK for the authenticator address identified by
984985 * &NL80211_ATTR_MAC.
986+ * @NL80211_CMD_PORT_AUTHORIZED: An event that indicates that the 4 way
987+ * handshake was completed successfully by the driver. The BSSID is
988+ * specified with &NL80211_ATTR_MAC. Drivers that support 4 way handshake
989+ * offload should send this event after indicating 802.11 association with
990+ * &NL80211_CMD_CONNECT or &NL80211_CMD_ROAM. If the 4 way handshake failed
991+ * &NL80211_CMD_DISCONNECT should be indicated instead.
992+ *
993+ * @NL80211_CMD_RELOAD_REGDB: Request that the regdb firmware file is reloaded.
985994 *
986995 * @NL80211_CMD_MAX: highest used command number
987996 * @__NL80211_CMD_AFTER_LAST: internal use
@@ -1185,6 +1194,10 @@ enum nl80211_commands { · 197 unmodified lines
11851194 NL80211_CMD_SET_PMK,
11861195 NL80211_CMD_DEL_PMK,
11871196
1197+ NL80211_CMD_PORT_AUTHORIZED,
1198+
1199+ NL80211_CMD_RELOAD_REGDB,
1200+
11881201 /* add new commands above here */
11891202
11901203 /* used to define NL80211_CMD_MAX below */
@@ -1407,8 +1420,12 @@ enum nl80211_commands { · 216 unmodified lines
14071420 *
14081421 * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
14091422 * used for the association (&enum nl80211_mfp, represented as a u32);
1410− * this attribute can be used
1411− * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests
1423+ * this attribute can be used with %NL80211_CMD_ASSOCIATE and
1424+ * %NL80211_CMD_CONNECT requests. %NL80211_MFP_OPTIONAL is not allowed for
1425+ * %NL80211_CMD_ASSOCIATE since user space SME is expected and hence, it
1426+ * must have decided whether to use management frame protection or not.
1427+ * Setting %NL80211_MFP_OPTIONAL with a %NL80211_CMD_CONNECT request will
1428+ * let the driver (or the firmware) decide whether to use MFP or not.
14121429 *
14131430 * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
14141431 * &struct nl80211_sta_flag_update.
@@ -2134,10 +2151,7 @@ enum nl80211_commands { · 719 unmodified lines
21342151 * in %NL80211_CMD_CONNECT to indicate that for 802.1X authentication it
21352152 * wants to use the supported offload of the 4-way handshake.
21362153 * @NL80211_ATTR_PMKR0_NAME: PMK-R0 Name for offloaded FT.
2137− * @NL80211_ATTR_PORT_AUTHORIZED: flag attribute used in %NL80211_CMD_ROAMED
2138− * notification indicating that that 802.1X authentication was done by
2139− * the driver or is not needed (because roaming used the Fast Transition
2140− * protocol).
2154+ * @NL80211_ATTR_PORT_AUTHORIZED: (reserved)
21412155 *
21422156 * @NUM_NL80211_ATTR: total number of nl80211_attrs available
21432157 * @NL80211_ATTR_MAX: highest attribute number currently defined
@@ -3947,10 +3961,12 @@ enum nl80211_key_type { · 1803 unmodified lines
39473961 * enum nl80211_mfp - Management frame protection state
39483962 * @NL80211_MFP_NO: Management frame protection not used
39493963 * @NL80211_MFP_REQUIRED: Management frame protection required
3964+ * @NL80211_MFP_OPTIONAL: Management frame protection is optional
39503965 */
39513966 enum nl80211_mfp {
39523967 NL80211_MFP_NO,
39533968 NL80211_MFP_REQUIRED,
3969+ NL80211_MFP_OPTIONAL,
39543970 };
39553971
39563972 enum nl80211_wpa_versions {
@@ -4914,6 +4930,17 @@ enum nl80211_feature_flags { · 957 unmodified lines
49144930 * handshake with 802.1X in station mode (will pass EAP frames to the host
49154931 * and accept the set_pmk/del_pmk commands), doing it in the host might not
49164932 * be supported.
4933+ * @NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME: Driver is capable of overriding
4934+ * the max channel attribute in the FILS request params IE with the
4935+ * actual dwell time.
4936+ * @NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP: Driver accepts broadcast probe
4937+ * response
4938+ * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE: Driver supports sending
4939+ * the first probe request in each channel at rate of at least 5.5Mbps.
4940+ * @NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: Driver supports
4941+ * probe request tx deferral and suppression
4942+ * @NL80211_EXT_FEATURE_MFP_OPTIONAL: Driver supports the %NL80211_MFP_OPTIONAL
4943+ * value in %NL80211_ATTR_USE_MFP.
49174944 *
49184945 * @NUM_NL80211_EXT_FEATURES: number of extended features.
49194946 * @MAX_NL80211_EXT_FEATURES: highest extended feature index.
@@ -4936,6 +4963,11 @@ enum nl80211_ext_feature_index { · 16 unmodified lines
49364963 NL80211_EXT_FEATURE_FILS_SK_OFFLOAD,
49374964 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
49384965 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
4966+ NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
4967+ NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
4968+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
4969+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
4970+ NL80211_EXT_FEATURE_MFP_OPTIONAL,
49394971
49404972 /* add new features before the definition below */
49414973 NUM_NL80211_EXT_FEATURES,
@@ -5012,12 +5044,28 @@ enum nl80211_timeout_reason { · 70 unmodified lines
50125044 * locally administered 1, multicast 0) is assumed.
50135045 * This flag must not be requested when the feature isn't supported, check
50145046 * the nl80211 feature flags for the device.
5047+ * @NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME: fill the dwell time in the FILS
5048+ * request parameters IE in the probe request
5049+ * @NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP: accept broadcast probe responses
5050+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE: send probe request frames at
5051+ * rate of at least 5.5M. In case non OCE AP is dicovered in the channel,
5052+ * only the first probe req in the channel will be sent in high rate.
5053+ * @NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION: allow probe request
5054+ * tx deferral (dot11FILSProbeDelay shall be set to 15ms)
5055+ * and suppression (if it has received a broadcast Probe Response frame,
5056+ * Beacon frame or FILS Discovery frame from an AP that the STA considers
5057+ * a suitable candidate for (re-)association - suitable in terms of
5058+ * SSID and/or RSSI
50155059 */
50165060 enum nl80211_scan_flags {
5017− NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
5018− NL80211_SCAN_FLAG_FLUSH = 1<<1,
5019− NL80211_SCAN_FLAG_AP = 1<<2,
5020− NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3,
5061+ NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
5062+ NL80211_SCAN_FLAG_FLUSH = 1<<1,
5063+ NL80211_SCAN_FLAG_AP = 1<<2,
5064+ NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3,
5065+ NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME = 1<<4,
5066+ NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP = 1<<5,
5067+ NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE = 1<<6,
5068+ NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION = 1<<7,
50215069 };
50225070
50235071 /**
net/mac80211/Makefile+1−2
@@ -6,6 +6,7 @@ mac80211-y := \ · 5 unmodified lines
66 driver-ops.o \
77 sta_info.o \
88 wep.o \
9+ aead_api.o \
910 wpa.o \
1011 scan.o offchannel.o \
1112 ht.o agg-tx.o agg-rx.o \
@@ -15,8 +16,6 @@ mac80211-y := \ · 3 unmodified lines
1516 rate.o \
1617 michael.o \
1718 tkip.o \
18− aes_ccm.o \
19− aes_gcm.o \
2019 aes_cmac.o \
2120 aes_gmac.o \
2221 fils_aead.o \
net/mac80211/aead_api.crenamed from net/mac80211/aes_ccm.c+20−20
@@ -1,6 +1,7 @@
11 /*
22 * Copyright 2003-2004, Instant802 Networks, Inc.
33 * Copyright 2005-2006, Devicescape Software, Inc.
4+ * Copyright 2014-2015, Qualcomm Atheros, Inc.
45 *
56 * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
67 *
@@ -12,30 +13,29 @@ · 5 unmodified lines
1213 #include <linux/kernel.h>
1314 #include <linux/types.h>
1415 #include <linux/err.h>
16+#include <linux/scatterlist.h>
1517 #include <crypto/aead.h>
1618
17−#include <net/mac80211.h>
18−#include "key.h"
19−#include "aes_ccm.h"
19+#include "aead_api.h"
2020
21−int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
22− u8 *data, size_t data_len, u8 *mic,
23− size_t mic_len)
21+int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
22+ u8 *data, size_t data_len, u8 *mic)
2423 {
24+ size_t mic_len = tfm->authsize;
2525 struct scatterlist sg[3];
2626 struct aead_request *aead_req;
2727 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
2828 u8 *__aad;
2929
30− aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
30+ aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
3131 if (!aead_req)
3232 return -ENOMEM;
3333
3434 __aad = (u8 *)aead_req + reqsize;
35− memcpy(__aad, aad, CCM_AAD_LEN);
35+ memcpy(__aad, aad, aad_len);
3636
3737 sg_init_table(sg, 3);
38− sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
38+ sg_set_buf(&sg[0], __aad, aad_len);
3939 sg_set_buf(&sg[1], data, data_len);
4040 sg_set_buf(&sg[2], mic, mic_len);
4141
@@ -49,10 +49,10 @@ int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 7 unmodified lines
4949 return 0;
5050 }
5151
52−int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
53− u8 *data, size_t data_len, u8 *mic,
54− size_t mic_len)
52+int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, size_t aad_len,
53+ u8 *data, size_t data_len, u8 *mic)
5554 {
55+ size_t mic_len = tfm->authsize;
5656 struct scatterlist sg[3];
5757 struct aead_request *aead_req;
5858 int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
@@ -62,15 +62,15 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 3 unmodified lines
6262 if (data_len == 0)
6363 return -EINVAL;
6464
65− aead_req = kzalloc(reqsize + CCM_AAD_LEN, GFP_ATOMIC);
65+ aead_req = kzalloc(reqsize + aad_len, GFP_ATOMIC);
6666 if (!aead_req)
6767 return -ENOMEM;
6868
6969 __aad = (u8 *)aead_req + reqsize;
70− memcpy(__aad, aad, CCM_AAD_LEN);
70+ memcpy(__aad, aad, aad_len);
7171
7272 sg_init_table(sg, 3);
73− sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
73+ sg_set_buf(&sg[0], __aad, aad_len);
7474 sg_set_buf(&sg[1], data, data_len);
7575 sg_set_buf(&sg[2], mic, mic_len);
7676
@@ -84,14 +84,14 @@ int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad, · 7 unmodified lines
8484 return err;
8585 }
8686
87−struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
88− size_t key_len,
89− size_t mic_len)
87+struct crypto_aead *
88+aead_key_setup_encrypt(const char *alg, const u8 key[],
89+ size_t key_len, size_t mic_len)
9090 {
9191 struct crypto_aead *tfm;
9292 int err;
9393
94− tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
94+ tfm = crypto_alloc_aead(alg, 0, CRYPTO_ALG_ASYNC);
9595 if (IS_ERR(tfm))
9696 return tfm;
9797
@@ -109,7 +109,7 @@ free_aead: · 11 unmodified lines
109109 return ERR_PTR(err);
110110 }
111111
112−void ieee80211_aes_key_free(struct crypto_aead *tfm)
112+void aead_key_free(struct crypto_aead *tfm)
113113 {
114114 crypto_free_aead(tfm);
115115 }
net/mac80211/aead_api.h+27−0
@@ -0,0 +1,27 @@
1+/*
2+ * This program is free software; you can redistribute it and/or modify
3+ * it under the terms of the GNU General Public License version 2 as
4+ * published by the Free Software Foundation.
5+ */
6+
7+#ifndef _AEAD_API_H
8+#define _AEAD_API_H
9+
10+#include <crypto/aead.h>
11+#include <linux/crypto.h>
12+
13+struct crypto_aead *
14+aead_key_setup_encrypt(const char *alg, const u8 key[],
15+ size_t key_len, size_t mic_len);
16+
17+int aead_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
18+ size_t aad_len, u8 *data,
19+ size_t data_len, u8 *mic);
20+
21+int aead_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
22+ size_t aad_len, u8 *data,
23+ size_t data_len, u8 *mic);
24+
25+void aead_key_free(struct crypto_aead *tfm);
26+
27+#endif /* _AEAD_API_H */
net/mac80211/aes_ccm.h+31−11
@@ -10,19 +10,39 @@ · 9 unmodified lines
1010 #ifndef AES_CCM_H
1111 #define AES_CCM_H
1212
13−#include <linux/crypto.h>
13+#include "aead_api.h"
1414
1515 #define CCM_AAD_LEN 32
1616
17−struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[],
18− size_t key_len,
19− size_t mic_len);
20−int ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
21− u8 *data, size_t data_len, u8 *mic,
22− size_t mic_len);
23−int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
24− u8 *data, size_t data_len, u8 *mic,
25− size_t mic_len);
26−void ieee80211_aes_key_free(struct crypto_aead *tfm);
17+static inline struct crypto_aead *
18+ieee80211_aes_key_setup_encrypt(const u8 key[], size_t key_len, size_t mic_len)
19+{
20+ return aead_key_setup_encrypt("ccm(aes)", key, key_len, mic_len);
21+}
22+
23+static inline int
24+ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm,
25+ u8 *b_0, u8 *aad, u8 *data,
26+ size_t data_len, u8 *mic)
27+{
28+ return aead_encrypt(tfm, b_0, aad + 2,
29+ be16_to_cpup((__be16 *)aad),
30+ data, data_len, mic);
31+}
32+
33+static inline int
34+ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm,
35+ u8 *b_0, u8 *aad, u8 *data,
36+ size_t data_len, u8 *mic)
37+{
38+ return aead_decrypt(tfm, b_0, aad + 2,
39+ be16_to_cpup((__be16 *)aad),
40+ data, data_len, mic);
41+}
42+
43+static inline void ieee80211_aes_key_free(struct crypto_aead *tfm)
44+{
45+ return aead_key_free(tfm);
46+}
2747
2848 #endif /* AES_CCM_H */
net/mac80211/aes_gcm.c+0−109
@@ -1,109 +0,0 @@
1−/*
2− * Copyright 2014-2015, Qualcomm Atheros, Inc.
3− *
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License version 2 as
6− * published by the Free Software Foundation.
7− */
8−
9−#include <linux/kernel.h>
10−#include <linux/types.h>
11−#include <linux/err.h>
12−#include <crypto/aead.h>
13−
14−#include <net/mac80211.h>
15−#include "key.h"
16−#include "aes_gcm.h"
17−
18−int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
19− u8 *data, size_t data_len, u8 *mic)
20−{
21− struct scatterlist sg[3];
22− struct aead_request *aead_req;
23− int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
24− u8 *__aad;
25−
26− aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
27− if (!aead_req)
28− return -ENOMEM;
29−
30− __aad = (u8 *)aead_req + reqsize;
31− memcpy(__aad, aad, GCM_AAD_LEN);
32−
33− sg_init_table(sg, 3);
34− sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
35− sg_set_buf(&sg[1], data, data_len);
36− sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
37−
38− aead_request_set_tfm(aead_req, tfm);
39− aead_request_set_crypt(aead_req, sg, sg, data_len, j_0);
40− aead_request_set_ad(aead_req, sg[0].length);
41−
42− crypto_aead_encrypt(aead_req);
43− kzfree(aead_req);
44− return 0;
45−}
46−
47−int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
48− u8 *data, size_t data_len, u8 *mic)
49−{
50− struct scatterlist sg[3];
51− struct aead_request *aead_req;
52− int reqsize = sizeof(*aead_req) + crypto_aead_reqsize(tfm);
53− u8 *__aad;
54− int err;
55−
56− if (data_len == 0)
57− return -EINVAL;
58−
59− aead_req = kzalloc(reqsize + GCM_AAD_LEN, GFP_ATOMIC);
60− if (!aead_req)
61− return -ENOMEM;
62−
63− __aad = (u8 *)aead_req + reqsize;
64− memcpy(__aad, aad, GCM_AAD_LEN);
65−
66− sg_init_table(sg, 3);
67− sg_set_buf(&sg[0], &__aad[2], be16_to_cpup((__be16 *)__aad));
68− sg_set_buf(&sg[1], data, data_len);
69− sg_set_buf(&sg[2], mic, IEEE80211_GCMP_MIC_LEN);
70−
71− aead_request_set_tfm(aead_req, tfm);
72− aead_request_set_crypt(aead_req, sg, sg,
73− data_len + IEEE80211_GCMP_MIC_LEN, j_0);
74− aead_request_set_ad(aead_req, sg[0].length);
75−
76− err = crypto_aead_decrypt(aead_req);
77− kzfree(aead_req);
78−
79− return err;
80−}
81−
82−struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
83− size_t key_len)
84−{
85− struct crypto_aead *tfm;
86− int err;
87−
88− tfm = crypto_alloc_aead("gcm(aes)", 0, CRYPTO_ALG_ASYNC);
89− if (IS_ERR(tfm))
90− return tfm;
91−
92− err = crypto_aead_setkey(tfm, key, key_len);
93− if (err)
94− goto free_aead;
95− err = crypto_aead_setauthsize(tfm, IEEE80211_GCMP_MIC_LEN);
96− if (err)
97− goto free_aead;
98−
99− return tfm;
100−
101−free_aead:
102− crypto_free_aead(tfm);
103− return ERR_PTR(err);
104−}
105−
106−void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
107−{
108− crypto_free_aead(tfm);
109−}
net/mac80211/aes_gcm.h+30−8
@@ -9,16 +9,38 @@ · 8 unmodified lines
99 #ifndef AES_GCM_H
1010 #define AES_GCM_H
1111
12−#include <linux/crypto.h>
12+#include "aead_api.h"
1313
1414 #define GCM_AAD_LEN 32
1515
16−int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
17− u8 *data, size_t data_len, u8 *mic);
18−int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm, u8 *j_0, u8 *aad,
19− u8 *data, size_t data_len, u8 *mic);
20−struct crypto_aead *ieee80211_aes_gcm_key_setup_encrypt(const u8 key[],
21− size_t key_len);
22−void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm);
16+static inline int ieee80211_aes_gcm_encrypt(struct crypto_aead *tfm,
17+ u8 *j_0, u8 *aad, u8 *data,
18+ size_t data_len, u8 *mic)
19+{
20+ return aead_encrypt(tfm, j_0, aad + 2,
21+ be16_to_cpup((__be16 *)aad),
22+ data, data_len, mic);
23+}
24+
25+static inline int ieee80211_aes_gcm_decrypt(struct crypto_aead *tfm,
26+ u8 *j_0, u8 *aad, u8 *data,
27+ size_t data_len, u8 *mic)
28+{
29+ return aead_decrypt(tfm, j_0, aad + 2,
30+ be16_to_cpup((__be16 *)aad),
31+ data, data_len, mic);
32+}
33+
34+static inline struct crypto_aead *
35+ieee80211_aes_gcm_key_setup_encrypt(const u8 key[], size_t key_len)
36+{
37+ return aead_key_setup_encrypt("gcm(aes)", key,
38+ key_len, IEEE80211_GCMP_MIC_LEN);
39+}
40+
41+static inline void ieee80211_aes_gcm_key_free(struct crypto_aead *tfm)
42+{
43+ return aead_key_free(tfm);
44+}
2345
2446 #endif /* AES_GCM_H */
net/mac80211/agg-rx.c+2−2
@@ -459,7 +459,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, · 458 unmodified lines
459459 }
460460
461461 void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
462− const u8 *addr, unsigned int bit)
462+ const u8 *addr, unsigned int tid)
463463 {
464464 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
465465 struct ieee80211_local *local = sdata->local;
@@ -470,7 +470,7 @@ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif, · 4 unmodified lines
470470 if (!sta)
471471 goto unlock;
472472
473− set_bit(bit, sta->ampdu_mlme.tid_rx_manage_offl);
473+ set_bit(tid, sta->ampdu_mlme.tid_rx_manage_offl);
474474 ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
475475 unlock:
476476 rcu_read_unlock();
net/mac80211/ht.c+7−5
@@ -290,13 +290,15 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, · 289 unmodified lines
290290 {
291291 int i;
292292
293+ mutex_lock(&sta->ampdu_mlme.mtx);
293294 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
294− __ieee80211_stop_tx_ba_session(sta, i, reason);
295− __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
296− WLAN_REASON_QSTA_LEAVE_QBSS,
297− reason != AGG_STOP_DESTROY_STA &&
298− reason != AGG_STOP_PEER_REQUEST);
295+ ___ieee80211_stop_tx_ba_session(sta, i, reason);
296+ ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
297+ WLAN_REASON_QSTA_LEAVE_QBSS,
298+ reason != AGG_STOP_DESTROY_STA &&
299+ reason != AGG_STOP_PEER_REQUEST);
299300 }
301+ mutex_unlock(&sta->ampdu_mlme.mtx);
300302
301303 /* stopping might queue the work again - so cancel only afterwards */
302304 cancel_work_sync(&sta->ampdu_mlme.work);
net/mac80211/ieee80211_i.h+2−0
@@ -2009,6 +2009,8 @@ void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata, · 2008 unmodified lines
20092009 struct txq_info *txq, int tid);
20102010 void ieee80211_txq_purge(struct ieee80211_local *local,
20112011 struct txq_info *txqi);
2012+void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
2013+ struct ieee80211_sub_if_data *sdata);
20122014 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
20132015 u16 transaction, u16 auth_alg, u16 status,
20142016 const u8 *extra, size_t extra_len, const u8 *bssid,
net/mac80211/iface.c+6−23
@@ -793,9 +793,7 @@ static int ieee80211_open(struct net_device *dev) · 792 unmodified lines
793793 static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
794794 bool going_down)
795795 {
796− struct ieee80211_sub_if_data *txq_sdata = sdata;
797796 struct ieee80211_local *local = sdata->local;
798− struct fq *fq = &local->fq;
799797 unsigned long flags;
800798 struct sk_buff *skb, *tmp;
801799 u32 hw_reconf_flags = 0;
@@ -939,9 +937,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 137 unmodified lines
939937
940938 switch (sdata->vif.type) {
941939 case NL80211_IFTYPE_AP_VLAN:
942− txq_sdata = container_of(sdata->bss,
943− struct ieee80211_sub_if_data, u.ap);
944−
945940 mutex_lock(&local->mtx);
946941 list_del(&sdata->u.vlan.list);
947942 mutex_unlock(&local->mtx);
@@ -998,8 +993,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 50 unmodified lines
998993 skb_queue_purge(&sdata->skb_queue);
999994 }
1000995
1001− sdata->bss = NULL;
1002−
1003996 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1004997 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
1005998 skb_queue_walk_safe(&local->pending[i], skb, tmp) {
@@ -1012,22 +1005,10 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, · 6 unmodified lines
10121005 }
10131006 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
10141007
1015− if (txq_sdata->vif.txq) {
1016− struct txq_info *txqi = to_txq_info(txq_sdata->vif.txq);
1017−
1018− /*
1019− * FIXME FIXME
1020− *
1021− * We really shouldn't purge the *entire* txqi since that
1022− * contains frames for the other AP_VLANs (and possibly
1023− * the AP itself) as well, but there's no API in FQ now
1024− * to be able to filter.
1025− */
1008+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1009+ ieee80211_txq_remove_vlan(local, sdata);
10261010
1027− spin_lock_bh(&fq->lock);
1028− ieee80211_txq_purge(local, txqi);
1029− spin_unlock_bh(&fq->lock);
1030− }
1011+ sdata->bss = NULL;
10311012
10321013 if (local->open_count == 0)
10331014 ieee80211_clear_tx_pending(local);
@@ -1772,7 +1753,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, · 738 unmodified lines
17721753 sizeof(void *));
17731754 int txq_size = 0;
17741755
1775− if (local->ops->wake_tx_queue)
1756+ if (local->ops->wake_tx_queue &&
1757+ type != NL80211_IFTYPE_AP_VLAN &&
1758+ type != NL80211_IFTYPE_MONITOR)
17761759 txq_size += sizeof(struct txq_info) +
17771760 local->hw.txq_data_size;
17781761
net/mac80211/mesh.c+1−2
@@ -675,8 +675,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh) · 674 unmodified lines
675675 enum nl80211_band band;
676676 u8 *pos;
677677 struct ieee80211_sub_if_data *sdata;
678− int hdr_len = offsetof(struct ieee80211_mgmt, u.beacon) +
679− sizeof(mgmt->u.beacon);
678+ int hdr_len = offsetofend(struct ieee80211_mgmt, u.beacon);
680679
681680 sdata = container_of(ifmsh, struct ieee80211_sub_if_data, u.mesh);
682681 rcu_read_lock();
net/mac80211/mesh.h+1−0
@@ -275,6 +275,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, · 274 unmodified lines
275275 u8 *hw_addr, struct ieee802_11_elems *ie);
276276 bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
277277 u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
278+void mesh_plink_timer(struct timer_list *t);
278279 void mesh_plink_broken(struct sta_info *sta);
279280 u32 mesh_plink_deactivate(struct sta_info *sta);
280281 u32 mesh_plink_open(struct sta_info *sta);
net/mac80211/mesh_hwmp.c+4−4
@@ -111,8 +111,8 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, · 110 unmodified lines
111111 struct sk_buff *skb;
112112 struct ieee80211_mgmt *mgmt;
113113 u8 *pos, ie_len;
114− int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
115− sizeof(mgmt->u.action.u.mesh_action);
114+ int hdr_len = offsetofend(struct ieee80211_mgmt,
115+ u.action.u.mesh_action);
116116
117117 skb = dev_alloc_skb(local->tx_headroom +
118118 hdr_len +
@@ -242,8 +242,8 @@ int mesh_path_error_tx(struct ieee80211_sub_if_data *sdata, · 123 unmodified lines
242242 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
243243 struct ieee80211_mgmt *mgmt;
244244 u8 *pos, ie_len;
245− int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.mesh_action) +
246− sizeof(mgmt->u.action.u.mesh_action);
245+ int hdr_len = offsetofend(struct ieee80211_mgmt,
246+ u.action.u.mesh_action);
247247
248248 if (time_before(jiffies, ifmsh->next_perr))
249249 return -EAGAIN;
net/mac80211/mesh_plink.c+5−8
@@ -220,8 +220,7 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, · 219 unmodified lines
220220 bool include_plid = false;
221221 u16 peering_proto = 0;
222222 u8 *pos, ie_len = 4;
223− int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.self_prot) +
224− sizeof(mgmt->u.action.u.self_prot);
223+ int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
225224 int err = -ENOMEM;
226225
227226 skb = dev_alloc_skb(local->tx_headroom +
@@ -604,8 +603,9 @@ out: · 376 unmodified lines
604603 ieee80211_mbss_info_change_notify(sdata, changed);
605604 }
606605
607−static void mesh_plink_timer(unsigned long data)
606+void mesh_plink_timer(struct timer_list *t)
608607 {
608+ struct mesh_sta *mesh = from_timer(mesh, t, plink_timer);
609609 struct sta_info *sta;
610610 u16 reason = 0;
611611 struct ieee80211_sub_if_data *sdata;
@@ -617,7 +617,7 @@ static void mesh_plink_timer(unsigned long data) · 5 unmodified lines
617617 * del_timer_sync() this timer after having made sure
618618 * it cannot be readded (by deleting the plink.)
619619 */
620− sta = (struct sta_info *) data;
620+ sta = mesh->plink_sta;
621621
622622 if (sta->sdata->local->quiescing)
623623 return;
@@ -697,11 +697,8 @@ static void mesh_plink_timer(unsigned long data) · 73 unmodified lines
697697
698698 static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)
699699 {
700− sta->mesh->plink_timer.expires = jiffies + msecs_to_jiffies(timeout);
701− sta->mesh->plink_timer.data = (unsigned long) sta;
702− sta->mesh->plink_timer.function = mesh_plink_timer;
703700 sta->mesh->plink_timeout = timeout;
704− add_timer(&sta->mesh->plink_timer);
701+ mod_timer(&sta->mesh->plink_timer, jiffies + msecs_to_jiffies(timeout));
705702 }
706703
707704 static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
net/mac80211/mlme.c+7−12
@@ -780,11 +780,12 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) · 779 unmodified lines
780780 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
781781 WLAN_EID_HT_CAPABILITY,
782782 WLAN_EID_BSS_COEX_2040,
783+ /* luckily this is almost always there */
783784 WLAN_EID_EXT_CAPABILITY,
784785 WLAN_EID_QOS_TRAFFIC_CAPA,
785786 WLAN_EID_TIM_BCAST_REQ,
786787 WLAN_EID_INTERWORKING,
787− /* 60GHz doesn't happen right now */
788+ /* 60 GHz (Multi-band, DMG, MMS) can't happen */
788789 WLAN_EID_VHT_CAPABILITY,
789790 WLAN_EID_OPMODE_NOTIF,
790791 };
@@ -811,22 +812,16 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) · 20 unmodified lines
811812 /* if present, add any custom IEs that go before VHT */
812813 if (assoc_data->ie_len) {
813814 static const u8 before_vht[] = {
814− WLAN_EID_SSID,
815− WLAN_EID_SUPP_RATES,
816− WLAN_EID_EXT_SUPP_RATES,
817− WLAN_EID_PWR_CAPABILITY,
818− WLAN_EID_SUPPORTED_CHANNELS,
819− WLAN_EID_RSN,
820− WLAN_EID_QOS_CAPA,
821− WLAN_EID_RRM_ENABLED_CAPABILITIES,
822− WLAN_EID_MOBILITY_DOMAIN,
823− WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
824− WLAN_EID_HT_CAPABILITY,
815+ /*
816+ * no need to list the ones split off before HT
817+ * or generated here
818+ */
825819 WLAN_EID_BSS_COEX_2040,
826820 WLAN_EID_EXT_CAPABILITY,
827821 WLAN_EID_QOS_TRAFFIC_CAPA,
828822 WLAN_EID_TIM_BCAST_REQ,
829823 WLAN_EID_INTERWORKING,
824+ /* 60 GHz (Multi-band, DMG, MMS) can't happen */
830825 };
831826
832827 /* RIC already taken above, so no need to handle here anymore */
net/mac80211/scan.c+28−9
@@ -7,7 +7,7 @@ · 6 unmodified lines
77 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
88 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
99 * Copyright 2013-2015 Intel Mobile Communications GmbH
10− * Copyright 2016 Intel Deutschland GmbH
10+ * Copyright 2016-2017 Intel Deutschland GmbH
1111 *
1212 * This program is free software; you can redistribute it and/or modify
1313 * it under the terms of the GNU General Public License version 2 as
@@ -183,6 +183,20 @@ ieee80211_bss_info_update(struct ieee80211_local *local, · 169 unmodified lines
183183 return bss;
184184 }
185185
186+static bool ieee80211_scan_accept_presp(struct ieee80211_sub_if_data *sdata,
187+ u32 scan_flags, const u8 *da)
188+{
189+ if (!sdata)
190+ return false;
191+ /* accept broadcast for OCE */
192+ if (scan_flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP &&
193+ is_broadcast_ether_addr(da))
194+ return true;
195+ if (scan_flags & NL80211_SCAN_FLAG_RANDOM_ADDR)
196+ return true;
197+ return ether_addr_equal(da, sdata->vif.addr);
198+}
199+
186200 void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb)
187201 {
188202 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb);
@@ -208,19 +222,24 @@ void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) · 19 unmodified lines
208222 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
209223 struct cfg80211_scan_request *scan_req;
210224 struct cfg80211_sched_scan_request *sched_scan_req;
225+ u32 scan_req_flags = 0, sched_scan_req_flags = 0;
211226
212227 scan_req = rcu_dereference(local->scan_req);
213228 sched_scan_req = rcu_dereference(local->sched_scan_req);
214229
215− /* ignore ProbeResp to foreign address unless scanning
216− * with randomised address
230+ if (scan_req)
231+ scan_req_flags = scan_req->flags;
232+
233+ if (sched_scan_req)
234+ sched_scan_req_flags = sched_scan_req->flags;
235+
236+ /* ignore ProbeResp to foreign address or non-bcast (OCE)
237+ * unless scanning with randomised address
217238 */
218− if (!(sdata1 &&
219− (ether_addr_equal(mgmt->da, sdata1->vif.addr) ||
220− scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) &&
221− !(sdata2 &&
222− (ether_addr_equal(mgmt->da, sdata2->vif.addr) ||
223− sched_scan_req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)))
239+ if (!ieee80211_scan_accept_presp(sdata1, scan_req_flags,
240+ mgmt->da) &&
241+ !ieee80211_scan_accept_presp(sdata2, sched_scan_req_flags,
242+ mgmt->da))
224243 return;
225244
226245 elements = mgmt->u.probe_resp.variable;
net/mac80211/sta_info.c+35−26
@@ -329,10 +329,12 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, · 328 unmodified lines
329329 sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
330330 if (!sta->mesh)
331331 goto free;
332+ sta->mesh->plink_sta = sta;
332333 spin_lock_init(&sta->mesh->plink_lock);
333334 if (ieee80211_vif_is_mesh(&sdata->vif) &&
334335 !sdata->u.mesh.user_mpm)
335− init_timer(&sta->mesh->plink_timer);
336+ timer_setup(&sta->mesh->plink_timer, mesh_plink_timer,
337+ 0);
336338 sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
337339 }
338340 #endif
@@ -515,6 +517,31 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, · 176 unmodified lines
515517 return err;
516518 }
517519
520+static void
521+ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
522+{
523+ struct ieee80211_local *local = sdata->local;
524+ bool allow_p2p_go_ps = sdata->vif.p2p;
525+ struct sta_info *sta;
526+
527+ rcu_read_lock();
528+ list_for_each_entry_rcu(sta, &local->sta_list, list) {
529+ if (sdata != sta->sdata ||
530+ !test_sta_flag(sta, WLAN_STA_ASSOC))
531+ continue;
532+ if (!sta->sta.support_p2p_ps) {
533+ allow_p2p_go_ps = false;
534+ break;
535+ }
536+ }
537+ rcu_read_unlock();
538+
539+ if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
540+ sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
541+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
542+ }
543+}
544+
518545 /*
519546 * should be called with sta_mtx locked
520547 * this function replaces the mutex lock
@@ -561,6 +588,13 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) · 40 unmodified lines
561588 goto out_remove;
562589
563590 set_sta_flag(sta, WLAN_STA_INSERTED);
591+
592+ if (sta->sta_state >= IEEE80211_STA_ASSOC) {
593+ ieee80211_recalc_min_chandef(sta->sdata);
594+ if (!sta->sta.support_p2p_ps)
595+ ieee80211_recalc_p2p_go_ps_allowed(sta->sdata);
596+ }
597+
564598 /* accept BA sessions now */
565599 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
566600
@@ -1788,31 +1822,6 @@ void ieee80211_sta_set_buffered(struct ieee80211_sta *pubsta, · 1221 unmodified lines
17881822 }
17891823 EXPORT_SYMBOL(ieee80211_sta_set_buffered);
17901824
1791−static void
1792−ieee80211_recalc_p2p_go_ps_allowed(struct ieee80211_sub_if_data *sdata)
1793−{
1794− struct ieee80211_local *local = sdata->local;
1795− bool allow_p2p_go_ps = sdata->vif.p2p;
1796− struct sta_info *sta;
1797−
1798− rcu_read_lock();
1799− list_for_each_entry_rcu(sta, &local->sta_list, list) {
1800− if (sdata != sta->sdata ||
1801− !test_sta_flag(sta, WLAN_STA_ASSOC))
1802− continue;
1803− if (!sta->sta.support_p2p_ps) {
1804− allow_p2p_go_ps = false;
1805− break;
1806− }
1807− }
1808− rcu_read_unlock();
1809−
1810− if (allow_p2p_go_ps != sdata->vif.bss_conf.allow_p2p_go_ps) {
1811− sdata->vif.bss_conf.allow_p2p_go_ps = allow_p2p_go_ps;
1812− ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_P2P_PS);
1813− }
1814−}
1815−
18161825 int sta_info_move_state(struct sta_info *sta,
18171826 enum ieee80211_sta_state new_state)
18181827 {
net/mac80211/sta_info.h+3−1
@@ -344,6 +344,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8) · 343 unmodified lines
344344 * @plink_state: peer link state
345345 * @plink_timeout: timeout of peer link
346346 * @plink_timer: peer link watch timer
347+ * @plink_sta: peer link watch timer's sta_info
347348 * @t_offset: timing offset relative to this host
348349 * @t_offset_setpoint: reference timing offset of this sta to be used when
349350 * calculating clockdrift
@@ -356,6 +357,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8) · 6 unmodified lines
356357 */
357358 struct mesh_sta {
358359 struct timer_list plink_timer;
360+ struct sta_info *plink_sta;
359361
360362 s64 t_offset;
361363 s64 t_offset_setpoint;
@@ -398,7 +400,7 @@ struct ieee80211_sta_rx_stats { · 36 unmodified lines
398400 u64 msdu[IEEE80211_NUM_TIDS + 1];
399401 };
400402
401−/**
403+/*
402404 * The bandwidth threshold below which the per-station CoDel parameters will be
403405 * scaled to be more lenient (to prevent starvation of slow stations). This
404406 * value will be scaled by the number of active stations when it is being
net/mac80211/tx.c+34−0
@@ -1396,6 +1396,40 @@ static void ieee80211_txq_enqueue(struct ieee80211_local *local, · 1395 unmodified lines
13961396 fq_flow_get_default_func);
13971397 }
13981398
1399+static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin,
1400+ struct fq_flow *flow, struct sk_buff *skb,
1401+ void *data)
1402+{
1403+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1404+
1405+ return info->control.vif == data;
1406+}
1407+
1408+void ieee80211_txq_remove_vlan(struct ieee80211_local *local,
1409+ struct ieee80211_sub_if_data *sdata)
1410+{
1411+ struct fq *fq = &local->fq;
1412+ struct txq_info *txqi;
1413+ struct fq_tin *tin;
1414+ struct ieee80211_sub_if_data *ap;
1415+
1416+ if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
1417+ return;
1418+
1419+ ap = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap);
1420+
1421+ if (!ap->vif.txq)
1422+ return;
1423+
1424+ txqi = to_txq_info(ap->vif.txq);
1425+ tin = &txqi->tin;
1426+
1427+ spin_lock_bh(&fq->lock);
1428+ fq_tin_filter(fq, tin, fq_vlan_filter_func, &sdata->vif,
1429+ fq_skb_free_func);
1430+ spin_unlock_bh(&fq->lock);
1431+}
1432+
13991433 void ieee80211_txq_init(struct ieee80211_sub_if_data *sdata,
14001434 struct sta_info *sta,
14011435 struct txq_info *txqi, int tid)
net/mac80211/util.c+11−14
@@ -1392,10 +1392,10 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, · 1391 unmodified lines
13921392 /* insert custom IEs that go before HT */
13931393 if (ie && ie_len) {
13941394 static const u8 before_ht[] = {
1395− WLAN_EID_SSID,
1396− WLAN_EID_SUPP_RATES,
1397− WLAN_EID_REQUEST,
1398− WLAN_EID_EXT_SUPP_RATES,
1395+ /*
1396+ * no need to list the ones split off already
1397+ * (or generated here)
1398+ */
13991399 WLAN_EID_DS_PARAMS,
14001400 WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
14011401 };
@@ -1424,20 +1424,17 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_local *local, · 22 unmodified lines
14241424 /* insert custom IEs that go before VHT */
14251425 if (ie && ie_len) {
14261426 static const u8 before_vht[] = {
1427− WLAN_EID_SSID,
1428− WLAN_EID_SUPP_RATES,
1429− WLAN_EID_REQUEST,
1430− WLAN_EID_EXT_SUPP_RATES,
1431− WLAN_EID_DS_PARAMS,
1432− WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
1433− WLAN_EID_HT_CAPABILITY,
1427+ /*
1428+ * no need to list the ones split off already
1429+ * (or generated here)
1430+ */
14341431 WLAN_EID_BSS_COEX_2040,
14351432 WLAN_EID_EXT_CAPABILITY,
14361433 WLAN_EID_SSID_LIST,
14371434 WLAN_EID_CHANNEL_USAGE,
14381435 WLAN_EID_INTERWORKING,
14391436 WLAN_EID_MESH_ID,
1440− /* 60 GHz can't happen here right now */
1437+ /* 60 GHz (Multi-band, DMG, MMS) can't happen */
14411438 };
14421439 noffset = ieee80211_ie_split(ie, ie_len,
14431440 before_vht, ARRAY_SIZE(before_vht),
@@ -2980,8 +2977,8 @@ int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata, · 1536 unmodified lines
29802977 struct ieee80211_mgmt *mgmt;
29812978 struct ieee80211_local *local = sdata->local;
29822979 int freq;
2983− int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +
2984− sizeof(mgmt->u.action.u.chan_switch);
2980+ int hdr_len = offsetofend(struct ieee80211_mgmt,
2981+ u.action.u.chan_switch);
29852982 u8 *pos;
29862983
29872984 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
net/mac80211/vht.c+10−0
@@ -386,6 +386,16 @@ enum ieee80211_sta_rx_bandwidth ieee80211_sta_cur_vht_bw(struct sta_info *sta) · 385 unmodified lines
386386
387387 bw = ieee80211_sta_cap_rx_bw(sta);
388388 bw = min(bw, sta->cur_max_bandwidth);
389+
390+ /* Don't consider AP's bandwidth for TDLS peers, section 11.23.1 of
391+ * IEEE80211-2016 specification makes higher bandwidth operation
392+ * possible on the TDLS link if the peers have wider bandwidth
393+ * capability.
394+ */
395+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
396+ test_sta_flag(sta, WLAN_STA_TDLS_WIDER_BW))
397+ return bw;
398+
389399 bw = min(bw, ieee80211_chan_width_to_rx_bw(bss_width));
390400
391401 return bw;
net/mac80211/wpa.c+2−2
@@ -464,7 +464,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb, · 463 unmodified lines
464464 pos += IEEE80211_CCMP_HDR_LEN;
465465 ccmp_special_blocks(skb, pn, b_0, aad);
466466 return ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
467− skb_put(skb, mic_len), mic_len);
467+ skb_put(skb, mic_len));
468468 }
469469
470470
@@ -543,7 +543,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, · 72 unmodified lines
543543 key->u.ccmp.tfm, b_0, aad,
544544 skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
545545 data_len,
546− skb->data + skb->len - mic_len, mic_len))
546+ skb->data + skb->len - mic_len))
547547 return RX_DROP_UNUSABLE;
548548 }
549549
net/wireless/.gitignore+2−1
@@ -1 +1,2 @@
1−regdb.c
1+shipped-certs.c
2+extra-certs.c
net/wireless/Kconfig+34−24
@@ -19,6 +19,7 @@ config WEXT_PRIV · 18 unmodified lines
1919 config CFG80211
2020 tristate "cfg80211 - wireless configuration API"
2121 depends on RFKILL || !RFKILL
22+ select FW_LOADER
2223 ---help---
2324 cfg80211 is the Linux wireless LAN (802.11) configuration API.
2425 Enable this if you have a wireless device.
@@ -82,6 +83,36 @@ config CFG80211_CERTIFICATION_ONUS · 57 unmodified lines
8283 you are a wireless researcher and are working in a controlled
8384 and approved environment by your local regulatory agency.
8485
86+config CFG80211_REQUIRE_SIGNED_REGDB
87+ bool "require regdb signature" if CFG80211_CERTIFICATION_ONUS
88+ default y
89+ select SYSTEM_DATA_VERIFICATION
90+ help
91+ Require that in addition to the "regulatory.db" file a
92+ "regulatory.db.p7s" can be loaded with a valid PKCS#7
93+ signature for the regulatory.db file made by one of the
94+ keys in the certs/ directory.
95+
96+config CFG80211_USE_KERNEL_REGDB_KEYS
97+ bool "allow regdb keys shipped with the kernel" if CFG80211_CERTIFICATION_ONUS
98+ default y
99+ depends on CFG80211_REQUIRE_SIGNED_REGDB
100+ help
101+ Allow the regulatory database to be signed by one of the keys for
102+ which certificates are part of the kernel sources
103+ (in net/wireless/certs/).
104+
105+ This is currently only Seth Forshee's key, who is the regulatory
106+ database maintainer.
107+
108+config CFG80211_EXTRA_REGDB_KEYDIR
109+ string "additional regdb key directory" if CFG80211_CERTIFICATION_ONUS
110+ depends on CFG80211_REQUIRE_SIGNED_REGDB
111+ help
112+ If selected, point to a directory with DER-encoded X.509
113+ certificates like in the kernel sources (net/wireless/certs/)
114+ that shall be accepted for a signed regulatory database.
115+
85116 config CFG80211_REG_CELLULAR_HINTS
86117 bool "cfg80211 regulatory support for cellular base station hints"
87118 depends on CFG80211_CERTIFICATION_ONUS
@@ -139,35 +170,14 @@ config CFG80211_DEBUGFS · 51 unmodified lines
139170
140171 If unsure, say N.
141172
142−config CFG80211_INTERNAL_REGDB
143− bool "use statically compiled regulatory rules database" if EXPERT
144− default n
145− depends on CFG80211
146− ---help---
147− This option generates an internal data structure representing
148− the wireless regulatory rules described in net/wireless/db.txt
149− and includes code to query that database. This is an alternative
150− to using CRDA for defining regulatory rules for the kernel.
151−
152− Using this option requires some parsing of the db.txt at build time,
153− the parser will be upkept with the latest wireless-regdb updates but
154− older wireless-regdb formats will be ignored. The parser may later
155− be replaced to avoid issues with conflicts on versions of
156− wireless-regdb.
157−
158− For details see:
159−
160− http://wireless.kernel.org/en/developers/Regulatory
161−
162− Most distributions have a CRDA package. So if unsure, say N.
163−
164173 config CFG80211_CRDA_SUPPORT
165− bool "support CRDA" if CFG80211_INTERNAL_REGDB
174+ bool "support CRDA" if EXPERT
166175 default y
167176 depends on CFG80211
168177 help
169178 You should enable this option unless you know for sure you have no
170− need for it, for example when using internal regdb (above.)
179+ need for it, for example when using internal regdb (above) or the
180+ database loaded as a firmware file.
171181
172182 If unsure, say Y.
173183
net/wireless/Makefile+20−4
@@ -14,11 +14,27 @@ cfg80211-y += mlme.o ibss.o sme.o chan.o ethtool.o mesh.o ap.o trace.o ocb.o · 13 unmodified lines
1414 cfg80211-$(CONFIG_OF) += of.o
1515 cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
1616 cfg80211-$(CONFIG_CFG80211_WEXT) += wext-compat.o wext-sme.o
17−cfg80211-$(CONFIG_CFG80211_INTERNAL_REGDB) += regdb.o
1817
1918 CFLAGS_trace.o := -I$(src)
2019
21−$(obj)/regdb.c: $(src)/db.txt $(src)/genregdb.awk
22− @$(AWK) -f $(srctree)/$(src)/genregdb.awk < $< > $@
20+cfg80211-$(CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS) += shipped-certs.o
21+ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),)
22+cfg80211-y += extra-certs.o
23+endif
2324
24−clean-files := regdb.c
25+$(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.x509)
26+ @echo " GEN $@"
27+ @echo '#include "reg.h"' > $@
28+ @echo 'const u8 shipped_regdb_certs[] = {' >> $@
29+ @for f in $^ ; do hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ ; done
30+ @echo '};' >> $@
31+ @echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);' >> $@
32+
33+$(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \
34+ $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509)
35+ @echo " GEN $@"
36+ @echo '#include "reg.h"' > $@
37+ @echo 'const u8 extra_regdb_certs[] = {' >> $@
38+ @for f in $^ ; do test -f $$f && hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ || true ; done
39+ @echo '};' >> $@
40+ @echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);' >> $@
net/wireless/certs/sforshee.x509+0−0

Binary file not shown.

net/wireless/core.c+1−1
@@ -1384,7 +1384,7 @@ out_fail_sysfs: · 1383 unmodified lines
13841384 out_fail_pernet:
13851385 return err;
13861386 }
1387−subsys_initcall(cfg80211_init);
1387+fs_initcall(cfg80211_init);
13881388
13891389 static void __exit cfg80211_exit(void)
13901390 {
net/wireless/core.h+5−0
@@ -216,6 +216,7 @@ enum cfg80211_event_type { · 215 unmodified lines
216216 EVENT_DISCONNECTED,
217217 EVENT_IBSS_JOINED,
218218 EVENT_STOPPED,
219+ EVENT_PORT_AUTHORIZED,
219220 };
220221
221222 struct cfg80211_event {
@@ -235,6 +236,9 @@ struct cfg80211_event { · 13 unmodified lines
235236 u8 bssid[ETH_ALEN];
236237 struct ieee80211_channel *channel;
237238 } ij;
239+ struct {
240+ u8 bssid[ETH_ALEN];
241+ } pa;
238242 };
239243 };
240244
@@ -385,6 +389,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, · 144 unmodified lines
385389 bool wextev);
386390 void __cfg80211_roamed(struct wireless_dev *wdev,
387391 struct cfg80211_roam_info *info);
392+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid);
388393 int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
389394 struct wireless_dev *wdev);
390395 void cfg80211_autodisconnect_wk(struct work_struct *work);
net/wireless/db.txt+0−17
@@ -1,17 +0,0 @@
1−#
2−# This file is a placeholder to prevent accidental build breakage if someone
3−# enables CONFIG_CFG80211_INTERNAL_REGDB. Almost no one actually needs to
4−# enable that build option.
5−#
6−# You should be using CRDA instead. It is even better if you use the CRDA
7−# package provided by your distribution, since they will probably keep it
8−# up-to-date on your behalf.
9−#
10−# If you _really_ intend to use CONFIG_CFG80211_INTERNAL_REGDB then you will
11−# need to replace this file with one containing appropriately formatted
12−# regulatory rules that cover the regulatory domains you will be using. Your
13−# best option is to extract the db.txt file from the wireless-regdb git
14−# repository:
15−#
16−# git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-regdb.git
17−#
net/wireless/genregdb.awk+0−158
@@ -1,158 +0,0 @@
1−#!/usr/bin/awk -f
2−#
3−# genregdb.awk -- generate regdb.c from db.txt
4−#
5−# Actually, it reads from stdin (presumed to be db.txt) and writes
6−# to stdout (presumed to be regdb.c), but close enough...
7−#
8−# Copyright 2009 John W. Linville <linville@tuxdriver.com>
9−#
10−# Permission to use, copy, modify, and/or distribute this software for any
11−# purpose with or without fee is hereby granted, provided that the above
12−# copyright notice and this permission notice appear in all copies.
13−#
14−# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
15−# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
16−# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
17−# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18−# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19−# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
20−# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21−
22−BEGIN {
23− active = 0
24− rules = 0;
25− print "/*"
26− print " * DO NOT EDIT -- file generated from data in db.txt"
27− print " */"
28− print ""
29− print "#include <linux/nl80211.h>"
30− print "#include <net/cfg80211.h>"
31− print "#include \"regdb.h\""
32− print ""
33− regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n"
34−}
35−
36−function parse_country_head() {
37− country=$2
38− sub(/:/, "", country)
39− printf "static const struct ieee80211_regdomain regdom_%s = {\n", country
40− printf "\t.alpha2 = \"%s\",\n", country
41− if ($NF ~ /DFS-ETSI/)
42− printf "\t.dfs_region = NL80211_DFS_ETSI,\n"
43− else if ($NF ~ /DFS-FCC/)
44− printf "\t.dfs_region = NL80211_DFS_FCC,\n"
45− else if ($NF ~ /DFS-JP/)
46− printf "\t.dfs_region = NL80211_DFS_JP,\n"
47− printf "\t.reg_rules = {\n"
48− active = 1
49− regdb = regdb "\t&regdom_" country ",\n"
50−}
51−
52−function parse_reg_rule()
53−{
54− flag_starts_at = 7
55−
56− start = $1
57− sub(/\(/, "", start)
58− end = $3
59− bw = $5
60− sub(/\),/, "", bw)
61− gain = 0
62− power = $6
63− # power might be in mW...
64− units = $7
65− dfs_cac = 0
66−
67− sub(/\(/, "", power)
68− sub(/\),/, "", power)
69− sub(/\),/, "", units)
70− sub(/\)/, "", units)
71−
72− if (units == "mW") {
73− flag_starts_at = 8
74− power = 10 * log(power)/log(10)
75− if ($8 ~ /[[:digit:]]/) {
76− flag_starts_at = 9
77− dfs_cac = $8
78− }
79− } else {
80− if ($7 ~ /[[:digit:]]/) {
81− flag_starts_at = 8
82− dfs_cac = $7
83− }
84− }
85− sub(/\(/, "", dfs_cac)
86− sub(/\),/, "", dfs_cac)
87− flagstr = ""
88− for (i=flag_starts_at; i<=NF; i++)
89− flagstr = flagstr $i
90− split(flagstr, flagarray, ",")
91− flags = ""
92− for (arg in flagarray) {
93− if (flagarray[arg] == "NO-OFDM") {
94− flags = flags "\n\t\t\tNL80211_RRF_NO_OFDM | "
95− } else if (flagarray[arg] == "NO-CCK") {
96− flags = flags "\n\t\t\tNL80211_RRF_NO_CCK | "
97− } else if (flagarray[arg] == "NO-INDOOR") {
98− flags = flags "\n\t\t\tNL80211_RRF_NO_INDOOR | "
99− } else if (flagarray[arg] == "NO-OUTDOOR") {
100− flags = flags "\n\t\t\tNL80211_RRF_NO_OUTDOOR | "
101− } else if (flagarray[arg] == "DFS") {
102− flags = flags "\n\t\t\tNL80211_RRF_DFS | "
103− } else if (flagarray[arg] == "PTP-ONLY") {
104− flags = flags "\n\t\t\tNL80211_RRF_PTP_ONLY | "
105− } else if (flagarray[arg] == "PTMP-ONLY") {
106− flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | "
107− } else if (flagarray[arg] == "PASSIVE-SCAN") {
108− flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
109− } else if (flagarray[arg] == "NO-IBSS") {
110− flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
111− } else if (flagarray[arg] == "NO-IR") {
112− flags = flags "\n\t\t\tNL80211_RRF_NO_IR | "
113− } else if (flagarray[arg] == "AUTO-BW") {
114− flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | "
115− }
116−
117− }
118− flags = flags "0"
119− printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags
120− rules++
121−}
122−
123−function print_tail_country()
124−{
125− active = 0
126− printf "\t},\n"
127− printf "\t.n_reg_rules = %d\n", rules
128− printf "};\n\n"
129− rules = 0;
130−}
131−
132−/^[ \t]*#/ {
133− # Ignore
134−}
135−
136−!active && /^[ \t]*$/ {
137− # Ignore
138−}
139−
140−!active && /country/ {
141− parse_country_head()
142−}
143−
144−active && /^[ \t]*\(/ {
145− parse_reg_rule()
146−}
147−
148−active && /^[ \t]*$/ {
149− print_tail_country()
150−}
151−
152−END {
153− if (active)
154− print_tail_country()
155− print regdb "};"
156− print ""
157− print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);"
158−}
net/wireless/nl80211.c+136−63
@@ -2130,6 +2130,15 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, · 2129 unmodified lines
21302130 case NL80211_CHAN_HT40MINUS:
21312131 cfg80211_chandef_create(chandef, chandef->chan,
21322132 chantype);
2133+ /* user input for center_freq is incorrect */
2134+ if (info->attrs[NL80211_ATTR_CENTER_FREQ1] &&
2135+ chandef->center_freq1 != nla_get_u32(
2136+ info->attrs[NL80211_ATTR_CENTER_FREQ1]))
2137+ return -EINVAL;
2138+ /* center_freq2 must be zero */
2139+ if (info->attrs[NL80211_ATTR_CENTER_FREQ2] &&
2140+ nla_get_u32(info->attrs[NL80211_ATTR_CENTER_FREQ2]))
2141+ return -EINVAL;
21332142 break;
21342143 default:
21352144 return -EINVAL;
@@ -5677,6 +5686,11 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) · 3541 unmodified lines
56775686 }
56785687 }
56795688
5689+static int nl80211_reload_regdb(struct sk_buff *skb, struct genl_info *info)
5690+{
5691+ return reg_reload_regdb();
5692+}
5693+
56805694 static int nl80211_get_mesh_config(struct sk_buff *skb,
56815695 struct genl_info *info)
56825696 {
@@ -6618,6 +6632,77 @@ static bool cfg80211_off_channel_oper_allowed(struct wireless_dev *wdev) · 935 unmodified lines
66186632 return regulatory_pre_cac_allowed(wdev->wiphy);
66196633 }
66206634
6635+static int
6636+nl80211_check_scan_flags(struct wiphy *wiphy, struct wireless_dev *wdev,
6637+ void *request, struct nlattr **attrs,
6638+ bool is_sched_scan)
6639+{
6640+ u8 *mac_addr, *mac_addr_mask;
6641+ u32 *flags;
6642+ enum nl80211_feature_flags randomness_flag;
6643+
6644+ if (!attrs[NL80211_ATTR_SCAN_FLAGS])
6645+ return 0;
6646+
6647+ if (is_sched_scan) {
6648+ struct cfg80211_sched_scan_request *req = request;
6649+
6650+ randomness_flag = wdev ?
6651+ NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR :
6652+ NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6653+ flags = &req->flags;
6654+ mac_addr = req->mac_addr;
6655+ mac_addr_mask = req->mac_addr_mask;
6656+ } else {
6657+ struct cfg80211_scan_request *req = request;
6658+
6659+ randomness_flag = NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
6660+ flags = &req->flags;
6661+ mac_addr = req->mac_addr;
6662+ mac_addr_mask = req->mac_addr_mask;
6663+ }
6664+
6665+ *flags = nla_get_u32(attrs[NL80211_ATTR_SCAN_FLAGS]);
6666+
6667+ if ((*flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6668+ !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN))
6669+ return -EOPNOTSUPP;
6670+
6671+ if (*flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6672+ int err;
6673+
6674+ if (!(wiphy->features & randomness_flag) ||
6675+ (wdev && wdev->current_bss))
6676+ return -EOPNOTSUPP;
6677+
6678+ err = nl80211_parse_random_mac(attrs, mac_addr, mac_addr_mask);
6679+ if (err)
6680+ return err;
6681+ }
6682+
6683+ if ((*flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME) &&
6684+ !wiphy_ext_feature_isset(wiphy,
6685+ NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME))
6686+ return -EOPNOTSUPP;
6687+
6688+ if ((*flags & NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP) &&
6689+ !wiphy_ext_feature_isset(wiphy,
6690+ NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP))
6691+ return -EOPNOTSUPP;
6692+
6693+ if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
6694+ !wiphy_ext_feature_isset(wiphy,
6695+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION))
6696+ return -EOPNOTSUPP;
6697+
6698+ if ((*flags & NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE) &&
6699+ !wiphy_ext_feature_isset(wiphy,
6700+ NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE))
6701+ return -EOPNOTSUPP;
6702+
6703+ return 0;
6704+}
6705+
66216706 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
66226707 {
66236708 struct cfg80211_registered_device *rdev = info->user_ptr[0];
@@ -6823,34 +6908,10 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) · 199 unmodified lines
68236908 nla_get_flag(info->attrs[NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY]);
68246909 }
68256910
6826− if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) {
6827− request->flags = nla_get_u32(
6828− info->attrs[NL80211_ATTR_SCAN_FLAGS]);
6829− if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
6830− !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
6831− err = -EOPNOTSUPP;
6832− goto out_free;
6833− }
6834−
6835− if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
6836− if (!(wiphy->features &
6837− NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR)) {
6838− err = -EOPNOTSUPP;
6839− goto out_free;
6840− }
6841−
6842− if (wdev->current_bss) {
6843− err = -EOPNOTSUPP;
6844− goto out_free;
6845− }
6846−
6847− err = nl80211_parse_random_mac(info->attrs,
6848− request->mac_addr,
6849− request->mac_addr_mask);
6850− if (err)
6851− goto out_free;
6852− }
6853− }
6911+ err = nl80211_check_scan_flags(wiphy, wdev, request, info->attrs,
6912+ false);
6913+ if (err)
6914+ goto out_free;
68546915
68556916 request->no_cck =
68566917 nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
@@ -7298,37 +7359,9 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev, · 441 unmodified lines
72987359 request->ie_len);
72997360 }
73007361
7301− if (attrs[NL80211_ATTR_SCAN_FLAGS]) {
7302− request->flags = nla_get_u32(
7303− attrs[NL80211_ATTR_SCAN_FLAGS]);
7304− if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
7305− !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) {
7306− err = -EOPNOTSUPP;
7307− goto out_free;
7308− }
7309−
7310− if (request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
7311− u32 flg = NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
7312−
7313− if (!wdev) /* must be net-detect */
7314− flg = NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
7315−
7316− if (!(wiphy->features & flg)) {
7317− err = -EOPNOTSUPP;
7318− goto out_free;
7319− }
7320−
7321− if (wdev && wdev->current_bss) {
7322− err = -EOPNOTSUPP;
7323− goto out_free;
7324− }
7325−
7326− err = nl80211_parse_random_mac(attrs, request->mac_addr,
7327− request->mac_addr_mask);
7328− if (err)
7329− goto out_free;
7330− }
7331− }
7362+ err = nl80211_check_scan_flags(wiphy, wdev, request, attrs, true);
7363+ if (err)
7364+ goto out_free;
73327365
73337366 if (attrs[NL80211_ATTR_SCHED_SCAN_DELAY])
73347367 request->delay =
@@ -8932,8 +8965,14 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) · 1597 unmodified lines
89328965
89338966 if (info->attrs[NL80211_ATTR_USE_MFP]) {
89348967 connect.mfp = nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
8968+ if (connect.mfp == NL80211_MFP_OPTIONAL &&
8969+ !wiphy_ext_feature_isset(&rdev->wiphy,
8970+ NL80211_EXT_FEATURE_MFP_OPTIONAL))
8971+ return -EOPNOTSUPP;
8972+
89358973 if (connect.mfp != NL80211_MFP_REQUIRED &&
8936− connect.mfp != NL80211_MFP_NO)
8974+ connect.mfp != NL80211_MFP_NO &&
8975+ connect.mfp != NL80211_MFP_OPTIONAL)
89378976 return -EINVAL;
89388977 } else {
89398978 connect.mfp = NL80211_MFP_NO;
@@ -12684,6 +12723,12 @@ static const struct genl_ops nl80211_ops[] = { · 3744 unmodified lines
1268412723 .policy = nl80211_policy,
1268512724 .flags = GENL_ADMIN_PERM,
1268612725 },
12726+ {
12727+ .cmd = NL80211_CMD_RELOAD_REGDB,
12728+ .doit = nl80211_reload_regdb,
12729+ .policy = nl80211_policy,
12730+ .flags = GENL_ADMIN_PERM,
12731+ },
1268712732 {
1268812733 .cmd = NL80211_CMD_GET_MESH_CONFIG,
1268912734 .doit = nl80211_get_mesh_config,
@@ -13812,9 +13857,7 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 1122 unmodified lines
1381213857 info->req_ie)) ||
1381313858 (info->resp_ie &&
1381413859 nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
13815− info->resp_ie)) ||
13816− (info->authorized &&
13817− nla_put_flag(msg, NL80211_ATTR_PORT_AUTHORIZED)))
13860+ info->resp_ie)))
1381813861 goto nla_put_failure;
1381913862
1382013863 genlmsg_end(msg, hdr);
@@ -13828,6 +13871,36 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev, · 7 unmodified lines
1382813871 nlmsg_free(msg);
1382913872 }
1383013873
13874+void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
13875+ struct net_device *netdev, const u8 *bssid)
13876+{
13877+ struct sk_buff *msg;
13878+ void *hdr;
13879+
13880+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
13881+ if (!msg)
13882+ return;
13883+
13884+ hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PORT_AUTHORIZED);
13885+ if (!hdr) {
13886+ nlmsg_free(msg);
13887+ return;
13888+ }
13889+
13890+ if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
13891+ goto nla_put_failure;
13892+
13893+ genlmsg_end(msg, hdr);
13894+
13895+ genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0,
13896+ NL80211_MCGRP_MLME, GFP_KERNEL);
13897+ return;
13898+
13899+ nla_put_failure:
13900+ genlmsg_cancel(msg, hdr);
13901+ nlmsg_free(msg);
13902+}
13903+
1383113904 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
1383213905 struct net_device *netdev, u16 reason,
1383313906 const u8 *ie, size_t ie_len, bool from_ap)
net/wireless/nl80211.h+2−0
@@ -58,6 +58,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, · 57 unmodified lines
5858 void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
5959 struct net_device *netdev,
6060 struct cfg80211_roam_info *info, gfp_t gfp);
61+void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
62+ struct net_device *netdev, const u8 *bssid);
6163 void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
6264 struct net_device *netdev, u16 reason,
6365 const u8 *ie, size_t ie_len, bool from_ap);
net/wireless/reg.c+411−41
@@ -53,12 +53,13 @@ · 52 unmodified lines
5353 #include <linux/ctype.h>
5454 #include <linux/nl80211.h>
5555 #include <linux/platform_device.h>
56+#include <linux/verification.h>
5657 #include <linux/moduleparam.h>
58+#include <linux/firmware.h>
5759 #include <net/cfg80211.h>
5860 #include "core.h"
5961 #include "reg.h"
6062 #include "rdev-ops.h"
61−#include "regdb.h"
6263 #include "nl80211.h"
6364
6465 /*
@@ -100,7 +101,7 @@ static struct regulatory_request core_request_world = { · 35 unmodified lines
100101 static struct regulatory_request __rcu *last_request =
101102 (void __force __rcu *)&core_request_world;
102103
103−/* To trigger userspace events */
104+/* To trigger userspace events and load firmware */
104105 static struct platform_device *reg_pdev;
105106
106107 /*
@@ -443,7 +444,6 @@ reg_copy_regd(const struct ieee80211_regdomain *src_regd) · 336 unmodified lines
443444 return regd;
444445 }
445446
446−#ifdef CONFIG_CFG80211_INTERNAL_REGDB
447447 struct reg_regdb_apply_request {
448448 struct list_head list;
449449 const struct ieee80211_regdomain *regdom;
@@ -475,55 +475,26 @@ static void reg_regdb_apply(struct work_struct *work) · 25 unmodified lines
475475
476476 static DECLARE_WORK(reg_regdb_work, reg_regdb_apply);
477477
478−static int reg_query_builtin(const char *alpha2)
478+static int reg_schedule_apply(const struct ieee80211_regdomain *regdom)
479479 {
480− const struct ieee80211_regdomain *regdom = NULL;
481480 struct reg_regdb_apply_request *request;
482− unsigned int i;
483−
484− for (i = 0; i < reg_regdb_size; i++) {
485− if (alpha2_equal(alpha2, reg_regdb[i]->alpha2)) {
486− regdom = reg_regdb[i];
487− break;
488− }
489− }
490−
491− if (!regdom)
492− return -ENODATA;
493481
494482 request = kzalloc(sizeof(struct reg_regdb_apply_request), GFP_KERNEL);
495− if (!request)
496− return -ENOMEM;
497−
498− request->regdom = reg_copy_regd(regdom);
499− if (IS_ERR_OR_NULL(request->regdom)) {
500− kfree(request);
483+ if (!request) {
484+ kfree(regdom);
501485 return -ENOMEM;
502486 }
503487
488+ request->regdom = regdom;
489+
504490 mutex_lock(&reg_regdb_apply_mutex);
505491 list_add_tail(&request->list, &reg_regdb_apply_list);
506492 mutex_unlock(&reg_regdb_apply_mutex);
507493
508494 schedule_work(&reg_regdb_work);
509−
510495 return 0;
511496 }
512497
513−/* Feel free to add any other sanity checks here */
514−static void reg_regdb_size_check(void)
515−{
516− /* We should ideally BUILD_BUG_ON() but then random builds would fail */
517− WARN_ONCE(!reg_regdb_size, "db.txt is empty, you should update it...");
518−}
519−#else
520−static inline void reg_regdb_size_check(void) {}
521−static inline int reg_query_builtin(const char *alpha2)
522−{
523− return -ENODATA;
524−}
525−#endif /* CONFIG_CFG80211_INTERNAL_REGDB */
526−
527498 #ifdef CONFIG_CFG80211_CRDA_SUPPORT
528499 /* Max number of consecutive attempts to communicate with CRDA */
529500 #define REG_MAX_CRDA_TIMEOUTS 10
@@ -599,10 +570,402 @@ static inline int call_crda(const char *alpha2) · 69 unmodified lines
599570 }
600571 #endif /* CONFIG_CFG80211_CRDA_SUPPORT */
601572
573+/* code to directly load a firmware database through request_firmware */
574+static const struct fwdb_header *regdb;
575+
576+struct fwdb_country {
577+ u8 alpha2[2];
578+ __be16 coll_ptr;
579+ /* this struct cannot be extended */
580+} __packed __aligned(4);
581+
582+struct fwdb_collection {
583+ u8 len;
584+ u8 n_rules;
585+ u8 dfs_region;
586+ /* no optional data yet */
587+ /* aligned to 2, then followed by __be16 array of rule pointers */
588+} __packed __aligned(4);
589+
590+enum fwdb_flags {
591+ FWDB_FLAG_NO_OFDM = BIT(0),
592+ FWDB_FLAG_NO_OUTDOOR = BIT(1),
593+ FWDB_FLAG_DFS = BIT(2),
594+ FWDB_FLAG_NO_IR = BIT(3),
595+ FWDB_FLAG_AUTO_BW = BIT(4),
596+};
597+
598+struct fwdb_rule {
599+ u8 len;
600+ u8 flags;
601+ __be16 max_eirp;
602+ __be32 start, end, max_bw;
603+ /* start of optional data */
604+ __be16 cac_timeout;
605+} __packed __aligned(4);
606+
607+#define FWDB_MAGIC 0x52474442
608+#define FWDB_VERSION 20
609+
610+struct fwdb_header {
611+ __be32 magic;
612+ __be32 version;
613+ struct fwdb_country country[];
614+} __packed __aligned(4);
615+
616+static bool valid_rule(const u8 *data, unsigned int size, u16 rule_ptr)
617+{
618+ struct fwdb_rule *rule = (void *)(data + (rule_ptr << 2));
619+
620+ if ((u8 *)rule + sizeof(rule->len) > data + size)
621+ return false;
622+
623+ /* mandatory fields */
624+ if (rule->len < offsetofend(struct fwdb_rule, max_bw))
625+ return false;
626+
627+ return true;
628+}
629+
630+static bool valid_country(const u8 *data, unsigned int size,
631+ const struct fwdb_country *country)
632+{
633+ unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
634+ struct fwdb_collection *coll = (void *)(data + ptr);
635+ __be16 *rules_ptr;
636+ unsigned int i;
637+
638+ /* make sure we can read len/n_rules */
639+ if ((u8 *)coll + offsetofend(typeof(*coll), n_rules) > data + size)
640+ return false;
641+
642+ /* make sure base struct and all rules fit */
643+ if ((u8 *)coll + ALIGN(coll->len, 2) +
644+ (coll->n_rules * 2) > data + size)
645+ return false;
646+
647+ /* mandatory fields must exist */
648+ if (coll->len < offsetofend(struct fwdb_collection, dfs_region))
649+ return false;
650+
651+ rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2));
652+
653+ for (i = 0; i < coll->n_rules; i++) {
654+ u16 rule_ptr = be16_to_cpu(rules_ptr[i]);
655+
656+ if (!valid_rule(data, size, rule_ptr))
657+ return false;
658+ }
659+
660+ return true;
661+}
662+
663+#ifdef CONFIG_CFG80211_REQUIRE_SIGNED_REGDB
664+static struct key *builtin_regdb_keys;
665+
666+static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen)
667+{
668+ const u8 *end = p + buflen;
669+ size_t plen;
670+ key_ref_t key;
671+
672+ while (p < end) {
673+ /* Each cert begins with an ASN.1 SEQUENCE tag and must be more
674+ * than 256 bytes in size.
675+ */
676+ if (end - p < 4)
677+ goto dodgy_cert;
678+ if (p[0] != 0x30 &&
679+ p[1] != 0x82)
680+ goto dodgy_cert;
681+ plen = (p[2] << 8) | p[3];
682+ plen += 4;
683+ if (plen > end - p)
684+ goto dodgy_cert;
685+
686+ key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1),
687+ "asymmetric", NULL, p, plen,
688+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
689+ KEY_USR_VIEW | KEY_USR_READ),
690+ KEY_ALLOC_NOT_IN_QUOTA |
691+ KEY_ALLOC_BUILT_IN |
692+ KEY_ALLOC_BYPASS_RESTRICTION);
693+ if (IS_ERR(key)) {
694+ pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
695+ PTR_ERR(key));
696+ } else {
697+ pr_notice("Loaded X.509 cert '%s'\n",
698+ key_ref_to_ptr(key)->description);
699+ key_ref_put(key);
700+ }
701+ p += plen;
702+ }
703+
704+ return;
705+
706+dodgy_cert:
707+ pr_err("Problem parsing in-kernel X.509 certificate list\n");
708+}
709+
710+static int __init load_builtin_regdb_keys(void)
711+{
712+ builtin_regdb_keys =
713+ keyring_alloc(".builtin_regdb_keys",
714+ KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
715+ ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
716+ KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
717+ KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
718+ if (IS_ERR(builtin_regdb_keys))
719+ return PTR_ERR(builtin_regdb_keys);
720+
721+ pr_notice("Loading compiled-in X.509 certificates for regulatory database\n");
722+
723+#ifdef CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS
724+ load_keys_from_buffer(shipped_regdb_certs, shipped_regdb_certs_len);
725+#endif
726+#ifdef CFG80211_EXTRA_REGDB_KEYDIR
727+ if (CONFIG_CFG80211_EXTRA_REGDB_KEYDIR[0] != '\0')
728+ load_keys_from_buffer(extra_regdb_certs, extra_regdb_certs_len);
729+#endif
730+
731+ return 0;
732+}
733+
734+static bool regdb_has_valid_signature(const u8 *data, unsigned int size)
735+{
736+ const struct firmware *sig;
737+ bool result;
738+
739+ if (request_firmware(&sig, "regulatory.db.p7s", &reg_pdev->dev))
740+ return false;
741+
742+ result = verify_pkcs7_signature(data, size, sig->data, sig->size,
743+ builtin_regdb_keys,
744+ VERIFYING_UNSPECIFIED_SIGNATURE,
745+ NULL, NULL) == 0;
746+
747+ release_firmware(sig);
748+
749+ return result;
750+}
751+
752+static void free_regdb_keyring(void)
753+{
754+ key_put(builtin_regdb_keys);
755+}
756+#else
757+static int load_builtin_regdb_keys(void)
758+{
759+ return 0;
760+}
761+
762+static bool regdb_has_valid_signature(const u8 *data, unsigned int size)
763+{
764+ return true;
765+}
766+
767+static void free_regdb_keyring(void)
768+{
769+}
770+#endif /* CONFIG_CFG80211_REQUIRE_SIGNED_REGDB */
771+
772+static bool valid_regdb(const u8 *data, unsigned int size)
773+{
774+ const struct fwdb_header *hdr = (void *)data;
775+ const struct fwdb_country *country;
776+
777+ if (size < sizeof(*hdr))
778+ return false;
779+
780+ if (hdr->magic != cpu_to_be32(FWDB_MAGIC))
781+ return false;
782+
783+ if (hdr->version != cpu_to_be32(FWDB_VERSION))
784+ return false;
785+
786+ if (!regdb_has_valid_signature(data, size))
787+ return false;
788+
789+ country = &hdr->country[0];
790+ while ((u8 *)(country + 1) <= data + size) {
791+ if (!country->coll_ptr)
792+ break;
793+ if (!valid_country(data, size, country))
794+ return false;
795+ country++;
796+ }
797+
798+ return true;
799+}
800+
801+static int regdb_query_country(const struct fwdb_header *db,
802+ const struct fwdb_country *country)
803+{
804+ unsigned int ptr = be16_to_cpu(country->coll_ptr) << 2;
805+ struct fwdb_collection *coll = (void *)((u8 *)db + ptr);
806+ struct ieee80211_regdomain *regdom;
807+ unsigned int size_of_regd;
808+ unsigned int i;
809+
810+ size_of_regd =
811+ sizeof(struct ieee80211_regdomain) +
812+ coll->n_rules * sizeof(struct ieee80211_reg_rule);
813+
814+ regdom = kzalloc(size_of_regd, GFP_KERNEL);
815+ if (!regdom)
816+ return -ENOMEM;
817+
818+ regdom->n_reg_rules = coll->n_rules;
819+ regdom->alpha2[0] = country->alpha2[0];
820+ regdom->alpha2[1] = country->alpha2[1];
821+ regdom->dfs_region = coll->dfs_region;
822+
823+ for (i = 0; i < regdom->n_reg_rules; i++) {
824+ __be16 *rules_ptr = (void *)((u8 *)coll + ALIGN(coll->len, 2));
825+ unsigned int rule_ptr = be16_to_cpu(rules_ptr[i]) << 2;
826+ struct fwdb_rule *rule = (void *)((u8 *)db + rule_ptr);
827+ struct ieee80211_reg_rule *rrule = &regdom->reg_rules[i];
828+
829+ rrule->freq_range.start_freq_khz = be32_to_cpu(rule->start);
830+ rrule->freq_range.end_freq_khz = be32_to_cpu(rule->end);
831+ rrule->freq_range.max_bandwidth_khz = be32_to_cpu(rule->max_bw);
832+
833+ rrule->power_rule.max_antenna_gain = 0;
834+ rrule->power_rule.max_eirp = be16_to_cpu(rule->max_eirp);
835+
836+ rrule->flags = 0;
837+ if (rule->flags & FWDB_FLAG_NO_OFDM)
838+ rrule->flags |= NL80211_RRF_NO_OFDM;
839+ if (rule->flags & FWDB_FLAG_NO_OUTDOOR)
840+ rrule->flags |= NL80211_RRF_NO_OUTDOOR;
841+ if (rule->flags & FWDB_FLAG_DFS)
842+ rrule->flags |= NL80211_RRF_DFS;
843+ if (rule->flags & FWDB_FLAG_NO_IR)
844+ rrule->flags |= NL80211_RRF_NO_IR;
845+ if (rule->flags & FWDB_FLAG_AUTO_BW)
846+ rrule->flags |= NL80211_RRF_AUTO_BW;
847+
848+ rrule->dfs_cac_ms = 0;
849+
850+ /* handle optional data */
851+ if (rule->len >= offsetofend(struct fwdb_rule, cac_timeout))
852+ rrule->dfs_cac_ms =
853+ 1000 * be16_to_cpu(rule->cac_timeout);
854+ }
855+
856+ return reg_schedule_apply(regdom);
857+}
858+
859+static int query_regdb(const char *alpha2)
860+{
861+ const struct fwdb_header *hdr = regdb;
862+ const struct fwdb_country *country;
863+
864+ ASSERT_RTNL();
865+
866+ if (IS_ERR(regdb))
867+ return PTR_ERR(regdb);
868+
869+ country = &hdr->country[0];
870+ while (country->coll_ptr) {
871+ if (alpha2_equal(alpha2, country->alpha2))
872+ return regdb_query_country(regdb, country);
873+ country++;
874+ }
875+
876+ return -ENODATA;
877+}
878+
879+static void regdb_fw_cb(const struct firmware *fw, void *context)
880+{
881+ int set_error = 0;
882+ bool restore = true;
883+ void *db;
884+
885+ if (!fw) {
886+ pr_info("failed to load regulatory.db\n");
887+ set_error = -ENODATA;
888+ } else if (!valid_regdb(fw->data, fw->size)) {
889+ pr_info("loaded regulatory.db is malformed or signature is missing/invalid\n");
890+ set_error = -EINVAL;
891+ }
892+
893+ rtnl_lock();
894+ if (WARN_ON(regdb && !IS_ERR(regdb))) {
895+ /* just restore and free new db */
896+ } else if (set_error) {
897+ regdb = ERR_PTR(set_error);
898+ } else if (fw) {
899+ db = kmemdup(fw->data, fw->size, GFP_KERNEL);
900+ if (db) {
901+ regdb = db;
902+ restore = context && query_regdb(context);
903+ } else {
904+ restore = true;
905+ }
906+ }
907+
908+ if (restore)
909+ restore_regulatory_settings(true);
910+
911+ rtnl_unlock();
912+
913+ kfree(context);
914+
915+ release_firmware(fw);
916+}
917+
918+static int query_regdb_file(const char *alpha2)
919+{
920+ ASSERT_RTNL();
921+
922+ if (regdb)
923+ return query_regdb(alpha2);
924+
925+ alpha2 = kmemdup(alpha2, 2, GFP_KERNEL);
926+ if (!alpha2)
927+ return -ENOMEM;
928+
929+ return request_firmware_nowait(THIS_MODULE, true, "regulatory.db",
930+ &reg_pdev->dev, GFP_KERNEL,
931+ (void *)alpha2, regdb_fw_cb);
932+}
933+
934+int reg_reload_regdb(void)
935+{
936+ const struct firmware *fw;
937+ void *db;
938+ int err;
939+
940+ err = request_firmware(&fw, "regulatory.db", &reg_pdev->dev);
941+ if (err)
942+ return err;
943+
944+ if (!valid_regdb(fw->data, fw->size)) {
945+ err = -ENODATA;
946+ goto out;
947+ }
948+
949+ db = kmemdup(fw->data, fw->size, GFP_KERNEL);
950+ if (!db) {
951+ err = -ENOMEM;
952+ goto out;
953+ }
954+
955+ rtnl_lock();
956+ if (!IS_ERR_OR_NULL(regdb))
957+ kfree(regdb);
958+ regdb = db;
959+ rtnl_unlock();
960+
961+ out:
962+ release_firmware(fw);
963+ return err;
964+}
965+
602966 static bool reg_query_database(struct regulatory_request *request)
603967 {
604− /* query internal regulatory database (if it exists) */
605− if (reg_query_builtin(request->alpha2) == 0)
968+ if (query_regdb_file(request->alpha2) == 0)
606969 return true;
607970
608971 if (call_crda(request->alpha2) == 0)
@@ -3285,6 +3648,10 @@ int __init regulatory_init(void) · 2676 unmodified lines
32853648 {
32863649 int err = 0;
32873650
3651+ err = load_builtin_regdb_keys();
3652+ if (err)
3653+ return err;
3654+
32883655 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
32893656 if (IS_ERR(reg_pdev))
32903657 return PTR_ERR(reg_pdev);
@@ -3293,8 +3660,6 @@ int __init regulatory_init(void) · 2 unmodified lines
32933660 spin_lock_init(&reg_pending_beacons_lock);
32943661 spin_lock_init(&reg_indoor_lock);
32953662
3296− reg_regdb_size_check();
3297−
32983663 rcu_assign_pointer(cfg80211_regdomain, cfg80211_world_regdom);
32993664
33003665 user_alpha2[0] = '9';
@@ -3360,4 +3725,9 @@ void regulatory_exit(void) · 59 unmodified lines
33603725 list_del(&reg_request->list);
33613726 kfree(reg_request);
33623727 }
3728+
3729+ if (!IS_ERR_OR_NULL(regdb))
3730+ kfree(regdb);
3731+
3732+ free_regdb_keyring();
33633733 }
net/wireless/reg.h+14−0
@@ -1,5 +1,8 @@
11 #ifndef __NET_WIRELESS_REG_H
22 #define __NET_WIRELESS_REG_H
3+
4+#include <net/cfg80211.h>
5+
36 /*
47 * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
58 *
@@ -179,4 +182,15 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy, · 173 unmodified lines
179182 * @wiphy2 - wiphy it's dfs_region to be checked against that of wiphy1
180183 */
181184 bool reg_dfs_domain_same(struct wiphy *wiphy1, struct wiphy *wiphy2);
185+
186+/**
187+ * reg_reload_regdb - reload the regulatory.db firmware file
188+ */
189+int reg_reload_regdb(void);
190+
191+extern const u8 shipped_regdb_certs[];
192+extern unsigned int shipped_regdb_certs_len;
193+extern const u8 extra_regdb_certs[];
194+extern unsigned int extra_regdb_certs_len;
195+
182196 #endif /* __NET_WIRELESS_REG_H */
net/wireless/regdb.h+0−23
@@ -1,23 +0,0 @@
1−#ifndef __REGDB_H__
2−#define __REGDB_H__
3−
4−/*
5− * Copyright 2009 John W. Linville <linville@tuxdriver.com>
6− *
7− * Permission to use, copy, modify, and/or distribute this software for any
8− * purpose with or without fee is hereby granted, provided that the above
9− * copyright notice and this permission notice appear in all copies.
10− *
11− * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12− * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13− * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14− * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15− * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16− * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17− * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18− */
19−
20−extern const struct ieee80211_regdomain *reg_regdb[];
21−extern int reg_regdb_size;
22−
23−#endif /* __REGDB_H__ */
net/wireless/sme.c+44−1
@@ -960,7 +960,6 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 959 unmodified lines
960960 ev->rm.resp_ie_len = info->resp_ie_len;
961961 memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len);
962962 ev->rm.bss = info->bss;
963− ev->rm.authorized = info->authorized;
964963
965964 spin_lock_irqsave(&wdev->event_lock, flags);
966965 list_add_tail(&ev->list, &wdev->event_list);
@@ -969,6 +968,50 @@ void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info, · 2 unmodified lines
969968 }
970969 EXPORT_SYMBOL(cfg80211_roamed);
971970
971+void __cfg80211_port_authorized(struct wireless_dev *wdev, const u8 *bssid)
972+{
973+ ASSERT_WDEV_LOCK(wdev);
974+
975+ if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
976+ return;
977+
978+ if (WARN_ON(!wdev->current_bss) ||
979+ WARN_ON(!ether_addr_equal(wdev->current_bss->pub.bssid, bssid)))
980+ return;
981+
982+ nl80211_send_port_authorized(wiphy_to_rdev(wdev->wiphy), wdev->netdev,
983+ bssid);
984+}
985+
986+void cfg80211_port_authorized(struct net_device *dev, const u8 *bssid,
987+ gfp_t gfp)
988+{
989+ struct wireless_dev *wdev = dev->ieee80211_ptr;
990+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
991+ struct cfg80211_event *ev;
992+ unsigned long flags;
993+
994+ if (WARN_ON(!bssid))
995+ return;
996+
997+ ev = kzalloc(sizeof(*ev), gfp);
998+ if (!ev)
999+ return;
1000+
1001+ ev->type = EVENT_PORT_AUTHORIZED;
1002+ memcpy(ev->pa.bssid, bssid, ETH_ALEN);
1003+
1004+ /*
1005+ * Use the wdev event list so that if there are pending
1006+ * connected/roamed events, they will be reported first.
1007+ */
1008+ spin_lock_irqsave(&wdev->event_lock, flags);
1009+ list_add_tail(&ev->list, &wdev->event_list);
1010+ spin_unlock_irqrestore(&wdev->event_lock, flags);
1011+ queue_work(cfg80211_wq, &rdev->event_work);
1012+}
1013+EXPORT_SYMBOL(cfg80211_port_authorized);
1014+
9721015 void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
9731016 size_t ie_len, u16 reason, bool from_ap)
9741017 {
net/wireless/util.c+63−139
@@ -157,32 +157,30 @@ static void set_mandatory_flags_band(struct ieee80211_supported_band *sband) · 156 unmodified lines
157157 case NL80211_BAND_2GHZ:
158158 want = 7;
159159 for (i = 0; i < sband->n_bitrates; i++) {
160− if (sband->bitrates[i].bitrate == 10) {
160+ switch (sband->bitrates[i].bitrate) {
161+ case 10:
162+ case 20:
163+ case 55:
164+ case 110:
161165 sband->bitrates[i].flags |=
162166 IEEE80211_RATE_MANDATORY_B |
163167 IEEE80211_RATE_MANDATORY_G;
164168 want--;
165− }
166−
167− if (sband->bitrates[i].bitrate == 20 ||
168− sband->bitrates[i].bitrate == 55 ||
169− sband->bitrates[i].bitrate == 110 ||
170− sband->bitrates[i].bitrate == 60 ||
171− sband->bitrates[i].bitrate == 120 ||
172− sband->bitrates[i].bitrate == 240) {
169+ break;
170+ case 60:
171+ case 120:
172+ case 240:
173173 sband->bitrates[i].flags |=
174174 IEEE80211_RATE_MANDATORY_G;
175175 want--;
176− }
177−
178− if (sband->bitrates[i].bitrate != 10 &&
179− sband->bitrates[i].bitrate != 20 &&
180− sband->bitrates[i].bitrate != 55 &&
181− sband->bitrates[i].bitrate != 110)
176+ /* fall through */
177+ default:
182178 sband->bitrates[i].flags |=
183179 IEEE80211_RATE_ERP_G;
180+ break;
181+ }
184182 }
185− WARN_ON(want != 0 && want != 3 && want != 6);
183+ WARN_ON(want != 0 && want != 3);
186184 break;
187185 case NL80211_BAND_60GHZ:
188186 /* check for mandatory HT MCS 1..4 */
@@ -529,121 +527,6 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, · 340 unmodified lines
529527 }
530528 EXPORT_SYMBOL(ieee80211_data_to_8023_exthdr);
531529
532−int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr,
533− enum nl80211_iftype iftype,
534− const u8 *bssid, bool qos)
535−{
536− struct ieee80211_hdr hdr;
537− u16 hdrlen, ethertype;
538− __le16 fc;
539− const u8 *encaps_data;
540− int encaps_len, skip_header_bytes;
541− int nh_pos, h_pos;
542− int head_need;
543−
544− if (unlikely(skb->len < ETH_HLEN))
545− return -EINVAL;
546−
547− nh_pos = skb_network_header(skb) - skb->data;
548− h_pos = skb_transport_header(skb) - skb->data;
549−
550− /* convert Ethernet header to proper 802.11 header (based on
551− * operation mode) */
552− ethertype = (skb->data[12] << 8) | skb->data[13];
553− fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
554−
555− switch (iftype) {
556− case NL80211_IFTYPE_AP:
557− case NL80211_IFTYPE_AP_VLAN:
558− case NL80211_IFTYPE_P2P_GO:
559− fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
560− /* DA BSSID SA */
561− memcpy(hdr.addr1, skb->data, ETH_ALEN);
562− memcpy(hdr.addr2, addr, ETH_ALEN);
563− memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
564− hdrlen = 24;
565− break;
566− case NL80211_IFTYPE_STATION:
567− case NL80211_IFTYPE_P2P_CLIENT:
568− fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
569− /* BSSID SA DA */
570− memcpy(hdr.addr1, bssid, ETH_ALEN);
571− memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
572− memcpy(hdr.addr3, skb->data, ETH_ALEN);
573− hdrlen = 24;
574− break;
575− case NL80211_IFTYPE_OCB:
576− case NL80211_IFTYPE_ADHOC:
577− /* DA SA BSSID */
578− memcpy(hdr.addr1, skb->data, ETH_ALEN);
579− memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
580− memcpy(hdr.addr3, bssid, ETH_ALEN);
581− hdrlen = 24;
582− break;
583− default:
584− return -EOPNOTSUPP;
585− }
586−
587− if (qos) {
588− fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
589− hdrlen += 2;
590− }
591−
592− hdr.frame_control = fc;
593− hdr.duration_id = 0;
594− hdr.seq_ctrl = 0;
595−
596− skip_header_bytes = ETH_HLEN;
597− if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
598− encaps_data = bridge_tunnel_header;
599− encaps_len = sizeof(bridge_tunnel_header);
600− skip_header_bytes -= 2;
601− } else if (ethertype >= ETH_P_802_3_MIN) {
602− encaps_data = rfc1042_header;
603− encaps_len = sizeof(rfc1042_header);
604− skip_header_bytes -= 2;
605− } else {
606− encaps_data = NULL;
607− encaps_len = 0;
608− }
609−
610− skb_pull(skb, skip_header_bytes);
611− nh_pos -= skip_header_bytes;
612− h_pos -= skip_header_bytes;
613−
614− head_need = hdrlen + encaps_len - skb_headroom(skb);
615−
616− if (head_need > 0 || skb_cloned(skb)) {
617− head_need = max(head_need, 0);
618− if (head_need)
619− skb_orphan(skb);
620−
621− if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC))
622− return -ENOMEM;
623− }
624−
625− if (encaps_data) {
626− memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
627− nh_pos += encaps_len;
628− h_pos += encaps_len;
629− }
630−
631− memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
632−
633− nh_pos += hdrlen;
634− h_pos += hdrlen;
635−
636− /* Update skb pointers to various headers since this modified frame
637− * is going to go through Linux networking code that may potentially
638− * need things like pointer to IP header. */
639− skb_reset_mac_header(skb);
640− skb_set_network_header(skb, nh_pos);
641− skb_set_transport_header(skb, h_pos);
642−
643− return 0;
644−}
645−EXPORT_SYMBOL(ieee80211_data_from_8023);
646−
647530 static void
648531 __frame_add_frag(struct sk_buff *skb, struct page *page,
649532 void *ptr, int len, int size)
@@ -963,6 +846,9 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev) · 313 unmodified lines
963846 case EVENT_STOPPED:
964847 __cfg80211_leave(wiphy_to_rdev(wdev->wiphy), wdev);
965848 break;
849+ case EVENT_PORT_AUTHORIZED:
850+ __cfg80211_port_authorized(wdev, ev->pa.bssid);
851+ break;
966852 }
967853 wdev_unlock(wdev);
968854
@@ -1367,13 +1253,29 @@ int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, · 398 unmodified lines
13671253 }
13681254 EXPORT_SYMBOL(cfg80211_get_p2p_attr);
13691255
1370−static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id)
1256+static bool ieee80211_id_in_list(const u8 *ids, int n_ids, u8 id, bool id_ext)
13711257 {
13721258 int i;
13731259
1374− for (i = 0; i < n_ids; i++)
1375− if (ids[i] == id)
1260+ /* Make sure array values are legal */
1261+ if (WARN_ON(ids[n_ids - 1] == WLAN_EID_EXTENSION))
1262+ return false;
1263+
1264+ i = 0;
1265+ while (i < n_ids) {
1266+ if (ids[i] == WLAN_EID_EXTENSION) {
1267+ if (id_ext && (ids[i + 1] == id))
1268+ return true;
1269+
1270+ i += 2;
1271+ continue;
1272+ }
1273+
1274+ if (ids[i] == id && !id_ext)
13761275 return true;
1276+
1277+ i++;
1278+ }
13771279 return false;
13781280 }
13791281
@@ -1403,14 +1305,36 @@ size_t ieee80211_ie_split_ric(const u8 *ies, size_t ielen, · 23 unmodified lines
14031305 {
14041306 size_t pos = offset;
14051307
1406− while (pos < ielen && ieee80211_id_in_list(ids, n_ids, ies[pos])) {
1308+ while (pos < ielen) {
1309+ u8 ext = 0;
1310+
1311+ if (ies[pos] == WLAN_EID_EXTENSION)
1312+ ext = 2;
1313+ if ((pos + ext) >= ielen)
1314+ break;
1315+
1316+ if (!ieee80211_id_in_list(ids, n_ids, ies[pos + ext],
1317+ ies[pos] == WLAN_EID_EXTENSION))
1318+ break;
1319+
14071320 if (ies[pos] == WLAN_EID_RIC_DATA && n_after_ric) {
14081321 pos = skip_ie(ies, ielen, pos);
14091322
1410− while (pos < ielen &&
1411− !ieee80211_id_in_list(after_ric, n_after_ric,
1412− ies[pos]))
1413− pos = skip_ie(ies, ielen, pos);
1323+ while (pos < ielen) {
1324+ if (ies[pos] == WLAN_EID_EXTENSION)
1325+ ext = 2;
1326+ else
1327+ ext = 0;
1328+
1329+ if ((pos + ext) >= ielen)
1330+ break;
1331+
1332+ if (!ieee80211_id_in_list(after_ric,
1333+ n_after_ric,
1334+ ies[pos + ext],
1335+ ext == 2))
1336+ pos = skip_ie(ies, ielen, pos);
1337+ }
14141338 } else {
14151339 pos = skip_ie(ies, ielen, pos);
14161340 }