diff options
| -rw-r--r-- | net/wireless/reg.c | 126 |
1 files changed, 63 insertions, 63 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index a20dd13c709..9dff716d1b0 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -298,69 +298,6 @@ static int call_crda(const char *alpha2) | |||
| 298 | return kobject_uevent_env(®_pdev->dev.kobj, KOBJ_CHANGE, envp); | 298 | return kobject_uevent_env(®_pdev->dev.kobj, KOBJ_CHANGE, envp); |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | /* This has the logic which determines when a new request | ||
| 302 | * should be ignored. */ | ||
| 303 | static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, | ||
| 304 | const char *alpha2) | ||
| 305 | { | ||
| 306 | /* All initial requests are respected */ | ||
| 307 | if (!last_request) | ||
| 308 | return 0; | ||
| 309 | |||
| 310 | switch (set_by) { | ||
| 311 | case REGDOM_SET_BY_INIT: | ||
| 312 | return -EINVAL; | ||
| 313 | case REGDOM_SET_BY_CORE: | ||
| 314 | /* | ||
| 315 | * Always respect new wireless core hints, should only happen | ||
| 316 | * when updating the world regulatory domain at init. | ||
| 317 | */ | ||
| 318 | return 0; | ||
| 319 | case REGDOM_SET_BY_COUNTRY_IE: | ||
| 320 | if (unlikely(!is_an_alpha2(alpha2))) | ||
| 321 | return -EINVAL; | ||
| 322 | if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { | ||
| 323 | if (last_request->wiphy != wiphy) { | ||
| 324 | /* | ||
| 325 | * Two cards with two APs claiming different | ||
| 326 | * different Country IE alpha2s. We could | ||
| 327 | * intersect them, but that seems unlikely | ||
| 328 | * to be correct. Reject second one for now. | ||
| 329 | */ | ||
| 330 | if (!alpha2_equal(alpha2, | ||
| 331 | cfg80211_regdomain->alpha2)) | ||
| 332 | return -EOPNOTSUPP; | ||
| 333 | return -EALREADY; | ||
| 334 | } | ||
| 335 | /* Two consecutive Country IE hints on the same wiphy */ | ||
| 336 | if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2)) | ||
| 337 | return 0; | ||
| 338 | return -EALREADY; | ||
| 339 | } | ||
| 340 | /* | ||
| 341 | * Ignore Country IE hints for now, need to think about | ||
| 342 | * what we need to do to support multi-domain operation. | ||
| 343 | */ | ||
| 344 | return -EOPNOTSUPP; | ||
| 345 | case REGDOM_SET_BY_DRIVER: | ||
| 346 | if (last_request->initiator == REGDOM_SET_BY_DRIVER) | ||
| 347 | return -EALREADY; | ||
| 348 | return 0; | ||
| 349 | case REGDOM_SET_BY_USER: | ||
| 350 | /* | ||
| 351 | * If the user wants to override the AP's hint, we may | ||
| 352 | * need to follow both and use the intersection. For now, | ||
| 353 | * reject any such attempt (but we don't support country | ||
| 354 | * IEs right now anyway.) | ||
| 355 | */ | ||
| 356 | if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) | ||
| 357 | return -EOPNOTSUPP; | ||
| 358 | return 0; | ||
| 359 | } | ||
| 360 | |||
| 361 | return -EINVAL; | ||
| 362 | } | ||
| 363 | |||
| 364 | /* Used by nl80211 before kmalloc'ing our regulatory domain */ | 301 | /* Used by nl80211 before kmalloc'ing our regulatory domain */ |
| 365 | bool reg_is_valid_request(const char *alpha2) | 302 | bool reg_is_valid_request(const char *alpha2) |
| 366 | { | 303 | { |
| @@ -531,6 +468,69 @@ void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby) | |||
| 531 | } | 468 | } |
| 532 | } | 469 | } |
| 533 | 470 | ||
| 471 | /* This has the logic which determines when a new request | ||
| 472 | * should be ignored. */ | ||
| 473 | static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by, | ||
| 474 | const char *alpha2) | ||
| 475 | { | ||
| 476 | /* All initial requests are respected */ | ||
| 477 | if (!last_request) | ||
| 478 | return 0; | ||
| 479 | |||
| 480 | switch (set_by) { | ||
| 481 | case REGDOM_SET_BY_INIT: | ||
| 482 | return -EINVAL; | ||
| 483 | case REGDOM_SET_BY_CORE: | ||
| 484 | /* | ||
| 485 | * Always respect new wireless core hints, should only happen | ||
| 486 | * when updating the world regulatory domain at init. | ||
| 487 | */ | ||
| 488 | return 0; | ||
| 489 | case REGDOM_SET_BY_COUNTRY_IE: | ||
| 490 | if (unlikely(!is_an_alpha2(alpha2))) | ||
| 491 | return -EINVAL; | ||
| 492 | if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) { | ||
| 493 | if (last_request->wiphy != wiphy) { | ||
| 494 | /* | ||
| 495 | * Two cards with two APs claiming different | ||
| 496 | * different Country IE alpha2s. We could | ||
| 497 | * intersect them, but that seems unlikely | ||
| 498 | * to be correct. Reject second one for now. | ||
| 499 | */ | ||
| 500 | if (!alpha2_equal(alpha2, | ||
| 501 | cfg80211_regdomain->alpha2)) | ||
| 502 | return -EOPNOTSUPP; | ||
| 503 | return -EALREADY; | ||
| 504 | } | ||
| 505 | /* Two consecutive Country IE hints on the same wiphy */ | ||
| 506 | if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2)) | ||
| 507 | return 0; | ||
| 508 | return -EALREADY; | ||
| 509 | } | ||
| 510 | /* | ||
| 511 | * Ignore Country IE hints for now, need to think about | ||
| 512 | * what we need to do to support multi-domain operation. | ||
| 513 | */ | ||
| 514 | return -EOPNOTSUPP; | ||
| 515 | case REGDOM_SET_BY_DRIVER: | ||
| 516 | if (last_request->initiator == REGDOM_SET_BY_DRIVER) | ||
| 517 | return -EALREADY; | ||
| 518 | return 0; | ||
| 519 | case REGDOM_SET_BY_USER: | ||
| 520 | /* | ||
| 521 | * If the user wants to override the AP's hint, we may | ||
| 522 | * need to follow both and use the intersection. For now, | ||
| 523 | * reject any such attempt (but we don't support country | ||
| 524 | * IEs right now anyway.) | ||
| 525 | */ | ||
| 526 | if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE) | ||
| 527 | return -EOPNOTSUPP; | ||
| 528 | return 0; | ||
| 529 | } | ||
| 530 | |||
| 531 | return -EINVAL; | ||
| 532 | } | ||
| 533 | |||
| 534 | /* Caller must hold &cfg80211_drv_mutex */ | 534 | /* Caller must hold &cfg80211_drv_mutex */ |
| 535 | int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, | 535 | int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by, |
| 536 | const char *alpha2) | 536 | const char *alpha2) |
