Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'wireless-next-2023-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next

Johannes Berg says:

====================
wireless-next patches for 6.4

Major changes:

cfg80211
* 6 GHz improvements
* HW timestamping support
* support for randomized auth/deauth TA for PASN privacy
(also for mac80211)

mac80211
* radiotap TLV and EHT support for the iwlwifi sniffer
* HW timestamping support
* per-link debugfs for multi-link

brcmfmac
* support for Apple (M1 Pro/Max) devices

iwlwifi
* support for a few new devices
* EHT sniffer support

rtw88
* better support for some SDIO devices
(e.g. MAC address from efuse)

rtw89
* HW scan support for 8852b
* better support for 6 GHz scanning

* tag 'wireless-next-2023-03-10' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless-next: (84 commits)
wifi: iwlwifi: mvm: fix EOF bit reporting
wifi: iwlwifi: Do not include radiotap EHT user info if not needed
wifi: iwlwifi: mvm: add EHT RU allocation to radiotap
wifi: iwlwifi: Update logs for yoyo reset sw changes
wifi: iwlwifi: mvm: clean up duplicated defines
wifi: iwlwifi: rs-fw: break out for unsupported bandwidth
wifi: iwlwifi: Add support for B step of BnJ-Fm4
wifi: iwlwifi: mvm: make flush code a bit clearer
wifi: iwlwifi: mvm: avoid UB shift of snif_queue
wifi: iwlwifi: mvm: add primary 80 known for EHT radiotap
wifi: iwlwifi: mvm: parse FW frame metadata for EHT sniffer mode
wifi: iwlwifi: mvm: decode USIG_B1_B7 RU to nl80211 RU width
wifi: iwlwifi: mvm: rename define to generic name
wifi: iwlwifi: mvm: allow Microsoft to use TAS
wifi: iwlwifi: mvm: add all EHT based on data0 info from HW
wifi: iwlwifi: mvm: add EHT radiotap info based on rate_n_flags
wifi: iwlwifi: mvm: add an helper function radiotap TLVs
wifi: radiotap: separate vendor TLV into header/content
wifi: iwlwifi: reduce verbosity of some logging events
wifi: iwlwifi: Adding the code to get RF name for MsP device
...
====================

Link: https://lore.kernel.org/r/20230310120159.36518-1-johannes@sipsolutions.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+2645 -643
+2
drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
··· 48 48 of.o 49 49 brcmfmac-$(CONFIG_DMI) += \ 50 50 dmi.o 51 + brcmfmac-$(CONFIG_ACPI) += \ 52 + acpi.o 51 53 52 54 ifeq ($(CONFIG_BRCMFMAC),m) 53 55 obj-m += wcc/
+51
drivers/net/wireless/broadcom/brcm80211/brcmfmac/acpi.c
··· 1 + // SPDX-License-Identifier: ISC 2 + /* 3 + * Copyright The Asahi Linux Contributors 4 + */ 5 + 6 + #include <linux/acpi.h> 7 + #include "debug.h" 8 + #include "core.h" 9 + #include "common.h" 10 + 11 + void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type, 12 + struct brcmf_mp_device *settings) 13 + { 14 + acpi_status status; 15 + const union acpi_object *o; 16 + struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL}; 17 + struct acpi_device *adev = ACPI_COMPANION(dev); 18 + 19 + if (!adev) 20 + return; 21 + 22 + if (!ACPI_FAILURE(acpi_dev_get_property(adev, "module-instance", 23 + ACPI_TYPE_STRING, &o))) { 24 + brcmf_dbg(INFO, "ACPI module-instance=%s\n", o->string.pointer); 25 + settings->board_type = devm_kasprintf(dev, GFP_KERNEL, 26 + "apple,%s", 27 + o->string.pointer); 28 + } else { 29 + brcmf_dbg(INFO, "No ACPI module-instance\n"); 30 + return; 31 + } 32 + 33 + status = acpi_evaluate_object(adev->handle, "RWCV", NULL, &buf); 34 + o = buf.pointer; 35 + if (!ACPI_FAILURE(status) && o && o->type == ACPI_TYPE_BUFFER && 36 + o->buffer.length >= 2) { 37 + char *antenna_sku = devm_kzalloc(dev, 3, GFP_KERNEL); 38 + 39 + if (antenna_sku) { 40 + memcpy(antenna_sku, o->buffer.pointer, 2); 41 + brcmf_dbg(INFO, "ACPI RWCV data=%*phN antenna-sku=%s\n", 42 + (int)o->buffer.length, o->buffer.pointer, 43 + antenna_sku); 44 + settings->antenna_sku = antenna_sku; 45 + } 46 + 47 + kfree(buf.pointer); 48 + } else { 49 + brcmf_dbg(INFO, "No ACPI antenna-sku\n"); 50 + } 51 + }
+1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
··· 55 55 /* Firmware blobs that may be available */ 56 56 enum brcmf_blob_type { 57 57 BRCMF_BLOB_CLM, 58 + BRCMF_BLOB_TXCAP, 58 59 }; 59 60 60 61 struct brcmf_mp_device;
+221 -103
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
··· 1039 1039 } 1040 1040 } 1041 1041 1042 + static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le, 1043 + struct brcmf_scan_params_le *params_le) 1044 + { 1045 + size_t params_size; 1046 + u32 ch; 1047 + int n_channels, n_ssids; 1048 + 1049 + memcpy(&params_le->ssid_le, &params_v2_le->ssid_le, 1050 + sizeof(params_le->ssid_le)); 1051 + memcpy(&params_le->bssid, &params_v2_le->bssid, 1052 + sizeof(params_le->bssid)); 1053 + 1054 + params_le->bss_type = params_v2_le->bss_type; 1055 + params_le->scan_type = le32_to_cpu(params_v2_le->scan_type); 1056 + params_le->nprobes = params_v2_le->nprobes; 1057 + params_le->active_time = params_v2_le->active_time; 1058 + params_le->passive_time = params_v2_le->passive_time; 1059 + params_le->home_time = params_v2_le->home_time; 1060 + params_le->channel_num = params_v2_le->channel_num; 1061 + 1062 + ch = le32_to_cpu(params_v2_le->channel_num); 1063 + n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK; 1064 + n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT; 1065 + 1066 + params_size = sizeof(u16) * n_channels; 1067 + if (n_ssids > 0) { 1068 + params_size = roundup(params_size, sizeof(u32)); 1069 + params_size += sizeof(struct brcmf_ssid_le) * n_ssids; 1070 + } 1071 + 1072 + memcpy(&params_le->channel_list[0], 1073 + &params_v2_le->channel_list[0], params_size); 1074 + } 1075 + 1076 + static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, 1077 + struct brcmf_scan_params_v2_le *params_le, 1078 + struct cfg80211_scan_request *request) 1079 + { 1080 + u32 n_ssids; 1081 + u32 n_channels; 1082 + s32 i; 1083 + s32 offset; 1084 + u16 chanspec; 1085 + char *ptr; 1086 + int length; 1087 + struct brcmf_ssid_le ssid_le; 1088 + 1089 + eth_broadcast_addr(params_le->bssid); 1090 + 1091 + length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE; 1092 + 1093 + params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V2); 1094 + params_le->bss_type = DOT11_BSSTYPE_ANY; 1095 + params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_ACTIVE); 1096 + params_le->channel_num = 0; 1097 + params_le->nprobes = cpu_to_le32(-1); 1098 + params_le->active_time = cpu_to_le32(-1); 1099 + params_le->passive_time = cpu_to_le32(-1); 1100 + params_le->home_time = cpu_to_le32(-1); 1101 + memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le)); 1102 + 1103 + /* Scan abort */ 1104 + if (!request) { 1105 + length += sizeof(u16); 1106 + params_le->channel_num = cpu_to_le32(1); 1107 + params_le->channel_list[0] = cpu_to_le16(-1); 1108 + params_le->length = cpu_to_le16(length); 1109 + return; 1110 + } 1111 + 1112 + n_ssids = request->n_ssids; 1113 + n_channels = request->n_channels; 1114 + 1115 + /* Copy channel array if applicable */ 1116 + brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", 1117 + n_channels); 1118 + if (n_channels > 0) { 1119 + length += roundup(sizeof(u16) * n_channels, sizeof(u32)); 1120 + for (i = 0; i < n_channels; i++) { 1121 + chanspec = channel_to_chanspec(&cfg->d11inf, 1122 + request->channels[i]); 1123 + brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n", 1124 + request->channels[i]->hw_value, chanspec); 1125 + params_le->channel_list[i] = cpu_to_le16(chanspec); 1126 + } 1127 + } else { 1128 + brcmf_dbg(SCAN, "Scanning all channels\n"); 1129 + } 1130 + 1131 + /* Copy ssid array if applicable */ 1132 + brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids); 1133 + if (n_ssids > 0) { 1134 + offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) + 1135 + n_channels * sizeof(u16); 1136 + offset = roundup(offset, sizeof(u32)); 1137 + length += sizeof(ssid_le) * n_ssids, 1138 + ptr = (char *)params_le + offset; 1139 + for (i = 0; i < n_ssids; i++) { 1140 + memset(&ssid_le, 0, sizeof(ssid_le)); 1141 + ssid_le.SSID_len = 1142 + cpu_to_le32(request->ssids[i].ssid_len); 1143 + memcpy(ssid_le.SSID, request->ssids[i].ssid, 1144 + request->ssids[i].ssid_len); 1145 + if (!ssid_le.SSID_len) 1146 + brcmf_dbg(SCAN, "%d: Broadcast scan\n", i); 1147 + else 1148 + brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n", 1149 + i, ssid_le.SSID, ssid_le.SSID_len); 1150 + memcpy(ptr, &ssid_le, sizeof(ssid_le)); 1151 + ptr += sizeof(ssid_le); 1152 + } 1153 + } else { 1154 + brcmf_dbg(SCAN, "Performing passive scan\n"); 1155 + params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_PASSIVE); 1156 + } 1157 + params_le->length = cpu_to_le16(length); 1158 + /* Adding mask to channel numbers */ 1159 + params_le->channel_num = 1160 + cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) | 1161 + (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK)); 1162 + } 1163 + 1042 1164 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, 1043 1165 struct brcmf_if *ifp, bool aborted, 1044 1166 bool fw_abort) 1045 1167 { 1046 1168 struct brcmf_pub *drvr = cfg->pub; 1047 - struct brcmf_scan_params_le params_le; 1169 + struct brcmf_scan_params_v2_le params_v2_le; 1048 1170 struct cfg80211_scan_request *scan_request; 1049 1171 u64 reqid; 1050 1172 u32 bucket; ··· 1185 1063 if (fw_abort) { 1186 1064 /* Do a scan abort to stop the driver's scan engine */ 1187 1065 brcmf_dbg(SCAN, "ABORT scan in firmware\n"); 1188 - memset(&params_le, 0, sizeof(params_le)); 1189 - eth_broadcast_addr(params_le.bssid); 1190 - params_le.bss_type = DOT11_BSSTYPE_ANY; 1191 - params_le.scan_type = 0; 1192 - params_le.channel_num = cpu_to_le32(1); 1193 - params_le.nprobes = cpu_to_le32(1); 1194 - params_le.active_time = cpu_to_le32(-1); 1195 - params_le.passive_time = cpu_to_le32(-1); 1196 - params_le.home_time = cpu_to_le32(-1); 1197 - /* Scan is aborted by setting channel_list[0] to -1 */ 1198 - params_le.channel_list[0] = cpu_to_le16(-1); 1066 + 1067 + brcmf_escan_prep(cfg, &params_v2_le, NULL); 1068 + 1199 1069 /* E-Scan (or anyother type) can be aborted by SCAN */ 1200 - err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, 1201 - &params_le, sizeof(params_le)); 1070 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) { 1071 + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, 1072 + &params_v2_le, 1073 + sizeof(params_v2_le)); 1074 + } else { 1075 + struct brcmf_scan_params_le params_le; 1076 + 1077 + brcmf_scan_params_v2_to_v1(&params_v2_le, &params_le); 1078 + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, 1079 + &params_le, 1080 + sizeof(params_le)); 1081 + } 1082 + 1202 1083 if (err) 1203 1084 bphy_err(drvr, "Scan abort failed\n"); 1204 1085 } ··· 1420 1295 return err; 1421 1296 } 1422 1297 1423 - static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg, 1424 - struct brcmf_scan_params_le *params_le, 1425 - struct cfg80211_scan_request *request) 1426 - { 1427 - u32 n_ssids; 1428 - u32 n_channels; 1429 - s32 i; 1430 - s32 offset; 1431 - u16 chanspec; 1432 - char *ptr; 1433 - struct brcmf_ssid_le ssid_le; 1434 - 1435 - eth_broadcast_addr(params_le->bssid); 1436 - params_le->bss_type = DOT11_BSSTYPE_ANY; 1437 - params_le->scan_type = BRCMF_SCANTYPE_ACTIVE; 1438 - params_le->channel_num = 0; 1439 - params_le->nprobes = cpu_to_le32(-1); 1440 - params_le->active_time = cpu_to_le32(-1); 1441 - params_le->passive_time = cpu_to_le32(-1); 1442 - params_le->home_time = cpu_to_le32(-1); 1443 - memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le)); 1444 - 1445 - n_ssids = request->n_ssids; 1446 - n_channels = request->n_channels; 1447 - 1448 - /* Copy channel array if applicable */ 1449 - brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n", 1450 - n_channels); 1451 - if (n_channels > 0) { 1452 - for (i = 0; i < n_channels; i++) { 1453 - chanspec = channel_to_chanspec(&cfg->d11inf, 1454 - request->channels[i]); 1455 - brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n", 1456 - request->channels[i]->hw_value, chanspec); 1457 - params_le->channel_list[i] = cpu_to_le16(chanspec); 1458 - } 1459 - } else { 1460 - brcmf_dbg(SCAN, "Scanning all channels\n"); 1461 - } 1462 - /* Copy ssid array if applicable */ 1463 - brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids); 1464 - if (n_ssids > 0) { 1465 - offset = offsetof(struct brcmf_scan_params_le, channel_list) + 1466 - n_channels * sizeof(u16); 1467 - offset = roundup(offset, sizeof(u32)); 1468 - ptr = (char *)params_le + offset; 1469 - for (i = 0; i < n_ssids; i++) { 1470 - memset(&ssid_le, 0, sizeof(ssid_le)); 1471 - ssid_le.SSID_len = 1472 - cpu_to_le32(request->ssids[i].ssid_len); 1473 - memcpy(ssid_le.SSID, request->ssids[i].ssid, 1474 - request->ssids[i].ssid_len); 1475 - if (!ssid_le.SSID_len) 1476 - brcmf_dbg(SCAN, "%d: Broadcast scan\n", i); 1477 - else 1478 - brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n", 1479 - i, ssid_le.SSID, ssid_le.SSID_len); 1480 - memcpy(ptr, &ssid_le, sizeof(ssid_le)); 1481 - ptr += sizeof(ssid_le); 1482 - } 1483 - } else { 1484 - brcmf_dbg(SCAN, "Performing passive scan\n"); 1485 - params_le->scan_type = BRCMF_SCANTYPE_PASSIVE; 1486 - } 1487 - /* Adding mask to channel numbers */ 1488 - params_le->channel_num = 1489 - cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) | 1490 - (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK)); 1491 - } 1492 - 1493 1298 static s32 1494 1299 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, 1495 1300 struct cfg80211_scan_request *request) 1496 1301 { 1497 1302 struct brcmf_pub *drvr = cfg->pub; 1498 - s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + 1499 - offsetof(struct brcmf_escan_params_le, params_le); 1303 + s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE + 1304 + offsetof(struct brcmf_escan_params_le, params_v2_le); 1500 1305 struct brcmf_escan_params_le *params; 1501 1306 s32 err = 0; 1502 1307 ··· 1446 1391 goto exit; 1447 1392 } 1448 1393 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN); 1449 - brcmf_escan_prep(cfg, &params->params_le, request); 1450 - params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); 1394 + brcmf_escan_prep(cfg, &params->params_v2_le, request); 1395 + 1396 + params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V2); 1397 + 1398 + if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) { 1399 + struct brcmf_escan_params_le *params_v1; 1400 + 1401 + params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE; 1402 + params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE; 1403 + params_v1 = kzalloc(params_size, GFP_KERNEL); 1404 + params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION); 1405 + brcmf_scan_params_v2_to_v1(&params->params_v2_le, &params_v1->params_le); 1406 + kfree(params); 1407 + params = params_v1; 1408 + } 1409 + 1451 1410 params->action = cpu_to_le16(WL_ESCAN_ACTION_START); 1452 1411 params->sync_id = cpu_to_le16(0x1234); 1453 1412 ··· 1686 1617 { 1687 1618 struct brcmf_pub *drvr = ifp->drvr; 1688 1619 struct brcmf_wsec_pmk_le pmk; 1689 - int i, err; 1620 + int err; 1690 1621 1691 - /* convert to firmware key format */ 1692 - pmk.key_len = cpu_to_le16(pmk_len << 1); 1693 - pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE); 1694 - for (i = 0; i < pmk_len; i++) 1695 - snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]); 1622 + memset(&pmk, 0, sizeof(pmk)); 1623 + 1624 + /* pass pmk directly */ 1625 + pmk.key_len = cpu_to_le16(pmk_len); 1626 + pmk.flags = cpu_to_le16(0); 1627 + memcpy(pmk.key, pmk_data, pmk_len); 1696 1628 1697 1629 /* store psk in firmware */ 1698 1630 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, ··· 4307 4237 return 0; 4308 4238 } 4309 4239 4240 + static s32 4241 + brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa, 4242 + bool alive) 4243 + { 4244 + struct brcmf_pmk_op_v3_le *pmk_op; 4245 + int length = offsetof(struct brcmf_pmk_op_v3_le, pmk); 4246 + int ret; 4247 + 4248 + pmk_op = kzalloc(sizeof(*pmk_op), GFP_KERNEL); 4249 + pmk_op->version = cpu_to_le16(BRCMF_PMKSA_VER_3); 4250 + 4251 + if (!pmksa) { 4252 + /* Flush operation, operate on entire list */ 4253 + pmk_op->count = cpu_to_le16(0); 4254 + } else { 4255 + /* Single PMK operation */ 4256 + pmk_op->count = cpu_to_le16(1); 4257 + length += sizeof(struct brcmf_pmksa_v3); 4258 + memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN); 4259 + memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN); 4260 + pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN; 4261 + pmk_op->pmk[0].time_left = cpu_to_le32(alive ? BRCMF_PMKSA_NO_EXPIRY : 0); 4262 + } 4263 + 4264 + pmk_op->length = cpu_to_le16(length); 4265 + 4266 + ret = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_op, sizeof(*pmk_op)); 4267 + kfree(pmk_op); 4268 + return ret; 4269 + } 4270 + 4310 4271 static __used s32 4311 4272 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp) 4312 4273 { ··· 4371 4270 if (!check_vif_up(ifp->vif)) 4372 4271 return -EIO; 4373 4272 4273 + brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmksa->bssid); 4274 + brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmksa->pmkid); 4275 + 4276 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3)) 4277 + return brcmf_pmksa_v3_op(ifp, pmksa, true); 4278 + 4279 + /* TODO: implement PMKID_V2 */ 4280 + 4374 4281 npmk = le32_to_cpu(cfg->pmk_list.npmk); 4375 4282 for (i = 0; i < npmk; i++) 4376 4283 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN)) ··· 4394 4285 bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk); 4395 4286 return -EINVAL; 4396 4287 } 4397 - 4398 - brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid); 4399 - brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmk[npmk].pmkid); 4400 4288 4401 4289 err = brcmf_update_pmklist(cfg, ifp); 4402 4290 ··· 4417 4311 return -EIO; 4418 4312 4419 4313 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid); 4314 + 4315 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3)) 4316 + return brcmf_pmksa_v3_op(ifp, pmksa, false); 4317 + 4318 + /* TODO: implement PMKID_V2 */ 4420 4319 4421 4320 npmk = le32_to_cpu(cfg->pmk_list.npmk); 4422 4321 for (i = 0; i < npmk; i++) ··· 4458 4347 brcmf_dbg(TRACE, "Enter\n"); 4459 4348 if (!check_vif_up(ifp->vif)) 4460 4349 return -EIO; 4350 + 4351 + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3)) 4352 + return brcmf_pmksa_v3_op(ifp, NULL, false); 4353 + 4354 + /* TODO: implement PMKID_V2 */ 4461 4355 4462 4356 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list)); 4463 4357 err = brcmf_update_pmklist(cfg, ifp); ··· 6605 6489 { 6606 6490 struct brcmf_cfg80211_vif *vif = ifp->vif; 6607 6491 struct brcmf_rssi_be *info = data; 6608 - s32 rssi, snr, noise; 6492 + s32 rssi, snr = 0, noise = 0; 6609 6493 s32 low, high, last; 6610 6494 6611 - if (e->datalen < sizeof(*info)) { 6495 + if (e->datalen >= sizeof(*info)) { 6496 + rssi = be32_to_cpu(info->rssi); 6497 + snr = be32_to_cpu(info->snr); 6498 + noise = be32_to_cpu(info->noise); 6499 + } else if (e->datalen >= sizeof(rssi)) { 6500 + rssi = be32_to_cpu(*(__be32 *)data); 6501 + } else { 6612 6502 brcmf_err("insufficient RSSI event data\n"); 6613 6503 return 0; 6614 6504 } 6615 - 6616 - rssi = be32_to_cpu(info->rssi); 6617 - snr = be32_to_cpu(info->snr); 6618 - noise = be32_to_cpu(info->noise); 6619 6505 6620 6506 low = vif->cqm_rssi_low; 6621 6507 high = vif->cqm_rssi_high;
+18 -7
drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
··· 212 212 #define ARMCR4_TCBANB_MASK 0xf 213 213 #define ARMCR4_TCBANB_SHIFT 0 214 214 215 - #define ARMCR4_BSZ_MASK 0x3f 215 + #define ARMCR4_BSZ_MASK 0x7f 216 216 #define ARMCR4_BSZ_MULT 8192 217 + #define ARMCR4_BLK_1K_MASK 0x200 217 218 218 219 struct brcmf_core_priv { 219 220 struct brcmf_core pub; ··· 685 684 u32 nbb; 686 685 u32 totb; 687 686 u32 bxinfo; 687 + u32 blksize; 688 688 u32 idx; 689 689 690 690 corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP); ··· 697 695 for (idx = 0; idx < totb; idx++) { 698 696 brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx); 699 697 bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO); 700 - memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT; 698 + blksize = ARMCR4_BSZ_MULT; 699 + if (bxinfo & ARMCR4_BLK_1K_MASK) 700 + blksize >>= 3; 701 + 702 + memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * blksize; 701 703 } 702 704 703 705 return memsize; ··· 743 737 return 0x170000; 744 738 case BRCM_CC_4378_CHIP_ID: 745 739 return 0x352000; 740 + case BRCM_CC_4387_CHIP_ID: 741 + return 0x740000; 746 742 default: 747 743 brcmf_err("unknown chip: %s\n", ci->pub.name); 748 744 break; ··· 1300 1292 static inline void 1301 1293 brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip) 1302 1294 { 1295 + int i; 1303 1296 struct brcmf_core *core; 1304 1297 1305 1298 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4); 1306 1299 1307 - core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211); 1308 - brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET | 1309 - D11_BCMA_IOCTL_PHYCLOCKEN, 1310 - D11_BCMA_IOCTL_PHYCLOCKEN, 1311 - D11_BCMA_IOCTL_PHYCLOCKEN); 1300 + /* Disable the cores only and let the firmware enable them. 1301 + * Releasing reset ourselves breaks BCM4387 in weird ways. 1302 + */ 1303 + for (i = 0; (core = brcmf_chip_get_d11core(&chip->pub, i)); i++) 1304 + brcmf_chip_coredisable(core, D11_BCMA_IOCTL_PHYRESET | 1305 + D11_BCMA_IOCTL_PHYCLOCKEN, 1306 + D11_BCMA_IOCTL_PHYCLOCKEN); 1312 1307 } 1313 1308 1314 1309 static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
+94 -24
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
··· 101 101 102 102 static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, 103 103 struct brcmf_dload_data_le *dload_buf, 104 - u32 len) 104 + u32 len, const char *var) 105 105 { 106 106 s32 err; 107 107 ··· 111 111 dload_buf->len = cpu_to_le32(len); 112 112 dload_buf->crc = cpu_to_le32(0); 113 113 114 - err = brcmf_fil_iovar_data_set(ifp, "clmload", dload_buf, 114 + err = brcmf_fil_iovar_data_set(ifp, var, dload_buf, 115 115 struct_size(dload_buf, data, len)); 116 116 117 117 return err; 118 118 } 119 119 120 - static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) 120 + static int brcmf_c_download_blob(struct brcmf_if *ifp, 121 + const void *data, size_t size, 122 + const char *loadvar, const char *statvar) 121 123 { 122 124 struct brcmf_pub *drvr = ifp->drvr; 123 - struct brcmf_bus *bus = drvr->bus_if; 124 125 struct brcmf_dload_data_le *chunk_buf; 125 - const struct firmware *clm = NULL; 126 126 u32 chunk_len; 127 127 u32 datalen; 128 128 u32 cumulative_len; ··· 132 132 133 133 brcmf_dbg(TRACE, "Enter\n"); 134 134 135 - err = brcmf_bus_get_blob(bus, &clm, BRCMF_BLOB_CLM); 136 - if (err || !clm) { 137 - brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", 138 - err); 139 - return 0; 140 - } 141 - 142 135 chunk_buf = kzalloc(struct_size(chunk_buf, data, MAX_CHUNK_LEN), 143 136 GFP_KERNEL); 144 137 if (!chunk_buf) { 145 138 err = -ENOMEM; 146 - goto done; 139 + return -ENOMEM; 147 140 } 148 141 149 - datalen = clm->size; 142 + datalen = size; 150 143 cumulative_len = 0; 151 144 do { 152 145 if (datalen > MAX_CHUNK_LEN) { ··· 148 155 chunk_len = datalen; 149 156 dl_flag |= DL_END; 150 157 } 151 - memcpy(chunk_buf->data, clm->data + cumulative_len, chunk_len); 158 + memcpy(chunk_buf->data, data + cumulative_len, chunk_len); 152 159 153 - err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len); 160 + err = brcmf_c_download(ifp, dl_flag, chunk_buf, chunk_len, 161 + loadvar); 154 162 155 163 dl_flag &= ~DL_BEGIN; 156 164 ··· 160 166 } while ((datalen > 0) && (err == 0)); 161 167 162 168 if (err) { 163 - bphy_err(drvr, "clmload (%zu byte file) failed (%d)\n", 164 - clm->size, err); 165 - /* Retrieve clmload_status and print */ 166 - err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); 169 + bphy_err(drvr, "%s (%zu byte file) failed (%d)\n", 170 + loadvar, size, err); 171 + /* Retrieve status and print */ 172 + err = brcmf_fil_iovar_int_get(ifp, statvar, &status); 167 173 if (err) 168 - bphy_err(drvr, "get clmload_status failed (%d)\n", err); 174 + bphy_err(drvr, "get %s failed (%d)\n", statvar, err); 169 175 else 170 - brcmf_dbg(INFO, "clmload_status=%d\n", status); 176 + brcmf_dbg(INFO, "%s=%d\n", statvar, status); 171 177 err = -EIO; 172 178 } 173 179 174 180 kfree(chunk_buf); 175 - done: 176 - release_firmware(clm); 181 + return err; 182 + } 183 + 184 + static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) 185 + { 186 + struct brcmf_pub *drvr = ifp->drvr; 187 + struct brcmf_bus *bus = drvr->bus_if; 188 + const struct firmware *fw = NULL; 189 + s32 err; 190 + 191 + brcmf_dbg(TRACE, "Enter\n"); 192 + 193 + err = brcmf_bus_get_blob(bus, &fw, BRCMF_BLOB_CLM); 194 + if (err || !fw) { 195 + brcmf_info("no clm_blob available (err=%d), device may have limited channels available\n", 196 + err); 197 + return 0; 198 + } 199 + 200 + err = brcmf_c_download_blob(ifp, fw->data, fw->size, 201 + "clmload", "clmload_status"); 202 + 203 + release_firmware(fw); 204 + return err; 205 + } 206 + 207 + static int brcmf_c_process_txcap_blob(struct brcmf_if *ifp) 208 + { 209 + struct brcmf_pub *drvr = ifp->drvr; 210 + struct brcmf_bus *bus = drvr->bus_if; 211 + const struct firmware *fw = NULL; 212 + s32 err; 213 + 214 + brcmf_dbg(TRACE, "Enter\n"); 215 + 216 + err = brcmf_bus_get_blob(bus, &fw, BRCMF_BLOB_TXCAP); 217 + if (err || !fw) { 218 + brcmf_info("no txcap_blob available (err=%d)\n", err); 219 + return 0; 220 + } 221 + 222 + brcmf_info("TxCap blob found, loading\n"); 223 + err = brcmf_c_download_blob(ifp, fw->data, fw->size, 224 + "txcapload", "txcapload_status"); 225 + 226 + release_firmware(fw); 177 227 return err; 178 228 } 179 229 ··· 245 207 static const u8 brcmf_default_mac_address[ETH_ALEN] = { 246 208 0x00, 0x90, 0x4c, 0xc5, 0x12, 0x38 247 209 }; 210 + 211 + static int brcmf_c_process_cal_blob(struct brcmf_if *ifp) 212 + { 213 + struct brcmf_pub *drvr = ifp->drvr; 214 + struct brcmf_mp_device *settings = drvr->settings; 215 + s32 err; 216 + 217 + brcmf_dbg(TRACE, "Enter\n"); 218 + 219 + if (!settings->cal_blob || !settings->cal_size) 220 + return 0; 221 + 222 + brcmf_info("Calibration blob provided by platform, loading\n"); 223 + err = brcmf_c_download_blob(ifp, settings->cal_blob, settings->cal_size, 224 + "calload", "calload_status"); 225 + return err; 226 + } 248 227 249 228 int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) 250 229 { ··· 343 288 err = brcmf_c_process_clm_blob(ifp); 344 289 if (err < 0) { 345 290 bphy_err(drvr, "download CLM blob file failed, %d\n", err); 291 + goto done; 292 + } 293 + 294 + /* Do TxCap downloading, if needed */ 295 + err = brcmf_c_process_txcap_blob(ifp); 296 + if (err < 0) { 297 + bphy_err(drvr, "download TxCap blob file failed, %d\n", err); 298 + goto done; 299 + } 300 + 301 + /* Download external calibration blob, if available */ 302 + err = brcmf_c_process_cal_blob(ifp); 303 + if (err < 0) { 304 + bphy_err(drvr, "download calibration blob file failed, %d\n", err); 346 305 goto done; 347 306 } 348 307 ··· 556 487 /* No platform data for this device, try OF and DMI data */ 557 488 brcmf_dmi_probe(settings, chip, chiprev); 558 489 brcmf_of_probe(dev, bus_type, settings); 490 + brcmf_acpi_probe(dev, bus_type, settings); 559 491 } 560 492 return settings; 561 493 }
+11
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
··· 54 54 const char *board_type; 55 55 unsigned char mac[ETH_ALEN]; 56 56 const char *antenna_sku; 57 + const void *cal_blob; 58 + int cal_size; 57 59 union { 58 60 struct brcmfmac_sdio_pd sdio; 59 61 } bus; ··· 77 75 #else 78 76 static inline void 79 77 brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {} 78 + #endif 79 + 80 + #ifdef CONFIG_ACPI 81 + void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type, 82 + struct brcmf_mp_device *settings); 83 + #else 84 + static inline void brcmf_acpi_probe(struct device *dev, 85 + enum brcmf_bus_type bus_type, 86 + struct brcmf_mp_device *settings) {} 80 87 #endif 81 88 82 89 u8 brcmf_map_prio_to_prec(void *cfg, u8 prio);
+49
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
··· 126 126 drv->feat_flags |= feat_flags; 127 127 } 128 128 129 + struct brcmf_feat_wlcfeat { 130 + u16 min_ver_major; 131 + u16 min_ver_minor; 132 + u32 feat_flags; 133 + }; 134 + 135 + static const struct brcmf_feat_wlcfeat brcmf_feat_wlcfeat_map[] = { 136 + { 12, 0, BIT(BRCMF_FEAT_PMKID_V2) }, 137 + { 13, 0, BIT(BRCMF_FEAT_PMKID_V3) }, 138 + }; 139 + 140 + static void brcmf_feat_wlc_version_overrides(struct brcmf_pub *drv) 141 + { 142 + struct brcmf_if *ifp = brcmf_get_ifp(drv, 0); 143 + const struct brcmf_feat_wlcfeat *e; 144 + struct brcmf_wlc_version_le ver; 145 + u32 feat_flags = 0; 146 + int i, err, major, minor; 147 + 148 + err = brcmf_fil_iovar_data_get(ifp, "wlc_ver", &ver, sizeof(ver)); 149 + if (err) 150 + return; 151 + 152 + major = le16_to_cpu(ver.wlc_ver_major); 153 + minor = le16_to_cpu(ver.wlc_ver_minor); 154 + 155 + brcmf_dbg(INFO, "WLC version: %d.%d\n", major, minor); 156 + 157 + for (i = 0; i < ARRAY_SIZE(brcmf_feat_wlcfeat_map); i++) { 158 + e = &brcmf_feat_wlcfeat_map[i]; 159 + if (major > e->min_ver_major || 160 + (major == e->min_ver_major && 161 + minor >= e->min_ver_minor)) { 162 + feat_flags |= e->feat_flags; 163 + } 164 + } 165 + 166 + if (!feat_flags) 167 + return; 168 + 169 + for (i = 0; i < BRCMF_FEAT_LAST; i++) 170 + if (feat_flags & BIT(i)) 171 + brcmf_dbg(INFO, "enabling firmware feature: %s\n", 172 + brcmf_feat_names[i]); 173 + drv->feat_flags |= feat_flags; 174 + } 175 + 129 176 /** 130 177 * brcmf_feat_iovar_int_get() - determine feature through iovar query. 131 178 * ··· 337 290 ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_SCAN_RANDOM_MAC); 338 291 339 292 brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_FWSUP, "sup_wpa"); 293 + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_SCAN_V2, "scan_ver"); 340 294 341 295 if (drvr->settings->feature_disable) { 342 296 brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n", ··· 346 298 ifp->drvr->feat_flags &= ~drvr->settings->feature_disable; 347 299 } 348 300 301 + brcmf_feat_wlc_version_overrides(drvr); 349 302 brcmf_feat_firmware_overrides(drvr); 350 303 351 304 /* set chip related quirks */
+5 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
··· 30 30 * SAE: simultaneous authentication of equals 31 31 * FWAUTH: Firmware authenticator 32 32 * DUMP_OBSS: Firmware has capable to dump obss info to support ACS 33 + * SCAN_V2: Version 2 scan params 33 34 */ 34 35 #define BRCMF_FEAT_LIST \ 35 36 BRCMF_FEAT_DEF(MBSS) \ ··· 54 53 BRCMF_FEAT_DEF(DOT11H) \ 55 54 BRCMF_FEAT_DEF(SAE) \ 56 55 BRCMF_FEAT_DEF(FWAUTH) \ 57 - BRCMF_FEAT_DEF(DUMP_OBSS) 56 + BRCMF_FEAT_DEF(DUMP_OBSS) \ 57 + BRCMF_FEAT_DEF(SCAN_V2) \ 58 + BRCMF_FEAT_DEF(PMKID_V2) \ 59 + BRCMF_FEAT_DEF(PMKID_V3) 58 60 59 61 /* 60 62 * Quirks:
+156 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
··· 48 48 49 49 /* size of brcmf_scan_params not including variable length array */ 50 50 #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 51 + #define BRCMF_SCAN_PARAMS_V2_FIXED_SIZE 72 52 + 53 + /* version of brcmf_scan_params structure */ 54 + #define BRCMF_SCAN_PARAMS_VERSION_V2 2 51 55 52 56 /* masks for channel and ssid count */ 53 57 #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff ··· 71 67 #define BRCMF_PRIMARY_KEY (1 << 1) 72 68 #define DOT11_BSSTYPE_ANY 2 73 69 #define BRCMF_ESCAN_REQ_VERSION 1 70 + #define BRCMF_ESCAN_REQ_VERSION_V2 2 74 71 75 72 #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ 76 73 ··· 173 168 #define BRCMF_VHT_CAP_MCS_MAP_NSS_MAX 8 174 169 175 170 #define BRCMF_HE_CAP_MCS_MAP_NSS_MAX 8 171 + 172 + #define BRCMF_PMKSA_VER_2 2 173 + #define BRCMF_PMKSA_VER_3 3 174 + #define BRCMF_PMKSA_NO_EXPIRY 0xffffffff 176 175 177 176 /* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each 178 177 * ioctl. It is relatively small because firmware has small maximum size input ··· 359 350 unsigned char SSID[IEEE80211_MAX_SSID_LEN]; 360 351 }; 361 352 353 + /* Alternate SSID structure used in some places... */ 354 + struct brcmf_ssid8_le { 355 + u8 SSID_len; 356 + unsigned char SSID[IEEE80211_MAX_SSID_LEN]; 357 + }; 358 + 362 359 struct brcmf_scan_params_le { 363 360 struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ 364 361 u8 bssid[ETH_ALEN]; /* default: bcast */ ··· 373 358 */ 374 359 u8 scan_type; /* flags, 0 use default */ 375 360 __le32 nprobes; /* -1 use default, number of probes per channel */ 361 + __le32 active_time; /* -1 use default, dwell time per channel for 362 + * active scanning 363 + */ 364 + __le32 passive_time; /* -1 use default, dwell time per channel 365 + * for passive scanning 366 + */ 367 + __le32 home_time; /* -1 use default, dwell time for the 368 + * home channel between channel scans 369 + */ 370 + __le32 channel_num; /* count of channels and ssids that follow 371 + * 372 + * low half is count of channels in 373 + * channel_list, 0 means default (use all 374 + * available channels) 375 + * 376 + * high half is entries in struct brcmf_ssid 377 + * array that follows channel_list, aligned for 378 + * s32 (4 bytes) meaning an odd channel count 379 + * implies a 2-byte pad between end of 380 + * channel_list and first ssid 381 + * 382 + * if ssid count is zero, single ssid in the 383 + * fixed parameter portion is assumed, otherwise 384 + * ssid in the fixed portion is ignored 385 + */ 386 + __le16 channel_list[1]; /* list of chanspecs */ 387 + }; 388 + 389 + struct brcmf_scan_params_v2_le { 390 + __le16 version; /* structure version */ 391 + __le16 length; /* structure length */ 392 + struct brcmf_ssid_le ssid_le; /* default: {0, ""} */ 393 + u8 bssid[ETH_ALEN]; /* default: bcast */ 394 + s8 bss_type; /* default: any, 395 + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT 396 + */ 397 + u8 pad; 398 + __le32 scan_type; /* flags, 0 use default */ 399 + __le32 nprobes; /* -1 use default, number of probes per channel */ 376 400 __le32 active_time; /* -1 use default, dwell time per channel for 377 401 * active scanning 378 402 */ ··· 451 397 __le32 version; 452 398 __le16 action; 453 399 __le16 sync_id; 454 - struct brcmf_scan_params_le params_le; 400 + union { 401 + struct brcmf_scan_params_le params_le; 402 + struct brcmf_scan_params_v2_le params_v2_le; 403 + }; 455 404 }; 456 405 457 406 struct brcmf_escan_result_le { ··· 799 742 }; 800 743 801 744 /** 745 + * struct brcmf_wlc_version_le - firmware revision info. 746 + * 747 + * @version: structure version. 748 + * @length: structure length. 749 + * @epi_ver_major: EPI major version 750 + * @epi_ver_minor: EPI minor version 751 + * @epi_ver_rc: EPI rc version 752 + * @epi_ver_incr: EPI increment version 753 + * @wlc_ver_major: WLC major version 754 + * @wlc_ver_minor: WLC minor version 755 + */ 756 + struct brcmf_wlc_version_le { 757 + __le16 version; 758 + __le16 length; 759 + 760 + __le16 epi_ver_major; 761 + __le16 epi_ver_minor; 762 + __le16 epi_ver_rc; 763 + __le16 epi_ver_incr; 764 + 765 + __le16 wlc_ver_major; 766 + __le16 wlc_ver_minor; 767 + }; 768 + 769 + /** 802 770 * struct brcmf_assoclist_le - request assoc list. 803 771 * 804 772 * @count: indicates number of stations. ··· 886 804 }; 887 805 888 806 /** 807 + * struct brcmf_pmksa_v2 - PMK Security Association 808 + * 809 + * @length: Length of the structure. 810 + * @bssid: The AP's BSSID. 811 + * @pmkid: The PMK ID. 812 + * @pmk: PMK material for FILS key derivation. 813 + * @pmk_len: Length of PMK data. 814 + * @ssid: The AP's SSID. 815 + * @fils_cache_id: FILS cache identifier 816 + */ 817 + struct brcmf_pmksa_v2 { 818 + __le16 length; 819 + u8 bssid[ETH_ALEN]; 820 + u8 pmkid[WLAN_PMKID_LEN]; 821 + u8 pmk[WLAN_PMK_LEN_SUITE_B_192]; 822 + __le16 pmk_len; 823 + struct brcmf_ssid8_le ssid; 824 + u16 fils_cache_id; 825 + }; 826 + 827 + /** 828 + * struct brcmf_pmksa_v3 - PMK Security Association 829 + * 830 + * @bssid: The AP's BSSID. 831 + * @pmkid: The PMK ID. 832 + * @pmkid_len: The length of the PMK ID. 833 + * @pmk: PMK material for FILS key derivation. 834 + * @pmk_len: Length of PMK data. 835 + * @fils_cache_id: FILS cache identifier 836 + * @ssid: The AP's SSID. 837 + * @time_left: Remaining time until expiry. 0 = expired, ~0 = no expiry. 838 + */ 839 + struct brcmf_pmksa_v3 { 840 + u8 bssid[ETH_ALEN]; 841 + u8 pmkid[WLAN_PMKID_LEN]; 842 + u8 pmkid_len; 843 + u8 pmk[WLAN_PMK_LEN_SUITE_B_192]; 844 + u8 pmk_len; 845 + __le16 fils_cache_id; 846 + u8 pad; 847 + struct brcmf_ssid8_le ssid; 848 + __le32 time_left; 849 + }; 850 + 851 + /** 889 852 * struct brcmf_pmk_list_le - List of pmksa's. 890 853 * 891 854 * @npmk: Number of pmksa's. ··· 939 812 struct brcmf_pmk_list_le { 940 813 __le32 npmk; 941 814 struct brcmf_pmksa pmk[BRCMF_MAXPMKID]; 815 + }; 816 + 817 + /** 818 + * struct brcmf_pmk_list_v2_le - List of pmksa's. 819 + * 820 + * @version: Request version. 821 + * @length: Length of this structure. 822 + * @pmk: PMK SA information. 823 + */ 824 + struct brcmf_pmk_list_v2_le { 825 + __le16 version; 826 + __le16 length; 827 + struct brcmf_pmksa_v2 pmk[BRCMF_MAXPMKID]; 828 + }; 829 + 830 + /** 831 + * struct brcmf_pmk_op_v3_le - Operation on PMKSA list. 832 + * 833 + * @version: Request version. 834 + * @length: Length of this structure. 835 + * @pmk: PMK SA information. 836 + */ 837 + struct brcmf_pmk_op_v3_le { 838 + __le16 version; 839 + __le16 length; 840 + __le16 count; 841 + __le16 pad; 842 + struct brcmf_pmksa_v3 pmk[BRCMF_MAXPMKID]; 942 843 }; 943 844 944 845 /**
+7
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
··· 86 86 if (!of_property_read_string(np, "apple,antenna-sku", &prop)) 87 87 settings->antenna_sku = prop; 88 88 89 + /* The WLAN calibration blob is normally stored in SROM, but Apple 90 + * ARM64 platforms pass it via the DT instead. 91 + */ 92 + prop = of_get_property(np, "brcm,cal-blob", &settings->cal_size); 93 + if (prop && settings->cal_size) 94 + settings->cal_blob = prop; 95 + 89 96 /* Set board-type to the first string of the machine compatible prop */ 90 97 root = of_find_node_by_path("/"); 91 98 if (root && err) {
+59 -2
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
··· 15 15 #include <linux/sched/signal.h> 16 16 #include <linux/kthread.h> 17 17 #include <linux/io.h> 18 + #include <linux/random.h> 18 19 #include <asm/unaligned.h> 19 20 20 21 #include <soc.h> ··· 58 57 BRCMF_FW_CLM_DEF(43570, "brcmfmac43570-pcie"); 59 58 BRCMF_FW_DEF(4358, "brcmfmac4358-pcie"); 60 59 BRCMF_FW_DEF(4359, "brcmfmac4359-pcie"); 60 + BRCMF_FW_DEF(4359C, "brcmfmac4359c-pcie"); 61 61 BRCMF_FW_CLM_DEF(4364B2, "brcmfmac4364b2-pcie"); 62 62 BRCMF_FW_CLM_DEF(4364B3, "brcmfmac4364b3-pcie"); 63 63 BRCMF_FW_DEF(4365B, "brcmfmac4365b-pcie"); ··· 68 66 BRCMF_FW_DEF(4371, "brcmfmac4371-pcie"); 69 67 BRCMF_FW_CLM_DEF(4377B3, "brcmfmac4377b3-pcie"); 70 68 BRCMF_FW_CLM_DEF(4378B1, "brcmfmac4378b1-pcie"); 69 + BRCMF_FW_CLM_DEF(4378B3, "brcmfmac4378b3-pcie"); 70 + BRCMF_FW_CLM_DEF(4387C2, "brcmfmac4387c2-pcie"); 71 71 72 72 /* firmware config files */ 73 73 MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.txt"); ··· 78 74 /* per-board firmware binaries */ 79 75 MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.bin"); 80 76 MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.clm_blob"); 77 + MODULE_FIRMWARE(BRCMF_FW_DEFAULT_PATH "brcmfmac*-pcie.*.txcap_blob"); 81 78 82 79 static const struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { 83 80 BRCMF_FW_ENTRY(BRCM_CC_43602_CHIP_ID, 0xFFFFFFFF, 43602), ··· 93 88 BRCMF_FW_ENTRY(BRCM_CC_43569_CHIP_ID, 0xFFFFFFFF, 43570), 94 89 BRCMF_FW_ENTRY(BRCM_CC_43570_CHIP_ID, 0xFFFFFFFF, 43570), 95 90 BRCMF_FW_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), 96 - BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), 91 + BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0x000001FF, 4359), 92 + BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFE00, 4359C), 97 93 BRCMF_FW_ENTRY(BRCM_CC_4364_CHIP_ID, 0x0000000F, 4364B2), /* 3 */ 98 94 BRCMF_FW_ENTRY(BRCM_CC_4364_CHIP_ID, 0xFFFFFFF0, 4364B3), /* 4 */ 99 95 BRCMF_FW_ENTRY(BRCM_CC_4365_CHIP_ID, 0x0000000F, 4365B), ··· 105 99 BRCMF_FW_ENTRY(BRCM_CC_43666_CHIP_ID, 0xFFFFFFF0, 4366C), 106 100 BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), 107 101 BRCMF_FW_ENTRY(BRCM_CC_4377_CHIP_ID, 0xFFFFFFFF, 4377B3), /* revision ID 4 */ 108 - BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFFF, 4378B1), /* revision ID 3 */ 102 + BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0x0000000F, 4378B1), /* revision ID 3 */ 103 + BRCMF_FW_ENTRY(BRCM_CC_4378_CHIP_ID, 0xFFFFFFE0, 4378B3), /* revision ID 5 */ 104 + BRCMF_FW_ENTRY(BRCM_CC_4387_CHIP_ID, 0xFFFFFFFF, 4387C2), /* revision ID 7 */ 109 105 }; 110 106 111 107 #define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ ··· 334 326 char fw_name[BRCMF_FW_NAME_LEN]; 335 327 char nvram_name[BRCMF_FW_NAME_LEN]; 336 328 char clm_name[BRCMF_FW_NAME_LEN]; 329 + char txcap_name[BRCMF_FW_NAME_LEN]; 337 330 const struct firmware *clm_fw; 331 + const struct firmware *txcap_fw; 338 332 const struct brcmf_pcie_reginfo *reginfo; 339 333 void __iomem *regs; 340 334 void __iomem *tcm; ··· 1527 1517 *fw = devinfo->clm_fw; 1528 1518 devinfo->clm_fw = NULL; 1529 1519 break; 1520 + case BRCMF_BLOB_TXCAP: 1521 + *fw = devinfo->txcap_fw; 1522 + devinfo->txcap_fw = NULL; 1523 + break; 1530 1524 default: 1531 1525 return -ENOENT; 1532 1526 } ··· 1667 1653 return 0; 1668 1654 } 1669 1655 1656 + struct brcmf_random_seed_footer { 1657 + __le32 length; 1658 + __le32 magic; 1659 + }; 1660 + 1661 + #define BRCMF_RANDOM_SEED_MAGIC 0xfeedc0de 1662 + #define BRCMF_RANDOM_SEED_LENGTH 0x100 1670 1663 1671 1664 static int brcmf_pcie_download_fw_nvram(struct brcmf_pciedev_info *devinfo, 1672 1665 const struct firmware *fw, void *nvram, ··· 1710 1689 nvram_len; 1711 1690 memcpy_toio(devinfo->tcm + address, nvram, nvram_len); 1712 1691 brcmf_fw_nvram_free(nvram); 1692 + 1693 + if (devinfo->otp.valid) { 1694 + size_t rand_len = BRCMF_RANDOM_SEED_LENGTH; 1695 + struct brcmf_random_seed_footer footer = { 1696 + .length = cpu_to_le32(rand_len), 1697 + .magic = cpu_to_le32(BRCMF_RANDOM_SEED_MAGIC), 1698 + }; 1699 + void *randbuf; 1700 + 1701 + /* Some Apple chips/firmwares expect a buffer of random 1702 + * data to be present before NVRAM 1703 + */ 1704 + brcmf_dbg(PCIE, "Download random seed\n"); 1705 + 1706 + address -= sizeof(footer); 1707 + memcpy_toio(devinfo->tcm + address, &footer, 1708 + sizeof(footer)); 1709 + 1710 + address -= rand_len; 1711 + randbuf = kzalloc(rand_len, GFP_KERNEL); 1712 + get_random_bytes(randbuf, rand_len); 1713 + memcpy_toio(devinfo->tcm + address, randbuf, rand_len); 1714 + kfree(randbuf); 1715 + } 1713 1716 } else { 1714 1717 brcmf_dbg(PCIE, "No matching NVRAM file found %s\n", 1715 1718 devinfo->nvram_name); ··· 2061 2016 base = 0x1120; 2062 2017 words = 0x170; 2063 2018 break; 2019 + case BRCM_CC_4387_CHIP_ID: 2020 + coreid = BCMA_CORE_GCI; 2021 + base = 0x113c; 2022 + words = 0x170; 2023 + break; 2064 2024 default: 2065 2025 /* OTP not supported on this chip */ 2066 2026 return 0; ··· 2123 2073 #define BRCMF_PCIE_FW_CODE 0 2124 2074 #define BRCMF_PCIE_FW_NVRAM 1 2125 2075 #define BRCMF_PCIE_FW_CLM 2 2076 + #define BRCMF_PCIE_FW_TXCAP 3 2126 2077 2127 2078 static void brcmf_pcie_setup(struct device *dev, int ret, 2128 2079 struct brcmf_fw_request *fwreq) ··· 2150 2099 nvram = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.data; 2151 2100 nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; 2152 2101 devinfo->clm_fw = fwreq->items[BRCMF_PCIE_FW_CLM].binary; 2102 + devinfo->txcap_fw = fwreq->items[BRCMF_PCIE_FW_TXCAP].binary; 2153 2103 kfree(fwreq); 2154 2104 2155 2105 ret = brcmf_chip_get_raminfo(devinfo->ci); ··· 2232 2180 { ".bin", devinfo->fw_name }, 2233 2181 { ".txt", devinfo->nvram_name }, 2234 2182 { ".clm_blob", devinfo->clm_name }, 2183 + { ".txcap_blob", devinfo->txcap_name }, 2235 2184 }; 2236 2185 2237 2186 fwreq = brcmf_fw_alloc_request(devinfo->ci->chip, devinfo->ci->chiprev, ··· 2247 2194 fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL; 2248 2195 fwreq->items[BRCMF_PCIE_FW_CLM].type = BRCMF_FW_TYPE_BINARY; 2249 2196 fwreq->items[BRCMF_PCIE_FW_CLM].flags = BRCMF_FW_REQF_OPTIONAL; 2197 + fwreq->items[BRCMF_PCIE_FW_TXCAP].type = BRCMF_FW_TYPE_BINARY; 2198 + fwreq->items[BRCMF_PCIE_FW_TXCAP].flags = BRCMF_FW_REQF_OPTIONAL; 2250 2199 /* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */ 2251 2200 fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1; 2252 2201 fwreq->bus_nr = devinfo->pdev->bus->number; ··· 2546 2491 brcmf_pcie_reset_device(devinfo); 2547 2492 brcmf_pcie_release_resource(devinfo); 2548 2493 release_firmware(devinfo->clm_fw); 2494 + release_firmware(devinfo->txcap_fw); 2549 2495 2550 2496 if (devinfo->ci) 2551 2497 brcmf_chip_detach(devinfo->ci); ··· 2686 2630 BRCMF_PCIE_DEVICE(BRCM_PCIE_43596_DEVICE_ID, CYW), 2687 2631 BRCMF_PCIE_DEVICE(BRCM_PCIE_4377_DEVICE_ID, WCC), 2688 2632 BRCMF_PCIE_DEVICE(BRCM_PCIE_4378_DEVICE_ID, WCC), 2633 + BRCMF_PCIE_DEVICE(BRCM_PCIE_4387_DEVICE_ID, WCC), 2689 2634 2690 2635 { /* end: all zeroes */ } 2691 2636 };
+2
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
··· 54 54 #define BRCM_CC_4371_CHIP_ID 0x4371 55 55 #define BRCM_CC_4377_CHIP_ID 0x4377 56 56 #define BRCM_CC_4378_CHIP_ID 0x4378 57 + #define BRCM_CC_4387_CHIP_ID 0x4387 57 58 #define CY_CC_4373_CHIP_ID 0x4373 58 59 #define CY_CC_43012_CHIP_ID 43012 59 60 #define CY_CC_43439_CHIP_ID 43439 ··· 96 95 #define BRCM_PCIE_43596_DEVICE_ID 0x4415 97 96 #define BRCM_PCIE_4377_DEVICE_ID 0x4488 98 97 #define BRCM_PCIE_4378_DEVICE_ID 0x4425 98 + #define BRCM_PCIE_4387_DEVICE_ID 0x4433 99 99 100 100 /* brcmsmac IDs */ 101 101 #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
+12
drivers/net/wireless/intel/iwlwifi/cfg/22000.c
··· 62 62 #define IWL_BZ_Z_GF_A_FW_PRE "iwlwifi-bz-z0-gf-a0-" 63 63 #define IWL_BNJ_A_FM_A_FW_PRE "iwlwifi-BzBnj-a0-fm-a0-" 64 64 #define IWL_BNJ_A_FM4_A_FW_PRE "iwlwifi-BzBnj-a0-fm4-a0-" 65 + #define IWL_BNJ_B_FM4_B_FW_PRE "iwlwifi-BzBnj-b0-fm4-b0-" 65 66 #define IWL_BNJ_A_GF_A_FW_PRE "iwlwifi-BzBnj-a0-gf-a0-" 66 67 #define IWL_BNJ_A_GF4_A_FW_PRE "iwlwifi-BzBnj-a0-gf4-a0-" 67 68 #define IWL_BNJ_A_HR_B_FW_PRE "iwlwifi-BzBnj-a0-hr-b0-" ··· 133 132 IWL_BNJ_A_FM_A_FW_PRE __stringify(api) ".ucode" 134 133 #define IWL_BNJ_A_FM4_A_MODULE_FIRMWARE(api) \ 135 134 IWL_BNJ_A_FM4_A_FW_PRE __stringify(api) ".ucode" 135 + #define IWL_BNJ_B_FM4_B_MODULE_FIRMWARE(api) \ 136 + IWL_BNJ_B_FM4_B_FW_PRE __stringify(api) ".ucode" 136 137 #define IWL_BNJ_A_GF_A_MODULE_FIRMWARE(api) \ 137 138 IWL_BNJ_A_GF_A_FW_PRE __stringify(api) ".ucode" 138 139 #define IWL_BNJ_A_GF4_A_MODULE_FIRMWARE(api) \ ··· 1001 998 .num_rbds = IWL_NUM_RBDS_AX210_HE, 1002 999 }; 1003 1000 1001 + const struct iwl_cfg iwl_cfg_bnj_b0_fm4_b0 = { 1002 + .fw_name_pre = IWL_BNJ_B_FM4_B_FW_PRE, 1003 + .uhb_supported = true, 1004 + IWL_DEVICE_BZ, 1005 + .features = IWL_TX_CSUM_NETIF_FLAGS | NETIF_F_RXCSUM, 1006 + .num_rbds = IWL_NUM_RBDS_AX210_HE, 1007 + }; 1008 + 1004 1009 const struct iwl_cfg iwl_cfg_bnj_a0_gf_a0 = { 1005 1010 .fw_name_pre = IWL_BNJ_A_GF_A_FW_PRE, 1006 1011 .uhb_supported = true, ··· 1070 1059 MODULE_FIRMWARE(IWL_GL_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1071 1060 MODULE_FIRMWARE(IWL_BNJ_A_FM_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1072 1061 MODULE_FIRMWARE(IWL_BNJ_A_FM4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1062 + MODULE_FIRMWARE(IWL_BNJ_B_FM4_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1073 1063 MODULE_FIRMWARE(IWL_BNJ_A_GF_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1074 1064 MODULE_FIRMWARE(IWL_BNJ_A_GF4_A_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX)); 1075 1065 MODULE_FIRMWARE(IWL_BNJ_A_HR_B_MODULE_FIRMWARE(IWL_22000_UCODE_API_MAX));
+17 -10
drivers/net/wireless/intel/iwlwifi/fw/api/rs.h
··· 373 373 374 374 /* Bit 4-5: (0) SISO, (1) MIMO2 (2) MIMO3 */ 375 375 #define RATE_VHT_MCS_RATE_CODE_MSK 0xf 376 - #define RATE_VHT_MCS_NSS_POS 4 377 - #define RATE_VHT_MCS_NSS_MSK (3 << RATE_VHT_MCS_NSS_POS) 378 - #define RATE_VHT_MCS_MIMO2_MSK BIT(RATE_VHT_MCS_NSS_POS) 379 376 380 377 /* 381 378 * Legacy OFDM rate format for bits 7:0 ··· 446 449 * 1 2xLTF+0.8us 447 450 * 2 2xLTF+1.6us 448 451 * 3 4xLTF+3.2us 449 - * HE TRIG: 452 + * HE-EHT TRIG: 450 453 * 0 1xLTF+1.6us 451 454 * 1 2xLTF+1.6us 452 455 * 2 4xLTF+3.2us 453 456 * 3 (does not occur) 457 + * EHT MU: 458 + * 0 2xLTF+0.8us 459 + * 1 2xLTF+1.6us 460 + * 2 4xLTF+0.8us 461 + * 3 4xLTF+3.2us 454 462 */ 455 463 #define RATE_MCS_HE_GI_LTF_POS 20 456 464 #define RATE_MCS_HE_GI_LTF_MSK_V1 (3 << RATE_MCS_HE_GI_LTF_POS) ··· 548 546 /* 549 547 * Bits 13-11: (0) 20MHz, (1) 40MHz, (2) 80MHz, (3) 160MHz, (4) 320MHz 550 548 */ 551 - #define RATE_MCS_CHAN_WIDTH_MSK (0x7 << RATE_MCS_CHAN_WIDTH_POS) 552 - #define RATE_MCS_CHAN_WIDTH_20 (0 << RATE_MCS_CHAN_WIDTH_POS) 553 - #define RATE_MCS_CHAN_WIDTH_40 (1 << RATE_MCS_CHAN_WIDTH_POS) 554 - #define RATE_MCS_CHAN_WIDTH_80 (2 << RATE_MCS_CHAN_WIDTH_POS) 555 - #define RATE_MCS_CHAN_WIDTH_160 (3 << RATE_MCS_CHAN_WIDTH_POS) 556 - #define RATE_MCS_CHAN_WIDTH_320 (4 << RATE_MCS_CHAN_WIDTH_POS) 549 + #define RATE_MCS_CHAN_WIDTH_MSK (0x7 << RATE_MCS_CHAN_WIDTH_POS) 550 + #define RATE_MCS_CHAN_WIDTH_20_VAL 0 551 + #define RATE_MCS_CHAN_WIDTH_20 (RATE_MCS_CHAN_WIDTH_20_VAL << RATE_MCS_CHAN_WIDTH_POS) 552 + #define RATE_MCS_CHAN_WIDTH_40_VAL 1 553 + #define RATE_MCS_CHAN_WIDTH_40 (RATE_MCS_CHAN_WIDTH_40_VAL << RATE_MCS_CHAN_WIDTH_POS) 554 + #define RATE_MCS_CHAN_WIDTH_80_VAL 2 555 + #define RATE_MCS_CHAN_WIDTH_80 (RATE_MCS_CHAN_WIDTH_80_VAL << RATE_MCS_CHAN_WIDTH_POS) 556 + #define RATE_MCS_CHAN_WIDTH_160_VAL 3 557 + #define RATE_MCS_CHAN_WIDTH_160 (RATE_MCS_CHAN_WIDTH_160_VAL << RATE_MCS_CHAN_WIDTH_POS) 558 + #define RATE_MCS_CHAN_WIDTH_320_VAL 4 559 + #define RATE_MCS_CHAN_WIDTH_320 (RATE_MCS_CHAN_WIDTH_320_VAL << RATE_MCS_CHAN_WIDTH_POS) 557 560 558 561 /* Bit 15-14: Antenna selection: 559 562 * Bit 14: Ant A active
+61 -23
drivers/net/wireless/intel/iwlwifi/fw/api/rx.h
··· 367 367 /* number of EHT-LTF symbols 0 - 1 EHT-LTF, 1 - 2 EHT-LTFs, 2 - 4 EHT-LTFs, 368 368 * 3 - 6 EHT-LTFs, 4 - 8 EHT-LTFs */ 369 369 IWL_RX_PHY_DATA1_EHT_SIG_LTF_NUM = 0x000000e0, 370 - IWL_RX_PHY_DATA1_EHT_RU_ALLOC = 0x0000ff00, 370 + IWL_RX_PHY_DATA1_EHT_B0 = 0x00000100, 371 + IWL_RX_PHY_DATA1_EHT_RU_B1_B7_ALLOC = 0x0000fe00, 371 372 }; 372 373 373 374 /* goes into Metadata DW 7 */ ··· 414 413 /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_0_OUT */ 415 414 IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A1 = 0x000001ff, 416 415 IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A2 = 0x0003fe00, 417 - IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_A3 = 0x01fc0000, 416 + IWL_RX_PHY_DATA2_EHT_MU_EXT_RU_ALLOC_B1 = 0x07fc0000, 418 417 419 418 /* info type: EHT-TB-EXT */ 420 419 IWL_RX_PHY_DATA2_EHT_TB_EXT_TRIG_SIGA1 = 0xffffffff, ··· 424 423 enum iwl_rx_phy_eht_data3 { 425 424 /* info type: EHT-MU-EXT */ 426 425 /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_1_OUT */ 427 - IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B1 = 0x000001ff, 428 - IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B2 = 0x0003fe00, 429 - IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B3 = 0x01fc0000, 426 + IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_B2 = 0x000001ff, 427 + IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_C1 = 0x0003fe00, 428 + IWL_RX_PHY_DATA3_EHT_MU_EXT_RU_ALLOC_C2 = 0x07fc0000, 430 429 }; 431 430 432 431 /* goes into Metadata DW 4 */ 433 432 enum iwl_rx_phy_eht_data4 { 434 433 /* info type: EHT-MU-EXT */ 435 434 /* OFDM_RX_VECTOR_COMMON_RU_ALLOC_2_OUT */ 436 - IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C1 = 0x000001ff, 437 - IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C2 = 0x0003fe00, 438 - IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_C3 = 0x01fc0000, 439 - IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS = 0x18000000, 435 + IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_D1 = 0x000001ff, 436 + IWL_RX_PHY_DATA4_EHT_MU_EXT_RU_ALLOC_D2 = 0x0003fe00, 437 + IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS = 0x000c0000, 440 438 }; 441 439 442 440 /* goes into Metadata DW 16 */ ··· 673 673 * @mac_phy_idx: MAC/PHY index 674 674 */ 675 675 u8 mac_phy_idx; 676 - /* DW4 - carries csum data only when rpa_en == 1 */ 677 - /** 678 - * @raw_csum: raw checksum (alledgedly unreliable) 679 - */ 680 - __le16 raw_csum; 681 - 676 + /* DW4 */ 682 677 union { 683 - /** 684 - * @l3l4_flags: &enum iwl_rx_l3l4_flags 685 - */ 686 - __le16 l3l4_flags; 678 + struct { 679 + /* carries csum data only when rpa_en == 1 */ 680 + /** 681 + * @raw_csum: raw checksum (alledgedly unreliable) 682 + */ 683 + __le16 raw_csum; 687 684 685 + union { 686 + /** 687 + * @l3l4_flags: &enum iwl_rx_l3l4_flags 688 + */ 689 + __le16 l3l4_flags; 690 + 691 + /** 692 + * @phy_data4: depends on info type, see phy_data1 693 + */ 694 + __le16 phy_data4; 695 + }; 696 + }; 688 697 /** 689 - * @phy_data4: depends on info type, see phy_data1 698 + * @phy_eht_data4: depends on info type, see phy_data1 690 699 */ 691 - __le16 phy_data4; 700 + __le32 phy_eht_data4; 692 701 }; 693 702 /* DW5 */ 694 703 /** ··· 734 725 #define RX_NO_DATA_INFO_TYPE_RX_ERR 1 735 726 #define RX_NO_DATA_INFO_TYPE_NDP 2 736 727 #define RX_NO_DATA_INFO_TYPE_MU_UNMATCHED 3 737 - #define RX_NO_DATA_INFO_TYPE_HE_TB_UNMATCHED 4 728 + #define RX_NO_DATA_INFO_TYPE_TB_UNMATCHED 4 738 729 739 730 #define RX_NO_DATA_INFO_ERR_POS 8 740 731 #define RX_NO_DATA_INFO_ERR_MSK (0xff << RX_NO_DATA_INFO_ERR_POS) ··· 751 742 #define RX_NO_DATA_RX_VEC0_HE_NSTS_MSK 0x03800000 752 743 #define RX_NO_DATA_RX_VEC0_VHT_NSTS_MSK 0x38000000 753 744 #define RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK 0x00f00000 745 + 746 + /* content of OFDM_RX_VECTOR_USIG_A1_OUT */ 747 + enum iwl_rx_usig_a1 { 748 + IWL_RX_USIG_A1_ENHANCED_WIFI_VER_ID = 0x00000007, 749 + IWL_RX_USIG_A1_BANDWIDTH = 0x00000038, 750 + IWL_RX_USIG_A1_UL_FLAG = 0x00000040, 751 + IWL_RX_USIG_A1_BSS_COLOR = 0x00001f80, 752 + IWL_RX_USIG_A1_TXOP_DURATION = 0x000fe000, 753 + IWL_RX_USIG_A1_DISREGARD = 0x01f00000, 754 + IWL_RX_USIG_A1_VALIDATE = 0x02000000, 755 + IWL_RX_USIG_A1_EHT_BW320_SLOT = 0x04000000, 756 + IWL_RX_USIG_A1_EHT_TYPE = 0x18000000, 757 + IWL_RX_USIG_A1_RDY = 0x80000000, 758 + }; 759 + 760 + /* content of OFDM_RX_VECTOR_USIG_A2_EHT_OUT */ 761 + enum iwl_rx_usig_a2_eht { 762 + IWL_RX_USIG_A2_EHT_PPDU_TYPE = 0x00000003, 763 + IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B2 = 0x00000004, 764 + IWL_RX_USIG_A2_EHT_PUNC_CHANNEL = 0x000000f8, 765 + IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B8 = 0x00000100, 766 + IWL_RX_USIG_A2_EHT_SIG_MCS = 0x00000600, 767 + IWL_RX_USIG_A2_EHT_SIG_SYM_NUM = 0x0000f800, 768 + IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_1 = 0x000f0000, 769 + IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_2 = 0x00f00000, 770 + IWL_RX_USIG_A2_EHT_TRIG_USIG2_DISREGARD = 0x1f000000, 771 + IWL_RX_USIG_A2_EHT_CRC_OK = 0x40000000, 772 + IWL_RX_USIG_A2_EHT_RDY = 0x80000000, 773 + }; 754 774 755 775 /** 756 776 * struct iwl_rx_no_data - RX no data descriptor ··· 818 780 * @rx_vec: DW-12:9 raw RX vectors from DSP according to modulation type. 819 781 * for VHT: OFDM_RX_VECTOR_SIGA1_OUT, OFDM_RX_VECTOR_SIGA2_OUT 820 782 * for HE: OFDM_RX_VECTOR_HE_SIGA1_OUT, OFDM_RX_VECTOR_HE_SIGA2_OUT 821 - * for EHT: OFDM_RX_VECTOR_USIG_A1_OUT, OFDM_RX_VECTOR_USIG_A2_OUT, 783 + * for EHT: OFDM_RX_VECTOR_USIG_A1_OUT, OFDM_RX_VECTOR_USIG_A2_EHT_OUT, 822 784 * OFDM_RX_VECTOR_EHT_OUT, OFDM_RX_VECTOR_EHT_USER_FIELD_OUT 823 785 */ 824 786 struct iwl_rx_no_data_ver_3 {
+2 -2
drivers/net/wireless/intel/iwlwifi/fw/rs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2021 Intel Corporation 3 + * Copyright (C) 2021-2022 Intel Corporation 4 4 */ 5 5 6 6 #include <net/mac80211.h> ··· 126 126 rate_v1 & RATE_MCS_HE_MSK_V1) { 127 127 rate_v2 |= rate_v1 & RATE_VHT_MCS_RATE_CODE_MSK; 128 128 129 - rate_v2 |= rate_v1 & RATE_VHT_MCS_MIMO2_MSK; 129 + rate_v2 |= rate_v1 & RATE_MCS_NSS_MSK; 130 130 131 131 if (rate_v1 & RATE_MCS_HE_MSK_V1) { 132 132 u32 he_type_bits = rate_v1 & RATE_MCS_HE_TYPE_MSK_V1;
+1
drivers/net/wireless/intel/iwlwifi/iwl-config.h
··· 659 659 extern const struct iwl_cfg iwl_cfg_bnj_a0_gf4_a0; 660 660 extern const struct iwl_cfg iwl_cfg_bnj_a0_hr_b0; 661 661 extern const struct iwl_cfg iwl_cfg_bnj_b0_fm_b0; 662 + extern const struct iwl_cfg iwl_cfg_bnj_b0_fm4_b0; 662 663 #endif /* CONFIG_IWLMVM */ 663 664 664 665 #endif /* __IWL_CONFIG_H__ */
+1
drivers/net/wireless/intel/iwlwifi/iwl-csr.h
··· 348 348 #define CSR_HW_RF_ID_TYPE_HRCDB (0x00109F00) 349 349 #define CSR_HW_RF_ID_TYPE_GF (0x0010D000) 350 350 #define CSR_HW_RF_ID_TYPE_GF4 (0x0010E000) 351 + #define CSR_HW_RF_ID_TYPE_MS (0x00111000) 351 352 352 353 /* HW_RF CHIP STEP */ 353 354 #define CSR_HW_RF_STEP(_val) (((_val) >> 8) & 0xF)
+14 -12
drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
··· 350 350 351 351 ret = dbg_tlv_alloc[tlv_idx](trans, tlv); 352 352 if (ret) { 353 - IWL_ERR(trans, 354 - "WRT: Failed to allocate TLV 0x%x, ret %d, (ext=%d)\n", 355 - type, ret, ext); 353 + IWL_WARN(trans, 354 + "WRT: Failed to allocate TLV 0x%x, ret %d, (ext=%d)\n", 355 + type, ret, ext); 356 356 goto out_err; 357 357 } 358 358 ··· 1218 1218 } 1219 1219 1220 1220 fwrt->trans->dbg.restart_required = FALSE; 1221 - IWL_DEBUG_INFO(fwrt, "WRT: tp %d, reset_fw %d\n", 1222 - tp, dump_data.trig->reset_fw); 1223 - IWL_DEBUG_INFO(fwrt, "WRT: restart_required %d, last_tp_resetfw %d\n", 1224 - fwrt->trans->dbg.restart_required, 1225 - fwrt->trans->dbg.last_tp_resetfw); 1221 + IWL_DEBUG_FW(fwrt, "WRT: tp %d, reset_fw %d\n", 1222 + tp, dump_data.trig->reset_fw); 1223 + IWL_DEBUG_FW(fwrt, 1224 + "WRT: restart_required %d, last_tp_resetfw %d\n", 1225 + fwrt->trans->dbg.restart_required, 1226 + fwrt->trans->dbg.last_tp_resetfw); 1226 1227 1227 1228 if (fwrt->trans->trans_cfg->device_family == 1228 1229 IWL_DEVICE_FAMILY_9000) { ··· 1236 1235 IWL_DEBUG_FW(fwrt, "WRT: FW_ASSERT due to reset_fw_mode-no restart\n"); 1237 1236 } else if (le32_to_cpu(dump_data.trig->reset_fw) == 1238 1237 IWL_FW_INI_RESET_FW_MODE_STOP_AND_RELOAD_FW) { 1239 - IWL_DEBUG_INFO(fwrt, "WRT: stop and reload firmware\n"); 1238 + IWL_DEBUG_FW(fwrt, "WRT: stop and reload firmware\n"); 1240 1239 fwrt->trans->dbg.restart_required = TRUE; 1241 1240 } else if (le32_to_cpu(dump_data.trig->reset_fw) == 1242 1241 IWL_FW_INI_RESET_FW_MODE_STOP_FW_ONLY) { 1243 - IWL_DEBUG_INFO(fwrt, "WRT: stop only and no reload firmware\n"); 1242 + IWL_DEBUG_FW(fwrt, 1243 + "WRT: stop only and no reload firmware\n"); 1244 1244 fwrt->trans->dbg.restart_required = FALSE; 1245 1245 fwrt->trans->dbg.last_tp_resetfw = 1246 1246 le32_to_cpu(dump_data.trig->reset_fw); 1247 1247 } else if (le32_to_cpu(dump_data.trig->reset_fw) == 1248 1248 IWL_FW_INI_RESET_FW_MODE_NOTHING) { 1249 - IWL_DEBUG_INFO(fwrt, 1250 - "WRT: nothing need to be done after debug collection\n"); 1249 + IWL_DEBUG_FW(fwrt, 1250 + "WRT: nothing need to be done after debug collection\n"); 1251 1251 } else { 1252 1252 IWL_ERR(fwrt, "WRT: wrong resetfw %d\n", 1253 1253 le32_to_cpu(dump_data.trig->reset_fw));
+5
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
··· 1084 1084 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 1085 1085 }, 1086 1086 }, 1087 + { .ident = "MSFT", 1088 + .matches = { 1089 + DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), 1090 + }, 1091 + }, 1087 1092 1088 1093 /* keep last */ 1089 1094 {}
+9 -1
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
··· 654 654 u32 action) 655 655 { 656 656 struct iwl_mac_ctx_cmd cmd = {}; 657 - u32 tfd_queue_msk = BIT(mvm->snif_queue); 657 + u32 tfd_queue_msk = 0; 658 658 int ret; 659 659 660 660 WARN_ON(vif->type != NL80211_IFTYPE_MONITOR); ··· 668 668 MAC_FILTER_IN_CRC32 | 669 669 MAC_FILTER_ACCEPT_GRP); 670 670 ieee80211_hw_set(mvm->hw, RX_INCLUDES_FCS); 671 + 672 + /* 673 + * the queue mask is only relevant for old TX API, and 674 + * mvm->snif_queue isn't set here (it's still set to 675 + * IWL_MVM_INVALID_QUEUE so the BIT() of it is UB) 676 + */ 677 + if (!iwl_mvm_has_new_tx_api(mvm)) 678 + tfd_queue_msk = BIT(mvm->snif_queue); 671 679 672 680 /* Allocate sniffer station */ 673 681 ret = iwl_mvm_allocate_int_sta(mvm, &mvm->snif_sta, tfd_queue_msk,
+28 -2
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 1362 1362 ieee80211_chswitch_done(vif, false); 1363 1363 } 1364 1364 1365 + static u8 1366 + iwl_mvm_chandef_get_primary_80(struct cfg80211_chan_def *chandef) 1367 + { 1368 + int data_start; 1369 + int control_start; 1370 + int bw; 1371 + 1372 + if (chandef->width == NL80211_CHAN_WIDTH_320) 1373 + bw = 320; 1374 + else if (chandef->width == NL80211_CHAN_WIDTH_160) 1375 + bw = 160; 1376 + else 1377 + return 0; 1378 + 1379 + /* data is bw wide so the start is half the width */ 1380 + data_start = chandef->center_freq1 - bw / 2; 1381 + /* control is 20Mhz width */ 1382 + control_start = chandef->chan->center_freq - 10; 1383 + 1384 + return (control_start - data_start) / 80; 1385 + } 1386 + 1365 1387 static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, 1366 1388 struct ieee80211_vif *vif) 1367 1389 { ··· 1500 1478 INIT_DELAYED_WORK(&mvmvif->csa_work, 1501 1479 iwl_mvm_channel_switch_disconnect_wk); 1502 1480 1503 - if (vif->type == NL80211_IFTYPE_MONITOR) 1481 + if (vif->type == NL80211_IFTYPE_MONITOR) { 1504 1482 mvm->monitor_on = true; 1483 + mvm->monitor_p80 = 1484 + iwl_mvm_chandef_get_primary_80(&vif->bss_conf.chandef); 1485 + } 1505 1486 1506 1487 iwl_mvm_vif_dbgfs_register(mvm, vif); 1507 1488 ··· 5058 5033 if (iwl_mvm_flush_sta(mvm, mvmsta, false)) 5059 5034 IWL_ERR(mvm, "flush request fail\n"); 5060 5035 } else { 5061 - msk |= mvmsta->tfd_queue_msk; 5062 5036 if (iwl_mvm_has_new_tx_api(mvm)) 5063 5037 iwl_mvm_wait_sta_queues_empty(mvm, mvmsta); 5038 + else /* only used for !iwl_mvm_has_new_tx_api() below */ 5039 + msk |= mvmsta->tfd_queue_msk; 5064 5040 } 5065 5041 } 5066 5042
+5
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 1096 1096 1097 1097 /* does a monitor vif exist (only one can exist hence bool) */ 1098 1098 bool monitor_on; 1099 + /* 1100 + * primary channel position relative to he whole bandwidth, 1101 + * in steps of 80 MHz 1102 + */ 1103 + u8 monitor_p80; 1099 1104 1100 1105 /* sniffer data to include in radiotap */ 1101 1106 __le16 cur_aid;
+6 -2
drivers/net/wireless/intel/iwlwifi/mvm/rs-fw.c
··· 337 337 const struct ieee80211_eht_mcs_nss_supp_bw *mcs_tx = 338 338 rs_fw_rs_mcs2eht_mcs(bw, eht_tx_mcs); 339 339 340 - /* got unsuppored index for bw */ 340 + /* got unsupported index for bw */ 341 341 if (!mcs_rx || !mcs_tx) 342 342 continue; 343 + 344 + /* break out if we don't support the bandwidth */ 345 + if (cmd->max_ch_width < (bw + IWL_TLC_MNG_CH_WIDTH_80MHZ)) 346 + break; 343 347 344 348 rs_fw_set_eht_mcs_nss(cmd->ht_rates, bw, 345 349 MAX_NSS_MCS(9, mcs_rx, mcs_tx), GENMASK(9, 0)); ··· 554 550 struct iwl_tlc_config_cmd_v4 cfg_cmd = { 555 551 .sta_id = mvmsta->sta_id, 556 552 .max_ch_width = update ? 557 - rs_fw_bw_from_sta_bw(sta) : RATE_MCS_CHAN_WIDTH_20, 553 + rs_fw_bw_from_sta_bw(sta) : IWL_TLC_MNG_CH_WIDTH_20MHZ, 558 554 .flags = cpu_to_le16(rs_fw_get_config_flags(mvm, sta, sband)), 559 555 .chains = rs_fw_set_active_chains(iwl_mvm_get_valid_tx_ant(mvm)), 560 556 .sgi_ch_width_supp = rs_fw_sgi_cw_support(sta),
+6 -11
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /****************************************************************************** 3 3 * 4 - * Copyright(c) 2005 - 2014, 2018 - 2021 Intel Corporation. All rights reserved. 4 + * Copyright(c) 2005 - 2014, 2018 - 2022 Intel Corporation. All rights reserved. 5 5 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 6 6 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 7 7 *****************************************************************************/ ··· 895 895 WARN_ON_ONCE(1); 896 896 } 897 897 } else if (ucode_rate & RATE_MCS_VHT_MSK_V1) { 898 - nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> 899 - RATE_VHT_MCS_NSS_POS) + 1; 898 + nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1; 900 899 901 900 if (nss == 1) { 902 901 rate->type = LQ_VHT_SISO; ··· 909 910 WARN_ON_ONCE(1); 910 911 } 911 912 } else if (ucode_rate & RATE_MCS_HE_MSK_V1) { 912 - nss = ((ucode_rate & RATE_VHT_MCS_NSS_MSK) >> 913 - RATE_VHT_MCS_NSS_POS) + 1; 913 + nss = FIELD_GET(RATE_MCS_NSS_MSK, ucode_rate) + 1; 914 914 915 915 if (nss == 1) { 916 916 rate->type = LQ_HE_SISO; ··· 2883 2885 nss = ((rate & RATE_HT_MCS_NSS_MSK_V1) >> RATE_HT_MCS_NSS_POS_V1) + 1; 2884 2886 } else if (rate & RATE_MCS_VHT_MSK_V1) { 2885 2887 mvm->drv_rx_stats.vht_frames++; 2886 - nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> 2887 - RATE_VHT_MCS_NSS_POS) + 1; 2888 + nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; 2888 2889 } else { 2889 2890 mvm->drv_rx_stats.legacy_frames++; 2890 2891 } ··· 3662 3665 if (rate & RATE_MCS_VHT_MSK_V1) { 3663 3666 type = "VHT"; 3664 3667 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; 3665 - nss = ((rate & RATE_VHT_MCS_NSS_MSK) 3666 - >> RATE_VHT_MCS_NSS_POS) + 1; 3668 + nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; 3667 3669 } else if (rate & RATE_MCS_HT_MSK_V1) { 3668 3670 type = "HT"; 3669 3671 mcs = rate & RATE_HT_MCS_INDEX_MSK_V1; ··· 3671 3675 } else if (rate & RATE_MCS_HE_MSK_V1) { 3672 3676 type = "HE"; 3673 3677 mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; 3674 - nss = ((rate & RATE_VHT_MCS_NSS_MSK) 3675 - >> RATE_VHT_MCS_NSS_POS) + 1; 3678 + nss = FIELD_GET(RATE_MCS_NSS_MSK, rate) + 1; 3676 3679 } else { 3677 3680 type = "Unknown"; /* shouldn't happen */ 3678 3681 }
+3 -5
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
··· 190 190 default: 191 191 /* Expected in monitor (not having the keys) */ 192 192 if (!mvm->monitor_on) 193 - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 193 + IWL_WARN(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 194 194 } 195 195 196 196 return 0; ··· 253 253 ARRAY_SIZE(thresh_tpt))) 254 254 return; 255 255 thr = thresh_tpt[rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK]; 256 - thr *= 1 + ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 257 - RATE_VHT_MCS_NSS_POS); 256 + thr *= 1 + FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags); 258 257 } 259 258 260 259 thr <<= ((rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK_V1) >> ··· 499 500 u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >> 500 501 RATE_MCS_STBC_POS; 501 502 rx_status->nss = 502 - ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 503 - RATE_VHT_MCS_NSS_POS) + 1; 503 + FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags) + 1; 504 504 rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK; 505 505 rx_status->encoding = RX_ENC_VHT; 506 506 rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
+571 -30
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 - * Copyright (C) 2012-2014, 2018-2022 Intel Corporation 3 + * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 4 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 5 * Copyright (C) 2015-2017 Intel Deutschland GmbH 6 6 */ ··· 205 205 return 0; 206 206 } 207 207 208 + /* put a TLV on the skb and return data pointer 209 + * 210 + * Also pad to 4 the len and zero out all data part 211 + */ 212 + static void * 213 + iwl_mvm_radiotap_put_tlv(struct sk_buff *skb, u16 type, u16 len) 214 + { 215 + struct ieee80211_radiotap_tlv *tlv; 216 + 217 + tlv = skb_put(skb, sizeof(*tlv)); 218 + tlv->type = cpu_to_le16(type); 219 + tlv->len = cpu_to_le16(len); 220 + return skb_put_zero(skb, ALIGN(len, 4)); 221 + } 222 + 208 223 static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, 209 224 struct sk_buff *skb) 210 225 { 211 226 struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 212 - struct ieee80211_vendor_radiotap *radiotap; 213 - const int size = sizeof(*radiotap) + sizeof(__le16); 227 + struct ieee80211_radiotap_vendor_content *radiotap; 228 + const u16 vendor_data_len = sizeof(mvm->cur_aid); 214 229 215 230 if (!mvm->cur_aid) 216 231 return; 217 232 218 - /* ensure alignment */ 219 - BUILD_BUG_ON((size + 2) % 4); 233 + radiotap = iwl_mvm_radiotap_put_tlv(skb, 234 + IEEE80211_RADIOTAP_VENDOR_NAMESPACE, 235 + sizeof(*radiotap) + vendor_data_len); 220 236 221 - radiotap = skb_put(skb, size + 2); 222 - radiotap->align = 1; 223 237 /* Intel OUI */ 224 238 radiotap->oui[0] = 0xf6; 225 239 radiotap->oui[1] = 0x54; 226 240 radiotap->oui[2] = 0x25; 227 241 /* radiotap sniffer config sub-namespace */ 228 - radiotap->subns = 1; 229 - radiotap->present = 0x1; 230 - radiotap->len = size - sizeof(*radiotap); 231 - radiotap->pad = 2; 242 + radiotap->oui_subtype = 1; 243 + radiotap->vendor_type = 0; 232 244 233 245 /* fill the data now */ 234 246 memcpy(radiotap->data, &mvm->cur_aid, sizeof(mvm->cur_aid)); 235 - /* and clear the padding */ 236 - memset(radiotap->data + sizeof(__le16), 0, radiotap->pad); 237 247 238 - rx_status->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA; 248 + rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; 239 249 } 240 250 241 251 /* iwl_mvm_pass_packet_to_mac80211 - passes the packet for mac80211 */ ··· 453 443 */ 454 444 if (!is_multicast_ether_addr(hdr->addr1) && 455 445 !mvm->monitor_on && net_ratelimit()) 456 - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); 446 + IWL_WARN(mvm, "Unhandled alg: 0x%x\n", status); 457 447 } 458 448 459 449 return 0; ··· 1177 1167 1178 1168 struct iwl_mvm_rx_phy_data { 1179 1169 enum iwl_rx_phy_info_type info_type; 1180 - __le32 d0, d1, d2, d3; 1170 + __le32 d0, d1, d2, d3, eht_d4, d5; 1181 1171 __le16 d4; 1172 + bool with_data; 1173 + bool first_subframe; 1174 + __le32 rx_vec[4]; 1182 1175 1183 1176 u32 rate_n_flags; 1184 1177 u32 gp2_on_air_rise; ··· 1459 1446 } 1460 1447 } 1461 1448 1449 + #define LE32_DEC_ENC(value, dec_bits, enc_bits) \ 1450 + le32_encode_bits(le32_get_bits(value, dec_bits), enc_bits) 1451 + 1452 + #define IWL_MVM_ENC_USIG_VALUE_MASK(usig, in_value, dec_bits, enc_bits) do { \ 1453 + typeof(enc_bits) _enc_bits = enc_bits; \ 1454 + typeof(usig) _usig = usig; \ 1455 + (_usig)->mask |= cpu_to_le32(_enc_bits); \ 1456 + (_usig)->value |= LE32_DEC_ENC(in_value, dec_bits, _enc_bits); \ 1457 + } while (0) 1458 + 1459 + #define __IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 1460 + eht->data[(rt_data)] |= \ 1461 + (cpu_to_le32 \ 1462 + (IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru ## _KNOWN) | \ 1463 + LE32_DEC_ENC(data ## fw_data, \ 1464 + IWL_RX_PHY_DATA ## fw_data ## _EHT_MU_EXT_RU_ALLOC_ ## fw_ru, \ 1465 + IEEE80211_RADIOTAP_EHT_DATA ## rt_data ## _RU_ALLOC_CC_ ## rt_ru)) 1466 + 1467 + #define _IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) \ 1468 + __IWL_MVM_ENC_EHT_RU(rt_data, rt_ru, fw_data, fw_ru) 1469 + 1470 + #define IEEE80211_RADIOTAP_RU_DATA_1_1_1 1 1471 + #define IEEE80211_RADIOTAP_RU_DATA_2_1_1 2 1472 + #define IEEE80211_RADIOTAP_RU_DATA_1_1_2 2 1473 + #define IEEE80211_RADIOTAP_RU_DATA_2_1_2 2 1474 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_1 3 1475 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_1 3 1476 + #define IEEE80211_RADIOTAP_RU_DATA_1_2_2 3 1477 + #define IEEE80211_RADIOTAP_RU_DATA_2_2_2 4 1478 + 1479 + #define IWL_RX_RU_DATA_A1 2 1480 + #define IWL_RX_RU_DATA_A2 2 1481 + #define IWL_RX_RU_DATA_B1 2 1482 + #define IWL_RX_RU_DATA_B2 3 1483 + #define IWL_RX_RU_DATA_C1 3 1484 + #define IWL_RX_RU_DATA_C2 3 1485 + #define IWL_RX_RU_DATA_D1 4 1486 + #define IWL_RX_RU_DATA_D2 4 1487 + 1488 + #define IWL_MVM_ENC_EHT_RU(rt_ru, fw_ru) \ 1489 + _IWL_MVM_ENC_EHT_RU(IEEE80211_RADIOTAP_RU_DATA_ ## rt_ru, \ 1490 + rt_ru, \ 1491 + IWL_RX_RU_DATA_ ## fw_ru, \ 1492 + fw_ru) 1493 + 1494 + static void iwl_mvm_decode_eht_ext_mu(struct iwl_mvm *mvm, 1495 + struct iwl_mvm_rx_phy_data *phy_data, 1496 + struct ieee80211_rx_status *rx_status, 1497 + struct ieee80211_radiotap_eht *eht, 1498 + struct ieee80211_radiotap_eht_usig *usig) 1499 + { 1500 + if (phy_data->with_data) { 1501 + __le32 data1 = phy_data->d1; 1502 + __le32 data2 = phy_data->d2; 1503 + __le32 data3 = phy_data->d3; 1504 + __le32 data4 = phy_data->eht_d4; 1505 + __le32 data5 = phy_data->d5; 1506 + u32 phy_bw = phy_data->rate_n_flags & RATE_MCS_CHAN_WIDTH_MSK; 1507 + 1508 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5, 1509 + IWL_RX_PHY_DATA5_EHT_TYPE_AND_COMP, 1510 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE); 1511 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5, 1512 + IWL_RX_PHY_DATA5_EHT_MU_PUNC_CH_CODE, 1513 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO); 1514 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data4, 1515 + IWL_RX_PHY_DATA4_EHT_MU_EXT_SIGB_MCS, 1516 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS); 1517 + IWL_MVM_ENC_USIG_VALUE_MASK 1518 + (usig, data1, IWL_RX_PHY_DATA1_EHT_MU_NUM_SIG_SYM_USIGA2, 1519 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS); 1520 + 1521 + eht->user_info[0] |= 1522 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN) | 1523 + LE32_DEC_ENC(data5, IWL_RX_PHY_DATA5_EHT_MU_STA_ID_USR, 1524 + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID); 1525 + 1526 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M); 1527 + eht->data[7] |= LE32_DEC_ENC 1528 + (data5, IWL_RX_PHY_DATA5_EHT_MU_NUM_USR_NON_OFDMA, 1529 + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS); 1530 + 1531 + /* 1532 + * Hardware labels the content channels/RU allocation values 1533 + * as follows: 1534 + * Content Channel 1 Content Channel 2 1535 + * 20 MHz: A1 1536 + * 40 MHz: A1 B1 1537 + * 80 MHz: A1 C1 B1 D1 1538 + * 160 MHz: A1 C1 A2 C2 B1 D1 B2 D2 1539 + * 320 MHz: A1 C1 A2 C2 A3 C3 A4 C4 B1 D1 B2 D2 B3 D3 B4 D4 1540 + * 1541 + * However firmware can only give us A1-D2, so the higher 1542 + * frequencies are missing. 1543 + */ 1544 + 1545 + switch (phy_bw) { 1546 + case RATE_MCS_CHAN_WIDTH_320: 1547 + /* additional values are missing in RX metadata */ 1548 + case RATE_MCS_CHAN_WIDTH_160: 1549 + /* content channel 1 */ 1550 + IWL_MVM_ENC_EHT_RU(1_2_1, A2); 1551 + IWL_MVM_ENC_EHT_RU(1_2_2, C2); 1552 + /* content channel 2 */ 1553 + IWL_MVM_ENC_EHT_RU(2_2_1, B2); 1554 + IWL_MVM_ENC_EHT_RU(2_2_2, D2); 1555 + fallthrough; 1556 + case RATE_MCS_CHAN_WIDTH_80: 1557 + /* content channel 1 */ 1558 + IWL_MVM_ENC_EHT_RU(1_1_2, C1); 1559 + /* content channel 2 */ 1560 + IWL_MVM_ENC_EHT_RU(2_1_2, D1); 1561 + fallthrough; 1562 + case RATE_MCS_CHAN_WIDTH_40: 1563 + /* content channel 2 */ 1564 + IWL_MVM_ENC_EHT_RU(2_1_1, B1); 1565 + fallthrough; 1566 + case RATE_MCS_CHAN_WIDTH_20: 1567 + IWL_MVM_ENC_EHT_RU(1_1_1, A1); 1568 + break; 1569 + } 1570 + } else { 1571 + __le32 usig_a1 = phy_data->rx_vec[0]; 1572 + __le32 usig_a2 = phy_data->rx_vec[1]; 1573 + 1574 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a1, 1575 + IWL_RX_USIG_A1_DISREGARD, 1576 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD); 1577 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a1, 1578 + IWL_RX_USIG_A1_VALIDATE, 1579 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE); 1580 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1581 + IWL_RX_USIG_A2_EHT_PPDU_TYPE, 1582 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE); 1583 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1584 + IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B2, 1585 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE); 1586 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1587 + IWL_RX_USIG_A2_EHT_PUNC_CHANNEL, 1588 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO); 1589 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1590 + IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B8, 1591 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE); 1592 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1593 + IWL_RX_USIG_A2_EHT_SIG_MCS, 1594 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS); 1595 + IWL_MVM_ENC_USIG_VALUE_MASK 1596 + (usig, usig_a2, IWL_RX_USIG_A2_EHT_SIG_SYM_NUM, 1597 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS); 1598 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1599 + IWL_RX_USIG_A2_EHT_CRC_OK, 1600 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC); 1601 + } 1602 + } 1603 + 1604 + static void iwl_mvm_decode_eht_ext_tb(struct iwl_mvm *mvm, 1605 + struct iwl_mvm_rx_phy_data *phy_data, 1606 + struct ieee80211_rx_status *rx_status, 1607 + struct ieee80211_radiotap_eht *eht, 1608 + struct ieee80211_radiotap_eht_usig *usig) 1609 + { 1610 + if (phy_data->with_data) { 1611 + __le32 data5 = phy_data->d5; 1612 + 1613 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5, 1614 + IWL_RX_PHY_DATA5_EHT_TYPE_AND_COMP, 1615 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE); 1616 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5, 1617 + IWL_RX_PHY_DATA5_EHT_TB_SPATIAL_REUSE1, 1618 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1); 1619 + 1620 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, data5, 1621 + IWL_RX_PHY_DATA5_EHT_TB_SPATIAL_REUSE2, 1622 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2); 1623 + } else { 1624 + __le32 usig_a1 = phy_data->rx_vec[0]; 1625 + __le32 usig_a2 = phy_data->rx_vec[1]; 1626 + 1627 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a1, 1628 + IWL_RX_USIG_A1_DISREGARD, 1629 + IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD); 1630 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1631 + IWL_RX_USIG_A2_EHT_PPDU_TYPE, 1632 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE); 1633 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1634 + IWL_RX_USIG_A2_EHT_USIG2_VALIDATE_B2, 1635 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE); 1636 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1637 + IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_1, 1638 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1); 1639 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1640 + IWL_RX_USIG_A2_EHT_TRIG_SPATIAL_REUSE_2, 1641 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2); 1642 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1643 + IWL_RX_USIG_A2_EHT_TRIG_USIG2_DISREGARD, 1644 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD); 1645 + IWL_MVM_ENC_USIG_VALUE_MASK(usig, usig_a2, 1646 + IWL_RX_USIG_A2_EHT_CRC_OK, 1647 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC); 1648 + } 1649 + } 1650 + 1651 + static void iwl_mvm_decode_eht_ru(struct iwl_mvm *mvm, 1652 + struct ieee80211_rx_status *rx_status, 1653 + struct ieee80211_radiotap_eht *eht) 1654 + { 1655 + u32 ru = le32_get_bits(eht->data[8], 1656 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1); 1657 + enum nl80211_eht_ru_alloc nl_ru; 1658 + 1659 + /* Using D1.5 Table 9-53a - Encoding of PS160 and RU Allocation subfields 1660 + * in an EHT variant User Info field 1661 + */ 1662 + 1663 + switch (ru) { 1664 + case 0 ... 36: 1665 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_26; 1666 + break; 1667 + case 37 ... 52: 1668 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_52; 1669 + break; 1670 + case 53 ... 60: 1671 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_106; 1672 + break; 1673 + case 61 ... 64: 1674 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_242; 1675 + break; 1676 + case 65 ... 66: 1677 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_484; 1678 + break; 1679 + case 67: 1680 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_996; 1681 + break; 1682 + case 68: 1683 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_2x996; 1684 + break; 1685 + case 69: 1686 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_4x996; 1687 + break; 1688 + case 70 ... 81: 1689 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_52P26; 1690 + break; 1691 + case 82 ... 89: 1692 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_106P26; 1693 + break; 1694 + case 90 ... 93: 1695 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_484P242; 1696 + break; 1697 + case 94 ... 95: 1698 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_996P484; 1699 + break; 1700 + case 96 ... 99: 1701 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242; 1702 + break; 1703 + case 100 ... 103: 1704 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484; 1705 + break; 1706 + case 104: 1707 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_3x996; 1708 + break; 1709 + case 105 ... 106: 1710 + nl_ru = NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484; 1711 + break; 1712 + default: 1713 + return; 1714 + } 1715 + 1716 + rx_status->bw = RATE_INFO_BW_EHT_RU; 1717 + rx_status->eht.ru = nl_ru; 1718 + } 1719 + 1720 + static void iwl_mvm_decode_eht_phy_data(struct iwl_mvm *mvm, 1721 + struct iwl_mvm_rx_phy_data *phy_data, 1722 + struct ieee80211_rx_status *rx_status, 1723 + struct ieee80211_radiotap_eht *eht, 1724 + struct ieee80211_radiotap_eht_usig *usig) 1725 + 1726 + { 1727 + __le32 data0 = phy_data->d0; 1728 + __le32 data1 = phy_data->d1; 1729 + __le32 usig_a1 = phy_data->rx_vec[0]; 1730 + u8 info_type = phy_data->info_type; 1731 + 1732 + /* Not in EHT range */ 1733 + if (info_type < IWL_RX_PHY_INFO_TYPE_EHT_MU || 1734 + info_type > IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT) 1735 + return; 1736 + 1737 + usig->common |= cpu_to_le32 1738 + (IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN | 1739 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN); 1740 + if (phy_data->with_data) { 1741 + usig->common |= LE32_DEC_ENC(data0, 1742 + IWL_RX_PHY_DATA0_EHT_UPLINK, 1743 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL); 1744 + usig->common |= LE32_DEC_ENC(data0, 1745 + IWL_RX_PHY_DATA0_EHT_BSS_COLOR_MASK, 1746 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR); 1747 + } else { 1748 + usig->common |= LE32_DEC_ENC(usig_a1, 1749 + IWL_RX_USIG_A1_UL_FLAG, 1750 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL); 1751 + usig->common |= LE32_DEC_ENC(usig_a1, 1752 + IWL_RX_USIG_A1_BSS_COLOR, 1753 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR); 1754 + } 1755 + 1756 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE); 1757 + eht->data[0] |= LE32_DEC_ENC(data0, 1758 + IWL_RX_PHY_DATA0_ETH_SPATIAL_REUSE_MASK, 1759 + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE); 1760 + 1761 + /* All RU allocating size/index is in TB format */ 1762 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT); 1763 + eht->data[8] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PS160, 1764 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160); 1765 + eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_B0, 1766 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0); 1767 + eht->data[8] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_RU_B1_B7_ALLOC, 1768 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1); 1769 + 1770 + iwl_mvm_decode_eht_ru(mvm, rx_status, eht); 1771 + 1772 + /* We only get here in case of IWL_RX_MPDU_PHY_TSF_OVERLOAD is set 1773 + * which is on only in case of monitor mode so no need to check monitor 1774 + * mode 1775 + */ 1776 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80); 1777 + eht->data[1] |= 1778 + le32_encode_bits(mvm->monitor_p80, 1779 + IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80); 1780 + 1781 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN); 1782 + if (phy_data->with_data) 1783 + usig->common |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_TXOP_DUR_MASK, 1784 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); 1785 + else 1786 + usig->common |= LE32_DEC_ENC(usig_a1, IWL_RX_USIG_A1_TXOP_DURATION, 1787 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP); 1788 + 1789 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM); 1790 + eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_LDPC_EXT_SYM, 1791 + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM); 1792 + 1793 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM); 1794 + eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PRE_FEC_PAD_MASK, 1795 + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM); 1796 + 1797 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM); 1798 + eht->data[0] |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PE_DISAMBIG, 1799 + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM); 1800 + 1801 + /* TODO: what about IWL_RX_PHY_DATA0_EHT_BW320_SLOT */ 1802 + 1803 + if (!le32_get_bits(data0, IWL_RX_PHY_DATA0_EHT_SIGA_CRC_OK)) 1804 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC); 1805 + 1806 + usig->common |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN); 1807 + usig->common |= LE32_DEC_ENC(data0, IWL_RX_PHY_DATA0_EHT_PHY_VER, 1808 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER); 1809 + 1810 + /* 1811 + * TODO: what about TB - IWL_RX_PHY_DATA1_EHT_TB_PILOT_TYPE, 1812 + * IWL_RX_PHY_DATA1_EHT_TB_LOW_SS 1813 + */ 1814 + 1815 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF); 1816 + eht->data[0] |= LE32_DEC_ENC(data1, IWL_RX_PHY_DATA1_EHT_SIG_LTF_NUM, 1817 + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF); 1818 + 1819 + if (info_type == IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT || 1820 + info_type == IWL_RX_PHY_INFO_TYPE_EHT_TB) 1821 + iwl_mvm_decode_eht_ext_tb(mvm, phy_data, rx_status, eht, usig); 1822 + 1823 + if (info_type == IWL_RX_PHY_INFO_TYPE_EHT_MU_EXT || 1824 + info_type == IWL_RX_PHY_INFO_TYPE_EHT_MU) 1825 + iwl_mvm_decode_eht_ext_mu(mvm, phy_data, rx_status, eht, usig); 1826 + } 1827 + 1828 + static void iwl_mvm_rx_eht(struct iwl_mvm *mvm, struct sk_buff *skb, 1829 + struct iwl_mvm_rx_phy_data *phy_data, 1830 + int queue) 1831 + { 1832 + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 1833 + 1834 + struct ieee80211_radiotap_eht *eht; 1835 + struct ieee80211_radiotap_eht_usig *usig; 1836 + size_t eht_len = sizeof(*eht); 1837 + 1838 + u32 rate_n_flags = phy_data->rate_n_flags; 1839 + u32 he_type = rate_n_flags & RATE_MCS_HE_TYPE_MSK; 1840 + /* EHT and HE have the same valus for LTF */ 1841 + u8 ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN; 1842 + u16 phy_info = phy_data->phy_info; 1843 + u32 bw; 1844 + 1845 + /* u32 for 1 user_info */ 1846 + if (phy_data->with_data) 1847 + eht_len += sizeof(u32); 1848 + 1849 + eht = iwl_mvm_radiotap_put_tlv(skb, IEEE80211_RADIOTAP_EHT, eht_len); 1850 + 1851 + usig = iwl_mvm_radiotap_put_tlv(skb, IEEE80211_RADIOTAP_EHT_USIG, 1852 + sizeof(*usig)); 1853 + rx_status->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; 1854 + usig->common |= 1855 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN); 1856 + 1857 + /* specific handling for 320MHz */ 1858 + bw = FIELD_GET(RATE_MCS_CHAN_WIDTH_MSK, rate_n_flags); 1859 + if (bw == RATE_MCS_CHAN_WIDTH_320_VAL) 1860 + bw += FIELD_GET(IWL_RX_PHY_DATA0_EHT_BW320_SLOT, 1861 + le32_to_cpu(phy_data->d0)); 1862 + 1863 + usig->common |= cpu_to_le32 1864 + (FIELD_PREP(IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW, bw)); 1865 + 1866 + /* report the AMPDU-EOF bit on single frames */ 1867 + if (!queue && !(phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 1868 + rx_status->flag |= RX_FLAG_AMPDU_DETAILS; 1869 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1870 + if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 1871 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1872 + } 1873 + 1874 + /* update aggregation data for monitor sake on default queue */ 1875 + if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && 1876 + (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) { 1877 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1878 + if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 1879 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 1880 + } 1881 + 1882 + if (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) 1883 + iwl_mvm_decode_eht_phy_data(mvm, phy_data, rx_status, eht, usig); 1884 + 1885 + #define CHECK_TYPE(F) \ 1886 + BUILD_BUG_ON(IEEE80211_RADIOTAP_HE_DATA1_FORMAT_ ## F != \ 1887 + (RATE_MCS_HE_TYPE_ ## F >> RATE_MCS_HE_TYPE_POS)) 1888 + 1889 + CHECK_TYPE(SU); 1890 + CHECK_TYPE(EXT_SU); 1891 + CHECK_TYPE(MU); 1892 + CHECK_TYPE(TRIG); 1893 + 1894 + switch (FIELD_GET(RATE_MCS_HE_GI_LTF_MSK, rate_n_flags)) { 1895 + case 0: 1896 + if (he_type == RATE_MCS_HE_TYPE_TRIG) { 1897 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_1_6; 1898 + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_1X; 1899 + } else { 1900 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_0_8; 1901 + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; 1902 + } 1903 + break; 1904 + case 1: 1905 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_1_6; 1906 + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_2X; 1907 + break; 1908 + case 2: 1909 + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; 1910 + if (he_type == RATE_MCS_HE_TYPE_TRIG) 1911 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_3_2; 1912 + else 1913 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_0_8; 1914 + break; 1915 + case 3: 1916 + if (he_type != RATE_MCS_HE_TYPE_TRIG) { 1917 + ltf = IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_4X; 1918 + rx_status->eht.gi = NL80211_RATE_INFO_EHT_GI_3_2; 1919 + } 1920 + break; 1921 + default: 1922 + /* nothing here */ 1923 + break; 1924 + } 1925 + 1926 + if (ltf != IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE_UNKNOWN) { 1927 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_GI); 1928 + eht->data[0] |= cpu_to_le32 1929 + (FIELD_PREP(IEEE80211_RADIOTAP_EHT_DATA0_LTF, 1930 + ltf) | 1931 + FIELD_PREP(IEEE80211_RADIOTAP_EHT_DATA0_GI, 1932 + rx_status->eht.gi)); 1933 + } 1934 + 1935 + 1936 + if (!phy_data->with_data) { 1937 + eht->known |= cpu_to_le32(IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S | 1938 + IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S); 1939 + eht->data[7] |= 1940 + le32_encode_bits(le32_get_bits(phy_data->rx_vec[2], 1941 + RX_NO_DATA_RX_VEC2_EHT_NSTS_MSK), 1942 + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S); 1943 + if (rate_n_flags & RATE_MCS_BF_MSK) 1944 + eht->data[7] |= 1945 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S); 1946 + } else { 1947 + eht->user_info[0] |= 1948 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN | 1949 + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN | 1950 + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O | 1951 + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O | 1952 + IEEE80211_RADIOTAP_EHT_USER_INFO_DATA_FOR_USER); 1953 + 1954 + if (rate_n_flags & RATE_MCS_BF_MSK) 1955 + eht->user_info[0] |= 1956 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O); 1957 + 1958 + if (rate_n_flags & RATE_MCS_LDPC_MSK) 1959 + eht->user_info[0] |= 1960 + cpu_to_le32(IEEE80211_RADIOTAP_EHT_USER_INFO_CODING); 1961 + 1962 + eht->user_info[0] |= cpu_to_le32 1963 + (FIELD_PREP(IEEE80211_RADIOTAP_EHT_USER_INFO_MCS, 1964 + FIELD_GET(RATE_VHT_MCS_RATE_CODE_MSK, 1965 + rate_n_flags)) | 1966 + FIELD_PREP(IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O, 1967 + FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags))); 1968 + } 1969 + } 1970 + 1462 1971 static void iwl_mvm_rx_he(struct iwl_mvm *mvm, struct sk_buff *skb, 1463 1972 struct iwl_mvm_rx_phy_data *phy_data, 1464 1973 int queue) ··· 2032 1497 2033 1498 /* update aggregation data for monitor sake on default queue */ 2034 1499 if (!queue && (phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD) && 2035 - (phy_info & IWL_RX_MPDU_PHY_AMPDU)) { 2036 - bool toggle_bit = phy_info & IWL_RX_MPDU_PHY_AMPDU_TOGGLE; 2037 - 2038 - /* toggle is switched whenever new aggregation starts */ 2039 - if (toggle_bit != mvm->ampdu_toggle) { 2040 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 2041 - if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_HE_DELIM_EOF)) 2042 - rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 2043 - } 1500 + (phy_info & IWL_RX_MPDU_PHY_AMPDU) && phy_data->first_subframe) { 1501 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT_KNOWN; 1502 + if (phy_data->d0 & cpu_to_le32(IWL_RX_PHY_DATA0_EHT_DELIM_EOF)) 1503 + rx_status->flag |= RX_FLAG_AMPDU_EOF_BIT; 2044 1504 } 2045 1505 2046 1506 if (he_type == RATE_MCS_HE_TYPE_EXT_SU && ··· 2123 1593 case IWL_RX_PHY_INFO_TYPE_HE_MU: 2124 1594 case IWL_RX_PHY_INFO_TYPE_HE_MU_EXT: 2125 1595 case IWL_RX_PHY_INFO_TYPE_HE_TB: 1596 + case IWL_RX_PHY_INFO_TYPE_EHT_MU: 1597 + case IWL_RX_PHY_INFO_TYPE_EHT_TB: 1598 + case IWL_RX_PHY_INFO_TYPE_EHT_MU_EXT: 1599 + case IWL_RX_PHY_INFO_TYPE_EHT_TB_EXT: 2126 1600 lsig = skb_put(skb, sizeof(*lsig)); 2127 1601 lsig->data1 = cpu_to_le16(IEEE80211_RADIOTAP_LSIG_DATA1_LENGTH_KNOWN); 2128 1602 lsig->data2 = le16_encode_bits(le32_get_bits(phy_data->d1, ··· 2222 1688 rx_status->band); 2223 1689 iwl_mvm_get_signal_strength(mvm, rx_status, rate_n_flags, 2224 1690 phy_data->energy_a, phy_data->energy_b); 1691 + 1692 + /* using TLV format and must be after all fixed len fields */ 1693 + if (format == RATE_MCS_EHT_MSK) 1694 + iwl_mvm_rx_eht(mvm, skb, phy_data, queue); 2225 1695 2226 1696 if (unlikely(mvm->monitor_on)) 2227 1697 iwl_mvm_add_rtap_sniffer_config(mvm, skb); ··· 2326 1788 phy_data.d1 = desc->v3.phy_data1; 2327 1789 phy_data.d2 = desc->v3.phy_data2; 2328 1790 phy_data.d3 = desc->v3.phy_data3; 1791 + phy_data.eht_d4 = desc->phy_eht_data4; 1792 + phy_data.d5 = desc->v3.phy_data5; 2329 1793 } else { 2330 1794 phy_data.rate_n_flags = le32_to_cpu(desc->v1.rate_n_flags); 2331 1795 phy_data.channel = desc->v1.channel; ··· 2357 1817 return; 2358 1818 } 2359 1819 1820 + phy_data.with_data = true; 2360 1821 phy_data.phy_info = le16_to_cpu(desc->phy_info); 2361 1822 phy_data.d4 = desc->phy_data4; 2362 1823 ··· 2438 1897 if (mvm->ampdu_ref == 0) 2439 1898 mvm->ampdu_ref++; 2440 1899 mvm->ampdu_toggle = toggle_bit; 1900 + phy_data.first_subframe = true; 2441 1901 } 2442 1902 rx_status->ampdu_reference = mvm->ampdu_ref; 2443 1903 } ··· 2621 2079 phy_data.energy_a = u32_get_bits(rssi, RX_NO_DATA_CHAIN_A_MSK); 2622 2080 phy_data.energy_b = u32_get_bits(rssi, RX_NO_DATA_CHAIN_B_MSK); 2623 2081 phy_data.channel = u32_get_bits(rssi, RX_NO_DATA_CHANNEL_MSK); 2082 + phy_data.with_data = false; 2624 2083 2625 2084 if (iwl_fw_lookup_notif_ver(mvm->fw, DATA_PATH_GROUP, 2626 2085 RX_NO_DATA_NOTIF, 0) < 2) { ··· 2640 2097 sizeof(struct iwl_rx_no_data_ver_3))) 2641 2098 /* invalid len for ver 3 */ 2642 2099 return; 2100 + memcpy(phy_data.rx_vec, desc->rx_vec, sizeof(phy_data.rx_vec)); 2643 2101 } else { 2644 2102 if (format == RATE_MCS_EHT_MSK) 2645 2103 /* no support for EHT before version 3 API */ ··· 2667 2123 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING; 2668 2124 break; 2669 2125 case RX_NO_DATA_INFO_TYPE_MU_UNMATCHED: 2670 - case RX_NO_DATA_INFO_TYPE_HE_TB_UNMATCHED: 2126 + case RX_NO_DATA_INFO_TYPE_TB_UNMATCHED: 2671 2127 rx_status->zero_length_psdu_type = 2672 2128 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED; 2673 2129 break; ··· 2686 2142 * 2687 2143 * We mark it as mac header, for upper layers to know where 2688 2144 * all radio tap header ends. 2689 - * 2690 - * Since data doesn't move data while putting data on skb and that is 2691 - * the only way we use, data + len is the next place that hdr would be put 2692 2145 */ 2693 - skb_set_mac_header(skb, skb->len); 2146 + skb_reset_mac_header(skb); 2694 2147 2695 2148 /* 2696 2149 * Override the nss from the rx_vec since the rate_n_flags has
+3 -4
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
··· 1396 1396 r->idx = rate; 1397 1397 } else if (format == RATE_MCS_VHT_MSK) { 1398 1398 ieee80211_rate_set_vht(r, rate, 1399 - ((rate_n_flags & RATE_MCS_NSS_MSK) >> 1400 - RATE_MCS_NSS_POS) + 1); 1399 + FIELD_GET(RATE_MCS_NSS_MSK, 1400 + rate_n_flags) + 1); 1401 1401 r->flags |= IEEE80211_TX_RC_VHT_MCS; 1402 1402 } else if (format == RATE_MCS_HE_MSK) { 1403 1403 /* mac80211 cannot do this without ieee80211_tx_status_ext() ··· 1428 1428 } else if (rate_n_flags & RATE_MCS_VHT_MSK_V1) { 1429 1429 ieee80211_rate_set_vht( 1430 1430 r, rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK, 1431 - ((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >> 1432 - RATE_VHT_MCS_NSS_POS) + 1); 1431 + FIELD_GET(RATE_MCS_NSS_MSK, rate_n_flags) + 1); 1433 1432 r->flags |= IEEE80211_TX_RC_VHT_MCS; 1434 1433 } else { 1435 1434 r->idx = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
+5
drivers/net/wireless/intel/iwlwifi/pcie/drv.c
··· 1194 1194 IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_CDB, IWL_CFG_IS_JACKET, 1195 1195 iwl_cfg_bnj_a0_fm4_a0, iwl_bz_name), 1196 1196 _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1197 + IWL_CFG_MAC_TYPE_GL, SILICON_B_STEP, 1198 + IWL_CFG_RF_TYPE_FM, IWL_CFG_ANY, 1199 + IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_CDB, IWL_CFG_IS_JACKET, 1200 + iwl_cfg_bnj_b0_fm4_b0, iwl_bz_name), 1201 + _IWL_DEV_INFO(IWL_CFG_ANY, IWL_CFG_ANY, 1197 1202 IWL_CFG_MAC_TYPE_GL, IWL_CFG_ANY, 1198 1203 IWL_CFG_RF_TYPE_GF, IWL_CFG_ANY, 1199 1204 IWL_CFG_ANY, IWL_CFG_ANY, IWL_CFG_NO_CDB, IWL_CFG_IS_JACKET,
+4 -1
drivers/net/wireless/intel/iwlwifi/pcie/trans-gen2.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 2 /* 3 3 * Copyright (C) 2017 Intel Deutschland GmbH 4 - * Copyright (C) 2018-2021 Intel Corporation 4 + * Copyright (C) 2018-2022 Intel Corporation 5 5 */ 6 6 #include "iwl-trans.h" 7 7 #include "iwl-prph.h" ··· 276 276 break; 277 277 case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_HRCDB): 278 278 pos = scnprintf(buf, buflen, "HRCDB"); 279 + break; 280 + case CSR_HW_RFID_TYPE(CSR_HW_RF_ID_TYPE_MS): 281 + pos = scnprintf(buf, buflen, "MS"); 279 282 break; 280 283 default: 281 284 return;
+28 -24
drivers/net/wireless/mac80211_hwsim.c
··· 1534 1534 * the values accordingly. 1535 1535 */ 1536 1536 #ifdef HWSIM_RADIOTAP_OUI 1537 - struct ieee80211_vendor_radiotap *rtap; 1537 + struct ieee80211_radiotap_vendor_tlv *rtap; 1538 + static const char vendor_data[8] = "ABCDEFGH"; 1539 + 1540 + // Make sure no padding is needed 1541 + BUILD_BUG_ON(sizeof(vendor_data) % 4); 1542 + /* this is last radiotap info before the mac header, so 1543 + * skb_reset_mac_header for mac8022 to know the end of 1544 + * the radiotap TLV/beginning of the 802.11 header 1545 + */ 1546 + skb_reset_mac_header(skb); 1538 1547 1539 1548 /* 1540 1549 * Note that this code requires the headroom in the SKB 1541 1550 * that was allocated earlier. 1542 1551 */ 1543 - rtap = skb_push(skb, sizeof(*rtap) + 8 + 4); 1544 - rtap->oui[0] = HWSIM_RADIOTAP_OUI[0]; 1545 - rtap->oui[1] = HWSIM_RADIOTAP_OUI[1]; 1546 - rtap->oui[2] = HWSIM_RADIOTAP_OUI[2]; 1547 - rtap->subns = 127; 1552 + rtap = skb_push(skb, sizeof(*rtap) + sizeof(vendor_data)); 1548 1553 1549 - /* 1550 - * Radiotap vendor namespaces can (and should) also be 1551 - * split into fields by using the standard radiotap 1552 - * presence bitmap mechanism. Use just BIT(0) here for 1553 - * the presence bitmap. 1554 - */ 1555 - rtap->present = BIT(0); 1556 - /* We have 8 bytes of (dummy) data */ 1557 - rtap->len = 8; 1558 - /* For testing, also require it to be aligned */ 1559 - rtap->align = 8; 1560 - /* And also test that padding works, 4 bytes */ 1561 - rtap->pad = 4; 1562 - /* push the data */ 1563 - memcpy(rtap->data, "ABCDEFGH", 8); 1564 - /* make sure to clear padding, mac80211 doesn't */ 1565 - memset(rtap->data + 8, 0, 4); 1554 + rtap->len = cpu_to_le16(sizeof(*rtap) - 1555 + sizeof(struct ieee80211_radiotap_tlv) + 1556 + sizeof(vendor_data)); 1557 + rtap->type = cpu_to_le16(IEEE80211_RADIOTAP_VENDOR_NAMESPACE); 1566 1558 1567 - IEEE80211_SKB_RXCB(skb)->flag |= RX_FLAG_RADIOTAP_VENDOR_DATA; 1559 + rtap->content.oui[0] = HWSIM_RADIOTAP_OUI[0]; 1560 + rtap->content.oui[1] = HWSIM_RADIOTAP_OUI[1]; 1561 + rtap->content.oui[2] = HWSIM_RADIOTAP_OUI[2]; 1562 + rtap->content.oui_subtype = 127; 1563 + /* clear reserved field */ 1564 + rtap->content.reserved = 0; 1565 + rtap->content.vendor_type = 0; 1566 + memcpy(rtap->content.data, vendor_data, sizeof(vendor_data)); 1567 + 1568 + IEEE80211_SKB_RXCB(skb)->flag |= RX_FLAG_RADIOTAP_TLV_AT_END; 1568 1569 #endif 1569 1570 } 1570 1571 ··· 4446 4445 NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS); 4447 4446 wiphy_ext_feature_set(hw->wiphy, 4448 4447 NL80211_EXT_FEATURE_BEACON_RATE_LEGACY); 4448 + 4449 + wiphy_ext_feature_set(hw->wiphy, 4450 + NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT); 4449 4451 4450 4452 hw->wiphy->interface_modes = param->iftypes; 4451 4453
+6 -6
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8188e.c
··· 1699 1699 1700 1700 dev_dbg(dev, "%s: len: %d items: %d\n", __func__, tx_rpt_len, items); 1701 1701 1702 + /* We only use macid 0, so only the first item is relevant. 1703 + * AP mode will use more of them if it's ever implemented. 1704 + */ 1705 + if (!priv->vif || priv->vif->type == NL80211_IFTYPE_STATION) 1706 + items = 1; 1707 + 1702 1708 for (macid = 0; macid < items; macid++) { 1703 1709 valid = false; 1704 1710 ··· 1747 1741 min_rpt_time = ra->rpt_time; 1748 1742 1749 1743 rpt += TX_RPT2_ITEM_SIZE; 1750 - 1751 - /* 1752 - * We only use macid 0, so only the first item is relevant. 1753 - * AP mode will use more of them if it's ever implemented. 1754 - */ 1755 - break; 1756 1744 } 1757 1745 1758 1746 if (min_rpt_time != ra->pre_min_rpt_time) {
+1 -5
drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
··· 1575 1575 static void rtl8xxxu_print_chipinfo(struct rtl8xxxu_priv *priv) 1576 1576 { 1577 1577 struct device *dev = &priv->udev->dev; 1578 - char cut = '?'; 1579 - 1580 - /* Currently always true: chip_cut is 4 bits. */ 1581 - if (priv->chip_cut <= 15) 1582 - cut = 'A' + priv->chip_cut; 1578 + char cut = 'A' + priv->chip_cut; 1583 1579 1584 1580 dev_info(dev, 1585 1581 "RTL%s rev %c (%s) romver %d, %iT%iR, TX queues %i, WiFi=%i, BT=%i, GPS=%i, HI PA=%i\n",
+17 -8
drivers/net/wireless/realtek/rtlwifi/rtl8192ce/hw.c
··· 1428 1428 1429 1429 for (rf_path = 0; rf_path < 2; rf_path++) { 1430 1430 for (i = 0; i < 3; i++) { 1431 - if (!autoload_fail) { 1431 + if (!autoload_fail && 1432 + hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i] != 0xff && 1433 + hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + i] != 0xff) { 1432 1434 rtlefuse-> 1433 1435 eeprom_chnlarea_txpwr_cck[rf_path][i] = 1434 1436 hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; ··· 1450 1448 } 1451 1449 1452 1450 for (i = 0; i < 3; i++) { 1453 - if (!autoload_fail) 1451 + if (!autoload_fail && 1452 + hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i] != 0xff) 1454 1453 tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; 1455 1454 else 1456 1455 tempval = EEPROM_DEFAULT_HT40_2SDIFF; ··· 1521 1518 } 1522 1519 1523 1520 for (i = 0; i < 3; i++) { 1524 - if (!autoload_fail) { 1521 + if (!autoload_fail && 1522 + hwinfo[EEPROM_TXPWR_GROUP + i] != 0xff && 1523 + hwinfo[EEPROM_TXPWR_GROUP + 3 + i] != 0xff) { 1525 1524 rtlefuse->eeprom_pwrlimit_ht40[i] = 1526 1525 hwinfo[EEPROM_TXPWR_GROUP + i]; 1527 1526 rtlefuse->eeprom_pwrlimit_ht20[i] = ··· 1568 1563 for (i = 0; i < 14; i++) { 1569 1564 index = rtl92c_get_chnl_group((u8)i); 1570 1565 1571 - if (!autoload_fail) 1566 + if (!autoload_fail && 1567 + hwinfo[EEPROM_TXPOWERHT20DIFF + index] != 0xff) 1572 1568 tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; 1573 1569 else 1574 1570 tempval = EEPROM_DEFAULT_HT20_DIFF; ··· 1586 1580 1587 1581 index = rtl92c_get_chnl_group((u8)i); 1588 1582 1589 - if (!autoload_fail) 1583 + if (!autoload_fail && 1584 + hwinfo[EEPROM_TXPOWER_OFDMDIFF + index] != 0xff) 1590 1585 tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; 1591 1586 else 1592 1587 tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; ··· 1617 1610 "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 1618 1611 i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 1619 1612 1620 - if (!autoload_fail) 1613 + if (!autoload_fail && hwinfo[RF_OPTION1] != 0xff) 1621 1614 rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 1622 1615 else 1623 1616 rtlefuse->eeprom_regulatory = 0; 1624 1617 RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 1625 1618 "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 1626 1619 1627 - if (!autoload_fail) { 1620 + if (!autoload_fail && 1621 + hwinfo[EEPROM_TSSI_A] != 0xff && 1622 + hwinfo[EEPROM_TSSI_B] != 0xff) { 1628 1623 rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; 1629 1624 rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; 1630 1625 } else { ··· 1637 1628 rtlefuse->eeprom_tssi[RF90_PATH_A], 1638 1629 rtlefuse->eeprom_tssi[RF90_PATH_B]); 1639 1630 1640 - if (!autoload_fail) 1631 + if (!autoload_fail && hwinfo[EEPROM_THERMAL_METER] != 0xff) 1641 1632 tempval = hwinfo[EEPROM_THERMAL_METER]; 1642 1633 else 1643 1634 tempval = EEPROM_DEFAULT_THERMALMETER;
-6
drivers/net/wireless/realtek/rtlwifi/rtl8192de/hw.c
··· 1047 1047 struct rtl_priv *rtlpriv = rtl_priv(hw); 1048 1048 u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 1049 1049 enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 1050 - u8 bcnfunc_enable; 1051 1050 1052 1051 bt_msr &= 0xfc; 1053 1052 ··· 1063 1064 "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", 1064 1065 type); 1065 1066 } 1066 - bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); 1067 1067 switch (type) { 1068 1068 case NL80211_IFTYPE_UNSPECIFIED: 1069 1069 bt_msr |= MSR_NOLINK; 1070 1070 ledaction = LED_CTL_LINK; 1071 - bcnfunc_enable &= 0xF7; 1072 1071 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1073 1072 "Set Network type to NO LINK!\n"); 1074 1073 break; 1075 1074 case NL80211_IFTYPE_ADHOC: 1076 1075 bt_msr |= MSR_ADHOC; 1077 - bcnfunc_enable |= 0x08; 1078 1076 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1079 1077 "Set Network type to Ad Hoc!\n"); 1080 1078 break; 1081 1079 case NL80211_IFTYPE_STATION: 1082 1080 bt_msr |= MSR_INFRA; 1083 1081 ledaction = LED_CTL_LINK; 1084 - bcnfunc_enable &= 0xF7; 1085 1082 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1086 1083 "Set Network type to STA!\n"); 1087 1084 break; 1088 1085 case NL80211_IFTYPE_AP: 1089 1086 bt_msr |= MSR_AP; 1090 - bcnfunc_enable |= 0x08; 1091 1087 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1092 1088 "Set Network type to AP!\n"); 1093 1089 break;
-9
drivers/net/wireless/realtek/rtlwifi/rtl8192se/hw.c
··· 1552 1552 { 1553 1553 struct rtl_priv *rtlpriv = rtl_priv(hw); 1554 1554 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1555 - u16 bcntime_cfg = 0; 1556 - u16 bcn_cw = 6, bcn_ifs = 0xf; 1557 1555 u16 atim_window = 2; 1558 1556 1559 1557 /* ATIM Window (in unit of TU). */ ··· 1573 1575 * after receiving beacon frame from 1574 1576 * other ad hoc STA */ 1575 1577 rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100); 1576 - 1577 - /* Beacon Time Configuration */ 1578 - if (mac->opmode == NL80211_IFTYPE_ADHOC) 1579 - bcntime_cfg |= (bcn_cw << BCN_TCFG_CW_SHIFT); 1580 - 1581 - /* TODO: bcn_ifs may required to be changed on ASIC */ 1582 - bcntime_cfg |= bcn_ifs << BCN_TCFG_IFS; 1583 1578 1584 1579 /*for beacon changed */ 1585 1580 rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval);
+14 -3
drivers/net/wireless/realtek/rtw88/mac.c
··· 222 222 case RTW_HCI_TYPE_USB: 223 223 intf_mask = RTW_PWR_INTF_USB_MSK; 224 224 break; 225 + case RTW_HCI_TYPE_SDIO: 226 + intf_mask = RTW_PWR_INTF_SDIO_MSK; 227 + break; 225 228 default: 226 229 return -EINVAL; 227 230 } ··· 236 233 237 234 ret = rtw_sub_pwr_seq_parser(rtwdev, intf_mask, cut_mask, cmd); 238 235 if (ret) 239 - return -EBUSY; 236 + return ret; 240 237 241 238 idx++; 242 239 } while (1); ··· 250 247 const struct rtw_pwr_seq_cmd **pwr_seq; 251 248 u8 rpwm; 252 249 bool cur_pwr; 250 + int ret; 253 251 254 252 if (rtw_chip_wcpu_11ac(rtwdev)) { 255 253 rpwm = rtw_read8(rtwdev, rtwdev->hci.rpwm_addr); ··· 274 270 return -EALREADY; 275 271 276 272 pwr_seq = pwr_on ? chip->pwr_on_seq : chip->pwr_off_seq; 277 - if (rtw_pwr_seq_parser(rtwdev, pwr_seq)) 278 - return -EINVAL; 273 + ret = rtw_pwr_seq_parser(rtwdev, pwr_seq); 274 + if (ret) 275 + return ret; 279 276 280 277 if (pwr_on) 281 278 set_bit(RTW_FLAG_POWERON, rtwdev->flags); ··· 1045 1040 else 1046 1041 return -EINVAL; 1047 1042 break; 1043 + case RTW_HCI_TYPE_SDIO: 1044 + rqpn = &chip->rqpn_table[0]; 1045 + break; 1048 1046 default: 1049 1047 return -EINVAL; 1050 1048 } ··· 1209 1201 pg_tbl = &chip->page_table[4]; 1210 1202 else 1211 1203 return -EINVAL; 1204 + break; 1205 + case RTW_HCI_TYPE_SDIO: 1206 + pg_tbl = &chip->page_table[0]; 1212 1207 break; 1213 1208 default: 1214 1209 return -EINVAL;
+9
drivers/net/wireless/realtek/rtw88/rtw8821c.c
··· 32 32 ether_addr_copy(efuse->addr, map->u.mac_addr); 33 33 } 34 34 35 + static void rtw8821cs_efuse_parsing(struct rtw_efuse *efuse, 36 + struct rtw8821c_efuse *map) 37 + { 38 + ether_addr_copy(efuse->addr, map->s.mac_addr); 39 + } 40 + 35 41 enum rtw8821ce_rf_set { 36 42 SWITCH_TO_BTG, 37 43 SWITCH_TO_WLG, ··· 82 76 break; 83 77 case RTW_HCI_TYPE_USB: 84 78 rtw8821cu_efuse_parsing(efuse, map); 79 + break; 80 + case RTW_HCI_TYPE_SDIO: 81 + rtw8821cs_efuse_parsing(efuse, map); 85 82 break; 86 83 default: 87 84 /* unsupported now */
+6
drivers/net/wireless/realtek/rtw88/rtw8821c.h
··· 65 65 u8 res7; 66 66 }; 67 67 68 + struct rtw8821cs_efuse { 69 + u8 res4[0x4a]; /* 0xd0 */ 70 + u8 mac_addr[ETH_ALEN]; /* 0x11a */ 71 + } __packed; 72 + 68 73 struct rtw8821c_efuse { 69 74 __le16 rtl_id; 70 75 u8 res0[0x0e]; ··· 99 94 union { 100 95 struct rtw8821ce_efuse e; 101 96 struct rtw8821cu_efuse u; 97 + struct rtw8821cs_efuse s; 102 98 }; 103 99 }; 104 100
+9
drivers/net/wireless/realtek/rtw88/rtw8822b.c
··· 32 32 ether_addr_copy(efuse->addr, map->u.mac_addr); 33 33 } 34 34 35 + static void rtw8822bs_efuse_parsing(struct rtw_efuse *efuse, 36 + struct rtw8822b_efuse *map) 37 + { 38 + ether_addr_copy(efuse->addr, map->s.mac_addr); 39 + } 40 + 35 41 static int rtw8822b_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 36 42 { 37 43 struct rtw_efuse *efuse = &rtwdev->efuse; ··· 70 64 break; 71 65 case RTW_HCI_TYPE_USB: 72 66 rtw8822bu_efuse_parsing(efuse, map); 67 + break; 68 + case RTW_HCI_TYPE_SDIO: 69 + rtw8822bs_efuse_parsing(efuse, map); 73 70 break; 74 71 default: 75 72 /* unsupported now */
+7 -1
drivers/net/wireless/realtek/rtw88/rtw8822b.h
··· 65 65 u8 res7; 66 66 }; 67 67 68 + struct rtw8822bs_efuse { 69 + u8 res4[0x4a]; /* 0xd0 */ 70 + u8 mac_addr[ETH_ALEN]; /* 0x11a */ 71 + } __packed; 72 + 68 73 struct rtw8822b_efuse { 69 74 __le16 rtl_id; 70 75 u8 res0[0x0e]; ··· 97 92 u8 country_code[2]; 98 93 u8 res[3]; 99 94 union { 100 - struct rtw8822bu_efuse u; 101 95 struct rtw8822be_efuse e; 96 + struct rtw8822bu_efuse u; 97 + struct rtw8822bs_efuse s; 102 98 }; 103 99 }; 104 100
+9
drivers/net/wireless/realtek/rtw88/rtw8822c.c
··· 35 35 ether_addr_copy(efuse->addr, map->u.mac_addr); 36 36 } 37 37 38 + static void rtw8822cs_efuse_parsing(struct rtw_efuse *efuse, 39 + struct rtw8822c_efuse *map) 40 + { 41 + ether_addr_copy(efuse->addr, map->s.mac_addr); 42 + } 43 + 38 44 static int rtw8822c_read_efuse(struct rtw_dev *rtwdev, u8 *log_map) 39 45 { 40 46 struct rtw_efuse *efuse = &rtwdev->efuse; ··· 72 66 break; 73 67 case RTW_HCI_TYPE_USB: 74 68 rtw8822cu_efuse_parsing(efuse, map); 69 + break; 70 + case RTW_HCI_TYPE_SDIO: 71 + rtw8822cs_efuse_parsing(efuse, map); 75 72 break; 76 73 default: 77 74 /* unsupported now */
+7 -1
drivers/net/wireless/realtek/rtw88/rtw8822c.h
··· 16 16 u8 res2[0x3d]; 17 17 }; 18 18 19 + struct rtw8822cs_efuse { 20 + u8 res0[0x4a]; /* 0x120 */ 21 + u8 mac_addr[ETH_ALEN]; /* 0x16a */ 22 + } __packed; 23 + 19 24 struct rtw8822ce_efuse { 20 25 u8 mac_addr[ETH_ALEN]; /* 0x120 */ 21 26 u8 vender_id[2]; ··· 96 91 u8 res9; 97 92 u8 res10[0x42]; 98 93 union { 99 - struct rtw8822cu_efuse u; 100 94 struct rtw8822ce_efuse e; 95 + struct rtw8822cu_efuse u; 96 + struct rtw8822cs_efuse s; 101 97 }; 102 98 }; 103 99
+34 -1
drivers/net/wireless/realtek/rtw89/core.c
··· 1400 1400 } 1401 1401 } 1402 1402 1403 + static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, 1404 + struct sk_buff *skb) 1405 + { 1406 + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 1407 + struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; 1408 + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 1409 + struct rtw89_pktofld_info *info; 1410 + const u8 *ies = mgmt->u.beacon.variable, *ssid_ie; 1411 + 1412 + if (rx_status->band != NL80211_BAND_6GHZ) 1413 + return; 1414 + 1415 + ssid_ie = cfg80211_find_ie(WLAN_EID_SSID, ies, skb->len); 1416 + 1417 + list_for_each_entry(info, &pkt_list[NL80211_BAND_6GHZ], list) { 1418 + if (ether_addr_equal(info->bssid, mgmt->bssid)) { 1419 + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 1420 + continue; 1421 + } 1422 + 1423 + if (!ssid_ie || ssid_ie[1] != info->ssid_len || info->ssid_len == 0) 1424 + continue; 1425 + 1426 + if (memcmp(&ssid_ie[2], info->ssid, info->ssid_len) == 0) 1427 + rtw89_fw_h2c_del_pkt_offload(rtwdev, info->id); 1428 + } 1429 + } 1430 + 1403 1431 static void rtw89_vif_rx_stats_iter(void *data, u8 *mac, 1404 1432 struct ieee80211_vif *vif) 1405 1433 { ··· 1439 1411 struct sk_buff *skb = iter_data->skb; 1440 1412 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1441 1413 const u8 *bssid = iter_data->bssid; 1414 + 1415 + if (rtwdev->scanning && 1416 + (ieee80211_is_beacon(hdr->frame_control) || 1417 + ieee80211_is_probe_resp(hdr->frame_control))) 1418 + rtw89_core_cancel_6ghz_probe_tx(rtwdev, skb); 1442 1419 1443 1420 if (!vif->bss_conf.bssid) 1444 1421 return; ··· 3405 3372 3406 3373 hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS | 3407 3374 WIPHY_FLAG_TDLS_EXTERNAL_SETUP | 3408 - WIPHY_FLAG_AP_UAPSD; 3375 + WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_SPLIT_SCAN_6GHZ; 3409 3376 hw->wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; 3410 3377 3411 3378 hw->wiphy->max_scan_ssids = RTW89_SCANOFLD_MAX_SSID;
+1 -1
drivers/net/wireless/realtek/rtw89/core.h
··· 3023 3023 RTW89_FW_FEATURE_SCAN_OFFLOAD, 3024 3024 RTW89_FW_FEATURE_TX_WAKE, 3025 3025 RTW89_FW_FEATURE_CRASH_TRIGGER, 3026 - RTW89_FW_FEATURE_PACKET_DROP, 3026 + RTW89_FW_FEATURE_NO_PACKET_DROP, 3027 3027 RTW89_FW_FEATURE_NO_DEEP_PS, 3028 3028 RTW89_FW_FEATURE_NO_LPS_PG, 3029 3029 };
+127 -18
drivers/net/wireless/realtek/rtw89/fw.c
··· 235 235 236 236 __DEF_FW_FEAT_COND(ge, >=); /* greater or equal */ 237 237 __DEF_FW_FEAT_COND(le, <=); /* less or equal */ 238 + __DEF_FW_FEAT_COND(lt, <); /* less than */ 238 239 239 240 struct __fw_feat_cfg { 240 241 enum rtw89_core_chip_id chip_id; ··· 257 256 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, SCAN_OFFLOAD), 258 257 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 35, 0, TX_WAKE), 259 258 __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 36, 0, CRASH_TRIGGER), 260 - __CFG_FW_FEAT(RTL8852A, ge, 0, 13, 38, 0, PACKET_DROP), 259 + __CFG_FW_FEAT(RTL8852A, lt, 0, 13, 38, 0, NO_PACKET_DROP), 261 260 __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, NO_LPS_PG), 262 - __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 20, 0, PACKET_DROP), 261 + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 26, 0, TX_WAKE), 262 + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, CRASH_TRIGGER), 263 + __CFG_FW_FEAT(RTL8852B, ge, 0, 29, 29, 0, SCAN_OFFLOAD), 263 264 __CFG_FW_FEAT(RTL8852C, le, 0, 27, 33, 0, NO_DEEP_PS), 264 265 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 34, 0, TX_WAKE), 265 266 __CFG_FW_FEAT(RTL8852C, ge, 0, 27, 36, 0, SCAN_OFFLOAD), ··· 2705 2702 } 2706 2703 } 2707 2704 2705 + static bool rtw89_is_6ghz_wildcard_probe_req(struct rtw89_dev *rtwdev, 2706 + struct rtw89_vif *rtwvif, 2707 + struct rtw89_pktofld_info *info, 2708 + enum nl80211_band band, u8 ssid_idx) 2709 + { 2710 + struct cfg80211_scan_request *req = rtwvif->scan_req; 2711 + 2712 + if (band != NL80211_BAND_6GHZ) 2713 + return false; 2714 + 2715 + if (req->ssids[ssid_idx].ssid_len) { 2716 + memcpy(info->ssid, req->ssids[ssid_idx].ssid, 2717 + req->ssids[ssid_idx].ssid_len); 2718 + info->ssid_len = req->ssids[ssid_idx].ssid_len; 2719 + return false; 2720 + } else { 2721 + return true; 2722 + } 2723 + } 2724 + 2708 2725 static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, 2709 2726 struct rtw89_vif *rtwvif, 2710 - struct sk_buff *skb) 2727 + struct sk_buff *skb, u8 ssid_idx) 2711 2728 { 2712 2729 struct rtw89_hw_scan_info *scan_info = &rtwdev->scan_info; 2713 2730 struct ieee80211_scan_ies *ies = rtwvif->scan_ies; ··· 2752 2729 if (!info) { 2753 2730 ret = -ENOMEM; 2754 2731 kfree_skb(new); 2732 + goto out; 2733 + } 2734 + 2735 + if (rtw89_is_6ghz_wildcard_probe_req(rtwdev, rtwvif, info, band, 2736 + ssid_idx)) { 2737 + kfree_skb(new); 2738 + kfree(info); 2755 2739 goto out; 2756 2740 } 2757 2741 ··· 2792 2762 if (!skb) 2793 2763 return -ENOMEM; 2794 2764 2795 - ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb); 2765 + ret = rtw89_append_probe_req_ie(rtwdev, rtwvif, skb, i); 2796 2766 kfree_skb(skb); 2797 2767 2798 2768 if (ret) ··· 2800 2770 } 2801 2771 2802 2772 return 0; 2773 + } 2774 + 2775 + static int rtw89_update_6ghz_rnr_chan(struct rtw89_dev *rtwdev, 2776 + struct cfg80211_scan_request *req, 2777 + struct rtw89_mac_chinfo *ch_info) 2778 + { 2779 + struct ieee80211_vif *vif = rtwdev->scan_info.scanning_vif; 2780 + struct list_head *pkt_list = rtwdev->scan_info.pkt_list; 2781 + struct rtw89_vif *rtwvif = vif_to_rtwvif_safe(vif); 2782 + struct ieee80211_scan_ies *ies = rtwvif->scan_ies; 2783 + struct cfg80211_scan_6ghz_params *params; 2784 + struct rtw89_pktofld_info *info, *tmp; 2785 + struct ieee80211_hdr *hdr; 2786 + struct sk_buff *skb; 2787 + bool found; 2788 + int ret = 0; 2789 + u8 i; 2790 + 2791 + if (!req->n_6ghz_params) 2792 + return 0; 2793 + 2794 + for (i = 0; i < req->n_6ghz_params; i++) { 2795 + params = &req->scan_6ghz_params[i]; 2796 + 2797 + if (req->channels[params->channel_idx]->hw_value != 2798 + ch_info->pri_ch) 2799 + continue; 2800 + 2801 + found = false; 2802 + list_for_each_entry(tmp, &pkt_list[NL80211_BAND_6GHZ], list) { 2803 + if (ether_addr_equal(tmp->bssid, params->bssid)) { 2804 + found = true; 2805 + break; 2806 + } 2807 + } 2808 + if (found) 2809 + continue; 2810 + 2811 + skb = ieee80211_probereq_get(rtwdev->hw, rtwvif->mac_addr, 2812 + NULL, 0, req->ie_len); 2813 + skb_put_data(skb, ies->ies[NL80211_BAND_6GHZ], ies->len[NL80211_BAND_6GHZ]); 2814 + skb_put_data(skb, ies->common_ies, ies->common_ie_len); 2815 + hdr = (struct ieee80211_hdr *)skb->data; 2816 + ether_addr_copy(hdr->addr3, params->bssid); 2817 + 2818 + info = kzalloc(sizeof(*info), GFP_KERNEL); 2819 + if (!info) { 2820 + ret = -ENOMEM; 2821 + kfree_skb(skb); 2822 + goto out; 2823 + } 2824 + 2825 + ret = rtw89_fw_h2c_add_pkt_offload(rtwdev, &info->id, skb); 2826 + if (ret) { 2827 + kfree_skb(skb); 2828 + kfree(info); 2829 + goto out; 2830 + } 2831 + 2832 + ether_addr_copy(info->bssid, params->bssid); 2833 + info->channel_6ghz = req->channels[params->channel_idx]->hw_value; 2834 + list_add_tail(&info->list, &rtwdev->scan_info.pkt_list[NL80211_BAND_6GHZ]); 2835 + 2836 + ch_info->tx_pkt = true; 2837 + ch_info->period = RTW89_CHANNEL_TIME_6G + RTW89_DWELL_TIME_6G; 2838 + 2839 + kfree_skb(skb); 2840 + } 2841 + 2842 + out: 2843 + return ret; 2803 2844 } 2804 2845 2805 2846 static void rtw89_hw_scan_add_chan(struct rtw89_dev *rtwdev, int chan_type, ··· 2883 2782 struct cfg80211_scan_request *req = rtwvif->scan_req; 2884 2783 struct rtw89_pktofld_info *info; 2885 2784 u8 band, probe_count = 0; 2785 + int ret; 2886 2786 2887 2787 ch_info->notify_action = RTW89_SCANOFLD_DEBUG_MASK; 2888 2788 ch_info->dfs_ch = chan_type == RTW89_CHAN_DFS; ··· 2895 2793 ch_info->pause_data = false; 2896 2794 ch_info->probe_id = RTW89_SCANOFLD_PKT_NONE; 2897 2795 2898 - if (ssid_num) { 2899 - ch_info->num_pkt = ssid_num; 2900 - band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 2901 - 2902 - list_for_each_entry(info, &scan_info->pkt_list[band], list) { 2903 - ch_info->pkt_id[probe_count] = info->id; 2904 - if (++probe_count >= ssid_num) 2905 - break; 2906 - } 2907 - if (probe_count != ssid_num) 2908 - rtw89_err(rtwdev, "SSID num differs from list len\n"); 2909 - } 2910 - 2911 2796 if (ch_info->ch_band == RTW89_BAND_6G) { 2912 - if (ssid_num == 1 && req->ssids[0].ssid_len == 0) { 2797 + if ((ssid_num == 1 && req->ssids[0].ssid_len == 0) || 2798 + !ch_info->is_psc) { 2913 2799 ch_info->tx_pkt = false; 2914 2800 if (!req->duration_mandatory) 2915 2801 ch_info->period -= RTW89_DWELL_TIME_6G; 2916 2802 } 2803 + } 2804 + 2805 + ret = rtw89_update_6ghz_rnr_chan(rtwdev, req, ch_info); 2806 + if (ret) 2807 + rtw89_warn(rtwdev, "RNR fails: %d\n", ret); 2808 + 2809 + if (ssid_num) { 2810 + band = rtw89_hw_to_nl80211_band(ch_info->ch_band); 2811 + 2812 + list_for_each_entry(info, &scan_info->pkt_list[band], list) { 2813 + if (info->channel_6ghz && 2814 + ch_info->pri_ch != info->channel_6ghz) 2815 + continue; 2816 + ch_info->pkt_id[probe_count++] = info->id; 2817 + if (probe_count >= RTW89_SCANOFLD_MAX_SSID) 2818 + break; 2819 + } 2820 + ch_info->num_pkt = probe_count; 2917 2821 } 2918 2822 2919 2823 switch (chan_type) { ··· 2980 2872 ch_info->central_ch = channel->hw_value; 2981 2873 ch_info->pri_ch = channel->hw_value; 2982 2874 ch_info->rand_seq_num = random_seq; 2875 + ch_info->is_psc = cfg80211_channel_is_psc(channel); 2983 2876 2984 2877 if (channel->flags & 2985 2878 (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR))
+7
drivers/net/wireless/realtek/rtw89/fw.h
··· 237 237 u16 tx_pwr_idx; 238 238 u8 rsvd1; 239 239 struct list_head list; 240 + bool is_psc; 240 241 }; 241 242 242 243 struct rtw89_scan_option { ··· 248 247 struct rtw89_pktofld_info { 249 248 struct list_head list; 250 249 u8 id; 250 + 251 + /* Below fields are for 6 GHz RNR use only */ 252 + u8 ssid[IEEE80211_MAX_SSID_LEN]; 253 + u8 ssid_len; 254 + u8 bssid[ETH_ALEN]; 255 + u16 channel_6ghz; 251 256 }; 252 257 253 258 static inline void RTW89_SET_FWCMD_RA_IS_DIS(void *cmd, u32 val)
+1 -1
drivers/net/wireless/realtek/rtw89/mac.c
··· 5426 5426 for (i = 0; i < try_cnt; i++) { 5427 5427 ret = read_poll_timeout(mac_is_txq_empty, empty, empty, 50, 5428 5428 50000, false, rtwdev); 5429 - if (ret) 5429 + if (ret && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) 5430 5430 rtw89_fw_h2c_pkt_drop(rtwdev, &params); 5431 5431 else 5432 5432 return 0;
+1 -1
drivers/net/wireless/realtek/rtw89/mac80211.c
··· 676 676 rtw89_leave_lps(rtwdev); 677 677 rtw89_hci_flush_queues(rtwdev, queues, drop); 678 678 679 - if (drop && RTW89_CHK_FW_FEATURE(PACKET_DROP, &rtwdev->fw)) 679 + if (drop && !RTW89_CHK_FW_FEATURE(NO_PACKET_DROP, &rtwdev->fw)) 680 680 __rtw89_drop_packets(rtwdev, vif); 681 681 else 682 682 rtw89_mac_flush_txq(rtwdev, queues, drop);
+72
drivers/net/wireless/realtek/rtw89/phy.c
··· 4294 4294 data[RTW89_TSSI_SBW20]); 4295 4295 } 4296 4296 EXPORT_SYMBOL(rtw89_phy_tssi_ctrl_set_bandedge_cfg); 4297 + 4298 + static 4299 + const u8 rtw89_ch_base_table[16] = {1, 0xff, 4300 + 36, 100, 132, 149, 0xff, 4301 + 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; 4302 + #define RTW89_CH_BASE_IDX_2G 0 4303 + #define RTW89_CH_BASE_IDX_5G_FIRST 2 4304 + #define RTW89_CH_BASE_IDX_5G_LAST 5 4305 + #define RTW89_CH_BASE_IDX_6G_FIRST 7 4306 + #define RTW89_CH_BASE_IDX_6G_LAST 14 4307 + 4308 + #define RTW89_CH_BASE_IDX_MASK GENMASK(7, 4) 4309 + #define RTW89_CH_OFFSET_MASK GENMASK(3, 0) 4310 + 4311 + u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) 4312 + { 4313 + u8 chan_idx; 4314 + u8 last, first; 4315 + u8 idx; 4316 + 4317 + switch (band) { 4318 + case RTW89_BAND_2G: 4319 + chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, RTW89_CH_BASE_IDX_2G) | 4320 + FIELD_PREP(RTW89_CH_OFFSET_MASK, central_ch); 4321 + return chan_idx; 4322 + case RTW89_BAND_5G: 4323 + first = RTW89_CH_BASE_IDX_5G_FIRST; 4324 + last = RTW89_CH_BASE_IDX_5G_LAST; 4325 + break; 4326 + case RTW89_BAND_6G: 4327 + first = RTW89_CH_BASE_IDX_6G_FIRST; 4328 + last = RTW89_CH_BASE_IDX_6G_LAST; 4329 + break; 4330 + default: 4331 + rtw89_warn(rtwdev, "Unsupported band %d\n", band); 4332 + return 0; 4333 + } 4334 + 4335 + for (idx = last; idx >= first; idx--) 4336 + if (central_ch >= rtw89_ch_base_table[idx]) 4337 + break; 4338 + 4339 + if (idx < first) { 4340 + rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); 4341 + return 0; 4342 + } 4343 + 4344 + chan_idx = FIELD_PREP(RTW89_CH_BASE_IDX_MASK, idx) | 4345 + FIELD_PREP(RTW89_CH_OFFSET_MASK, 4346 + (central_ch - rtw89_ch_base_table[idx]) >> 1); 4347 + return chan_idx; 4348 + } 4349 + EXPORT_SYMBOL(rtw89_encode_chan_idx); 4350 + 4351 + void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, 4352 + u8 *ch, enum nl80211_band *band) 4353 + { 4354 + u8 idx, offset; 4355 + 4356 + idx = FIELD_GET(RTW89_CH_BASE_IDX_MASK, chan_idx); 4357 + offset = FIELD_GET(RTW89_CH_OFFSET_MASK, chan_idx); 4358 + 4359 + if (idx == RTW89_CH_BASE_IDX_2G) { 4360 + *band = NL80211_BAND_2GHZ; 4361 + *ch = offset; 4362 + return; 4363 + } 4364 + 4365 + *band = idx <= RTW89_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; 4366 + *ch = rtw89_ch_base_table[idx] + (offset << 1); 4367 + } 4368 + EXPORT_SYMBOL(rtw89_decode_chan_idx);
+3
drivers/net/wireless/realtek/rtw89/phy.h
··· 555 555 enum rtw89_tssi_bandedge_cfg bandedge_cfg); 556 556 void rtw89_phy_ul_tb_assoc(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif); 557 557 void rtw89_phy_ul_tb_ctrl_track(struct rtw89_dev *rtwdev); 558 + u8 rtw89_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band); 559 + void rtw89_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, 560 + u8 *ch, enum nl80211_band *band); 558 561 559 562 #endif
+7 -5
drivers/net/wireless/realtek/rtw89/rtw8852b.c
··· 1422 1422 { 1423 1423 bool cck_en = chan->channel <= 14; 1424 1424 u8 pri_ch_idx = chan->pri_ch_idx; 1425 + u8 band = chan->band_type, chan_idx; 1425 1426 1426 1427 if (cck_en) 1427 1428 rtw8852b_ctrl_sco_cck(rtwdev, chan->primary_channel); ··· 1445 1444 B_BT_DYN_DC_EST_EN_MSK, 0x0); 1446 1445 rtw89_phy_write32_mask(rtwdev, R_GNT_BT_WGT_EN, B_GNT_BT_WGT_EN, 0x0); 1447 1446 } 1448 - rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, 1449 - chan->primary_channel); 1447 + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); 1448 + rtw89_phy_write32_mask(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx); 1450 1449 rtw8852b_5m_mask(rtwdev, chan, phy_idx); 1451 1450 rtw8852b_bb_set_pop(rtwdev); 1452 1451 rtw8852b_bb_reset_all(rtwdev, phy_idx); ··· 2300 2299 struct ieee80211_rx_status *status) 2301 2300 { 2302 2301 u16 chan = phy_ppdu->chan_idx; 2303 - u8 band; 2302 + enum nl80211_band band; 2303 + u8 ch; 2304 2304 2305 2305 if (chan == 0) 2306 2306 return; 2307 2307 2308 - band = chan <= 14 ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; 2309 - status->freq = ieee80211_channel_to_frequency(chan, band); 2308 + rtw89_decode_chan_idx(rtwdev, chan, &ch, &band); 2309 + status->freq = ieee80211_channel_to_frequency(ch, band); 2310 2310 status->band = band; 2311 2311 } 2312 2312
+2 -72
drivers/net/wireless/realtek/rtw89/rtw8852c.c
··· 852 852 } 853 853 } 854 854 855 - static 856 - const u8 rtw8852c_ch_base_table[16] = {1, 0xff, 857 - 36, 100, 132, 149, 0xff, 858 - 1, 33, 65, 97, 129, 161, 193, 225, 0xff}; 859 - #define RTW8852C_CH_BASE_IDX_2G 0 860 - #define RTW8852C_CH_BASE_IDX_5G_FIRST 2 861 - #define RTW8852C_CH_BASE_IDX_5G_LAST 5 862 - #define RTW8852C_CH_BASE_IDX_6G_FIRST 7 863 - #define RTW8852C_CH_BASE_IDX_6G_LAST 14 864 - 865 - #define RTW8852C_CH_BASE_IDX_MASK GENMASK(7, 4) 866 - #define RTW8852C_CH_OFFSET_MASK GENMASK(3, 0) 867 - 868 - static u8 rtw8852c_encode_chan_idx(struct rtw89_dev *rtwdev, u8 central_ch, u8 band) 869 - { 870 - u8 chan_idx; 871 - u8 last, first; 872 - u8 idx; 873 - 874 - switch (band) { 875 - case RTW89_BAND_2G: 876 - chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, RTW8852C_CH_BASE_IDX_2G) | 877 - FIELD_PREP(RTW8852C_CH_OFFSET_MASK, central_ch); 878 - return chan_idx; 879 - case RTW89_BAND_5G: 880 - first = RTW8852C_CH_BASE_IDX_5G_FIRST; 881 - last = RTW8852C_CH_BASE_IDX_5G_LAST; 882 - break; 883 - case RTW89_BAND_6G: 884 - first = RTW8852C_CH_BASE_IDX_6G_FIRST; 885 - last = RTW8852C_CH_BASE_IDX_6G_LAST; 886 - break; 887 - default: 888 - rtw89_warn(rtwdev, "Unsupported band %d\n", band); 889 - return 0; 890 - } 891 - 892 - for (idx = last; idx >= first; idx--) 893 - if (central_ch >= rtw8852c_ch_base_table[idx]) 894 - break; 895 - 896 - if (idx < first) { 897 - rtw89_warn(rtwdev, "Unknown band %d channel %d\n", band, central_ch); 898 - return 0; 899 - } 900 - 901 - chan_idx = FIELD_PREP(RTW8852C_CH_BASE_IDX_MASK, idx) | 902 - FIELD_PREP(RTW8852C_CH_OFFSET_MASK, 903 - (central_ch - rtw8852c_ch_base_table[idx]) >> 1); 904 - return chan_idx; 905 - } 906 - 907 - static void rtw8852c_decode_chan_idx(struct rtw89_dev *rtwdev, u8 chan_idx, 908 - u8 *ch, enum nl80211_band *band) 909 - { 910 - u8 idx, offset; 911 - 912 - idx = FIELD_GET(RTW8852C_CH_BASE_IDX_MASK, chan_idx); 913 - offset = FIELD_GET(RTW8852C_CH_OFFSET_MASK, chan_idx); 914 - 915 - if (idx == RTW8852C_CH_BASE_IDX_2G) { 916 - *band = NL80211_BAND_2GHZ; 917 - *ch = offset; 918 - return; 919 - } 920 - 921 - *band = idx <= RTW8852C_CH_BASE_IDX_5G_LAST ? NL80211_BAND_5GHZ : NL80211_BAND_6GHZ; 922 - *ch = rtw8852c_ch_base_table[idx] + (offset << 1); 923 - } 924 - 925 855 static void rtw8852c_set_gain_offset(struct rtw89_dev *rtwdev, 926 856 const struct rtw89_chan *chan, 927 857 enum rtw89_phy_idx phy_idx, ··· 1014 1084 } 1015 1085 } 1016 1086 1017 - chan_idx = rtw8852c_encode_chan_idx(rtwdev, chan->primary_channel, band); 1087 + chan_idx = rtw89_encode_chan_idx(rtwdev, chan->primary_channel, band); 1018 1088 rtw89_phy_write32_idx(rtwdev, R_MAC_PIN_SEL, B_CH_IDX_SEG0, chan_idx, phy_idx); 1019 1089 } 1020 1090 ··· 2660 2730 if (chan_idx == 0) 2661 2731 return; 2662 2732 2663 - rtw8852c_decode_chan_idx(rtwdev, chan_idx, &ch, &band); 2733 + rtw89_decode_chan_idx(rtwdev, chan_idx, &ch, &band); 2664 2734 status->freq = ieee80211_channel_to_frequency(ch, band); 2665 2735 status->band = band; 2666 2736 }
+5
drivers/net/wireless/realtek/rtw89/ser.c
··· 414 414 415 415 static void ser_reset_trx_st_hdl(struct rtw89_ser *ser, u8 evt) 416 416 { 417 + struct rtw89_dev *rtwdev = container_of(ser, struct rtw89_dev, ser); 418 + 417 419 switch (evt) { 418 420 case SER_EV_STATE_IN: 421 + cancel_delayed_work_sync(&rtwdev->track_work); 419 422 drv_stop_tx(ser); 420 423 421 424 if (hal_stop_dma(ser)) { ··· 449 446 hal_enable_dma(ser); 450 447 drv_resume_rx(ser); 451 448 drv_resume_tx(ser); 449 + ieee80211_queue_delayed_work(rtwdev->hw, &rtwdev->track_work, 450 + RTW89_TRACK_WORK_PERIOD); 452 451 break; 453 452 454 453 default:
+3 -7
drivers/net/wireless/silabs/wfx/main.c
··· 358 358 359 359 wfx_bh_poll_irq(wdev); 360 360 err = wait_for_completion_timeout(&wdev->firmware_ready, 1 * HZ); 361 - if (err <= 0) { 362 - if (err == 0) { 363 - dev_err(wdev->dev, "timeout while waiting for startup indication\n"); 364 - err = -ETIMEDOUT; 365 - } else if (err == -ERESTARTSYS) { 366 - dev_info(wdev->dev, "probe interrupted by user\n"); 367 - } 361 + if (err == 0) { 362 + dev_err(wdev->dev, "timeout while waiting for startup indication\n"); 363 + err = -ETIMEDOUT; 368 364 goto bh_unregister; 369 365 } 370 366
+31 -5
include/net/cfg80211.h
··· 828 828 }; 829 829 830 830 /** 831 + * struct cfg80211_set_hw_timestamp - enable/disable HW timestamping 832 + * @macaddr: peer MAC address. NULL to enable/disable HW timestamping for all 833 + * addresses. 834 + * @enable: if set, enable HW timestamping for the specified MAC address. 835 + * Otherwise disable HW timestamping for the specified MAC address. 836 + */ 837 + struct cfg80211_set_hw_timestamp { 838 + const u8 *macaddr; 839 + bool enable; 840 + }; 841 + 842 + /** 831 843 * cfg80211_get_chandef_type - return old channel type from chandef 832 844 * @chandef: the channel definition 833 845 * ··· 4342 4330 * @add_link_station: Add a link to a station. 4343 4331 * @mod_link_station: Modify a link of a station. 4344 4332 * @del_link_station: Remove a link of a station. 4333 + * 4334 + * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames. 4345 4335 */ 4346 4336 struct cfg80211_ops { 4347 4337 int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); ··· 4697 4683 struct link_station_parameters *params); 4698 4684 int (*del_link_station)(struct wiphy *wiphy, struct net_device *dev, 4699 4685 struct link_station_del_parameters *params); 4686 + int (*set_hw_timestamp)(struct wiphy *wiphy, struct net_device *dev, 4687 + struct cfg80211_set_hw_timestamp *hwts); 4700 4688 }; 4701 4689 4702 4690 /* ··· 5155 5139 int n_akm_suites; 5156 5140 }; 5157 5141 5142 + #define CFG80211_HW_TIMESTAMP_ALL_PEERS 0xffff 5143 + 5158 5144 /** 5159 5145 * struct wiphy - wireless hardware description 5160 5146 * @mtx: mutex for the data (structures) of this device ··· 5366 5348 * NL80211_MAX_NR_AKM_SUITES in order to avoid compatibility issues with 5367 5349 * legacy userspace and maximum allowed value is 5368 5350 * CFG80211_MAX_NUM_AKM_SUITES. 5351 + * 5352 + * @hw_timestamp_max_peers: maximum number of peers that the driver supports 5353 + * enabling HW timestamping for concurrently. Setting this field to a 5354 + * non-zero value indicates that the driver supports HW timestamping. 5355 + * A value of %CFG80211_HW_TIMESTAMP_ALL_PEERS indicates the driver 5356 + * supports enabling HW timestamping for all peers (i.e. no need to 5357 + * specify a mac address). 5369 5358 */ 5370 5359 struct wiphy { 5371 5360 struct mutex mtx; ··· 5520 5495 u8 mbssid_max_interfaces; 5521 5496 u8 ema_max_profile_periodicity; 5522 5497 u16 max_num_akm_suites; 5498 + 5499 + u16 hw_timestamp_max_peers; 5523 5500 5524 5501 char priv[] __aligned(NETDEV_ALIGN); 5525 5502 }; ··· 6841 6814 * @ie: IEs 6842 6815 * @ielen: length of IEs 6843 6816 * @band: enum nl80211_band of the channel 6844 - * @ftype: frame type 6845 6817 * 6846 6818 * Returns the channel number, or -1 if none could be determined. 6847 6819 */ 6848 6820 int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen, 6849 - enum nl80211_band band, 6850 - enum cfg80211_bss_frame_type ftype); 6821 + enum nl80211_band band); 6851 6822 6852 6823 /** 6853 6824 * cfg80211_inform_bss_data - inform cfg80211 of a new BSS ··· 8126 8101 * responsible for any cleanup. The caller must also ensure that 8127 8102 * skb->protocol is set appropriately. 8128 8103 * @unencrypted: Whether the frame was received unencrypted 8104 + * @link_id: the link the frame was received on, -1 if not applicable or unknown 8129 8105 * 8130 8106 * This function is used to inform userspace about a received control port 8131 8107 * frame. It should only be used if userspace indicated it wants to receive ··· 8137 8111 * 8138 8112 * Return: %true if the frame was passed to userspace 8139 8113 */ 8140 - bool cfg80211_rx_control_port(struct net_device *dev, 8141 - struct sk_buff *skb, bool unencrypted); 8114 + bool cfg80211_rx_control_port(struct net_device *dev, struct sk_buff *skb, 8115 + bool unencrypted, int link_id); 8142 8116 8143 8117 /** 8144 8118 * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
+213 -2
include/net/ieee80211_radiotap.h
··· 1 1 /* 2 2 * Copyright (c) 2017 Intel Deutschland GmbH 3 - * Copyright (c) 2018-2019, 2021 Intel Corporation 3 + * Copyright (c) 2018-2019, 2021-2022 Intel Corporation 4 4 * 5 5 * Permission to use, copy, modify, and/or distribute this software for any 6 6 * purpose with or without fee is hereby granted, provided that the above ··· 82 82 IEEE80211_RADIOTAP_HE_MU = 24, 83 83 IEEE80211_RADIOTAP_ZERO_LEN_PSDU = 26, 84 84 IEEE80211_RADIOTAP_LSIG = 27, 85 + IEEE80211_RADIOTAP_TLV = 28, 85 86 86 87 /* valid in every it_present bitmap, even vendor namespaces */ 87 88 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, 88 89 IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30, 89 - IEEE80211_RADIOTAP_EXT = 31 90 + IEEE80211_RADIOTAP_EXT = 31, 91 + IEEE80211_RADIOTAP_EHT_USIG = 33, 92 + IEEE80211_RADIOTAP_EHT = 34, 90 93 }; 91 94 92 95 /* for IEEE80211_RADIOTAP_FLAGS */ ··· 361 358 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_SOUNDING = 0, 362 359 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_NOT_CAPTURED = 1, 363 360 IEEE80211_RADIOTAP_ZERO_LEN_PSDU_VENDOR = 0xff, 361 + }; 362 + 363 + struct ieee80211_radiotap_tlv { 364 + __le16 type; 365 + __le16 len; 366 + u8 data[]; 367 + } __packed; 368 + 369 + /** 370 + * struct ieee80211_radiotap_vendor_content - radiotap vendor data content 371 + * @oui: radiotap vendor namespace OUI 372 + * @oui_subtype: radiotap vendor sub namespace 373 + * @vendor_type: radiotap vendor type 374 + * @reserved: should always be set to zero (to avoid leaking memory) 375 + * @data: the actual vendor namespace data 376 + */ 377 + struct ieee80211_radiotap_vendor_content { 378 + u8 oui[3]; 379 + u8 oui_subtype; 380 + __le16 vendor_type; 381 + __le16 reserved; 382 + u8 data[]; 383 + } __packed; 384 + 385 + /** 386 + * struct ieee80211_radiotap_vendor_tlv - vendor radiotap data information 387 + * @type: should always be set to IEEE80211_RADIOTAP_VENDOR_NAMESPACE 388 + * @len: length of data 389 + * @content: vendor content see @ieee80211_radiotap_vendor_content 390 + */ 391 + struct ieee80211_radiotap_vendor_tlv { 392 + __le16 type; /* IEEE80211_RADIOTAP_VENDOR_NAMESPACE */ 393 + __le16 len; 394 + struct ieee80211_radiotap_vendor_content content; 395 + }; 396 + 397 + /* ieee80211_radiotap_eht_usig - content of U-SIG tlv (type 33) 398 + * see www.radiotap.org/fields/U-SIG.html for details 399 + */ 400 + struct ieee80211_radiotap_eht_usig { 401 + __le32 common; 402 + __le32 value; 403 + __le32 mask; 404 + } __packed; 405 + 406 + /* ieee80211_radiotap_eht - content of EHT tlv (type 34) 407 + * see www.radiotap.org/fields/EHT.html for details 408 + */ 409 + struct ieee80211_radiotap_eht { 410 + __le32 known; 411 + __le32 data[9]; 412 + __le32 user_info[]; 413 + } __packed; 414 + 415 + /* Known field for EHT TLV 416 + * The ending defines for what the field applies as following 417 + * O - OFDMA (including TB), M - MU-MIMO, S - EHT sounding. 418 + */ 419 + enum ieee80211_radiotap_eht_known { 420 + IEEE80211_RADIOTAP_EHT_KNOWN_SPATIAL_REUSE = 0x00000002, 421 + IEEE80211_RADIOTAP_EHT_KNOWN_GI = 0x00000004, 422 + IEEE80211_RADIOTAP_EHT_KNOWN_EHT_LTF = 0x00000010, 423 + IEEE80211_RADIOTAP_EHT_KNOWN_LDPC_EXTRA_SYM_OM = 0x00000020, 424 + IEEE80211_RADIOTAP_EHT_KNOWN_PRE_PADD_FACOR_OM = 0x00000040, 425 + IEEE80211_RADIOTAP_EHT_KNOWN_PE_DISAMBIGUITY_OM = 0x00000080, 426 + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_O = 0x00000100, 427 + IEEE80211_RADIOTAP_EHT_KNOWN_DISREGARD_S = 0x00000200, 428 + IEEE80211_RADIOTAP_EHT_KNOWN_CRC1 = 0x00002000, 429 + IEEE80211_RADIOTAP_EHT_KNOWN_TAIL1 = 0x00004000, 430 + IEEE80211_RADIOTAP_EHT_KNOWN_CRC2_O = 0x00008000, 431 + IEEE80211_RADIOTAP_EHT_KNOWN_TAIL2_O = 0x00010000, 432 + IEEE80211_RADIOTAP_EHT_KNOWN_NSS_S = 0x00020000, 433 + IEEE80211_RADIOTAP_EHT_KNOWN_BEAMFORMED_S = 0x00040000, 434 + IEEE80211_RADIOTAP_EHT_KNOWN_NR_NON_OFDMA_USERS_M = 0x00080000, 435 + IEEE80211_RADIOTAP_EHT_KNOWN_ENCODING_BLOCK_CRC_M = 0x00100000, 436 + IEEE80211_RADIOTAP_EHT_KNOWN_ENCODING_BLOCK_TAIL_M = 0x00200000, 437 + IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_SIZE_OM = 0x00400000, 438 + IEEE80211_RADIOTAP_EHT_KNOWN_RU_MRU_INDEX_OM = 0x00800000, 439 + IEEE80211_RADIOTAP_EHT_KNOWN_RU_ALLOC_TB_FMT = 0x01000000, 440 + IEEE80211_RADIOTAP_EHT_KNOWN_PRIMARY_80 = 0x02000000, 441 + }; 442 + 443 + enum ieee80211_radiotap_eht_data { 444 + /* Data 0 */ 445 + IEEE80211_RADIOTAP_EHT_DATA0_SPATIAL_REUSE = 0x00000078, 446 + IEEE80211_RADIOTAP_EHT_DATA0_GI = 0x00000180, 447 + IEEE80211_RADIOTAP_EHT_DATA0_LTF = 0x00000600, 448 + IEEE80211_RADIOTAP_EHT_DATA0_EHT_LTF = 0x00003800, 449 + IEEE80211_RADIOTAP_EHT_DATA0_LDPC_EXTRA_SYM_OM = 0x00004000, 450 + IEEE80211_RADIOTAP_EHT_DATA0_PRE_PADD_FACOR_OM = 0x00018000, 451 + IEEE80211_RADIOTAP_EHT_DATA0_PE_DISAMBIGUITY_OM = 0x00020000, 452 + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_S = 0x000c0000, 453 + IEEE80211_RADIOTAP_EHT_DATA0_DISREGARD_O = 0x003c0000, 454 + IEEE80211_RADIOTAP_EHT_DATA0_CRC1_O = 0x03c00000, 455 + IEEE80211_RADIOTAP_EHT_DATA0_TAIL1_O = 0xfc000000, 456 + /* Data 1 */ 457 + IEEE80211_RADIOTAP_EHT_DATA1_RU_SIZE = 0x0000001f, 458 + IEEE80211_RADIOTAP_EHT_DATA1_RU_INDEX = 0x00001fe0, 459 + IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1 = 0x003fe000, 460 + IEEE80211_RADIOTAP_EHT_DATA1_RU_ALLOC_CC_1_1_1_KNOWN = 0x00400000, 461 + IEEE80211_RADIOTAP_EHT_DATA1_PRIMARY_80 = 0xc0000000, 462 + /* Data 2 */ 463 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_1 = 0x000001ff, 464 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_1_KNOWN = 0x00000200, 465 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2 = 0x0007fc00, 466 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_1_1_2_KNOWN = 0x00080000, 467 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_2 = 0x1ff00000, 468 + IEEE80211_RADIOTAP_EHT_DATA2_RU_ALLOC_CC_2_1_2_KNOWN = 0x20000000, 469 + /* Data 3 */ 470 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1 = 0x000001ff, 471 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_1_KNOWN = 0x00000200, 472 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_2_2_1 = 0x0007fc00, 473 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_2_2_1_KNOWN = 0x00080000, 474 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2 = 0x1ff00000, 475 + IEEE80211_RADIOTAP_EHT_DATA3_RU_ALLOC_CC_1_2_2_KNOWN = 0x20000000, 476 + /* Data 4 */ 477 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_2 = 0x000001ff, 478 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_2_KNOWN = 0x00000200, 479 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3 = 0x0007fc00, 480 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_1_2_3_KNOWN = 0x00080000, 481 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_3 = 0x1ff00000, 482 + IEEE80211_RADIOTAP_EHT_DATA4_RU_ALLOC_CC_2_2_3_KNOWN = 0x20000000, 483 + /* Data 5 */ 484 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4 = 0x000001ff, 485 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_4_KNOWN = 0x00000200, 486 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_2_2_4 = 0x0007fc00, 487 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_2_2_4_KNOWN = 0x00080000, 488 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5 = 0x1ff00000, 489 + IEEE80211_RADIOTAP_EHT_DATA5_RU_ALLOC_CC_1_2_5_KNOWN = 0x20000000, 490 + /* Data 6 */ 491 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_5 = 0x000001ff, 492 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_5_KNOWN = 0x00000200, 493 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6 = 0x0007fc00, 494 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_1_2_6_KNOWN = 0x00080000, 495 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_6 = 0x1ff00000, 496 + IEEE80211_RADIOTAP_EHT_DATA6_RU_ALLOC_CC_2_2_6_KNOWN = 0x20000000, 497 + /* Data 7 */ 498 + IEEE80211_RADIOTAP_EHT_DATA7_CRC2_O = 0x0000000f, 499 + IEEE80211_RADIOTAP_EHT_DATA7_TAIL_2_O = 0x000003f0, 500 + IEEE80211_RADIOTAP_EHT_DATA7_NSS_S = 0x0000f000, 501 + IEEE80211_RADIOTAP_EHT_DATA7_BEAMFORMED_S = 0x00010000, 502 + IEEE80211_RADIOTAP_EHT_DATA7_NUM_OF_NON_OFDMA_USERS = 0x000e0000, 503 + IEEE80211_RADIOTAP_EHT_DATA7_USER_ENCODING_BLOCK_CRC = 0x00f00000, 504 + IEEE80211_RADIOTAP_EHT_DATA7_USER_ENCODING_BLOCK_TAIL = 0x3f000000, 505 + /* Data 8 */ 506 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_PS_160 = 0x00000001, 507 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B0 = 0x00000002, 508 + IEEE80211_RADIOTAP_EHT_DATA8_RU_ALLOC_TB_FMT_B7_B1 = 0x000001fc, 509 + }; 510 + 511 + enum ieee80211_radiotap_eht_user_info { 512 + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID_KNOWN = 0x00000001, 513 + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS_KNOWN = 0x00000002, 514 + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING_KNOWN = 0x00000004, 515 + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_KNOWN_O = 0x00000010, 516 + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_KNOWN_O = 0x00000020, 517 + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_KNOWN_M = 0x00000040, 518 + IEEE80211_RADIOTAP_EHT_USER_INFO_DATA_FOR_USER = 0x00000080, 519 + IEEE80211_RADIOTAP_EHT_USER_INFO_STA_ID = 0x0007ff00, 520 + IEEE80211_RADIOTAP_EHT_USER_INFO_CODING = 0x00080000, 521 + IEEE80211_RADIOTAP_EHT_USER_INFO_MCS = 0x00f00000, 522 + IEEE80211_RADIOTAP_EHT_USER_INFO_NSS_O = 0x0f000000, 523 + IEEE80211_RADIOTAP_EHT_USER_INFO_BEAMFORMING_O = 0x20000000, 524 + IEEE80211_RADIOTAP_EHT_USER_INFO_SPATIAL_CONFIG_M = 0x3f000000, 525 + IEEE80211_RADIOTAP_EHT_USER_INFO_RESEVED_c0000000 = 0xc0000000, 526 + }; 527 + 528 + enum ieee80211_radiotap_eht_usig_common { 529 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER_KNOWN = 0x00000001, 530 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW_KNOWN = 0x00000002, 531 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL_KNOWN = 0x00000004, 532 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR_KNOWN = 0x00000008, 533 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP_KNOWN = 0x00000010, 534 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BAD_USIG_CRC = 0x00000020, 535 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_PHY_VER = 0x00007000, 536 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BW = 0x00038000, 537 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_UL_DL = 0x00040000, 538 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_BSS_COLOR = 0x01f80000, 539 + IEEE80211_RADIOTAP_EHT_USIG_COMMON_TXOP = 0xfe000000, 540 + }; 541 + 542 + enum ieee80211_radiotap_eht_usig_mu { 543 + /* MU-USIG-1 */ 544 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B20_B24_DISREGARD = 0x0000001f, 545 + IEEE80211_RADIOTAP_EHT_USIG1_MU_B25_VALIDATE = 0x00000020, 546 + /* MU-USIG-2 */ 547 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B0_B1_PPDU_TYPE = 0x000000c0, 548 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B2_VALIDATE = 0x00000100, 549 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B3_B7_PUNCTURED_INFO = 0x00003e00, 550 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B8_VALIDATE = 0x00004000, 551 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B9_B10_SIG_MCS = 0x00018000, 552 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B11_B15_EHT_SIG_SYMBOLS = 0x003e0000, 553 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B16_B19_CRC = 0x03c00000, 554 + IEEE80211_RADIOTAP_EHT_USIG2_MU_B20_B25_TAIL = 0xfc000000, 555 + }; 556 + 557 + enum ieee80211_radiotap_eht_usig_tb { 558 + /* TB-USIG-1 */ 559 + IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD = 0x0000001f, 560 + 561 + /* TB-USIG-2 */ 562 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE = 0x000000c0, 563 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B2_VALIDATE = 0x00000100, 564 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B3_B6_SPATIAL_REUSE_1 = 0x00001e00, 565 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B7_B10_SPATIAL_REUSE_2 = 0x0001e000, 566 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B11_B15_DISREGARD = 0x003e0000, 567 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B16_B19_CRC = 0x03c00000, 568 + IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL = 0xfc000000, 364 569 }; 365 570 366 571 /**
+55 -37
include/net/mac80211.h
··· 534 534 * This structure keeps information about a BSS (and an association 535 535 * to that BSS) that can change during the lifetime of the BSS. 536 536 * 537 + * @vif: reference to owning VIF 537 538 * @addr: (link) address used locally 538 539 * @link_id: link ID, or 0 for non-MLO 539 540 * @htc_trig_based_pkt_ext: default PE in 4us units, if BSS supports HE ··· 657 656 * write-protected by sdata_lock and local->mtx so holding either is fine 658 657 * for read access. 659 658 * @color_change_color: the bss color that will be used after the change. 659 + * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability. 660 + * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability. 661 + * @he_ldpc: in AP mode, indicates interface has HE LDPC capability. 660 662 * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU 661 663 * beamformer 662 664 * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU ··· 677 673 * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission 678 674 * (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU 679 675 * bandwidth 676 + * @eht_su_beamformer: in AP-mode, does this BSS enable operation as an EHT SU 677 + * beamformer 678 + * @eht_su_beamformee: in AP-mode, does this BSS enable operation as an EHT SU 679 + * beamformee 680 + * @eht_mu_beamformer: in AP-mode, does this BSS enable operation as an EHT MU 681 + * beamformer 680 682 */ 681 683 struct ieee80211_bss_conf { 684 + struct ieee80211_vif *vif; 685 + 682 686 const u8 *bssid; 683 687 unsigned int link_id; 684 688 u8 addr[ETH_ALEN] __aligned(2); ··· 762 750 bool color_change_active; 763 751 u8 color_change_color; 764 752 753 + bool ht_ldpc; 754 + bool vht_ldpc; 755 + bool he_ldpc; 765 756 bool vht_su_beamformer; 766 757 bool vht_su_beamformee; 767 758 bool vht_mu_beamformer; ··· 773 758 bool he_su_beamformee; 774 759 bool he_mu_beamformer; 775 760 bool he_full_ul_mumimo; 761 + bool eht_su_beamformer; 762 + bool eht_su_beamformee; 763 + bool eht_mu_beamformer; 776 764 }; 777 765 778 766 /** ··· 1390 1372 * subframes share the same sequence number. Reported subframes can be 1391 1373 * either regular MSDU or singly A-MSDUs. Subframes must not be 1392 1374 * interleaved with other frames. 1393 - * @RX_FLAG_RADIOTAP_VENDOR_DATA: This frame contains vendor-specific 1394 - * radiotap data in the skb->data (before the frame) as described by 1395 - * the &struct ieee80211_vendor_radiotap. 1375 + * @RX_FLAG_RADIOTAP_TLV_AT_END: This frame contains radiotap TLVs in the 1376 + * skb->data (before the 802.11 header). 1377 + * If used, the SKB's mac_header pointer must be set to point 1378 + * to the 802.11 header after the TLVs, and any padding added after TLV 1379 + * data to align to 4 must be cleared by the driver putting the TLVs 1380 + * in the skb. 1396 1381 * @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before. 1397 1382 * This is used for AMSDU subframes which can have the same PN as 1398 1383 * the first subframe. ··· 1447 1426 RX_FLAG_ONLY_MONITOR = BIT(17), 1448 1427 RX_FLAG_SKIP_MONITOR = BIT(18), 1449 1428 RX_FLAG_AMSDU_MORE = BIT(19), 1450 - RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(20), 1429 + RX_FLAG_RADIOTAP_TLV_AT_END = BIT(20), 1451 1430 RX_FLAG_MIC_STRIPPED = BIT(21), 1452 1431 RX_FLAG_ALLOW_SAME_PN = BIT(22), 1453 1432 RX_FLAG_ICV_STRIPPED = BIT(23), ··· 1586 1565 return MHZ_TO_KHZ(rx_status->freq) + 1587 1566 (rx_status->freq_offset ? 500 : 0); 1588 1567 } 1589 - 1590 - /** 1591 - * struct ieee80211_vendor_radiotap - vendor radiotap data information 1592 - * @present: presence bitmap for this vendor namespace 1593 - * (this could be extended in the future if any vendor needs more 1594 - * bits, the radiotap spec does allow for that) 1595 - * @align: radiotap vendor namespace alignment. This defines the needed 1596 - * alignment for the @data field below, not for the vendor namespace 1597 - * description itself (which has a fixed 2-byte alignment) 1598 - * Must be a power of two, and be set to at least 1! 1599 - * @oui: radiotap vendor namespace OUI 1600 - * @subns: radiotap vendor sub namespace 1601 - * @len: radiotap vendor sub namespace skip length, if alignment is done 1602 - * then that's added to this, i.e. this is only the length of the 1603 - * @data field. 1604 - * @pad: number of bytes of padding after the @data, this exists so that 1605 - * the skb data alignment can be preserved even if the data has odd 1606 - * length 1607 - * @data: the actual vendor namespace data 1608 - * 1609 - * This struct, including the vendor data, goes into the skb->data before 1610 - * the 802.11 header. It's split up in mac80211 using the align/oui/subns 1611 - * data. 1612 - */ 1613 - struct ieee80211_vendor_radiotap { 1614 - u32 present; 1615 - u8 align; 1616 - u8 oui[3]; 1617 - u8 subns; 1618 - u8 pad; 1619 - u16 len; 1620 - u8 data[]; 1621 - } __packed; 1622 1568 1623 1569 /** 1624 1570 * enum ieee80211_conf_flags - configuration flags ··· 3829 3841 * the station. See @sta_pre_rcu_remove if needed. 3830 3842 * This callback can sleep. 3831 3843 * 3844 + * @link_add_debugfs: Drivers can use this callback to add debugfs files 3845 + * when a link is added to a mac80211 vif. This callback should be within 3846 + * a CONFIG_MAC80211_DEBUGFS conditional. This callback can sleep. 3847 + * For non-MLO the callback will be called once for the default bss_conf 3848 + * with the vif's directory rather than a separate subdirectory. 3849 + * 3832 3850 * @sta_add_debugfs: Drivers can use this callback to add debugfs files 3833 3851 * when a station is added to mac80211's station list. This callback 3834 3852 * should be within a CONFIG_MAC80211_DEBUGFS conditional. This ··· 4224 4230 * Note that a sta can also be inserted or removed with valid links, 4225 4231 * i.e. passed to @sta_add/@sta_state with sta->valid_links not zero. 4226 4232 * In fact, cannot change from having valid_links and not having them. 4233 + * @set_hw_timestamp: Enable/disable HW timestamping of TM/FTM frames. This is 4234 + * not restored at HW reset by mac80211 so drivers need to take care of 4235 + * that. 4227 4236 */ 4228 4237 struct ieee80211_ops { 4229 4238 void (*tx)(struct ieee80211_hw *hw, ··· 4316 4319 int (*sta_remove)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 4317 4320 struct ieee80211_sta *sta); 4318 4321 #ifdef CONFIG_MAC80211_DEBUGFS 4322 + void (*link_add_debugfs)(struct ieee80211_hw *hw, 4323 + struct ieee80211_vif *vif, 4324 + struct ieee80211_bss_conf *link_conf, 4325 + struct dentry *dir); 4319 4326 void (*sta_add_debugfs)(struct ieee80211_hw *hw, 4320 4327 struct ieee80211_vif *vif, 4321 4328 struct ieee80211_sta *sta, ··· 4590 4589 struct ieee80211_vif *vif, 4591 4590 struct ieee80211_sta *sta, 4592 4591 u16 old_links, u16 new_links); 4592 + int (*set_hw_timestamp)(struct ieee80211_hw *hw, 4593 + struct ieee80211_vif *vif, 4594 + struct cfg80211_set_hw_timestamp *hwts); 4593 4595 }; 4594 4596 4595 4597 /** ··· 5987 5983 void ieee80211_queue_delayed_work(struct ieee80211_hw *hw, 5988 5984 struct delayed_work *dwork, 5989 5985 unsigned long delay); 5986 + 5987 + /** 5988 + * ieee80211_refresh_tx_agg_session_timer - Refresh a tx agg session timer. 5989 + * @sta: the station for which to start a BA session 5990 + * @tid: the TID to BA on. 5991 + * 5992 + * This function allows low level driver to refresh tx agg session timer 5993 + * to maintain BA session, the session level will still be managed by the 5994 + * mac80211. 5995 + * 5996 + * Note: must be called in an RCU critical section. 5997 + */ 5998 + void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta, 5999 + u16 tid); 5990 6000 5991 6001 /** 5992 6002 * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
+35 -2
include/uapi/linux/nl80211.h
··· 1299 1299 * @NL80211_CMD_MODIFY_LINK_STA: Modify a link of an MLD station 1300 1300 * @NL80211_CMD_REMOVE_LINK_STA: Remove a link of an MLD station 1301 1301 * 1302 + * @NL80211_CMD_SET_HW_TIMESTAMP: Enable/disable HW timestamping of Timing 1303 + * measurement and Fine timing measurement frames. If %NL80211_ATTR_MAC 1304 + * is included, enable/disable HW timestamping only for frames to/from the 1305 + * specified MAC address. Otherwise enable/disable HW timestamping for 1306 + * all TM/FTM frames (including ones that were enabled with specific MAC 1307 + * address). If %NL80211_ATTR_HW_TIMESTAMP_ENABLED is not included, disable 1308 + * HW timestamping. 1309 + * The number of peers that HW timestamping can be enabled for concurrently 1310 + * is indicated by %NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS. 1311 + * 1302 1312 * @NL80211_CMD_MAX: highest used command number 1303 1313 * @__NL80211_CMD_AFTER_LAST: internal use 1304 1314 */ ··· 1559 1549 NL80211_CMD_ADD_LINK_STA, 1560 1550 NL80211_CMD_MODIFY_LINK_STA, 1561 1551 NL80211_CMD_REMOVE_LINK_STA, 1552 + 1553 + NL80211_CMD_SET_HW_TIMESTAMP, 1562 1554 1563 1555 /* add new commands above here */ 1564 1556 ··· 2787 2775 * indicates that the sub-channel is punctured. Higher 16 bits are 2788 2776 * reserved. 2789 2777 * 2778 + * @NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS: Maximum number of peers that HW 2779 + * timestamping can be enabled for concurrently (u16), a wiphy attribute. 2780 + * A value of 0xffff indicates setting for all peers (i.e. not specifying 2781 + * an address with %NL80211_CMD_SET_HW_TIMESTAMP) is supported. 2782 + * @NL80211_ATTR_HW_TIMESTAMP_ENABLED: Indicates whether HW timestamping should 2783 + * be enabled or not (flag attribute). 2784 + * 2790 2785 * @NUM_NL80211_ATTR: total number of nl80211_attrs available 2791 2786 * @NL80211_ATTR_MAX: highest attribute number currently defined 2792 2787 * @__NL80211_ATTR_AFTER_LAST: internal use ··· 3324 3305 NL80211_ATTR_TD_BITMAP, 3325 3306 3326 3307 NL80211_ATTR_PUNCT_BITMAP, 3308 + 3309 + NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS, 3310 + NL80211_ATTR_HW_TIMESTAMP_ENABLED, 3327 3311 3328 3312 /* add attributes here, update the policy in nl80211.c */ 3329 3313 ··· 6348 6326 * @NL80211_EXT_FEATURE_SECURE_NAN: Device supports NAN Pairing which enables 6349 6327 * authentication, data encryption and message integrity. 6350 6328 * 6329 + * @NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA: Device supports randomized TA 6330 + * in authentication and deauthentication frames sent to unassociated peer 6331 + * using @NL80211_CMD_FRAME. 6332 + * 6351 6333 * @NUM_NL80211_EXT_FEATURES: number of extended features. 6352 6334 * @MAX_NL80211_EXT_FEATURES: highest extended feature index. 6353 6335 */ ··· 6422 6396 NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE, 6423 6397 NL80211_EXT_FEATURE_PUNCT, 6424 6398 NL80211_EXT_FEATURE_SECURE_NAN, 6399 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA, 6425 6400 6426 6401 /* add new features before the definition below */ 6427 6402 NUM_NL80211_EXT_FEATURES, ··· 6537 6510 * @NL80211_SCAN_FLAG_FREQ_KHZ: report scan results with 6538 6511 * %NL80211_ATTR_SCAN_FREQ_KHZ. This also means 6539 6512 * %NL80211_ATTR_SCAN_FREQUENCIES will not be included. 6540 - * @NL80211_SCAN_FLAG_COLOCATED_6GHZ: scan for colocated APs reported by 6541 - * 2.4/5 GHz APs 6513 + * @NL80211_SCAN_FLAG_COLOCATED_6GHZ: scan for collocated APs reported by 6514 + * 2.4/5 GHz APs. When the flag is set, the scan logic will use the 6515 + * information from the RNR element found in beacons/probe responses 6516 + * received on the 2.4/5 GHz channels to actively scan only the 6GHz 6517 + * channels on which APs are expected to be found. Note that when not set, 6518 + * the scan logic would scan all 6GHz channels, but since transmission of 6519 + * probe requests on non PSC channels is limited, it is highly likely that 6520 + * these channels would passively be scanned. 6542 6521 */ 6543 6522 enum nl80211_scan_flags { 6544 6523 NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0,
+17
net/mac80211/agg-tx.c
··· 554 554 ieee80211_send_addba_with_timeout(sta, tid_tx); 555 555 } 556 556 557 + void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta, 558 + u16 tid) 559 + { 560 + struct sta_info *sta = container_of(pubsta, struct sta_info, sta); 561 + struct tid_ampdu_tx *tid_tx; 562 + 563 + if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS)) 564 + return; 565 + 566 + tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); 567 + if (!tid_tx) 568 + return; 569 + 570 + tid_tx->last_tx = jiffies; 571 + } 572 + EXPORT_SYMBOL(ieee80211_refresh_tx_agg_session_timer); 573 + 557 574 /* 558 575 * After accepting the AddBA Response we activated a timer, 559 576 * resetting it after each frame that we send.
+45 -1
net/mac80211/cfg.c
··· 1252 1252 prev_beacon_int = link_conf->beacon_int; 1253 1253 link_conf->beacon_int = params->beacon_interval; 1254 1254 1255 + if (params->ht_cap) 1256 + link_conf->ht_ldpc = 1257 + params->ht_cap->cap_info & 1258 + cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING); 1259 + 1255 1260 if (params->vht_cap) { 1261 + link_conf->vht_ldpc = 1262 + params->vht_cap->vht_cap_info & 1263 + cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC); 1256 1264 link_conf->vht_su_beamformer = 1257 1265 params->vht_cap->vht_cap_info & 1258 1266 cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); ··· 1290 1282 } 1291 1283 1292 1284 if (params->he_cap) { 1285 + link_conf->he_ldpc = 1286 + params->he_cap->phy_cap_info[1] & 1287 + IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; 1293 1288 link_conf->he_su_beamformer = 1294 1289 params->he_cap->phy_cap_info[3] & 1295 1290 IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; ··· 1310 1299 if (params->eht_cap) { 1311 1300 link_conf->eht_puncturing = params->punct_bitmap; 1312 1301 changed |= BSS_CHANGED_EHT_PUNCTURING; 1302 + 1303 + link_conf->eht_su_beamformer = 1304 + params->eht_cap->fixed.phy_cap_info[0] & 1305 + IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMER; 1306 + link_conf->eht_su_beamformee = 1307 + params->eht_cap->fixed.phy_cap_info[0] & 1308 + IEEE80211_EHT_PHY_CAP0_SU_BEAMFORMEE; 1309 + link_conf->eht_mu_beamformer = 1310 + params->eht_cap->fixed.phy_cap_info[7] & 1311 + (IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_80MHZ | 1312 + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_160MHZ | 1313 + IEEE80211_EHT_PHY_CAP7_MU_BEAMFORMER_320MHZ); 1314 + } else { 1315 + link_conf->eht_su_beamformer = false; 1316 + link_conf->eht_su_beamformee = false; 1317 + link_conf->eht_mu_beamformer = false; 1313 1318 } 1314 1319 1315 1320 if (sdata->vif.type == NL80211_IFTYPE_AP && ··· 1815 1788 (void *)params->he_6ghz_capa, 1816 1789 link_sta); 1817 1790 1818 - if (params->eht_capa) 1791 + if (params->he_capa && params->eht_capa) 1819 1792 ieee80211_eht_cap_ie_to_sta_eht_cap(sdata, sband, 1820 1793 (u8 *)params->he_capa, 1821 1794 params->he_capa_len, ··· 4931 4904 return ret; 4932 4905 } 4933 4906 4907 + static int ieee80211_set_hw_timestamp(struct wiphy *wiphy, 4908 + struct net_device *dev, 4909 + struct cfg80211_set_hw_timestamp *hwts) 4910 + { 4911 + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 4912 + struct ieee80211_local *local = sdata->local; 4913 + 4914 + if (!local->ops->set_hw_timestamp) 4915 + return -EOPNOTSUPP; 4916 + 4917 + if (!check_sdata_in_driver(sdata)) 4918 + return -EIO; 4919 + 4920 + return local->ops->set_hw_timestamp(&local->hw, &sdata->vif, hwts); 4921 + } 4922 + 4934 4923 const struct cfg80211_ops mac80211_config_ops = { 4935 4924 .add_virtual_intf = ieee80211_add_iface, 4936 4925 .del_virtual_intf = ieee80211_del_iface, ··· 5057 5014 .add_link_station = ieee80211_add_link_station, 5058 5015 .mod_link_station = ieee80211_mod_link_station, 5059 5016 .del_link_station = ieee80211_del_link_station, 5017 + .set_hw_timestamp = ieee80211_set_hw_timestamp, 5060 5018 };
+168 -55
net/mac80211/debugfs_netdev.c
··· 23 23 #include "driver-ops.h" 24 24 25 25 static ssize_t ieee80211_if_read( 26 - struct ieee80211_sub_if_data *sdata, 26 + void *data, 27 27 char __user *userbuf, 28 28 size_t count, loff_t *ppos, 29 - ssize_t (*format)(const struct ieee80211_sub_if_data *, char *, int)) 29 + ssize_t (*format)(const void *, char *, int)) 30 30 { 31 31 char buf[200]; 32 32 ssize_t ret = -EINVAL; 33 33 34 34 read_lock(&dev_base_lock); 35 - ret = (*format)(sdata, buf, sizeof(buf)); 35 + ret = (*format)(data, buf, sizeof(buf)); 36 36 read_unlock(&dev_base_lock); 37 37 38 38 if (ret >= 0) ··· 42 42 } 43 43 44 44 static ssize_t ieee80211_if_write( 45 - struct ieee80211_sub_if_data *sdata, 45 + void *data, 46 46 const char __user *userbuf, 47 47 size_t count, loff_t *ppos, 48 - ssize_t (*write)(struct ieee80211_sub_if_data *, const char *, int)) 48 + ssize_t (*write)(void *, const char *, int)) 49 49 { 50 50 char buf[64]; 51 51 ssize_t ret; ··· 58 58 buf[count] = '\0'; 59 59 60 60 rtnl_lock(); 61 - ret = (*write)(sdata, buf, count); 61 + ret = (*write)(data, buf, count); 62 62 rtnl_unlock(); 63 63 64 64 return ret; 65 65 } 66 66 67 - #define IEEE80211_IF_FMT(name, field, format_string) \ 67 + #define IEEE80211_IF_FMT(name, type, field, format_string) \ 68 68 static ssize_t ieee80211_if_fmt_##name( \ 69 - const struct ieee80211_sub_if_data *sdata, char *buf, \ 69 + const type *data, char *buf, \ 70 70 int buflen) \ 71 71 { \ 72 - return scnprintf(buf, buflen, format_string, sdata->field); \ 72 + return scnprintf(buf, buflen, format_string, data->field); \ 73 73 } 74 - #define IEEE80211_IF_FMT_DEC(name, field) \ 75 - IEEE80211_IF_FMT(name, field, "%d\n") 76 - #define IEEE80211_IF_FMT_HEX(name, field) \ 77 - IEEE80211_IF_FMT(name, field, "%#x\n") 78 - #define IEEE80211_IF_FMT_LHEX(name, field) \ 79 - IEEE80211_IF_FMT(name, field, "%#lx\n") 74 + #define IEEE80211_IF_FMT_DEC(name, type, field) \ 75 + IEEE80211_IF_FMT(name, type, field, "%d\n") 76 + #define IEEE80211_IF_FMT_HEX(name, type, field) \ 77 + IEEE80211_IF_FMT(name, type, field, "%#x\n") 78 + #define IEEE80211_IF_FMT_LHEX(name, type, field) \ 79 + IEEE80211_IF_FMT(name, type, field, "%#lx\n") 80 80 81 - #define IEEE80211_IF_FMT_HEXARRAY(name, field) \ 81 + #define IEEE80211_IF_FMT_HEXARRAY(name, type, field) \ 82 82 static ssize_t ieee80211_if_fmt_##name( \ 83 - const struct ieee80211_sub_if_data *sdata, \ 83 + const type *data, \ 84 84 char *buf, int buflen) \ 85 85 { \ 86 86 char *p = buf; \ 87 87 int i; \ 88 - for (i = 0; i < sizeof(sdata->field); i++) { \ 88 + for (i = 0; i < sizeof(data->field); i++) { \ 89 89 p += scnprintf(p, buflen + buf - p, "%.2x ", \ 90 - sdata->field[i]); \ 90 + data->field[i]); \ 91 91 } \ 92 92 p += scnprintf(p, buflen + buf - p, "\n"); \ 93 93 return p - buf; \ 94 94 } 95 95 96 - #define IEEE80211_IF_FMT_ATOMIC(name, field) \ 96 + #define IEEE80211_IF_FMT_ATOMIC(name, type, field) \ 97 97 static ssize_t ieee80211_if_fmt_##name( \ 98 - const struct ieee80211_sub_if_data *sdata, \ 98 + const type *data, \ 99 99 char *buf, int buflen) \ 100 100 { \ 101 - return scnprintf(buf, buflen, "%d\n", atomic_read(&sdata->field));\ 101 + return scnprintf(buf, buflen, "%d\n", atomic_read(&data->field));\ 102 102 } 103 103 104 - #define IEEE80211_IF_FMT_MAC(name, field) \ 104 + #define IEEE80211_IF_FMT_MAC(name, type, field) \ 105 105 static ssize_t ieee80211_if_fmt_##name( \ 106 - const struct ieee80211_sub_if_data *sdata, char *buf, \ 106 + const type *data, char *buf, \ 107 107 int buflen) \ 108 108 { \ 109 - return scnprintf(buf, buflen, "%pM\n", sdata->field); \ 109 + return scnprintf(buf, buflen, "%pM\n", data->field); \ 110 110 } 111 111 112 - #define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, field) \ 112 + #define IEEE80211_IF_FMT_JIFFIES_TO_MS(name, type, field) \ 113 113 static ssize_t ieee80211_if_fmt_##name( \ 114 - const struct ieee80211_sub_if_data *sdata, \ 114 + const type *data, \ 115 115 char *buf, int buflen) \ 116 116 { \ 117 117 return scnprintf(buf, buflen, "%d\n", \ 118 - jiffies_to_msecs(sdata->field)); \ 118 + jiffies_to_msecs(data->field)); \ 119 119 } 120 120 121 121 #define _IEEE80211_IF_FILE_OPS(name, _read, _write) \ ··· 126 126 .llseek = generic_file_llseek, \ 127 127 } 128 128 129 - #define _IEEE80211_IF_FILE_R_FN(name) \ 129 + #define _IEEE80211_IF_FILE_R_FN(name, type) \ 130 130 static ssize_t ieee80211_if_read_##name(struct file *file, \ 131 131 char __user *userbuf, \ 132 132 size_t count, loff_t *ppos) \ 133 133 { \ 134 + ssize_t (*fn)(const void *, char *, int) = (void *) \ 135 + ((ssize_t (*)(const type, char *, int)) \ 136 + ieee80211_if_fmt_##name); \ 134 137 return ieee80211_if_read(file->private_data, \ 135 - userbuf, count, ppos, \ 136 - ieee80211_if_fmt_##name); \ 138 + userbuf, count, ppos, fn); \ 137 139 } 138 140 139 - #define _IEEE80211_IF_FILE_W_FN(name) \ 141 + #define _IEEE80211_IF_FILE_W_FN(name, type) \ 140 142 static ssize_t ieee80211_if_write_##name(struct file *file, \ 141 143 const char __user *userbuf, \ 142 144 size_t count, loff_t *ppos) \ 143 145 { \ 146 + ssize_t (*fn)(void *, const char *, int) = (void *) \ 147 + ((ssize_t (*)(type, const char *, int)) \ 148 + ieee80211_if_parse_##name); \ 144 149 return ieee80211_if_write(file->private_data, userbuf, count, \ 145 - ppos, ieee80211_if_parse_##name); \ 150 + ppos, fn); \ 146 151 } 147 152 148 153 #define IEEE80211_IF_FILE_R(name) \ 149 - _IEEE80211_IF_FILE_R_FN(name) \ 154 + _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *) \ 150 155 _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, NULL) 151 156 152 157 #define IEEE80211_IF_FILE_W(name) \ 153 - _IEEE80211_IF_FILE_W_FN(name) \ 158 + _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *) \ 154 159 _IEEE80211_IF_FILE_OPS(name, NULL, ieee80211_if_write_##name) 155 160 156 161 #define IEEE80211_IF_FILE_RW(name) \ 157 - _IEEE80211_IF_FILE_R_FN(name) \ 158 - _IEEE80211_IF_FILE_W_FN(name) \ 162 + _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_sub_if_data *) \ 163 + _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_sub_if_data *) \ 159 164 _IEEE80211_IF_FILE_OPS(name, ieee80211_if_read_##name, \ 160 165 ieee80211_if_write_##name) 161 166 162 167 #define IEEE80211_IF_FILE(name, field, format) \ 163 - IEEE80211_IF_FMT_##format(name, field) \ 168 + IEEE80211_IF_FMT_##format(name, struct ieee80211_sub_if_data, field) \ 164 169 IEEE80211_IF_FILE_R(name) 170 + 171 + /* Same but with a link_ prefix in the ops variable name and different type */ 172 + #define IEEE80211_IF_LINK_FILE_R(name) \ 173 + _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *) \ 174 + _IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name, NULL) 175 + 176 + #define IEEE80211_IF_LINK_FILE_W(name) \ 177 + _IEEE80211_IF_FILE_W_FN(name) \ 178 + _IEEE80211_IF_FILE_OPS(link_##name, NULL, ieee80211_if_write_##name) 179 + 180 + #define IEEE80211_IF_LINK_FILE_RW(name) \ 181 + _IEEE80211_IF_FILE_R_FN(name, struct ieee80211_link_data *) \ 182 + _IEEE80211_IF_FILE_W_FN(name, struct ieee80211_link_data *) \ 183 + _IEEE80211_IF_FILE_OPS(link_##name, ieee80211_if_read_##name, \ 184 + ieee80211_if_write_##name) 185 + 186 + #define IEEE80211_IF_LINK_FILE(name, field, format) \ 187 + IEEE80211_IF_FMT_##format(name, struct ieee80211_link_data, field) \ 188 + IEEE80211_IF_LINK_FILE_R(name) 165 189 166 190 /* common attributes */ 167 191 IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[NL80211_BAND_2GHZ], ··· 231 207 232 208 IEEE80211_IF_FILE(flags, flags, HEX); 233 209 IEEE80211_IF_FILE(state, state, LHEX); 234 - IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC); 235 - IEEE80211_IF_FILE(ap_power_level, deflink.ap_power_level, DEC); 236 - IEEE80211_IF_FILE(user_power_level, deflink.user_power_level, DEC); 210 + IEEE80211_IF_LINK_FILE(txpower, conf->txpower, DEC); 211 + IEEE80211_IF_LINK_FILE(ap_power_level, ap_power_level, DEC); 212 + IEEE80211_IF_LINK_FILE(user_power_level, user_power_level, DEC); 237 213 238 214 static ssize_t 239 215 ieee80211_if_fmt_hw_queues(const struct ieee80211_sub_if_data *sdata, ··· 260 236 IEEE80211_IF_FILE(aid, vif.cfg.aid, DEC); 261 237 IEEE80211_IF_FILE(beacon_timeout, u.mgd.beacon_timeout, JIFFIES_TO_MS); 262 238 263 - static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, 239 + static int ieee80211_set_smps(struct ieee80211_link_data *link, 264 240 enum ieee80211_smps_mode smps_mode) 265 241 { 242 + struct ieee80211_sub_if_data *sdata = link->sdata; 266 243 struct ieee80211_local *local = sdata->local; 267 244 int err; 268 245 ··· 281 256 return -EOPNOTSUPP; 282 257 283 258 sdata_lock(sdata); 284 - err = __ieee80211_request_smps_mgd(sdata, &sdata->deflink, smps_mode); 259 + err = __ieee80211_request_smps_mgd(link->sdata, link, smps_mode); 285 260 sdata_unlock(sdata); 286 261 287 262 return err; ··· 294 269 [IEEE80211_SMPS_DYNAMIC] = "dynamic", 295 270 }; 296 271 297 - static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata, 272 + static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_link_data *link, 298 273 char *buf, int buflen) 299 274 { 300 - if (sdata->vif.type == NL80211_IFTYPE_STATION) 275 + if (link->sdata->vif.type == NL80211_IFTYPE_STATION) 301 276 return snprintf(buf, buflen, "request: %s\nused: %s\n", 302 - smps_modes[sdata->deflink.u.mgd.req_smps], 303 - smps_modes[sdata->deflink.smps_mode]); 277 + smps_modes[link->u.mgd.req_smps], 278 + smps_modes[link->smps_mode]); 304 279 return -EINVAL; 305 280 } 306 281 307 - static ssize_t ieee80211_if_parse_smps(struct ieee80211_sub_if_data *sdata, 282 + static ssize_t ieee80211_if_parse_smps(struct ieee80211_link_data *link, 308 283 const char *buf, int buflen) 309 284 { 310 285 enum ieee80211_smps_mode mode; 311 286 312 287 for (mode = 0; mode < IEEE80211_SMPS_NUM_MODES; mode++) { 313 288 if (strncmp(buf, smps_modes[mode], buflen) == 0) { 314 - int err = ieee80211_set_smps(sdata, mode); 289 + int err = ieee80211_set_smps(link, mode); 315 290 if (!err) 316 291 return buflen; 317 292 return err; ··· 320 295 321 296 return -EINVAL; 322 297 } 323 - IEEE80211_IF_FILE_RW(smps); 298 + IEEE80211_IF_LINK_FILE_RW(smps); 324 299 325 300 static ssize_t ieee80211_if_parse_tkip_mic_test( 326 301 struct ieee80211_sub_if_data *sdata, const char *buf, int buflen) ··· 620 595 } 621 596 IEEE80211_IF_FILE_RW(active_links); 622 597 598 + IEEE80211_IF_LINK_FILE(addr, conf->addr, MAC); 599 + 623 600 #ifdef CONFIG_MAC80211_MESH 624 601 IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC); 625 602 ··· 712 685 DEBUGFS_ADD(bssid); 713 686 DEBUGFS_ADD(aid); 714 687 DEBUGFS_ADD(beacon_timeout); 715 - DEBUGFS_ADD_MODE(smps, 0600); 716 688 DEBUGFS_ADD_MODE(tkip_mic_test, 0200); 717 689 DEBUGFS_ADD_MODE(beacon_loss, 0200); 718 690 DEBUGFS_ADD_MODE(uapsd_queues, 0600); ··· 724 698 static void add_ap_files(struct ieee80211_sub_if_data *sdata) 725 699 { 726 700 DEBUGFS_ADD(num_mcast_sta); 727 - DEBUGFS_ADD_MODE(smps, 0600); 728 701 DEBUGFS_ADD(num_sta_ps); 729 702 DEBUGFS_ADD(dtim_count); 730 703 DEBUGFS_ADD(num_buffered_multicast); ··· 814 789 815 790 DEBUGFS_ADD(flags); 816 791 DEBUGFS_ADD(state); 817 - DEBUGFS_ADD(txpower); 818 - DEBUGFS_ADD(user_power_level); 819 - DEBUGFS_ADD(ap_power_level); 820 792 821 793 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) 822 794 add_common_files(sdata); ··· 843 821 } 844 822 } 845 823 824 + #undef DEBUGFS_ADD_MODE 825 + #undef DEBUGFS_ADD 826 + 827 + #define DEBUGFS_ADD_MODE(dentry, name, mode) \ 828 + debugfs_create_file(#name, mode, dentry, \ 829 + link, &link_##name##_ops) 830 + 831 + #define DEBUGFS_ADD(dentry, name) DEBUGFS_ADD_MODE(dentry, name, 0400) 832 + 833 + static void add_link_files(struct ieee80211_link_data *link, 834 + struct dentry *dentry) 835 + { 836 + DEBUGFS_ADD(dentry, txpower); 837 + DEBUGFS_ADD(dentry, user_power_level); 838 + DEBUGFS_ADD(dentry, ap_power_level); 839 + 840 + switch (link->sdata->vif.type) { 841 + case NL80211_IFTYPE_STATION: 842 + DEBUGFS_ADD_MODE(dentry, smps, 0600); 843 + break; 844 + default: 845 + break; 846 + } 847 + } 848 + 846 849 void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) 847 850 { 848 851 char buf[10+IFNAMSIZ]; ··· 878 831 sdata->debugfs.subdir_stations = debugfs_create_dir("stations", 879 832 sdata->vif.debugfs_dir); 880 833 add_files(sdata); 834 + 835 + if (!(sdata->local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO)) 836 + add_link_files(&sdata->deflink, sdata->vif.debugfs_dir); 881 837 } 882 838 883 839 void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) ··· 905 855 906 856 sprintf(buf, "netdev:%s", sdata->name); 907 857 debugfs_rename(dir->d_parent, dir, dir->d_parent, buf); 858 + } 859 + 860 + void ieee80211_link_debugfs_add(struct ieee80211_link_data *link) 861 + { 862 + char link_dir_name[10]; 863 + 864 + if (WARN_ON(!link->sdata->vif.debugfs_dir)) 865 + return; 866 + 867 + /* For now, this should not be called for non-MLO capable drivers */ 868 + if (WARN_ON(!(link->sdata->local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO))) 869 + return; 870 + 871 + snprintf(link_dir_name, sizeof(link_dir_name), 872 + "link-%d", link->link_id); 873 + 874 + link->debugfs_dir = 875 + debugfs_create_dir(link_dir_name, 876 + link->sdata->vif.debugfs_dir); 877 + 878 + DEBUGFS_ADD(link->debugfs_dir, addr); 879 + add_link_files(link, link->debugfs_dir); 880 + } 881 + 882 + void ieee80211_link_debugfs_remove(struct ieee80211_link_data *link) 883 + { 884 + if (!link->sdata->vif.debugfs_dir || !link->debugfs_dir) { 885 + link->debugfs_dir = NULL; 886 + return; 887 + } 888 + 889 + if (link->debugfs_dir == link->sdata->vif.debugfs_dir) { 890 + WARN_ON(link != &link->sdata->deflink); 891 + link->debugfs_dir = NULL; 892 + return; 893 + } 894 + 895 + debugfs_remove_recursive(link->debugfs_dir); 896 + link->debugfs_dir = NULL; 897 + } 898 + 899 + void ieee80211_link_debugfs_drv_add(struct ieee80211_link_data *link) 900 + { 901 + if (WARN_ON(!link->debugfs_dir)) 902 + return; 903 + 904 + drv_link_add_debugfs(link->sdata->local, link->sdata, 905 + link->conf, link->debugfs_dir); 906 + } 907 + 908 + void ieee80211_link_debugfs_drv_remove(struct ieee80211_link_data *link) 909 + { 910 + if (!link || !link->debugfs_dir) 911 + return; 912 + 913 + if (WARN_ON(link->debugfs_dir == link->sdata->vif.debugfs_dir)) 914 + return; 915 + 916 + /* Recreate the directory excluding the driver data */ 917 + debugfs_remove_recursive(link->debugfs_dir); 918 + link->debugfs_dir = NULL; 919 + 920 + ieee80211_link_debugfs_add(link); 908 921 }
+16
net/mac80211/debugfs_netdev.h
··· 10 10 void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata); 11 11 void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata); 12 12 void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata); 13 + 14 + void ieee80211_link_debugfs_add(struct ieee80211_link_data *link); 15 + void ieee80211_link_debugfs_remove(struct ieee80211_link_data *link); 16 + 17 + void ieee80211_link_debugfs_drv_add(struct ieee80211_link_data *link); 18 + void ieee80211_link_debugfs_drv_remove(struct ieee80211_link_data *link); 13 19 #else 14 20 static inline void ieee80211_debugfs_add_netdev( 15 21 struct ieee80211_sub_if_data *sdata) ··· 25 19 {} 26 20 static inline void ieee80211_debugfs_rename_netdev( 27 21 struct ieee80211_sub_if_data *sdata) 22 + {} 23 + 24 + static inline void ieee80211_link_debugfs_add(struct ieee80211_link_data *link) 25 + {} 26 + static inline void ieee80211_link_debugfs_remove(struct ieee80211_link_data *link) 27 + {} 28 + 29 + static inline void ieee80211_link_debugfs_drv_add(struct ieee80211_link_data *link) 30 + {} 31 + static inline void ieee80211_link_debugfs_drv_remove(struct ieee80211_link_data *link) 28 32 {} 29 33 #endif 30 34
+24 -1
net/mac80211/driver-ops.c
··· 8 8 #include "trace.h" 9 9 #include "driver-ops.h" 10 10 #include "debugfs_sta.h" 11 + #include "debugfs_netdev.h" 11 12 12 13 int drv_start(struct ieee80211_local *local) 13 14 { ··· 478 477 u16 old_links, u16 new_links, 479 478 struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) 480 479 { 480 + struct ieee80211_link_data *link; 481 + unsigned long links_to_add; 482 + unsigned long links_to_rem; 483 + unsigned int link_id; 481 484 int ret = -EOPNOTSUPP; 482 485 483 486 might_sleep(); ··· 492 487 if (old_links == new_links) 493 488 return 0; 494 489 490 + links_to_add = ~old_links & new_links; 491 + links_to_rem = old_links & ~new_links; 492 + 493 + for_each_set_bit(link_id, &links_to_rem, IEEE80211_MLD_MAX_NUM_LINKS) { 494 + link = rcu_access_pointer(sdata->link[link_id]); 495 + 496 + ieee80211_link_debugfs_drv_remove(link); 497 + } 498 + 495 499 trace_drv_change_vif_links(local, sdata, old_links, new_links); 496 500 if (local->ops->change_vif_links) 497 501 ret = local->ops->change_vif_links(&local->hw, &sdata->vif, 498 502 old_links, new_links, old); 499 503 trace_drv_return_int(local, ret); 500 504 501 - return ret; 505 + if (ret) 506 + return ret; 507 + 508 + for_each_set_bit(link_id, &links_to_add, IEEE80211_MLD_MAX_NUM_LINKS) { 509 + link = rcu_access_pointer(sdata->link[link_id]); 510 + 511 + ieee80211_link_debugfs_drv_add(link); 512 + } 513 + 514 + return 0; 502 515 } 503 516 504 517 int drv_change_sta_links(struct ieee80211_local *local,
+16
net/mac80211/driver-ops.h
··· 465 465 } 466 466 467 467 #ifdef CONFIG_MAC80211_DEBUGFS 468 + static inline void drv_link_add_debugfs(struct ieee80211_local *local, 469 + struct ieee80211_sub_if_data *sdata, 470 + struct ieee80211_bss_conf *link_conf, 471 + struct dentry *dir) 472 + { 473 + might_sleep(); 474 + 475 + sdata = get_bss_sdata(sdata); 476 + if (!check_sdata_in_driver(sdata)) 477 + return; 478 + 479 + if (local->ops->link_add_debugfs) 480 + local->ops->link_add_debugfs(&local->hw, &sdata->vif, 481 + link_conf, dir); 482 + } 483 + 468 484 static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 469 485 struct ieee80211_sub_if_data *sdata, 470 486 struct ieee80211_sta *sta,
+4
net/mac80211/ieee80211_i.h
··· 999 999 struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; 1000 1000 1001 1001 struct ieee80211_bss_conf *conf; 1002 + 1003 + #ifdef CONFIG_MAC80211_DEBUGFS 1004 + struct dentry *debugfs_dir; 1005 + #endif 1002 1006 }; 1003 1007 1004 1008 struct ieee80211_sub_if_data {
+5
net/mac80211/link.c
··· 10 10 #include "ieee80211_i.h" 11 11 #include "driver-ops.h" 12 12 #include "key.h" 13 + #include "debugfs_netdev.h" 13 14 14 15 void ieee80211_link_setup(struct ieee80211_link_data *link) 15 16 { ··· 35 34 link->link_id = link_id; 36 35 link->conf = link_conf; 37 36 link_conf->link_id = link_id; 37 + link_conf->vif = &sdata->vif; 38 38 39 39 INIT_WORK(&link->csa_finalize_work, 40 40 ieee80211_csa_finalize_work); ··· 62 60 default: 63 61 WARN_ON(1); 64 62 } 63 + 64 + ieee80211_link_debugfs_add(link); 65 65 } 66 66 } 67 67 ··· 97 93 if (WARN_ON(!link)) 98 94 continue; 99 95 ieee80211_remove_link_keys(link, &keys); 96 + ieee80211_link_debugfs_remove(link); 100 97 ieee80211_link_stop(link); 101 98 } 102 99
+3 -3
net/mac80211/mlme.c
··· 2744 2744 return changed; 2745 2745 } 2746 2746 2747 - static u32 ieee80211_link_set_associated(struct ieee80211_link_data *link, 2747 + static u64 ieee80211_link_set_associated(struct ieee80211_link_data *link, 2748 2748 struct cfg80211_bss *cbss) 2749 2749 { 2750 2750 struct ieee80211_sub_if_data *sdata = link->sdata; ··· 3227 3227 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3228 3228 bool already = false; 3229 3229 3230 - if (WARN_ON(sdata->vif.valid_links)) 3230 + if (WARN_ON_ONCE(sdata->vif.valid_links)) 3231 3231 return; 3232 3232 3233 3233 if (!ieee80211_sdata_running(sdata)) ··· 5893 5893 goto free; 5894 5894 } 5895 5895 5896 - if (sta && elems->opmode_notif) 5896 + if (elems->opmode_notif) 5897 5897 ieee80211_vht_handle_opmode(sdata, link_sta, 5898 5898 *elems->opmode_notif, 5899 5899 rx_status->band);
+36 -57
net/mac80211/rx.c
··· 43 43 unsigned int present_fcs_len, 44 44 unsigned int rtap_space) 45 45 { 46 + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 46 47 struct ieee80211_hdr *hdr; 47 48 unsigned int hdrlen; 48 49 __le16 fc; ··· 51 50 if (present_fcs_len) 52 51 __pskb_trim(skb, skb->len - present_fcs_len); 53 52 pskb_pull(skb, rtap_space); 53 + 54 + /* After pulling radiotap header, clear all flags that indicate 55 + * info in skb->data. 56 + */ 57 + status->flag &= ~(RX_FLAG_RADIOTAP_TLV_AT_END | 58 + RX_FLAG_RADIOTAP_LSIG | 59 + RX_FLAG_RADIOTAP_HE_MU | 60 + RX_FLAG_RADIOTAP_HE); 54 61 55 62 hdr = (void *)skb->data; 56 63 fc = hdr->frame_control; ··· 126 117 /* allocate extra bitmaps */ 127 118 if (status->chains) 128 119 len += 4 * hweight8(status->chains); 129 - /* vendor presence bitmap */ 130 - if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) 131 - len += 4; 132 120 133 121 if (ieee80211_have_rx_timestamp(status)) { 134 122 len = ALIGN(len, 8); ··· 187 181 len += 2 * hweight8(status->chains); 188 182 } 189 183 190 - if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { 191 - struct ieee80211_vendor_radiotap *rtap; 192 - int vendor_data_offset = 0; 184 + if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) { 185 + int tlv_offset = 0; 193 186 194 187 /* 195 188 * The position to look at depends on the existence (or non- 196 189 * existence) of other elements, so take that into account... 197 190 */ 198 191 if (status->flag & RX_FLAG_RADIOTAP_HE) 199 - vendor_data_offset += 192 + tlv_offset += 200 193 sizeof(struct ieee80211_radiotap_he); 201 194 if (status->flag & RX_FLAG_RADIOTAP_HE_MU) 202 - vendor_data_offset += 195 + tlv_offset += 203 196 sizeof(struct ieee80211_radiotap_he_mu); 204 197 if (status->flag & RX_FLAG_RADIOTAP_LSIG) 205 - vendor_data_offset += 198 + tlv_offset += 206 199 sizeof(struct ieee80211_radiotap_lsig); 207 200 208 - rtap = (void *)&skb->data[vendor_data_offset]; 201 + /* ensure 4 byte alignment for TLV */ 202 + len = ALIGN(len, 4); 209 203 210 - /* alignment for fixed 6-byte vendor data header */ 211 - len = ALIGN(len, 2); 212 - /* vendor data header */ 213 - len += 6; 214 - if (WARN_ON(rtap->align == 0)) 215 - rtap->align = 1; 216 - len = ALIGN(len, rtap->align); 217 - len += rtap->len + rtap->pad; 204 + /* TLVs until the mac header */ 205 + len += skb_mac_header(skb) - &skb->data[tlv_offset]; 218 206 } 219 207 220 208 return len; ··· 304 304 u32 it_present_val; 305 305 u16 rx_flags = 0; 306 306 u16 channel_flags = 0; 307 + u32 tlvs_len = 0; 307 308 int mpdulen, chain; 308 309 unsigned long chains = status->chains; 309 - struct ieee80211_vendor_radiotap rtap = {}; 310 310 struct ieee80211_radiotap_he he = {}; 311 311 struct ieee80211_radiotap_he_mu he_mu = {}; 312 312 struct ieee80211_radiotap_lsig lsig = {}; ··· 327 327 skb_pull(skb, sizeof(lsig)); 328 328 } 329 329 330 - if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { 331 - rtap = *(struct ieee80211_vendor_radiotap *)skb->data; 332 - /* rtap.len and rtap.pad are undone immediately */ 333 - skb_pull(skb, sizeof(rtap) + rtap.len + rtap.pad); 330 + if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) { 331 + /* data is pointer at tlv all other info was pulled off */ 332 + tlvs_len = skb_mac_header(skb) - skb->data; 334 333 } 335 334 336 335 mpdulen = skb->len; 337 336 if (!(has_fcs && ieee80211_hw_check(&local->hw, RX_INCLUDES_FCS))) 338 337 mpdulen += FCS_LEN; 339 338 340 - rthdr = skb_push(skb, rtap_len); 341 - memset(rthdr, 0, rtap_len - rtap.len - rtap.pad); 339 + rthdr = skb_push(skb, rtap_len - tlvs_len); 340 + memset(rthdr, 0, rtap_len - tlvs_len); 342 341 it_present = &rthdr->it_present; 343 342 344 343 /* radiotap header, set always present flags */ ··· 359 360 BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL); 360 361 } 361 362 362 - if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { 363 - it_present_val |= BIT(IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | 364 - BIT(IEEE80211_RADIOTAP_EXT); 365 - put_unaligned_le32(it_present_val, it_present); 366 - it_present++; 367 - it_present_val = rtap.present; 368 - } 363 + if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) 364 + it_present_val |= BIT(IEEE80211_RADIOTAP_TLV); 369 365 370 366 put_unaligned_le32(it_present_val, it_present); 371 367 ··· 691 697 *pos++ = status->chain_signal[chain]; 692 698 *pos++ = chain; 693 699 } 694 - 695 - if (status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA) { 696 - /* ensure 2 byte alignment for the vendor field as required */ 697 - if ((pos - (u8 *)rthdr) & 1) 698 - *pos++ = 0; 699 - *pos++ = rtap.oui[0]; 700 - *pos++ = rtap.oui[1]; 701 - *pos++ = rtap.oui[2]; 702 - *pos++ = rtap.subns; 703 - put_unaligned_le16(rtap.len, pos); 704 - pos += 2; 705 - /* align the actual payload as requested */ 706 - while ((pos - (u8 *)rthdr) & (rtap.align - 1)) 707 - *pos++ = 0; 708 - /* data (and possible padding) already follows */ 709 - } 710 700 } 711 701 712 702 static struct sk_buff * ··· 766 788 bool only_monitor = false; 767 789 unsigned int min_head_len; 768 790 791 + if (WARN_ON_ONCE(status->flag & RX_FLAG_RADIOTAP_TLV_AT_END && 792 + !skb_mac_header_was_set(origskb))) { 793 + /* with this skb no way to know where frame payload starts */ 794 + dev_kfree_skb(origskb); 795 + return NULL; 796 + } 797 + 769 798 if (status->flag & RX_FLAG_RADIOTAP_HE) 770 799 rtap_space += sizeof(struct ieee80211_radiotap_he); 771 800 ··· 782 797 if (status->flag & RX_FLAG_RADIOTAP_LSIG) 783 798 rtap_space += sizeof(struct ieee80211_radiotap_lsig); 784 799 785 - if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) { 786 - struct ieee80211_vendor_radiotap *rtap = 787 - (void *)(origskb->data + rtap_space); 788 - 789 - rtap_space += sizeof(*rtap) + rtap->len + rtap->pad; 790 - } 800 + if (status->flag & RX_FLAG_RADIOTAP_TLV_AT_END) 801 + rtap_space += skb_mac_header(origskb) - &origskb->data[rtap_space]; 791 802 792 803 min_head_len = rtap_space; 793 804 ··· 2563 2582 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); 2564 2583 bool noencrypt = !(status->flag & RX_FLAG_DECRYPTED); 2565 2584 2566 - cfg80211_rx_control_port(dev, skb, noencrypt); 2585 + cfg80211_rx_control_port(dev, skb, noencrypt, rx->link_id); 2567 2586 dev_kfree_skb(skb); 2568 2587 } else { 2569 2588 struct ethhdr *ehdr = (void *)skb_mac_header(skb); ··· 3897 3916 if (!local->cooked_mntrs) 3898 3917 goto out_free_skb; 3899 3918 3900 - /* vendor data is long removed here */ 3901 - status->flag &= ~RX_FLAG_RADIOTAP_VENDOR_DATA; 3902 3919 /* room for the radiotap header based on driver features */ 3903 3920 needed_headroom = ieee80211_rx_radiotap_hdrlen(local, status, skb); 3904 3921
+4 -4
net/mac80211/scan.c
··· 9 9 * Copyright 2007, Michael Wu <flamingice@sourmilk.net> 10 10 * Copyright 2013-2015 Intel Mobile Communications GmbH 11 11 * Copyright 2016-2017 Intel Deutschland GmbH 12 - * Copyright (C) 2018-2021 Intel Corporation 12 + * Copyright (C) 2018-2022 Intel Corporation 13 13 */ 14 14 15 15 #include <linux/if_arp.h> ··· 1246 1246 return ret; 1247 1247 } 1248 1248 1249 - /* 1250 - * Only call this function when a scan can't be queued -- under RTNL. 1251 - */ 1252 1249 void ieee80211_scan_cancel(struct ieee80211_local *local) 1253 1250 { 1251 + /* ensure a new scan cannot be queued */ 1252 + lockdep_assert_wiphy(local->hw.wiphy); 1253 + 1254 1254 /* 1255 1255 * We are canceling software scan, or deferred scan that was not 1256 1256 * yet really started (see __ieee80211_start_scan ).
+10
net/mac80211/tx.c
··· 5115 5115 tx.key = rcu_dereference(link->default_beacon_key); 5116 5116 if (!tx.key) 5117 5117 return 0; 5118 + 5119 + if (unlikely(tx.key->flags & KEY_FLAG_TAINTED)) { 5120 + tx.key = NULL; 5121 + return -EINVAL; 5122 + } 5123 + 5124 + if (!(tx.key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT_TX) && 5125 + tx.key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) 5126 + IEEE80211_SKB_CB(skb)->control.hw_key = &tx.key->conf; 5127 + 5118 5128 tx.local = local; 5119 5129 tx.sdata = sdata; 5120 5130 __skb_queue_head_init(&tx.skbs);
+36 -19
net/wireless/mlme.c
··· 673 673 return ether_addr_equal(addr, wdev_address(wdev)); 674 674 } 675 675 676 + static bool cfg80211_allowed_random_address(struct wireless_dev *wdev, 677 + const struct ieee80211_mgmt *mgmt) 678 + { 679 + if (ieee80211_is_auth(mgmt->frame_control) || 680 + ieee80211_is_deauth(mgmt->frame_control)) { 681 + /* Allow random TA to be used with authentication and 682 + * deauthentication frames if the driver has indicated support. 683 + */ 684 + if (wiphy_ext_feature_isset( 685 + wdev->wiphy, 686 + NL80211_EXT_FEATURE_AUTH_AND_DEAUTH_RANDOM_TA)) 687 + return true; 688 + } else if (ieee80211_is_action(mgmt->frame_control) && 689 + mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) { 690 + /* Allow random TA to be used with Public Action frames if the 691 + * driver has indicated support. 692 + */ 693 + if (!wdev->connected && 694 + wiphy_ext_feature_isset( 695 + wdev->wiphy, 696 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA)) 697 + return true; 698 + 699 + if (wdev->connected && 700 + wiphy_ext_feature_isset( 701 + wdev->wiphy, 702 + NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED)) 703 + return true; 704 + } 705 + 706 + return false; 707 + } 708 + 676 709 int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, 677 710 struct wireless_dev *wdev, 678 711 struct cfg80211_mgmt_tx_params *params, u64 *cookie) ··· 807 774 return err; 808 775 } 809 776 810 - if (!cfg80211_allowed_address(wdev, mgmt->sa)) { 811 - /* Allow random TA to be used with Public Action frames if the 812 - * driver has indicated support for this. Otherwise, only allow 813 - * the local address to be used. 814 - */ 815 - if (!ieee80211_is_action(mgmt->frame_control) || 816 - mgmt->u.action.category != WLAN_CATEGORY_PUBLIC) 817 - return -EINVAL; 818 - if (!wdev->connected && 819 - !wiphy_ext_feature_isset( 820 - &rdev->wiphy, 821 - NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA)) 822 - return -EINVAL; 823 - if (wdev->connected && 824 - !wiphy_ext_feature_isset( 825 - &rdev->wiphy, 826 - NL80211_EXT_FEATURE_MGMT_TX_RANDOM_TA_CONNECTED)) 827 - return -EINVAL; 828 - } 777 + if (!cfg80211_allowed_address(wdev, mgmt->sa) && 778 + !cfg80211_allowed_random_address(wdev, mgmt)) 779 + return -EINVAL; 829 780 830 781 /* Transmit the management frame as requested by user space */ 831 782 return rdev_mgmt_tx(rdev, wdev, params, cookie);
+61 -17
net/wireless/nl80211.c
··· 806 806 [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, 807 807 [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, 808 808 [NL80211_ATTR_PUNCT_BITMAP] = NLA_POLICY_RANGE(NLA_U8, 0, 0xffff), 809 + 810 + [NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS] = { .type = NLA_U16 }, 811 + [NL80211_ATTR_HW_TIMESTAMP_ENABLED] = { .type = NLA_FLAG }, 809 812 }; 810 813 811 814 /* policy for the key attributes */ ··· 2966 2963 2967 2964 if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_MLO) 2968 2965 nla_put_flag(msg, NL80211_ATTR_MLO_SUPPORT); 2966 + 2967 + if (rdev->wiphy.hw_timestamp_max_peers && 2968 + nla_put_u16(msg, NL80211_ATTR_MAX_HW_TIMESTAMP_PEERS, 2969 + rdev->wiphy.hw_timestamp_max_peers)) 2970 + goto nla_put_failure; 2969 2971 2970 2972 /* done */ 2971 2973 state->split_start = 0; ··· 9027 9019 struct nlattr *attr; 9028 9020 struct wiphy *wiphy; 9029 9021 int err, tmp, n_ssids = 0, n_channels, i; 9030 - size_t ie_len; 9022 + size_t ie_len, size; 9031 9023 9032 9024 wiphy = &rdev->wiphy; 9033 9025 ··· 9072 9064 if (ie_len > wiphy->max_scan_ie_len) 9073 9065 return -EINVAL; 9074 9066 9075 - request = kzalloc(sizeof(*request) 9076 - + sizeof(*request->ssids) * n_ssids 9077 - + sizeof(*request->channels) * n_channels 9078 - + ie_len, GFP_KERNEL); 9067 + size = struct_size(request, channels, n_channels); 9068 + size = size_add(size, array_size(sizeof(*request->ssids), n_ssids)); 9069 + size = size_add(size, ie_len); 9070 + request = kzalloc(size, GFP_KERNEL); 9079 9071 if (!request) 9080 9072 return -ENOMEM; 9081 9073 ··· 9408 9400 struct nlattr *attr; 9409 9401 int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i, n_plans = 0; 9410 9402 enum nl80211_band band; 9411 - size_t ie_len; 9403 + size_t ie_len, size; 9412 9404 struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; 9413 9405 s32 default_match_rssi = NL80211_SCAN_RSSI_THOLD_OFF; 9414 9406 ··· 9517 9509 attrs[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST])) 9518 9510 return ERR_PTR(-EINVAL); 9519 9511 9520 - request = kzalloc(sizeof(*request) 9521 - + sizeof(*request->ssids) * n_ssids 9522 - + sizeof(*request->match_sets) * n_match_sets 9523 - + sizeof(*request->scan_plans) * n_plans 9524 - + sizeof(*request->channels) * n_channels 9525 - + ie_len, GFP_KERNEL); 9512 + size = struct_size(request, channels, n_channels); 9513 + size = size_add(size, array_size(sizeof(*request->ssids), n_ssids)); 9514 + size = size_add(size, array_size(sizeof(*request->match_sets), 9515 + n_match_sets)); 9516 + size = size_add(size, array_size(sizeof(*request->scan_plans), 9517 + n_plans)); 9518 + size = size_add(size, ie_len); 9519 + request = kzalloc(size, GFP_KERNEL); 9526 9520 if (!request) 9527 9521 return ERR_PTR(-ENOMEM); 9528 9522 ··· 16172 16162 return ret; 16173 16163 } 16174 16164 16165 + static int nl80211_set_hw_timestamp(struct sk_buff *skb, 16166 + struct genl_info *info) 16167 + { 16168 + struct cfg80211_registered_device *rdev = info->user_ptr[0]; 16169 + struct net_device *dev = info->user_ptr[1]; 16170 + struct cfg80211_set_hw_timestamp hwts = {}; 16171 + 16172 + if (!rdev->wiphy.hw_timestamp_max_peers) 16173 + return -EOPNOTSUPP; 16174 + 16175 + if (!info->attrs[NL80211_ATTR_MAC] && 16176 + rdev->wiphy.hw_timestamp_max_peers != CFG80211_HW_TIMESTAMP_ALL_PEERS) 16177 + return -EOPNOTSUPP; 16178 + 16179 + if (info->attrs[NL80211_ATTR_MAC]) 16180 + hwts.macaddr = nla_data(info->attrs[NL80211_ATTR_MAC]); 16181 + 16182 + hwts.enable = 16183 + nla_get_flag(info->attrs[NL80211_ATTR_HW_TIMESTAMP_ENABLED]); 16184 + 16185 + return rdev_set_hw_timestamp(rdev, dev, &hwts); 16186 + } 16187 + 16175 16188 #define NL80211_FLAG_NEED_WIPHY 0x01 16176 16189 #define NL80211_FLAG_NEED_NETDEV 0x02 16177 16190 #define NL80211_FLAG_NEED_RTNL 0x04 ··· 17368 17335 .flags = GENL_UNS_ADMIN_PERM, 17369 17336 .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | 17370 17337 NL80211_FLAG_MLO_VALID_LINK_ID), 17338 + }, 17339 + { 17340 + .cmd = NL80211_CMD_SET_HW_TIMESTAMP, 17341 + .doit = nl80211_set_hw_timestamp, 17342 + .flags = GENL_UNS_ADMIN_PERM, 17343 + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP), 17371 17344 }, 17372 17345 }; 17373 17346 ··· 18756 18717 18757 18718 static int __nl80211_rx_control_port(struct net_device *dev, 18758 18719 struct sk_buff *skb, 18759 - bool unencrypted, gfp_t gfp) 18720 + bool unencrypted, 18721 + int link_id, 18722 + gfp_t gfp) 18760 18723 { 18761 18724 struct wireless_dev *wdev = dev->ieee80211_ptr; 18762 18725 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); ··· 18790 18749 NL80211_ATTR_PAD) || 18791 18750 nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || 18792 18751 nla_put_u16(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE, proto) || 18752 + (link_id >= 0 && 18753 + nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)) || 18793 18754 (unencrypted && nla_put_flag(msg, 18794 18755 NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT))) 18795 18756 goto nla_put_failure; ··· 18810 18767 return -ENOBUFS; 18811 18768 } 18812 18769 18813 - bool cfg80211_rx_control_port(struct net_device *dev, 18814 - struct sk_buff *skb, bool unencrypted) 18770 + bool cfg80211_rx_control_port(struct net_device *dev, struct sk_buff *skb, 18771 + bool unencrypted, int link_id) 18815 18772 { 18816 18773 int ret; 18817 18774 18818 - trace_cfg80211_rx_control_port(dev, skb, unencrypted); 18819 - ret = __nl80211_rx_control_port(dev, skb, unencrypted, GFP_ATOMIC); 18775 + trace_cfg80211_rx_control_port(dev, skb, unencrypted, link_id); 18776 + ret = __nl80211_rx_control_port(dev, skb, unencrypted, link_id, 18777 + GFP_ATOMIC); 18820 18778 trace_cfg80211_return_bool(ret == 0); 18821 18779 return ret == 0; 18822 18780 }
+17
net/wireless/rdev-ops.h
··· 1494 1494 return ret; 1495 1495 } 1496 1496 1497 + static inline int 1498 + rdev_set_hw_timestamp(struct cfg80211_registered_device *rdev, 1499 + struct net_device *dev, 1500 + struct cfg80211_set_hw_timestamp *hwts) 1501 + { 1502 + struct wiphy *wiphy = &rdev->wiphy; 1503 + int ret; 1504 + 1505 + if (!rdev->ops->set_hw_timestamp) 1506 + return -EOPNOTSUPP; 1507 + 1508 + trace_rdev_set_hw_timestamp(wiphy, dev, hwts); 1509 + ret = rdev->ops->set_hw_timestamp(wiphy, dev, hwts); 1510 + trace_rdev_return_int(wiphy, ret); 1511 + 1512 + return ret; 1513 + } 1497 1514 #endif /* __CFG80211_RDEV_OPS */
+12 -26
net/wireless/scan.c
··· 1810 1810 } 1811 1811 1812 1812 int cfg80211_get_ies_channel_number(const u8 *ie, size_t ielen, 1813 - enum nl80211_band band, 1814 - enum cfg80211_bss_frame_type ftype) 1813 + enum nl80211_band band) 1815 1814 { 1816 1815 const struct element *tmp; 1817 1816 ··· 1829 1830 if (!he_6ghz_oper) 1830 1831 return -1; 1831 1832 1832 - if (ftype != CFG80211_BSS_FTYPE_BEACON || 1833 - he_6ghz_oper->control & IEEE80211_HE_6GHZ_OPER_CTRL_DUP_BEACON) 1834 - return he_6ghz_oper->primary; 1833 + return he_6ghz_oper->primary; 1835 1834 } 1836 1835 } else if (band == NL80211_BAND_S1GHZ) { 1837 1836 tmp = cfg80211_find_elem(WLAN_EID_S1G_OPERATION, ie, ielen); ··· 1867 1870 static struct ieee80211_channel * 1868 1871 cfg80211_get_bss_channel(struct wiphy *wiphy, const u8 *ie, size_t ielen, 1869 1872 struct ieee80211_channel *channel, 1870 - enum nl80211_bss_scan_width scan_width, 1871 - enum cfg80211_bss_frame_type ftype) 1873 + enum nl80211_bss_scan_width scan_width) 1872 1874 { 1873 1875 u32 freq; 1874 1876 int channel_number; 1875 1877 struct ieee80211_channel *alt_channel; 1876 1878 1877 1879 channel_number = cfg80211_get_ies_channel_number(ie, ielen, 1878 - channel->band, ftype); 1880 + channel->band); 1879 1881 1880 1882 if (channel_number < 0) { 1881 1883 /* No channel information in frame payload */ ··· 1884 1888 freq = ieee80211_channel_to_freq_khz(channel_number, channel->band); 1885 1889 1886 1890 /* 1887 - * In 6GHz, duplicated beacon indication is relevant for 1888 - * beacons only. 1891 + * Frame info (beacon/prob res) is the same as received channel, 1892 + * no need for further processing. 1889 1893 */ 1890 - if (channel->band == NL80211_BAND_6GHZ && 1891 - (freq == channel->center_freq || 1892 - abs(freq - channel->center_freq) > 80)) 1894 + if (freq == ieee80211_channel_to_khz(channel)) 1893 1895 return channel; 1894 1896 1895 1897 alt_channel = ieee80211_get_channel_khz(wiphy, freq); 1896 1898 if (!alt_channel) { 1897 - if (channel->band == NL80211_BAND_2GHZ) { 1899 + if (channel->band == NL80211_BAND_2GHZ || 1900 + channel->band == NL80211_BAND_6GHZ) { 1898 1901 /* 1899 1902 * Better not allow unexpected channels when that could 1900 1903 * be going beyond the 1-11 range (e.g., discovering 1901 1904 * BSS on channel 12 when radio is configured for 1902 - * channel 11. 1905 + * channel 11) or beyond the 6 GHz channel range. 1903 1906 */ 1904 1907 return NULL; 1905 1908 } ··· 1952 1957 return NULL; 1953 1958 1954 1959 channel = cfg80211_get_bss_channel(wiphy, ie, ielen, data->chan, 1955 - data->scan_width, ftype); 1960 + data->scan_width); 1956 1961 if (!channel) 1957 1962 return NULL; 1958 1963 ··· 2386 2391 size_t ielen, min_hdr_len = offsetof(struct ieee80211_mgmt, 2387 2392 u.probe_resp.variable); 2388 2393 int bss_type; 2389 - enum cfg80211_bss_frame_type ftype; 2390 2394 2391 2395 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 2392 2396 offsetof(struct ieee80211_mgmt, u.beacon.variable)); ··· 2422 2428 variable = ext->u.s1g_beacon.variable; 2423 2429 } 2424 2430 2425 - if (ieee80211_is_beacon(mgmt->frame_control)) 2426 - ftype = CFG80211_BSS_FTYPE_BEACON; 2427 - else if (ieee80211_is_probe_resp(mgmt->frame_control)) 2428 - ftype = CFG80211_BSS_FTYPE_PRESP; 2429 - else 2430 - ftype = CFG80211_BSS_FTYPE_UNKNOWN; 2431 - 2432 2431 channel = cfg80211_get_bss_channel(wiphy, variable, 2433 - ielen, data->chan, data->scan_width, 2434 - ftype); 2432 + ielen, data->chan, data->scan_width); 2435 2433 if (!channel) 2436 2434 return NULL; 2437 2435
+32 -4
net/wireless/trace.h
··· 3165 3165 3166 3166 TRACE_EVENT(cfg80211_rx_control_port, 3167 3167 TP_PROTO(struct net_device *netdev, struct sk_buff *skb, 3168 - bool unencrypted), 3169 - TP_ARGS(netdev, skb, unencrypted), 3168 + bool unencrypted, int link_id), 3169 + TP_ARGS(netdev, skb, unencrypted, link_id), 3170 3170 TP_STRUCT__entry( 3171 3171 NETDEV_ENTRY 3172 3172 __field(int, len) 3173 3173 MAC_ENTRY(from) 3174 3174 __field(u16, proto) 3175 3175 __field(bool, unencrypted) 3176 + __field(int, link_id) 3176 3177 ), 3177 3178 TP_fast_assign( 3178 3179 NETDEV_ASSIGN; ··· 3181 3180 MAC_ASSIGN(from, eth_hdr(skb)->h_source); 3182 3181 __entry->proto = be16_to_cpu(skb->protocol); 3183 3182 __entry->unencrypted = unencrypted; 3183 + __entry->link_id = link_id; 3184 3184 ), 3185 - TP_printk(NETDEV_PR_FMT ", len=%d, %pM, proto: 0x%x, unencrypted: %s", 3185 + TP_printk(NETDEV_PR_FMT ", len=%d, %pM, proto: 0x%x, unencrypted: %s, link: %d", 3186 3186 NETDEV_PR_ARG, __entry->len, __entry->from, 3187 - __entry->proto, BOOL_TO_STR(__entry->unencrypted)) 3187 + __entry->proto, BOOL_TO_STR(__entry->unencrypted), 3188 + __entry->link_id) 3188 3189 ); 3189 3190 3190 3191 TRACE_EVENT(cfg80211_cqm_rssi_notify, ··· 3919 3916 ", link id: %u", 3920 3917 WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->mld_mac, 3921 3918 __entry->link_id) 3919 + ); 3920 + 3921 + TRACE_EVENT(rdev_set_hw_timestamp, 3922 + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, 3923 + struct cfg80211_set_hw_timestamp *hwts), 3924 + 3925 + TP_ARGS(wiphy, netdev, hwts), 3926 + 3927 + TP_STRUCT__entry( 3928 + WIPHY_ENTRY 3929 + NETDEV_ENTRY 3930 + MAC_ENTRY(macaddr) 3931 + __field(bool, enable) 3932 + ), 3933 + 3934 + TP_fast_assign( 3935 + WIPHY_ASSIGN; 3936 + NETDEV_ASSIGN; 3937 + MAC_ASSIGN(macaddr, hwts->macaddr); 3938 + __entry->enable = hwts->enable; 3939 + ), 3940 + 3941 + TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", mac %pM, enable: %u", 3942 + WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->macaddr, 3943 + __entry->enable) 3922 3944 ); 3923 3945 3924 3946 #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */