diff options
Diffstat (limited to 'net/mac80211/driver-ops.h')
-rw-r--r-- | net/mac80211/driver-ops.h | 210 |
1 files changed, 168 insertions, 42 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index ef8b385eff04..11423958116a 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -5,11 +5,11 @@ | |||
5 | #include "ieee80211_i.h" | 5 | #include "ieee80211_i.h" |
6 | #include "trace.h" | 6 | #include "trace.h" |
7 | 7 | ||
8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) | 8 | static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) |
9 | { | 9 | { |
10 | WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), | 10 | return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), |
11 | "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", | 11 | "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", |
12 | sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); | 12 | sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); |
13 | } | 13 | } |
14 | 14 | ||
15 | static inline struct ieee80211_sub_if_data * | 15 | static inline struct ieee80211_sub_if_data * |
@@ -168,7 +168,8 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
168 | 168 | ||
169 | might_sleep(); | 169 | might_sleep(); |
170 | 170 | ||
171 | check_sdata_in_driver(sdata); | 171 | if (!check_sdata_in_driver(sdata)) |
172 | return -EIO; | ||
172 | 173 | ||
173 | trace_drv_change_interface(local, sdata, type, p2p); | 174 | trace_drv_change_interface(local, sdata, type, p2p); |
174 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); | 175 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); |
@@ -181,7 +182,8 @@ static inline void drv_remove_interface(struct ieee80211_local *local, | |||
181 | { | 182 | { |
182 | might_sleep(); | 183 | might_sleep(); |
183 | 184 | ||
184 | check_sdata_in_driver(sdata); | 185 | if (!check_sdata_in_driver(sdata)) |
186 | return; | ||
185 | 187 | ||
186 | trace_drv_remove_interface(local, sdata); | 188 | trace_drv_remove_interface(local, sdata); |
187 | local->ops->remove_interface(&local->hw, &sdata->vif); | 189 | local->ops->remove_interface(&local->hw, &sdata->vif); |
@@ -219,7 +221,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
219 | sdata->vif.type == NL80211_IFTYPE_MONITOR)) | 221 | sdata->vif.type == NL80211_IFTYPE_MONITOR)) |
220 | return; | 222 | return; |
221 | 223 | ||
222 | check_sdata_in_driver(sdata); | 224 | if (!check_sdata_in_driver(sdata)) |
225 | return; | ||
223 | 226 | ||
224 | trace_drv_bss_info_changed(local, sdata, info, changed); | 227 | trace_drv_bss_info_changed(local, sdata, info, changed); |
225 | if (local->ops->bss_info_changed) | 228 | if (local->ops->bss_info_changed) |
@@ -278,7 +281,8 @@ static inline int drv_set_key(struct ieee80211_local *local, | |||
278 | might_sleep(); | 281 | might_sleep(); |
279 | 282 | ||
280 | sdata = get_bss_sdata(sdata); | 283 | sdata = get_bss_sdata(sdata); |
281 | check_sdata_in_driver(sdata); | 284 | if (!check_sdata_in_driver(sdata)) |
285 | return -EIO; | ||
282 | 286 | ||
283 | trace_drv_set_key(local, cmd, sdata, sta, key); | 287 | trace_drv_set_key(local, cmd, sdata, sta, key); |
284 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); | 288 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); |
@@ -298,7 +302,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
298 | ista = &sta->sta; | 302 | ista = &sta->sta; |
299 | 303 | ||
300 | sdata = get_bss_sdata(sdata); | 304 | sdata = get_bss_sdata(sdata); |
301 | check_sdata_in_driver(sdata); | 305 | if (!check_sdata_in_driver(sdata)) |
306 | return; | ||
302 | 307 | ||
303 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); | 308 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); |
304 | if (local->ops->update_tkip_key) | 309 | if (local->ops->update_tkip_key) |
@@ -309,13 +314,14 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
309 | 314 | ||
310 | static inline int drv_hw_scan(struct ieee80211_local *local, | 315 | static inline int drv_hw_scan(struct ieee80211_local *local, |
311 | struct ieee80211_sub_if_data *sdata, | 316 | struct ieee80211_sub_if_data *sdata, |
312 | struct cfg80211_scan_request *req) | 317 | struct ieee80211_scan_request *req) |
313 | { | 318 | { |
314 | int ret; | 319 | int ret; |
315 | 320 | ||
316 | might_sleep(); | 321 | might_sleep(); |
317 | 322 | ||
318 | check_sdata_in_driver(sdata); | 323 | if (!check_sdata_in_driver(sdata)) |
324 | return -EIO; | ||
319 | 325 | ||
320 | trace_drv_hw_scan(local, sdata); | 326 | trace_drv_hw_scan(local, sdata); |
321 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); | 327 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
@@ -328,7 +334,8 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | |||
328 | { | 334 | { |
329 | might_sleep(); | 335 | might_sleep(); |
330 | 336 | ||
331 | check_sdata_in_driver(sdata); | 337 | if (!check_sdata_in_driver(sdata)) |
338 | return; | ||
332 | 339 | ||
333 | trace_drv_cancel_hw_scan(local, sdata); | 340 | trace_drv_cancel_hw_scan(local, sdata); |
334 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | 341 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); |
@@ -339,13 +346,14 @@ static inline int | |||
339 | drv_sched_scan_start(struct ieee80211_local *local, | 346 | drv_sched_scan_start(struct ieee80211_local *local, |
340 | struct ieee80211_sub_if_data *sdata, | 347 | struct ieee80211_sub_if_data *sdata, |
341 | struct cfg80211_sched_scan_request *req, | 348 | struct cfg80211_sched_scan_request *req, |
342 | struct ieee80211_sched_scan_ies *ies) | 349 | struct ieee80211_scan_ies *ies) |
343 | { | 350 | { |
344 | int ret; | 351 | int ret; |
345 | 352 | ||
346 | might_sleep(); | 353 | might_sleep(); |
347 | 354 | ||
348 | check_sdata_in_driver(sdata); | 355 | if (!check_sdata_in_driver(sdata)) |
356 | return -EIO; | ||
349 | 357 | ||
350 | trace_drv_sched_scan_start(local, sdata); | 358 | trace_drv_sched_scan_start(local, sdata); |
351 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, | 359 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, |
@@ -354,16 +362,21 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
354 | return ret; | 362 | return ret; |
355 | } | 363 | } |
356 | 364 | ||
357 | static inline void drv_sched_scan_stop(struct ieee80211_local *local, | 365 | static inline int drv_sched_scan_stop(struct ieee80211_local *local, |
358 | struct ieee80211_sub_if_data *sdata) | 366 | struct ieee80211_sub_if_data *sdata) |
359 | { | 367 | { |
368 | int ret; | ||
369 | |||
360 | might_sleep(); | 370 | might_sleep(); |
361 | 371 | ||
362 | check_sdata_in_driver(sdata); | 372 | if (!check_sdata_in_driver(sdata)) |
373 | return -EIO; | ||
363 | 374 | ||
364 | trace_drv_sched_scan_stop(local, sdata); | 375 | trace_drv_sched_scan_stop(local, sdata); |
365 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 376 | ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
366 | trace_drv_return_void(local); | 377 | trace_drv_return_int(local, ret); |
378 | |||
379 | return ret; | ||
367 | } | 380 | } |
368 | 381 | ||
369 | static inline void drv_sw_scan_start(struct ieee80211_local *local) | 382 | static inline void drv_sw_scan_start(struct ieee80211_local *local) |
@@ -458,7 +471,8 @@ static inline void drv_sta_notify(struct ieee80211_local *local, | |||
458 | struct ieee80211_sta *sta) | 471 | struct ieee80211_sta *sta) |
459 | { | 472 | { |
460 | sdata = get_bss_sdata(sdata); | 473 | sdata = get_bss_sdata(sdata); |
461 | check_sdata_in_driver(sdata); | 474 | if (!check_sdata_in_driver(sdata)) |
475 | return; | ||
462 | 476 | ||
463 | trace_drv_sta_notify(local, sdata, cmd, sta); | 477 | trace_drv_sta_notify(local, sdata, cmd, sta); |
464 | if (local->ops->sta_notify) | 478 | if (local->ops->sta_notify) |
@@ -475,7 +489,8 @@ static inline int drv_sta_add(struct ieee80211_local *local, | |||
475 | might_sleep(); | 489 | might_sleep(); |
476 | 490 | ||
477 | sdata = get_bss_sdata(sdata); | 491 | sdata = get_bss_sdata(sdata); |
478 | check_sdata_in_driver(sdata); | 492 | if (!check_sdata_in_driver(sdata)) |
493 | return -EIO; | ||
479 | 494 | ||
480 | trace_drv_sta_add(local, sdata, sta); | 495 | trace_drv_sta_add(local, sdata, sta); |
481 | if (local->ops->sta_add) | 496 | if (local->ops->sta_add) |
@@ -493,7 +508,8 @@ static inline void drv_sta_remove(struct ieee80211_local *local, | |||
493 | might_sleep(); | 508 | might_sleep(); |
494 | 509 | ||
495 | sdata = get_bss_sdata(sdata); | 510 | sdata = get_bss_sdata(sdata); |
496 | check_sdata_in_driver(sdata); | 511 | if (!check_sdata_in_driver(sdata)) |
512 | return; | ||
497 | 513 | ||
498 | trace_drv_sta_remove(local, sdata, sta); | 514 | trace_drv_sta_remove(local, sdata, sta); |
499 | if (local->ops->sta_remove) | 515 | if (local->ops->sta_remove) |
@@ -511,7 +527,8 @@ static inline void drv_sta_add_debugfs(struct ieee80211_local *local, | |||
511 | might_sleep(); | 527 | might_sleep(); |
512 | 528 | ||
513 | sdata = get_bss_sdata(sdata); | 529 | sdata = get_bss_sdata(sdata); |
514 | check_sdata_in_driver(sdata); | 530 | if (!check_sdata_in_driver(sdata)) |
531 | return; | ||
515 | 532 | ||
516 | if (local->ops->sta_add_debugfs) | 533 | if (local->ops->sta_add_debugfs) |
517 | local->ops->sta_add_debugfs(&local->hw, &sdata->vif, | 534 | local->ops->sta_add_debugfs(&local->hw, &sdata->vif, |
@@ -541,7 +558,8 @@ static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, | |||
541 | might_sleep(); | 558 | might_sleep(); |
542 | 559 | ||
543 | sdata = get_bss_sdata(sdata); | 560 | sdata = get_bss_sdata(sdata); |
544 | check_sdata_in_driver(sdata); | 561 | if (!check_sdata_in_driver(sdata)) |
562 | return; | ||
545 | 563 | ||
546 | trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); | 564 | trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); |
547 | if (local->ops->sta_pre_rcu_remove) | 565 | if (local->ops->sta_pre_rcu_remove) |
@@ -562,7 +580,8 @@ int drv_sta_state(struct ieee80211_local *local, | |||
562 | might_sleep(); | 580 | might_sleep(); |
563 | 581 | ||
564 | sdata = get_bss_sdata(sdata); | 582 | sdata = get_bss_sdata(sdata); |
565 | check_sdata_in_driver(sdata); | 583 | if (!check_sdata_in_driver(sdata)) |
584 | return -EIO; | ||
566 | 585 | ||
567 | trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); | 586 | trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); |
568 | if (local->ops->sta_state) { | 587 | if (local->ops->sta_state) { |
@@ -586,7 +605,8 @@ static inline void drv_sta_rc_update(struct ieee80211_local *local, | |||
586 | struct ieee80211_sta *sta, u32 changed) | 605 | struct ieee80211_sta *sta, u32 changed) |
587 | { | 606 | { |
588 | sdata = get_bss_sdata(sdata); | 607 | sdata = get_bss_sdata(sdata); |
589 | check_sdata_in_driver(sdata); | 608 | if (!check_sdata_in_driver(sdata)) |
609 | return; | ||
590 | 610 | ||
591 | WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && | 611 | WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && |
592 | (sdata->vif.type != NL80211_IFTYPE_ADHOC && | 612 | (sdata->vif.type != NL80211_IFTYPE_ADHOC && |
@@ -608,7 +628,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local, | |||
608 | 628 | ||
609 | might_sleep(); | 629 | might_sleep(); |
610 | 630 | ||
611 | check_sdata_in_driver(sdata); | 631 | if (!check_sdata_in_driver(sdata)) |
632 | return -EIO; | ||
612 | 633 | ||
613 | trace_drv_conf_tx(local, sdata, ac, params); | 634 | trace_drv_conf_tx(local, sdata, ac, params); |
614 | if (local->ops->conf_tx) | 635 | if (local->ops->conf_tx) |
@@ -625,7 +646,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local, | |||
625 | 646 | ||
626 | might_sleep(); | 647 | might_sleep(); |
627 | 648 | ||
628 | check_sdata_in_driver(sdata); | 649 | if (!check_sdata_in_driver(sdata)) |
650 | return ret; | ||
629 | 651 | ||
630 | trace_drv_get_tsf(local, sdata); | 652 | trace_drv_get_tsf(local, sdata); |
631 | if (local->ops->get_tsf) | 653 | if (local->ops->get_tsf) |
@@ -640,7 +662,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local, | |||
640 | { | 662 | { |
641 | might_sleep(); | 663 | might_sleep(); |
642 | 664 | ||
643 | check_sdata_in_driver(sdata); | 665 | if (!check_sdata_in_driver(sdata)) |
666 | return; | ||
644 | 667 | ||
645 | trace_drv_set_tsf(local, sdata, tsf); | 668 | trace_drv_set_tsf(local, sdata, tsf); |
646 | if (local->ops->set_tsf) | 669 | if (local->ops->set_tsf) |
@@ -653,7 +676,8 @@ static inline void drv_reset_tsf(struct ieee80211_local *local, | |||
653 | { | 676 | { |
654 | might_sleep(); | 677 | might_sleep(); |
655 | 678 | ||
656 | check_sdata_in_driver(sdata); | 679 | if (!check_sdata_in_driver(sdata)) |
680 | return; | ||
657 | 681 | ||
658 | trace_drv_reset_tsf(local, sdata); | 682 | trace_drv_reset_tsf(local, sdata); |
659 | if (local->ops->reset_tsf) | 683 | if (local->ops->reset_tsf) |
@@ -685,7 +709,8 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
685 | might_sleep(); | 709 | might_sleep(); |
686 | 710 | ||
687 | sdata = get_bss_sdata(sdata); | 711 | sdata = get_bss_sdata(sdata); |
688 | check_sdata_in_driver(sdata); | 712 | if (!check_sdata_in_driver(sdata)) |
713 | return -EIO; | ||
689 | 714 | ||
690 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); | 715 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); |
691 | 716 | ||
@@ -722,13 +747,19 @@ static inline void drv_rfkill_poll(struct ieee80211_local *local) | |||
722 | } | 747 | } |
723 | 748 | ||
724 | static inline void drv_flush(struct ieee80211_local *local, | 749 | static inline void drv_flush(struct ieee80211_local *local, |
750 | struct ieee80211_sub_if_data *sdata, | ||
725 | u32 queues, bool drop) | 751 | u32 queues, bool drop) |
726 | { | 752 | { |
753 | struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL; | ||
754 | |||
727 | might_sleep(); | 755 | might_sleep(); |
728 | 756 | ||
757 | if (sdata && !check_sdata_in_driver(sdata)) | ||
758 | return; | ||
759 | |||
729 | trace_drv_flush(local, queues, drop); | 760 | trace_drv_flush(local, queues, drop); |
730 | if (local->ops->flush) | 761 | if (local->ops->flush) |
731 | local->ops->flush(&local->hw, queues, drop); | 762 | local->ops->flush(&local->hw, vif, queues, drop); |
732 | trace_drv_return_void(local); | 763 | trace_drv_return_void(local); |
733 | } | 764 | } |
734 | 765 | ||
@@ -844,7 +875,8 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local, | |||
844 | 875 | ||
845 | might_sleep(); | 876 | might_sleep(); |
846 | 877 | ||
847 | check_sdata_in_driver(sdata); | 878 | if (!check_sdata_in_driver(sdata)) |
879 | return -EIO; | ||
848 | 880 | ||
849 | trace_drv_set_bitrate_mask(local, sdata, mask); | 881 | trace_drv_set_bitrate_mask(local, sdata, mask); |
850 | if (local->ops->set_bitrate_mask) | 882 | if (local->ops->set_bitrate_mask) |
@@ -859,7 +891,8 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
859 | struct ieee80211_sub_if_data *sdata, | 891 | struct ieee80211_sub_if_data *sdata, |
860 | struct cfg80211_gtk_rekey_data *data) | 892 | struct cfg80211_gtk_rekey_data *data) |
861 | { | 893 | { |
862 | check_sdata_in_driver(sdata); | 894 | if (!check_sdata_in_driver(sdata)) |
895 | return; | ||
863 | 896 | ||
864 | trace_drv_set_rekey_data(local, sdata, data); | 897 | trace_drv_set_rekey_data(local, sdata, data); |
865 | if (local->ops->set_rekey_data) | 898 | if (local->ops->set_rekey_data) |
@@ -927,7 +960,8 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | |||
927 | { | 960 | { |
928 | might_sleep(); | 961 | might_sleep(); |
929 | 962 | ||
930 | check_sdata_in_driver(sdata); | 963 | if (!check_sdata_in_driver(sdata)) |
964 | return; | ||
931 | WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); | 965 | WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); |
932 | 966 | ||
933 | trace_drv_mgd_prepare_tx(local, sdata); | 967 | trace_drv_mgd_prepare_tx(local, sdata); |
@@ -936,6 +970,22 @@ static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | |||
936 | trace_drv_return_void(local); | 970 | trace_drv_return_void(local); |
937 | } | 971 | } |
938 | 972 | ||
973 | static inline void | ||
974 | drv_mgd_protect_tdls_discover(struct ieee80211_local *local, | ||
975 | struct ieee80211_sub_if_data *sdata) | ||
976 | { | ||
977 | might_sleep(); | ||
978 | |||
979 | if (!check_sdata_in_driver(sdata)) | ||
980 | return; | ||
981 | WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); | ||
982 | |||
983 | trace_drv_mgd_protect_tdls_discover(local, sdata); | ||
984 | if (local->ops->mgd_protect_tdls_discover) | ||
985 | local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); | ||
986 | trace_drv_return_void(local); | ||
987 | } | ||
988 | |||
939 | static inline int drv_add_chanctx(struct ieee80211_local *local, | 989 | static inline int drv_add_chanctx(struct ieee80211_local *local, |
940 | struct ieee80211_chanctx *ctx) | 990 | struct ieee80211_chanctx *ctx) |
941 | { | 991 | { |
@@ -954,6 +1004,9 @@ static inline int drv_add_chanctx(struct ieee80211_local *local, | |||
954 | static inline void drv_remove_chanctx(struct ieee80211_local *local, | 1004 | static inline void drv_remove_chanctx(struct ieee80211_local *local, |
955 | struct ieee80211_chanctx *ctx) | 1005 | struct ieee80211_chanctx *ctx) |
956 | { | 1006 | { |
1007 | if (WARN_ON(!ctx->driver_present)) | ||
1008 | return; | ||
1009 | |||
957 | trace_drv_remove_chanctx(local, ctx); | 1010 | trace_drv_remove_chanctx(local, ctx); |
958 | if (local->ops->remove_chanctx) | 1011 | if (local->ops->remove_chanctx) |
959 | local->ops->remove_chanctx(&local->hw, &ctx->conf); | 1012 | local->ops->remove_chanctx(&local->hw, &ctx->conf); |
@@ -979,7 +1032,8 @@ static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, | |||
979 | { | 1032 | { |
980 | int ret = 0; | 1033 | int ret = 0; |
981 | 1034 | ||
982 | check_sdata_in_driver(sdata); | 1035 | if (!check_sdata_in_driver(sdata)) |
1036 | return -EIO; | ||
983 | 1037 | ||
984 | trace_drv_assign_vif_chanctx(local, sdata, ctx); | 1038 | trace_drv_assign_vif_chanctx(local, sdata, ctx); |
985 | if (local->ops->assign_vif_chanctx) { | 1039 | if (local->ops->assign_vif_chanctx) { |
@@ -997,7 +1051,8 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, | |||
997 | struct ieee80211_sub_if_data *sdata, | 1051 | struct ieee80211_sub_if_data *sdata, |
998 | struct ieee80211_chanctx *ctx) | 1052 | struct ieee80211_chanctx *ctx) |
999 | { | 1053 | { |
1000 | check_sdata_in_driver(sdata); | 1054 | if (!check_sdata_in_driver(sdata)) |
1055 | return; | ||
1001 | 1056 | ||
1002 | trace_drv_unassign_vif_chanctx(local, sdata, ctx); | 1057 | trace_drv_unassign_vif_chanctx(local, sdata, ctx); |
1003 | if (local->ops->unassign_vif_chanctx) { | 1058 | if (local->ops->unassign_vif_chanctx) { |
@@ -1009,12 +1064,66 @@ static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, | |||
1009 | trace_drv_return_void(local); | 1064 | trace_drv_return_void(local); |
1010 | } | 1065 | } |
1011 | 1066 | ||
1067 | static inline int | ||
1068 | drv_switch_vif_chanctx(struct ieee80211_local *local, | ||
1069 | struct ieee80211_vif_chanctx_switch *vifs, | ||
1070 | int n_vifs, | ||
1071 | enum ieee80211_chanctx_switch_mode mode) | ||
1072 | { | ||
1073 | int ret = 0; | ||
1074 | int i; | ||
1075 | |||
1076 | if (!local->ops->switch_vif_chanctx) | ||
1077 | return -EOPNOTSUPP; | ||
1078 | |||
1079 | for (i = 0; i < n_vifs; i++) { | ||
1080 | struct ieee80211_chanctx *new_ctx = | ||
1081 | container_of(vifs[i].new_ctx, | ||
1082 | struct ieee80211_chanctx, | ||
1083 | conf); | ||
1084 | struct ieee80211_chanctx *old_ctx = | ||
1085 | container_of(vifs[i].old_ctx, | ||
1086 | struct ieee80211_chanctx, | ||
1087 | conf); | ||
1088 | |||
1089 | WARN_ON_ONCE(!old_ctx->driver_present); | ||
1090 | WARN_ON_ONCE((mode == CHANCTX_SWMODE_SWAP_CONTEXTS && | ||
1091 | new_ctx->driver_present) || | ||
1092 | (mode == CHANCTX_SWMODE_REASSIGN_VIF && | ||
1093 | !new_ctx->driver_present)); | ||
1094 | } | ||
1095 | |||
1096 | trace_drv_switch_vif_chanctx(local, vifs, n_vifs, mode); | ||
1097 | ret = local->ops->switch_vif_chanctx(&local->hw, | ||
1098 | vifs, n_vifs, mode); | ||
1099 | trace_drv_return_int(local, ret); | ||
1100 | |||
1101 | if (!ret && mode == CHANCTX_SWMODE_SWAP_CONTEXTS) { | ||
1102 | for (i = 0; i < n_vifs; i++) { | ||
1103 | struct ieee80211_chanctx *new_ctx = | ||
1104 | container_of(vifs[i].new_ctx, | ||
1105 | struct ieee80211_chanctx, | ||
1106 | conf); | ||
1107 | struct ieee80211_chanctx *old_ctx = | ||
1108 | container_of(vifs[i].old_ctx, | ||
1109 | struct ieee80211_chanctx, | ||
1110 | conf); | ||
1111 | |||
1112 | new_ctx->driver_present = true; | ||
1113 | old_ctx->driver_present = false; | ||
1114 | } | ||
1115 | } | ||
1116 | |||
1117 | return ret; | ||
1118 | } | ||
1119 | |||
1012 | static inline int drv_start_ap(struct ieee80211_local *local, | 1120 | static inline int drv_start_ap(struct ieee80211_local *local, |
1013 | struct ieee80211_sub_if_data *sdata) | 1121 | struct ieee80211_sub_if_data *sdata) |
1014 | { | 1122 | { |
1015 | int ret = 0; | 1123 | int ret = 0; |
1016 | 1124 | ||
1017 | check_sdata_in_driver(sdata); | 1125 | if (!check_sdata_in_driver(sdata)) |
1126 | return -EIO; | ||
1018 | 1127 | ||
1019 | trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); | 1128 | trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); |
1020 | if (local->ops->start_ap) | 1129 | if (local->ops->start_ap) |
@@ -1026,7 +1135,8 @@ static inline int drv_start_ap(struct ieee80211_local *local, | |||
1026 | static inline void drv_stop_ap(struct ieee80211_local *local, | 1135 | static inline void drv_stop_ap(struct ieee80211_local *local, |
1027 | struct ieee80211_sub_if_data *sdata) | 1136 | struct ieee80211_sub_if_data *sdata) |
1028 | { | 1137 | { |
1029 | check_sdata_in_driver(sdata); | 1138 | if (!check_sdata_in_driver(sdata)) |
1139 | return; | ||
1030 | 1140 | ||
1031 | trace_drv_stop_ap(local, sdata); | 1141 | trace_drv_stop_ap(local, sdata); |
1032 | if (local->ops->stop_ap) | 1142 | if (local->ops->stop_ap) |
@@ -1049,7 +1159,8 @@ drv_set_default_unicast_key(struct ieee80211_local *local, | |||
1049 | struct ieee80211_sub_if_data *sdata, | 1159 | struct ieee80211_sub_if_data *sdata, |
1050 | int key_idx) | 1160 | int key_idx) |
1051 | { | 1161 | { |
1052 | check_sdata_in_driver(sdata); | 1162 | if (!check_sdata_in_driver(sdata)) |
1163 | return; | ||
1053 | 1164 | ||
1054 | WARN_ON_ONCE(key_idx < -1 || key_idx > 3); | 1165 | WARN_ON_ONCE(key_idx < -1 || key_idx > 3); |
1055 | 1166 | ||
@@ -1091,7 +1202,8 @@ static inline int drv_join_ibss(struct ieee80211_local *local, | |||
1091 | int ret = 0; | 1202 | int ret = 0; |
1092 | 1203 | ||
1093 | might_sleep(); | 1204 | might_sleep(); |
1094 | check_sdata_in_driver(sdata); | 1205 | if (!check_sdata_in_driver(sdata)) |
1206 | return -EIO; | ||
1095 | 1207 | ||
1096 | trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); | 1208 | trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); |
1097 | if (local->ops->join_ibss) | 1209 | if (local->ops->join_ibss) |
@@ -1104,7 +1216,8 @@ static inline void drv_leave_ibss(struct ieee80211_local *local, | |||
1104 | struct ieee80211_sub_if_data *sdata) | 1216 | struct ieee80211_sub_if_data *sdata) |
1105 | { | 1217 | { |
1106 | might_sleep(); | 1218 | might_sleep(); |
1107 | check_sdata_in_driver(sdata); | 1219 | if (!check_sdata_in_driver(sdata)) |
1220 | return; | ||
1108 | 1221 | ||
1109 | trace_drv_leave_ibss(local, sdata); | 1222 | trace_drv_leave_ibss(local, sdata); |
1110 | if (local->ops->leave_ibss) | 1223 | if (local->ops->leave_ibss) |
@@ -1112,4 +1225,17 @@ static inline void drv_leave_ibss(struct ieee80211_local *local, | |||
1112 | trace_drv_return_void(local); | 1225 | trace_drv_return_void(local); |
1113 | } | 1226 | } |
1114 | 1227 | ||
1228 | static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, | ||
1229 | struct ieee80211_sta *sta) | ||
1230 | { | ||
1231 | u32 ret = 0; | ||
1232 | |||
1233 | trace_drv_get_expected_throughput(sta); | ||
1234 | if (local->ops->get_expected_throughput) | ||
1235 | ret = local->ops->get_expected_throughput(sta); | ||
1236 | trace_drv_return_u32(local, ret); | ||
1237 | |||
1238 | return ret; | ||
1239 | } | ||
1240 | |||
1115 | #endif /* __MAC80211_DRIVER_OPS */ | 1241 | #endif /* __MAC80211_DRIVER_OPS */ |