diff options
Diffstat (limited to 'net/mac80211/driver-ops.h')
-rw-r--r-- | net/mac80211/driver-ops.h | 90 |
1 files changed, 84 insertions, 6 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 5f165d7eb2db..e8960ae39861 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -5,11 +5,34 @@ | |||
5 | #include "ieee80211_i.h" | 5 | #include "ieee80211_i.h" |
6 | #include "driver-trace.h" | 6 | #include "driver-trace.h" |
7 | 7 | ||
8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) | ||
9 | { | ||
10 | WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER)); | ||
11 | } | ||
12 | |||
13 | static inline struct ieee80211_sub_if_data * | ||
14 | get_bss_sdata(struct ieee80211_sub_if_data *sdata) | ||
15 | { | ||
16 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
17 | sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, | ||
18 | u.ap); | ||
19 | |||
20 | return sdata; | ||
21 | } | ||
22 | |||
8 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) | 23 | static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) |
9 | { | 24 | { |
10 | local->ops->tx(&local->hw, skb); | 25 | local->ops->tx(&local->hw, skb); |
11 | } | 26 | } |
12 | 27 | ||
28 | static inline void drv_tx_frags(struct ieee80211_local *local, | ||
29 | struct ieee80211_vif *vif, | ||
30 | struct ieee80211_sta *sta, | ||
31 | struct sk_buff_head *skbs) | ||
32 | { | ||
33 | local->ops->tx_frags(&local->hw, vif, sta, skbs); | ||
34 | } | ||
35 | |||
13 | static inline int drv_start(struct ieee80211_local *local) | 36 | static inline int drv_start(struct ieee80211_local *local) |
14 | { | 37 | { |
15 | int ret; | 38 | int ret; |
@@ -69,15 +92,23 @@ static inline int drv_resume(struct ieee80211_local *local) | |||
69 | #endif | 92 | #endif |
70 | 93 | ||
71 | static inline int drv_add_interface(struct ieee80211_local *local, | 94 | static inline int drv_add_interface(struct ieee80211_local *local, |
72 | struct ieee80211_vif *vif) | 95 | struct ieee80211_sub_if_data *sdata) |
73 | { | 96 | { |
74 | int ret; | 97 | int ret; |
75 | 98 | ||
76 | might_sleep(); | 99 | might_sleep(); |
77 | 100 | ||
78 | trace_drv_add_interface(local, vif_to_sdata(vif)); | 101 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
79 | ret = local->ops->add_interface(&local->hw, vif); | 102 | sdata->vif.type == NL80211_IFTYPE_MONITOR)) |
103 | return -EINVAL; | ||
104 | |||
105 | trace_drv_add_interface(local, sdata); | ||
106 | ret = local->ops->add_interface(&local->hw, &sdata->vif); | ||
80 | trace_drv_return_int(local, ret); | 107 | trace_drv_return_int(local, ret); |
108 | |||
109 | if (ret == 0) | ||
110 | sdata->flags |= IEEE80211_SDATA_IN_DRIVER; | ||
111 | |||
81 | return ret; | 112 | return ret; |
82 | } | 113 | } |
83 | 114 | ||
@@ -89,6 +120,8 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
89 | 120 | ||
90 | might_sleep(); | 121 | might_sleep(); |
91 | 122 | ||
123 | check_sdata_in_driver(sdata); | ||
124 | |||
92 | trace_drv_change_interface(local, sdata, type, p2p); | 125 | trace_drv_change_interface(local, sdata, type, p2p); |
93 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); | 126 | ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); |
94 | trace_drv_return_int(local, ret); | 127 | trace_drv_return_int(local, ret); |
@@ -96,12 +129,15 @@ static inline int drv_change_interface(struct ieee80211_local *local, | |||
96 | } | 129 | } |
97 | 130 | ||
98 | static inline void drv_remove_interface(struct ieee80211_local *local, | 131 | static inline void drv_remove_interface(struct ieee80211_local *local, |
99 | struct ieee80211_vif *vif) | 132 | struct ieee80211_sub_if_data *sdata) |
100 | { | 133 | { |
101 | might_sleep(); | 134 | might_sleep(); |
102 | 135 | ||
103 | trace_drv_remove_interface(local, vif_to_sdata(vif)); | 136 | check_sdata_in_driver(sdata); |
104 | local->ops->remove_interface(&local->hw, vif); | 137 | |
138 | trace_drv_remove_interface(local, sdata); | ||
139 | local->ops->remove_interface(&local->hw, &sdata->vif); | ||
140 | sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; | ||
105 | trace_drv_return_void(local); | 141 | trace_drv_return_void(local); |
106 | } | 142 | } |
107 | 143 | ||
@@ -124,6 +160,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
124 | { | 160 | { |
125 | might_sleep(); | 161 | might_sleep(); |
126 | 162 | ||
163 | check_sdata_in_driver(sdata); | ||
164 | |||
127 | trace_drv_bss_info_changed(local, sdata, info, changed); | 165 | trace_drv_bss_info_changed(local, sdata, info, changed); |
128 | if (local->ops->bss_info_changed) | 166 | if (local->ops->bss_info_changed) |
129 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); | 167 | local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); |
@@ -139,6 +177,8 @@ static inline int drv_tx_sync(struct ieee80211_local *local, | |||
139 | 177 | ||
140 | might_sleep(); | 178 | might_sleep(); |
141 | 179 | ||
180 | check_sdata_in_driver(sdata); | ||
181 | |||
142 | trace_drv_tx_sync(local, sdata, bssid, type); | 182 | trace_drv_tx_sync(local, sdata, bssid, type); |
143 | if (local->ops->tx_sync) | 183 | if (local->ops->tx_sync) |
144 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, | 184 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, |
@@ -154,6 +194,8 @@ static inline void drv_finish_tx_sync(struct ieee80211_local *local, | |||
154 | { | 194 | { |
155 | might_sleep(); | 195 | might_sleep(); |
156 | 196 | ||
197 | check_sdata_in_driver(sdata); | ||
198 | |||
157 | trace_drv_finish_tx_sync(local, sdata, bssid, type); | 199 | trace_drv_finish_tx_sync(local, sdata, bssid, type); |
158 | if (local->ops->finish_tx_sync) | 200 | if (local->ops->finish_tx_sync) |
159 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, | 201 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, |
@@ -211,6 +253,8 @@ static inline int drv_set_key(struct ieee80211_local *local, | |||
211 | 253 | ||
212 | might_sleep(); | 254 | might_sleep(); |
213 | 255 | ||
256 | check_sdata_in_driver(sdata); | ||
257 | |||
214 | trace_drv_set_key(local, cmd, sdata, sta, key); | 258 | trace_drv_set_key(local, cmd, sdata, sta, key); |
215 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); | 259 | ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); |
216 | trace_drv_return_int(local, ret); | 260 | trace_drv_return_int(local, ret); |
@@ -228,6 +272,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local, | |||
228 | if (sta) | 272 | if (sta) |
229 | ista = &sta->sta; | 273 | ista = &sta->sta; |
230 | 274 | ||
275 | check_sdata_in_driver(sdata); | ||
276 | |||
231 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); | 277 | trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); |
232 | if (local->ops->update_tkip_key) | 278 | if (local->ops->update_tkip_key) |
233 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, | 279 | local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, |
@@ -243,6 +289,8 @@ static inline int drv_hw_scan(struct ieee80211_local *local, | |||
243 | 289 | ||
244 | might_sleep(); | 290 | might_sleep(); |
245 | 291 | ||
292 | check_sdata_in_driver(sdata); | ||
293 | |||
246 | trace_drv_hw_scan(local, sdata); | 294 | trace_drv_hw_scan(local, sdata); |
247 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); | 295 | ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); |
248 | trace_drv_return_int(local, ret); | 296 | trace_drv_return_int(local, ret); |
@@ -254,6 +302,8 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local, | |||
254 | { | 302 | { |
255 | might_sleep(); | 303 | might_sleep(); |
256 | 304 | ||
305 | check_sdata_in_driver(sdata); | ||
306 | |||
257 | trace_drv_cancel_hw_scan(local, sdata); | 307 | trace_drv_cancel_hw_scan(local, sdata); |
258 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); | 308 | local->ops->cancel_hw_scan(&local->hw, &sdata->vif); |
259 | trace_drv_return_void(local); | 309 | trace_drv_return_void(local); |
@@ -269,6 +319,8 @@ drv_sched_scan_start(struct ieee80211_local *local, | |||
269 | 319 | ||
270 | might_sleep(); | 320 | might_sleep(); |
271 | 321 | ||
322 | check_sdata_in_driver(sdata); | ||
323 | |||
272 | trace_drv_sched_scan_start(local, sdata); | 324 | trace_drv_sched_scan_start(local, sdata); |
273 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, | 325 | ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, |
274 | req, ies); | 326 | req, ies); |
@@ -281,6 +333,8 @@ static inline void drv_sched_scan_stop(struct ieee80211_local *local, | |||
281 | { | 333 | { |
282 | might_sleep(); | 334 | might_sleep(); |
283 | 335 | ||
336 | check_sdata_in_driver(sdata); | ||
337 | |||
284 | trace_drv_sched_scan_stop(local, sdata); | 338 | trace_drv_sched_scan_stop(local, sdata); |
285 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); | 339 | local->ops->sched_scan_stop(&local->hw, &sdata->vif); |
286 | trace_drv_return_void(local); | 340 | trace_drv_return_void(local); |
@@ -377,6 +431,9 @@ static inline void drv_sta_notify(struct ieee80211_local *local, | |||
377 | enum sta_notify_cmd cmd, | 431 | enum sta_notify_cmd cmd, |
378 | struct ieee80211_sta *sta) | 432 | struct ieee80211_sta *sta) |
379 | { | 433 | { |
434 | sdata = get_bss_sdata(sdata); | ||
435 | check_sdata_in_driver(sdata); | ||
436 | |||
380 | trace_drv_sta_notify(local, sdata, cmd, sta); | 437 | trace_drv_sta_notify(local, sdata, cmd, sta); |
381 | if (local->ops->sta_notify) | 438 | if (local->ops->sta_notify) |
382 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); | 439 | local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); |
@@ -391,6 +448,9 @@ static inline int drv_sta_add(struct ieee80211_local *local, | |||
391 | 448 | ||
392 | might_sleep(); | 449 | might_sleep(); |
393 | 450 | ||
451 | sdata = get_bss_sdata(sdata); | ||
452 | check_sdata_in_driver(sdata); | ||
453 | |||
394 | trace_drv_sta_add(local, sdata, sta); | 454 | trace_drv_sta_add(local, sdata, sta); |
395 | if (local->ops->sta_add) | 455 | if (local->ops->sta_add) |
396 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); | 456 | ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); |
@@ -406,6 +466,9 @@ static inline void drv_sta_remove(struct ieee80211_local *local, | |||
406 | { | 466 | { |
407 | might_sleep(); | 467 | might_sleep(); |
408 | 468 | ||
469 | sdata = get_bss_sdata(sdata); | ||
470 | check_sdata_in_driver(sdata); | ||
471 | |||
409 | trace_drv_sta_remove(local, sdata, sta); | 472 | trace_drv_sta_remove(local, sdata, sta); |
410 | if (local->ops->sta_remove) | 473 | if (local->ops->sta_remove) |
411 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); | 474 | local->ops->sta_remove(&local->hw, &sdata->vif, sta); |
@@ -421,6 +484,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local, | |||
421 | 484 | ||
422 | might_sleep(); | 485 | might_sleep(); |
423 | 486 | ||
487 | check_sdata_in_driver(sdata); | ||
488 | |||
424 | trace_drv_conf_tx(local, sdata, queue, params); | 489 | trace_drv_conf_tx(local, sdata, queue, params); |
425 | if (local->ops->conf_tx) | 490 | if (local->ops->conf_tx) |
426 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, | 491 | ret = local->ops->conf_tx(&local->hw, &sdata->vif, |
@@ -436,6 +501,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local, | |||
436 | 501 | ||
437 | might_sleep(); | 502 | might_sleep(); |
438 | 503 | ||
504 | check_sdata_in_driver(sdata); | ||
505 | |||
439 | trace_drv_get_tsf(local, sdata); | 506 | trace_drv_get_tsf(local, sdata); |
440 | if (local->ops->get_tsf) | 507 | if (local->ops->get_tsf) |
441 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); | 508 | ret = local->ops->get_tsf(&local->hw, &sdata->vif); |
@@ -449,6 +516,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local, | |||
449 | { | 516 | { |
450 | might_sleep(); | 517 | might_sleep(); |
451 | 518 | ||
519 | check_sdata_in_driver(sdata); | ||
520 | |||
452 | trace_drv_set_tsf(local, sdata, tsf); | 521 | trace_drv_set_tsf(local, sdata, tsf); |
453 | if (local->ops->set_tsf) | 522 | if (local->ops->set_tsf) |
454 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); | 523 | local->ops->set_tsf(&local->hw, &sdata->vif, tsf); |
@@ -460,6 +529,8 @@ static inline void drv_reset_tsf(struct ieee80211_local *local, | |||
460 | { | 529 | { |
461 | might_sleep(); | 530 | might_sleep(); |
462 | 531 | ||
532 | check_sdata_in_driver(sdata); | ||
533 | |||
463 | trace_drv_reset_tsf(local, sdata); | 534 | trace_drv_reset_tsf(local, sdata); |
464 | if (local->ops->reset_tsf) | 535 | if (local->ops->reset_tsf) |
465 | local->ops->reset_tsf(&local->hw, &sdata->vif); | 536 | local->ops->reset_tsf(&local->hw, &sdata->vif); |
@@ -489,6 +560,9 @@ static inline int drv_ampdu_action(struct ieee80211_local *local, | |||
489 | 560 | ||
490 | might_sleep(); | 561 | might_sleep(); |
491 | 562 | ||
563 | sdata = get_bss_sdata(sdata); | ||
564 | check_sdata_in_driver(sdata); | ||
565 | |||
492 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); | 566 | trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); |
493 | 567 | ||
494 | if (local->ops->ampdu_action) | 568 | if (local->ops->ampdu_action) |
@@ -644,6 +718,8 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local, | |||
644 | 718 | ||
645 | might_sleep(); | 719 | might_sleep(); |
646 | 720 | ||
721 | check_sdata_in_driver(sdata); | ||
722 | |||
647 | trace_drv_set_bitrate_mask(local, sdata, mask); | 723 | trace_drv_set_bitrate_mask(local, sdata, mask); |
648 | if (local->ops->set_bitrate_mask) | 724 | if (local->ops->set_bitrate_mask) |
649 | ret = local->ops->set_bitrate_mask(&local->hw, | 725 | ret = local->ops->set_bitrate_mask(&local->hw, |
@@ -657,6 +733,8 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local, | |||
657 | struct ieee80211_sub_if_data *sdata, | 733 | struct ieee80211_sub_if_data *sdata, |
658 | struct cfg80211_gtk_rekey_data *data) | 734 | struct cfg80211_gtk_rekey_data *data) |
659 | { | 735 | { |
736 | check_sdata_in_driver(sdata); | ||
737 | |||
660 | trace_drv_set_rekey_data(local, sdata, data); | 738 | trace_drv_set_rekey_data(local, sdata, data); |
661 | if (local->ops->set_rekey_data) | 739 | if (local->ops->set_rekey_data) |
662 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); | 740 | local->ops->set_rekey_data(&local->hw, &sdata->vif, data); |