1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Copyright (C) 2018 - 2021, 2023 - 2026 Intel Corporation 4 */ 5 #include <net/cfg80211.h> 6 #include "core.h" 7 #include "nl80211.h" 8 #include "rdev-ops.h" 9 10 static int pmsr_parse_ftm(struct cfg80211_registered_device *rdev, 11 struct nlattr *ftmreq, 12 struct cfg80211_pmsr_request_peer *out, 13 struct genl_info *info) 14 { 15 const struct cfg80211_pmsr_capabilities *capa = rdev->wiphy.pmsr_capa; 16 struct nlattr *tb[NL80211_PMSR_FTM_REQ_ATTR_MAX + 1]; 17 u32 preamble = NL80211_PREAMBLE_DMG; /* only optional in DMG */ 18 19 /* validate existing data */ 20 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_INFRA && 21 !(capa->ftm.bandwidths & BIT(out->chandef.width))) { 22 NL_SET_ERR_MSG(info->extack, "FTM: unsupported bandwidth"); 23 return -EINVAL; 24 } 25 26 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 27 !(capa->ftm.pd_bandwidths & BIT(out->chandef.width))) { 28 NL_SET_ERR_MSG(info->extack, 29 "FTM: unsupported bandwidth for PD request"); 30 return -EINVAL; 31 } 32 33 /* no validation needed - was already done via nested policy */ 34 nla_parse_nested_deprecated(tb, NL80211_PMSR_FTM_REQ_ATTR_MAX, ftmreq, 35 NULL, NULL); 36 37 if (tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]) 38 preamble = nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]); 39 40 /* set up values - struct is 0-initialized */ 41 out->ftm.requested = true; 42 43 switch (out->chandef.chan->band) { 44 case NL80211_BAND_60GHZ: 45 /* optional */ 46 break; 47 default: 48 if (!tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE]) { 49 NL_SET_ERR_MSG(info->extack, 50 "FTM: must specify preamble"); 51 return -EINVAL; 52 } 53 } 54 55 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_INFRA && 56 !(capa->ftm.preambles & BIT(preamble))) { 57 NL_SET_ERR_MSG_ATTR(info->extack, 58 tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE], 59 "FTM: invalid preamble"); 60 return -EINVAL; 61 } 62 63 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 64 !(capa->ftm.pd_preambles & BIT(preamble))) { 65 NL_SET_ERR_MSG_ATTR(info->extack, 66 tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE], 67 "FTM: invalid preamble for PD request"); 68 return -EINVAL; 69 } 70 71 out->ftm.preamble = preamble; 72 73 out->ftm.burst_period = 0; 74 if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]) 75 out->ftm.burst_period = 76 nla_get_u16(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_PERIOD]); 77 78 out->ftm.asap = !!tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP]; 79 if (out->ftm.asap && !capa->ftm.asap) { 80 NL_SET_ERR_MSG_ATTR(info->extack, 81 tb[NL80211_PMSR_FTM_REQ_ATTR_ASAP], 82 "FTM: ASAP mode not supported"); 83 return -EINVAL; 84 } 85 86 if (!out->ftm.asap && !capa->ftm.non_asap) { 87 NL_SET_ERR_MSG(info->extack, 88 "FTM: non-ASAP mode not supported"); 89 return -EINVAL; 90 } 91 92 out->ftm.num_bursts_exp = 0; 93 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]) 94 out->ftm.num_bursts_exp = 95 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP]); 96 97 if (capa->ftm.max_bursts_exponent >= 0 && 98 out->ftm.num_bursts_exp > capa->ftm.max_bursts_exponent) { 99 NL_SET_ERR_MSG_ATTR(info->extack, 100 tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_BURSTS_EXP], 101 "FTM: max NUM_BURSTS_EXP must be set lower than the device limit"); 102 return -EINVAL; 103 } 104 105 out->ftm.ftms_per_burst = 0; 106 if (tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]) 107 out->ftm.ftms_per_burst = 108 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST]); 109 110 if (capa->ftm.max_ftms_per_burst && 111 out->ftm.ftms_per_burst > capa->ftm.max_ftms_per_burst) { 112 NL_SET_ERR_MSG_ATTR(info->extack, 113 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST], 114 "FTM: FTMs per burst must be set lower than the device limit"); 115 return -EINVAL; 116 } 117 118 out->ftm.ftmr_retries = 3; 119 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]) 120 out->ftm.ftmr_retries = 121 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_FTMR_RETRIES]); 122 123 out->ftm.request_lci = !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI]; 124 if (out->ftm.request_lci && !capa->ftm.request_lci) { 125 NL_SET_ERR_MSG_ATTR(info->extack, 126 tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_LCI], 127 "FTM: LCI request not supported"); 128 } 129 130 out->ftm.request_civicloc = 131 !!tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC]; 132 if (out->ftm.request_civicloc && !capa->ftm.request_civicloc) { 133 NL_SET_ERR_MSG_ATTR(info->extack, 134 tb[NL80211_PMSR_FTM_REQ_ATTR_REQUEST_CIVICLOC], 135 "FTM: civic location request not supported"); 136 } 137 138 out->ftm.trigger_based = 139 !!tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED]; 140 if (out->ftm.trigger_based && !capa->ftm.trigger_based) { 141 NL_SET_ERR_MSG_ATTR(info->extack, 142 tb[NL80211_PMSR_FTM_REQ_ATTR_TRIGGER_BASED], 143 "FTM: trigger based ranging is not supported"); 144 return -EINVAL; 145 } 146 147 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 148 out->ftm.trigger_based) { 149 NL_SET_ERR_MSG_ATTR(info->extack, 150 ftmreq, 151 "FTM: TB ranging is not supported for PD request type"); 152 return -EINVAL; 153 } 154 155 out->ftm.non_trigger_based = 156 !!tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED]; 157 if (out->ftm.non_trigger_based && !capa->ftm.non_trigger_based) { 158 NL_SET_ERR_MSG_ATTR(info->extack, 159 tb[NL80211_PMSR_FTM_REQ_ATTR_NON_TRIGGER_BASED], 160 "FTM: trigger based ranging is not supported"); 161 return -EINVAL; 162 } 163 164 if (out->ftm.trigger_based && out->ftm.non_trigger_based) { 165 NL_SET_ERR_MSG(info->extack, 166 "FTM: can't set both trigger based and non trigger based"); 167 return -EINVAL; 168 } 169 170 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 171 out->ftm.non_trigger_based && out->ftm.ftms_per_burst > 4) { 172 NL_SET_ERR_MSG_ATTR(info->extack, 173 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST], 174 "FTM: FTMs per burst must not exceed 4 for PD NTB ranging"); 175 return -ERANGE; 176 } 177 178 if (out->ftm.ftms_per_burst > 31 && !out->ftm.non_trigger_based && 179 !out->ftm.trigger_based) { 180 NL_SET_ERR_MSG_ATTR(info->extack, 181 tb[NL80211_PMSR_FTM_REQ_ATTR_FTMS_PER_BURST], 182 "FTM: FTMs per burst must be set lower than 31"); 183 return -ERANGE; 184 } 185 186 if ((out->ftm.trigger_based || out->ftm.non_trigger_based) && 187 out->ftm.preamble != NL80211_PREAMBLE_HE) { 188 NL_SET_ERR_MSG_ATTR(info->extack, 189 tb[NL80211_PMSR_FTM_REQ_ATTR_PREAMBLE], 190 "FTM: non EDCA based ranging must use HE preamble"); 191 return -EINVAL; 192 } 193 194 if (tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]) 195 out->ftm.burst_duration = 196 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BURST_DURATION]); 197 else if (!out->ftm.non_trigger_based && !out->ftm.trigger_based) 198 out->ftm.burst_duration = 15; 199 200 out->ftm.lmr_feedback = 201 !!tb[NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK]; 202 if (!out->ftm.trigger_based && !out->ftm.non_trigger_based && 203 out->ftm.lmr_feedback) { 204 NL_SET_ERR_MSG_ATTR(info->extack, 205 tb[NL80211_PMSR_FTM_REQ_ATTR_LMR_FEEDBACK], 206 "FTM: LMR feedback set for EDCA based ranging"); 207 return -EINVAL; 208 } 209 210 if (tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]) { 211 if (!out->ftm.non_trigger_based && !out->ftm.trigger_based) { 212 NL_SET_ERR_MSG_ATTR(info->extack, 213 tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR], 214 "FTM: BSS color set for EDCA based ranging"); 215 return -EINVAL; 216 } 217 218 out->ftm.bss_color = 219 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_BSS_COLOR]); 220 } 221 222 out->ftm.rsta = !!tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA]; 223 if (out->ftm.rsta && out->ftm.non_trigger_based && 224 !capa->ftm.rsta.support_ntb) { 225 NL_SET_ERR_MSG_ATTR(info->extack, 226 tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA], 227 "FTM: NTB RSTA not supported by device"); 228 return -EOPNOTSUPP; 229 } 230 231 if (out->ftm.rsta && out->ftm.trigger_based && 232 !capa->ftm.rsta.support_tb) { 233 NL_SET_ERR_MSG_ATTR(info->extack, 234 tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA], 235 "FTM: TB RSTA not supported by device"); 236 return -EOPNOTSUPP; 237 } 238 239 if (out->ftm.rsta && !out->ftm.non_trigger_based && 240 !out->ftm.trigger_based && 241 !capa->ftm.rsta.support_edca) { 242 NL_SET_ERR_MSG_ATTR(info->extack, 243 tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA], 244 "FTM: EDCA RSTA not supported by device"); 245 return -EOPNOTSUPP; 246 } 247 248 if (out->ftm.rsta && 249 (out->ftm.non_trigger_based || out->ftm.trigger_based) && 250 !out->ftm.lmr_feedback) { 251 NL_SET_ERR_MSG_ATTR(info->extack, 252 tb[NL80211_PMSR_FTM_REQ_ATTR_RSTA], 253 "FTM: RSTA set without LMR feedback"); 254 return -EINVAL; 255 } 256 257 if (out->ftm.non_trigger_based) { 258 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 259 !tb[NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME]) { 260 NL_SET_ERR_MSG(info->extack, 261 "FTM: nominal time is required for PD NTB ranging"); 262 return -EINVAL; 263 } 264 out->ftm.nominal_time = 265 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NOMINAL_TIME]); 266 267 if (tb[NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS]) 268 out->ftm.min_time_between_measurements = 269 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_MIN_TIME_BETWEEN_MEASUREMENTS]); 270 271 if (tb[NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS]) 272 out->ftm.max_time_between_measurements = 273 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_MAX_TIME_BETWEEN_MEASUREMENTS]); 274 275 if (tb[NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION]) 276 out->ftm.availability_window = 277 nla_get_u8(tb[NL80211_PMSR_FTM_REQ_ATTR_AW_DURATION]); 278 279 if (tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS]) 280 out->ftm.num_measurements = 281 nla_get_u32(tb[NL80211_PMSR_FTM_REQ_ATTR_NUM_MEASUREMENTS]); 282 } 283 284 if (tb[NL80211_PMSR_FTM_REQ_ATTR_INGRESS]) 285 out->ftm.ingress_distance = 286 nla_get_u64(tb[NL80211_PMSR_FTM_REQ_ATTR_INGRESS]); 287 288 if (tb[NL80211_PMSR_FTM_REQ_ATTR_EGRESS]) 289 out->ftm.egress_distance = 290 nla_get_u64(tb[NL80211_PMSR_FTM_REQ_ATTR_EGRESS]); 291 292 out->ftm.pd_suppress_range_results = 293 nla_get_flag(tb[NL80211_PMSR_FTM_REQ_ATTR_PD_SUPPRESS_RESULTS]); 294 295 if (out->ftm.request_type != NL80211_PMSR_FTM_REQ_TYPE_PD && 296 out->ftm.pd_suppress_range_results) { 297 NL_SET_ERR_MSG_ATTR(info->extack, 298 tb[NL80211_PMSR_FTM_REQ_ATTR_PD_SUPPRESS_RESULTS], 299 "FTM: suppress range result flag only valid for PD requests"); 300 return -EINVAL; 301 } 302 303 return 0; 304 } 305 306 static int pmsr_parse_peer(struct cfg80211_registered_device *rdev, 307 struct nlattr *peer, 308 struct cfg80211_pmsr_request_peer *out, 309 struct genl_info *info) 310 { 311 struct nlattr *tb[NL80211_PMSR_PEER_ATTR_MAX + 1]; 312 struct nlattr *req[NL80211_PMSR_REQ_ATTR_MAX + 1]; 313 struct nlattr *treq; 314 int err, rem; 315 316 /* no validation needed - was already done via nested policy */ 317 nla_parse_nested_deprecated(tb, NL80211_PMSR_PEER_ATTR_MAX, peer, 318 NULL, NULL); 319 320 if (!tb[NL80211_PMSR_PEER_ATTR_ADDR] || 321 !tb[NL80211_PMSR_PEER_ATTR_CHAN] || 322 !tb[NL80211_PMSR_PEER_ATTR_REQ]) { 323 NL_SET_ERR_MSG_ATTR(info->extack, peer, 324 "insufficient peer data"); 325 return -EINVAL; 326 } 327 328 memcpy(out->addr, nla_data(tb[NL80211_PMSR_PEER_ATTR_ADDR]), ETH_ALEN); 329 330 if (tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE]) 331 out->ftm.request_type = 332 nla_get_u32(tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE]); 333 else 334 out->ftm.request_type = NL80211_PMSR_FTM_REQ_TYPE_INFRA; 335 336 if (out->ftm.request_type == NL80211_PMSR_FTM_REQ_TYPE_PD && 337 !rdev->wiphy.pmsr_capa->ftm.type.pd_support) { 338 NL_SET_ERR_MSG_ATTR(info->extack, 339 tb[NL80211_PMSR_PEER_ATTR_REQ_TYPE], 340 "FTM: PD request type not supported by device"); 341 return -EINVAL; 342 } 343 /* reuse info->attrs */ 344 memset(info->attrs, 0, sizeof(*info->attrs) * (NL80211_ATTR_MAX + 1)); 345 err = nla_parse_nested_deprecated(info->attrs, NL80211_ATTR_MAX, 346 tb[NL80211_PMSR_PEER_ATTR_CHAN], 347 NULL, info->extack); 348 if (err) 349 return err; 350 351 err = nl80211_parse_chandef(rdev, info->extack, info->attrs, 352 &out->chandef, false); 353 if (err) 354 return err; 355 356 /* no validation needed - was already done via nested policy */ 357 nla_parse_nested_deprecated(req, NL80211_PMSR_REQ_ATTR_MAX, 358 tb[NL80211_PMSR_PEER_ATTR_REQ], NULL, 359 NULL); 360 361 if (!req[NL80211_PMSR_REQ_ATTR_DATA]) { 362 NL_SET_ERR_MSG_ATTR(info->extack, 363 tb[NL80211_PMSR_PEER_ATTR_REQ], 364 "missing request type/data"); 365 return -EINVAL; 366 } 367 368 if (req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF]) 369 out->report_ap_tsf = true; 370 371 if (out->report_ap_tsf && !rdev->wiphy.pmsr_capa->report_ap_tsf) { 372 NL_SET_ERR_MSG_ATTR(info->extack, 373 req[NL80211_PMSR_REQ_ATTR_GET_AP_TSF], 374 "reporting AP TSF is not supported"); 375 return -EINVAL; 376 } 377 378 nla_for_each_nested(treq, req[NL80211_PMSR_REQ_ATTR_DATA], rem) { 379 switch (nla_type(treq)) { 380 case NL80211_PMSR_TYPE_FTM: 381 err = pmsr_parse_ftm(rdev, treq, out, info); 382 break; 383 default: 384 NL_SET_ERR_MSG_ATTR(info->extack, treq, 385 "unsupported measurement type"); 386 err = -EINVAL; 387 } 388 } 389 390 if (err) 391 return err; 392 393 return 0; 394 } 395 396 int nl80211_pmsr_start(struct sk_buff *skb, struct genl_info *info) 397 { 398 struct nlattr *reqattr = info->attrs[NL80211_ATTR_PEER_MEASUREMENTS]; 399 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 400 int count, rem, err, idx, peer_count; 401 struct wireless_dev *wdev = info->user_ptr[1]; 402 const struct cfg80211_pmsr_capabilities *capa; 403 struct cfg80211_pmsr_request *req; 404 struct nlattr *peers, *peer; 405 406 capa = rdev->wiphy.pmsr_capa; 407 408 if (!capa) 409 return -EOPNOTSUPP; 410 411 if (!reqattr) 412 return -EINVAL; 413 414 peers = nla_find(nla_data(reqattr), nla_len(reqattr), 415 NL80211_PMSR_ATTR_PEERS); 416 if (!peers) 417 return -EINVAL; 418 419 count = 0; 420 nla_for_each_nested(peer, peers, rem) { 421 count++; 422 423 if (count > capa->max_peers) { 424 NL_SET_ERR_MSG_ATTR(info->extack, peer, 425 "Too many peers used"); 426 return -EINVAL; 427 } 428 } 429 430 req = kzalloc_flex(*req, peers, count); 431 if (!req) 432 return -ENOMEM; 433 req->n_peers = count; 434 435 if (info->attrs[NL80211_ATTR_TIMEOUT]) 436 req->timeout = nla_get_u32(info->attrs[NL80211_ATTR_TIMEOUT]); 437 438 if (info->attrs[NL80211_ATTR_MAC]) { 439 if (!capa->randomize_mac_addr) { 440 NL_SET_ERR_MSG_ATTR(info->extack, 441 info->attrs[NL80211_ATTR_MAC], 442 "device cannot randomize MAC address"); 443 err = -EINVAL; 444 goto out_err; 445 } 446 447 err = nl80211_parse_random_mac(info->attrs, req->mac_addr, 448 req->mac_addr_mask); 449 if (err) 450 goto out_err; 451 } else { 452 memcpy(req->mac_addr, wdev_address(wdev), ETH_ALEN); 453 eth_broadcast_addr(req->mac_addr_mask); 454 } 455 456 idx = 0; 457 nla_for_each_nested(peer, peers, rem) { 458 /* NB: this reuses info->attrs, but we no longer need it */ 459 err = pmsr_parse_peer(rdev, peer, &req->peers[idx], info); 460 if (err) 461 goto out_err; 462 idx++; 463 } 464 465 /* Validate per-role peer limits if advertised */ 466 if (capa->ftm.ista.max_peers) { 467 peer_count = 0; 468 469 for (idx = 0; idx < req->n_peers; idx++) { 470 if (!req->peers[idx].ftm.rsta) { 471 peer_count++; 472 473 if (peer_count > capa->ftm.ista.max_peers) { 474 NL_SET_ERR_MSG(info->extack, 475 "Too many ISTA peers for device limit"); 476 err = -EINVAL; 477 goto out_err; 478 } 479 } 480 } 481 } 482 483 if (capa->ftm.rsta.max_peers) { 484 peer_count = 0; 485 486 for (idx = 0; idx < req->n_peers; idx++) { 487 if (req->peers[idx].ftm.rsta) { 488 peer_count++; 489 490 if (peer_count > capa->ftm.rsta.max_peers) { 491 NL_SET_ERR_MSG(info->extack, 492 "Too many RSTA peers for device limit"); 493 err = -EINVAL; 494 goto out_err; 495 } 496 } 497 } 498 } 499 req->cookie = cfg80211_assign_cookie(rdev); 500 req->nl_portid = info->snd_portid; 501 502 err = rdev_start_pmsr(rdev, wdev, req); 503 if (err) 504 goto out_err; 505 506 list_add_tail(&req->list, &wdev->pmsr_list); 507 508 nl_set_extack_cookie_u64(info->extack, req->cookie); 509 return 0; 510 out_err: 511 kfree(req); 512 return err; 513 } 514 515 void cfg80211_pmsr_complete(struct wireless_dev *wdev, 516 struct cfg80211_pmsr_request *req, 517 gfp_t gfp) 518 { 519 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 520 struct cfg80211_pmsr_request *tmp, *prev, *to_free = NULL; 521 struct sk_buff *msg; 522 void *hdr; 523 524 trace_cfg80211_pmsr_complete(wdev->wiphy, wdev, req->cookie); 525 526 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 527 if (!msg) 528 goto free_request; 529 530 hdr = nl80211hdr_put(msg, 0, 0, 0, 531 NL80211_CMD_PEER_MEASUREMENT_COMPLETE); 532 if (!hdr) 533 goto free_msg; 534 535 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 536 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), 537 NL80211_ATTR_PAD)) 538 goto free_msg; 539 540 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie, 541 NL80211_ATTR_PAD)) 542 goto free_msg; 543 544 genlmsg_end(msg, hdr); 545 genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid); 546 goto free_request; 547 free_msg: 548 nlmsg_free(msg); 549 free_request: 550 spin_lock_bh(&wdev->pmsr_lock); 551 /* 552 * cfg80211_pmsr_process_abort() may have already moved this request 553 * to the free list, and will free it later. In this case, don't free 554 * it here. 555 */ 556 list_for_each_entry_safe(tmp, prev, &wdev->pmsr_list, list) { 557 if (tmp == req) { 558 list_del(&req->list); 559 to_free = req; 560 break; 561 } 562 } 563 spin_unlock_bh(&wdev->pmsr_lock); 564 kfree(to_free); 565 } 566 EXPORT_SYMBOL_GPL(cfg80211_pmsr_complete); 567 568 static int nl80211_pmsr_send_ftm_res(struct sk_buff *msg, 569 struct cfg80211_pmsr_result *res) 570 { 571 if (res->status == NL80211_PMSR_STATUS_FAILURE) { 572 if (nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_FAIL_REASON, 573 res->ftm.failure_reason)) 574 goto error; 575 576 if (res->ftm.failure_reason == 577 NL80211_PMSR_FTM_FAILURE_PEER_BUSY && 578 res->ftm.busy_retry_time && 579 nla_put_u32(msg, NL80211_PMSR_FTM_RESP_ATTR_BUSY_RETRY_TIME, 580 res->ftm.busy_retry_time)) 581 goto error; 582 583 return 0; 584 } 585 586 #define PUT(tp, attr, val) \ 587 do { \ 588 if (nla_put_##tp(msg, \ 589 NL80211_PMSR_FTM_RESP_ATTR_##attr, \ 590 res->ftm.val)) \ 591 goto error; \ 592 } while (0) 593 594 #define PUTOPT(tp, attr, val) \ 595 do { \ 596 if (res->ftm.val##_valid) \ 597 PUT(tp, attr, val); \ 598 } while (0) 599 600 #define PUT_U64(attr, val) \ 601 do { \ 602 if (nla_put_u64_64bit(msg, \ 603 NL80211_PMSR_FTM_RESP_ATTR_##attr,\ 604 res->ftm.val, \ 605 NL80211_PMSR_FTM_RESP_ATTR_PAD)) \ 606 goto error; \ 607 } while (0) 608 609 #define PUTOPT_U64(attr, val) \ 610 do { \ 611 if (res->ftm.val##_valid) \ 612 PUT_U64(attr, val); \ 613 } while (0) 614 615 if (res->ftm.burst_index >= 0) 616 PUT(u32, BURST_INDEX, burst_index); 617 PUTOPT(u32, NUM_FTMR_ATTEMPTS, num_ftmr_attempts); 618 PUTOPT(u32, NUM_FTMR_SUCCESSES, num_ftmr_successes); 619 PUT(u8, NUM_BURSTS_EXP, num_bursts_exp); 620 PUT(u8, BURST_DURATION, burst_duration); 621 PUT(u8, FTMS_PER_BURST, ftms_per_burst); 622 PUT(u16, BURST_PERIOD, burst_period); 623 PUTOPT(s32, RSSI_AVG, rssi_avg); 624 PUTOPT(s32, RSSI_SPREAD, rssi_spread); 625 if (res->ftm.tx_rate_valid && 626 !nl80211_put_sta_rate(msg, &res->ftm.tx_rate, 627 NL80211_PMSR_FTM_RESP_ATTR_TX_RATE)) 628 goto error; 629 if (res->ftm.rx_rate_valid && 630 !nl80211_put_sta_rate(msg, &res->ftm.rx_rate, 631 NL80211_PMSR_FTM_RESP_ATTR_RX_RATE)) 632 goto error; 633 PUTOPT_U64(RTT_AVG, rtt_avg); 634 PUTOPT_U64(RTT_VARIANCE, rtt_variance); 635 PUTOPT_U64(RTT_SPREAD, rtt_spread); 636 PUTOPT_U64(DIST_AVG, dist_avg); 637 PUTOPT_U64(DIST_VARIANCE, dist_variance); 638 PUTOPT_U64(DIST_SPREAD, dist_spread); 639 PUTOPT(u32, TX_LTF_REPETITION_COUNT, tx_ltf_repetition_count); 640 PUTOPT(u32, RX_LTF_REPETITION_COUNT, rx_ltf_repetition_count); 641 PUTOPT(u32, MAX_TIME_BETWEEN_MEASUREMENTS, 642 max_time_between_measurements); 643 PUTOPT(u32, MIN_TIME_BETWEEN_MEASUREMENTS, 644 min_time_between_measurements); 645 PUTOPT(u8, NUM_TX_SPATIAL_STREAMS, num_tx_spatial_streams); 646 PUTOPT(u8, NUM_RX_SPATIAL_STREAMS, num_rx_spatial_streams); 647 PUTOPT(u32, NOMINAL_TIME, nominal_time); 648 PUTOPT(u8, AVAILABILITY_WINDOW, availability_window); 649 PUTOPT(u32, CHANNEL_WIDTH, chan_width); 650 PUTOPT(u32, PREAMBLE, preamble); 651 if (res->ftm.is_delayed_lmr && 652 nla_put_flag(msg, NL80211_PMSR_FTM_RESP_ATTR_IS_DELAYED_LMR)) 653 goto error; 654 if (res->ftm.lci && res->ftm.lci_len && 655 nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_LCI, 656 res->ftm.lci_len, res->ftm.lci)) 657 goto error; 658 if (res->ftm.civicloc && res->ftm.civicloc_len && 659 nla_put(msg, NL80211_PMSR_FTM_RESP_ATTR_CIVICLOC, 660 res->ftm.civicloc_len, res->ftm.civicloc)) 661 goto error; 662 #undef PUT 663 #undef PUTOPT 664 #undef PUT_U64 665 #undef PUTOPT_U64 666 667 return 0; 668 error: 669 return -ENOSPC; 670 } 671 672 static int nl80211_pmsr_send_result(struct sk_buff *msg, 673 struct cfg80211_pmsr_result *res) 674 { 675 struct nlattr *pmsr, *peers, *peer, *resp, *data, *typedata; 676 677 pmsr = nla_nest_start_noflag(msg, NL80211_ATTR_PEER_MEASUREMENTS); 678 if (!pmsr) 679 goto error; 680 681 peers = nla_nest_start_noflag(msg, NL80211_PMSR_ATTR_PEERS); 682 if (!peers) 683 goto error; 684 685 peer = nla_nest_start_noflag(msg, 1); 686 if (!peer) 687 goto error; 688 689 if (nla_put(msg, NL80211_PMSR_PEER_ATTR_ADDR, ETH_ALEN, res->addr)) 690 goto error; 691 692 resp = nla_nest_start_noflag(msg, NL80211_PMSR_PEER_ATTR_RESP); 693 if (!resp) 694 goto error; 695 696 if (nla_put_u32(msg, NL80211_PMSR_RESP_ATTR_STATUS, res->status) || 697 nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_HOST_TIME, 698 res->host_time, NL80211_PMSR_RESP_ATTR_PAD)) 699 goto error; 700 701 if (res->ap_tsf_valid && 702 nla_put_u64_64bit(msg, NL80211_PMSR_RESP_ATTR_AP_TSF, 703 res->ap_tsf, NL80211_PMSR_RESP_ATTR_PAD)) 704 goto error; 705 706 if (res->final && nla_put_flag(msg, NL80211_PMSR_RESP_ATTR_FINAL)) 707 goto error; 708 709 data = nla_nest_start_noflag(msg, NL80211_PMSR_RESP_ATTR_DATA); 710 if (!data) 711 goto error; 712 713 typedata = nla_nest_start_noflag(msg, res->type); 714 if (!typedata) 715 goto error; 716 717 switch (res->type) { 718 case NL80211_PMSR_TYPE_FTM: 719 if (nl80211_pmsr_send_ftm_res(msg, res)) 720 goto error; 721 break; 722 default: 723 WARN_ON(1); 724 } 725 726 nla_nest_end(msg, typedata); 727 nla_nest_end(msg, data); 728 nla_nest_end(msg, resp); 729 nla_nest_end(msg, peer); 730 nla_nest_end(msg, peers); 731 nla_nest_end(msg, pmsr); 732 733 return 0; 734 error: 735 return -ENOSPC; 736 } 737 738 void cfg80211_pmsr_report(struct wireless_dev *wdev, 739 struct cfg80211_pmsr_request *req, 740 struct cfg80211_pmsr_result *result, 741 gfp_t gfp) 742 { 743 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 744 struct sk_buff *msg; 745 void *hdr; 746 int err; 747 748 trace_cfg80211_pmsr_report(wdev->wiphy, wdev, req->cookie, 749 result->addr); 750 751 /* 752 * Currently, only variable items are LCI and civic location, 753 * both of which are reasonably short so we don't need to 754 * worry about them here for the allocation. 755 */ 756 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); 757 if (!msg) 758 return; 759 760 hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PEER_MEASUREMENT_RESULT); 761 if (!hdr) 762 goto free; 763 764 if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || 765 nla_put_u64_64bit(msg, NL80211_ATTR_WDEV, wdev_id(wdev), 766 NL80211_ATTR_PAD)) 767 goto free; 768 769 if (nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, req->cookie, 770 NL80211_ATTR_PAD)) 771 goto free; 772 773 err = nl80211_pmsr_send_result(msg, result); 774 if (err) { 775 pr_err_ratelimited("peer measurement result: message didn't fit!"); 776 goto free; 777 } 778 779 genlmsg_end(msg, hdr); 780 genlmsg_unicast(wiphy_net(wdev->wiphy), msg, req->nl_portid); 781 return; 782 free: 783 nlmsg_free(msg); 784 } 785 EXPORT_SYMBOL_GPL(cfg80211_pmsr_report); 786 787 static void cfg80211_pmsr_process_abort(struct wireless_dev *wdev) 788 { 789 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); 790 struct cfg80211_pmsr_request *req, *tmp; 791 LIST_HEAD(free_list); 792 793 lockdep_assert_wiphy(wdev->wiphy); 794 795 spin_lock_bh(&wdev->pmsr_lock); 796 list_for_each_entry_safe(req, tmp, &wdev->pmsr_list, list) { 797 if (req->nl_portid) 798 continue; 799 list_move_tail(&req->list, &free_list); 800 } 801 spin_unlock_bh(&wdev->pmsr_lock); 802 803 list_for_each_entry_safe(req, tmp, &free_list, list) { 804 rdev_abort_pmsr(rdev, wdev, req); 805 806 kfree(req); 807 } 808 } 809 810 void cfg80211_pmsr_free_wk(struct work_struct *work) 811 { 812 struct wireless_dev *wdev = container_of(work, struct wireless_dev, 813 pmsr_free_wk); 814 815 guard(wiphy)(wdev->wiphy); 816 817 cfg80211_pmsr_process_abort(wdev); 818 } 819 820 void cfg80211_pmsr_wdev_down(struct wireless_dev *wdev) 821 { 822 struct cfg80211_pmsr_request *req; 823 bool found = false; 824 825 spin_lock_bh(&wdev->pmsr_lock); 826 list_for_each_entry(req, &wdev->pmsr_list, list) { 827 found = true; 828 req->nl_portid = 0; 829 } 830 spin_unlock_bh(&wdev->pmsr_lock); 831 832 cancel_work_sync(&wdev->pmsr_free_wk); 833 if (found) 834 cfg80211_pmsr_process_abort(wdev); 835 836 WARN_ON(!list_empty(&wdev->pmsr_list)); 837 } 838 839 void cfg80211_release_pmsr(struct wireless_dev *wdev, u32 portid) 840 { 841 struct cfg80211_pmsr_request *req; 842 843 spin_lock_bh(&wdev->pmsr_lock); 844 list_for_each_entry(req, &wdev->pmsr_list, list) { 845 if (req->nl_portid == portid) { 846 req->nl_portid = 0; 847 schedule_work(&wdev->pmsr_free_wk); 848 } 849 } 850 spin_unlock_bh(&wdev->pmsr_lock); 851 } 852