00001 #ifndef __MAC80211_DRIVER_OPS
00002 #define __MAC80211_DRIVER_OPS
00003
00004 #include <net/mac80211.h>
00005 #include "ieee80211_i.h"
00006 #include "driver-trace.h"
00007
00008 static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
00009 {
00010 local->ops->tx(&local->hw, skb);
00011 }
00012
00013 static inline int drv_start(struct ieee80211_local *local)
00014 {
00015 int ret;
00016
00017 might_sleep();
00018
00019 trace_drv_start(local);
00020 local->started = true;
00021 smp_mb();
00022 ret = local->ops->start(&local->hw);
00023 trace_drv_return_int(local, ret);
00024 return ret;
00025 }
00026
00027 static inline void drv_stop(struct ieee80211_local *local)
00028 {
00029 might_sleep();
00030
00031 trace_drv_stop(local);
00032 local->ops->stop(&local->hw);
00033 trace_drv_return_void(local);
00034
00035
00036 tasklet_disable(&local->tasklet);
00037 tasklet_enable(&local->tasklet);
00038
00039 barrier();
00040
00041 local->started = false;
00042 }
00043
00044 #ifdef CONFIG_PM
00045 static inline int drv_suspend(struct ieee80211_local *local,
00046 struct cfg80211_wowlan *wowlan)
00047 {
00048 int ret;
00049
00050 might_sleep();
00051
00052 trace_drv_suspend(local);
00053 ret = local->ops->suspend(&local->hw, wowlan);
00054 trace_drv_return_int(local, ret);
00055 return ret;
00056 }
00057
00058 static inline int drv_resume(struct ieee80211_local *local)
00059 {
00060 int ret;
00061
00062 might_sleep();
00063
00064 trace_drv_resume(local);
00065 ret = local->ops->resume(&local->hw);
00066 trace_drv_return_int(local, ret);
00067 return ret;
00068 }
00069 #endif
00070
00071 static inline int drv_add_interface(struct ieee80211_local *local,
00072 struct ieee80211_vif *vif)
00073 {
00074 int ret;
00075
00076 might_sleep();
00077
00078 trace_drv_add_interface(local, vif_to_sdata(vif));
00079 ret = local->ops->add_interface(&local->hw, vif);
00080 trace_drv_return_int(local, ret);
00081 return ret;
00082 }
00083
00084 static inline int drv_change_interface(struct ieee80211_local *local,
00085 struct ieee80211_sub_if_data *sdata,
00086 enum nl80211_iftype type, bool p2p)
00087 {
00088 int ret;
00089
00090 might_sleep();
00091
00092 trace_drv_change_interface(local, sdata, type, p2p);
00093 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
00094 trace_drv_return_int(local, ret);
00095 return ret;
00096 }
00097
00098 static inline void drv_remove_interface(struct ieee80211_local *local,
00099 struct ieee80211_vif *vif)
00100 {
00101 might_sleep();
00102
00103 trace_drv_remove_interface(local, vif_to_sdata(vif));
00104 local->ops->remove_interface(&local->hw, vif);
00105 trace_drv_return_void(local);
00106 }
00107
00108 static inline int drv_config(struct ieee80211_local *local, u32 changed)
00109 {
00110 int ret;
00111
00112 might_sleep();
00113
00114 trace_drv_config(local, changed);
00115 ret = local->ops->config(&local->hw, changed);
00116 trace_drv_return_int(local, ret);
00117 return ret;
00118 }
00119
00120 static inline void drv_bss_info_changed(struct ieee80211_local *local,
00121 struct ieee80211_sub_if_data *sdata,
00122 struct ieee80211_bss_conf *info,
00123 u32 changed)
00124 {
00125 might_sleep();
00126
00127 trace_drv_bss_info_changed(local, sdata, info, changed);
00128 if (local->ops->bss_info_changed)
00129 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
00130 trace_drv_return_void(local);
00131 }
00132
00133 static inline int drv_tx_sync(struct ieee80211_local *local,
00134 struct ieee80211_sub_if_data *sdata,
00135 const u8 *bssid,
00136 enum ieee80211_tx_sync_type type)
00137 {
00138 int ret = 0;
00139
00140 might_sleep();
00141
00142 trace_drv_tx_sync(local, sdata, bssid, type);
00143 if (local->ops->tx_sync)
00144 ret = local->ops->tx_sync(&local->hw, &sdata->vif,
00145 bssid, type);
00146 trace_drv_return_int(local, ret);
00147 return ret;
00148 }
00149
00150 static inline void drv_finish_tx_sync(struct ieee80211_local *local,
00151 struct ieee80211_sub_if_data *sdata,
00152 const u8 *bssid,
00153 enum ieee80211_tx_sync_type type)
00154 {
00155 might_sleep();
00156
00157 trace_drv_finish_tx_sync(local, sdata, bssid, type);
00158 if (local->ops->finish_tx_sync)
00159 local->ops->finish_tx_sync(&local->hw, &sdata->vif,
00160 bssid, type);
00161 trace_drv_return_void(local);
00162 }
00163
00164 static inline u64 drv_prepare_multicast(struct ieee80211_local *local,
00165 struct netdev_hw_addr_list *mc_list)
00166 {
00167 u64 ret = 0;
00168
00169 trace_drv_prepare_multicast(local, mc_list->count);
00170
00171 if (local->ops->prepare_multicast)
00172 ret = local->ops->prepare_multicast(&local->hw, mc_list);
00173
00174 trace_drv_return_u64(local, ret);
00175
00176 return ret;
00177 }
00178
00179 static inline void drv_configure_filter(struct ieee80211_local *local,
00180 unsigned int changed_flags,
00181 unsigned int *total_flags,
00182 u64 multicast)
00183 {
00184 might_sleep();
00185
00186 trace_drv_configure_filter(local, changed_flags, total_flags,
00187 multicast);
00188 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
00189 multicast);
00190 trace_drv_return_void(local);
00191 }
00192
00193 static inline int drv_set_tim(struct ieee80211_local *local,
00194 struct ieee80211_sta *sta, bool set)
00195 {
00196 int ret = 0;
00197 trace_drv_set_tim(local, sta, set);
00198 if (local->ops->set_tim)
00199 ret = local->ops->set_tim(&local->hw, sta, set);
00200 trace_drv_return_int(local, ret);
00201 return ret;
00202 }
00203
00204 static inline int drv_set_key(struct ieee80211_local *local,
00205 enum set_key_cmd cmd,
00206 struct ieee80211_sub_if_data *sdata,
00207 struct ieee80211_sta *sta,
00208 struct ieee80211_key_conf *key)
00209 {
00210 int ret;
00211
00212 might_sleep();
00213
00214 trace_drv_set_key(local, cmd, sdata, sta, key);
00215 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
00216 trace_drv_return_int(local, ret);
00217 return ret;
00218 }
00219
00220 static inline void drv_update_tkip_key(struct ieee80211_local *local,
00221 struct ieee80211_sub_if_data *sdata,
00222 struct ieee80211_key_conf *conf,
00223 struct sta_info *sta, u32 iv32,
00224 u16 *phase1key)
00225 {
00226 struct ieee80211_sta *ista = NULL;
00227
00228 if (sta)
00229 ista = &sta->sta;
00230
00231 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
00232 if (local->ops->update_tkip_key)
00233 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
00234 ista, iv32, phase1key);
00235 trace_drv_return_void(local);
00236 }
00237
00238 static inline int drv_hw_scan(struct ieee80211_local *local,
00239 struct ieee80211_sub_if_data *sdata,
00240 struct cfg80211_scan_request *req)
00241 {
00242 int ret;
00243
00244 might_sleep();
00245
00246 trace_drv_hw_scan(local, sdata);
00247 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
00248 trace_drv_return_int(local, ret);
00249 return ret;
00250 }
00251
00252 static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
00253 struct ieee80211_sub_if_data *sdata)
00254 {
00255 might_sleep();
00256
00257 trace_drv_cancel_hw_scan(local, sdata);
00258 local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
00259 trace_drv_return_void(local);
00260 }
00261
00262 static inline int
00263 drv_sched_scan_start(struct ieee80211_local *local,
00264 struct ieee80211_sub_if_data *sdata,
00265 struct cfg80211_sched_scan_request *req,
00266 struct ieee80211_sched_scan_ies *ies)
00267 {
00268 int ret;
00269
00270 might_sleep();
00271
00272 trace_drv_sched_scan_start(local, sdata);
00273 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
00274 req, ies);
00275 trace_drv_return_int(local, ret);
00276 return ret;
00277 }
00278
00279 static inline void drv_sched_scan_stop(struct ieee80211_local *local,
00280 struct ieee80211_sub_if_data *sdata)
00281 {
00282 might_sleep();
00283
00284 trace_drv_sched_scan_stop(local, sdata);
00285 local->ops->sched_scan_stop(&local->hw, &sdata->vif);
00286 trace_drv_return_void(local);
00287 }
00288
00289 static inline void drv_sw_scan_start(struct ieee80211_local *local)
00290 {
00291 might_sleep();
00292
00293 trace_drv_sw_scan_start(local);
00294 if (local->ops->sw_scan_start)
00295 local->ops->sw_scan_start(&local->hw);
00296 trace_drv_return_void(local);
00297 }
00298
00299 static inline void drv_sw_scan_complete(struct ieee80211_local *local)
00300 {
00301 might_sleep();
00302
00303 trace_drv_sw_scan_complete(local);
00304 if (local->ops->sw_scan_complete)
00305 local->ops->sw_scan_complete(&local->hw);
00306 trace_drv_return_void(local);
00307 }
00308
00309 static inline int drv_get_stats(struct ieee80211_local *local,
00310 struct ieee80211_low_level_stats *stats)
00311 {
00312 int ret = -EOPNOTSUPP;
00313
00314 might_sleep();
00315
00316 if (local->ops->get_stats)
00317 ret = local->ops->get_stats(&local->hw, stats);
00318 trace_drv_get_stats(local, stats, ret);
00319
00320 return ret;
00321 }
00322
00323 static inline void drv_get_tkip_seq(struct ieee80211_local *local,
00324 u8 hw_key_idx, u32 *iv32, u16 *iv16)
00325 {
00326 if (local->ops->get_tkip_seq)
00327 local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
00328 trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
00329 }
00330
00331 static inline int drv_set_frag_threshold(struct ieee80211_local *local,
00332 u32 value)
00333 {
00334 int ret = 0;
00335
00336 might_sleep();
00337
00338 trace_drv_set_frag_threshold(local, value);
00339 if (local->ops->set_frag_threshold)
00340 ret = local->ops->set_frag_threshold(&local->hw, value);
00341 trace_drv_return_int(local, ret);
00342 return ret;
00343 }
00344
00345 static inline int drv_set_rts_threshold(struct ieee80211_local *local,
00346 u32 value)
00347 {
00348 int ret = 0;
00349
00350 might_sleep();
00351
00352 trace_drv_set_rts_threshold(local, value);
00353 if (local->ops->set_rts_threshold)
00354 ret = local->ops->set_rts_threshold(&local->hw, value);
00355 trace_drv_return_int(local, ret);
00356 return ret;
00357 }
00358
00359 static inline int drv_set_coverage_class(struct ieee80211_local *local,
00360 u8 value)
00361 {
00362 int ret = 0;
00363 might_sleep();
00364
00365 trace_drv_set_coverage_class(local, value);
00366 if (local->ops->set_coverage_class)
00367 local->ops->set_coverage_class(&local->hw, value);
00368 else
00369 ret = -EOPNOTSUPP;
00370
00371 trace_drv_return_int(local, ret);
00372 return ret;
00373 }
00374
00375 static inline void drv_sta_notify(struct ieee80211_local *local,
00376 struct ieee80211_sub_if_data *sdata,
00377 enum sta_notify_cmd cmd,
00378 struct ieee80211_sta *sta)
00379 {
00380 trace_drv_sta_notify(local, sdata, cmd, sta);
00381 if (local->ops->sta_notify)
00382 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
00383 trace_drv_return_void(local);
00384 }
00385
00386 static inline int drv_sta_add(struct ieee80211_local *local,
00387 struct ieee80211_sub_if_data *sdata,
00388 struct ieee80211_sta *sta)
00389 {
00390 int ret = 0;
00391
00392 might_sleep();
00393
00394 trace_drv_sta_add(local, sdata, sta);
00395 if (local->ops->sta_add)
00396 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
00397
00398 trace_drv_return_int(local, ret);
00399
00400 return ret;
00401 }
00402
00403 static inline void drv_sta_remove(struct ieee80211_local *local,
00404 struct ieee80211_sub_if_data *sdata,
00405 struct ieee80211_sta *sta)
00406 {
00407 might_sleep();
00408
00409 trace_drv_sta_remove(local, sdata, sta);
00410 if (local->ops->sta_remove)
00411 local->ops->sta_remove(&local->hw, &sdata->vif, sta);
00412
00413 trace_drv_return_void(local);
00414 }
00415
00416 static inline int drv_conf_tx(struct ieee80211_local *local,
00417 struct ieee80211_sub_if_data *sdata, u16 queue,
00418 const struct ieee80211_tx_queue_params *params)
00419 {
00420 int ret = -EOPNOTSUPP;
00421
00422 might_sleep();
00423
00424 trace_drv_conf_tx(local, sdata, queue, params);
00425 if (local->ops->conf_tx)
00426 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
00427 queue, params);
00428 trace_drv_return_int(local, ret);
00429 return ret;
00430 }
00431
00432 static inline u64 drv_get_tsf(struct ieee80211_local *local,
00433 struct ieee80211_sub_if_data *sdata)
00434 {
00435 u64 ret = -1ULL;
00436
00437 might_sleep();
00438
00439 trace_drv_get_tsf(local, sdata);
00440 if (local->ops->get_tsf)
00441 ret = local->ops->get_tsf(&local->hw, &sdata->vif);
00442 trace_drv_return_u64(local, ret);
00443 return ret;
00444 }
00445
00446 static inline void drv_set_tsf(struct ieee80211_local *local,
00447 struct ieee80211_sub_if_data *sdata,
00448 u64 tsf)
00449 {
00450 might_sleep();
00451
00452 trace_drv_set_tsf(local, sdata, tsf);
00453 if (local->ops->set_tsf)
00454 local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
00455 trace_drv_return_void(local);
00456 }
00457
00458 static inline void drv_reset_tsf(struct ieee80211_local *local,
00459 struct ieee80211_sub_if_data *sdata)
00460 {
00461 might_sleep();
00462
00463 trace_drv_reset_tsf(local, sdata);
00464 if (local->ops->reset_tsf)
00465 local->ops->reset_tsf(&local->hw, &sdata->vif);
00466 trace_drv_return_void(local);
00467 }
00468
00469 static inline int drv_tx_last_beacon(struct ieee80211_local *local)
00470 {
00471 int ret = 0;
00472
00473 might_sleep();
00474
00475 trace_drv_tx_last_beacon(local);
00476 if (local->ops->tx_last_beacon)
00477 ret = local->ops->tx_last_beacon(&local->hw);
00478 trace_drv_return_int(local, ret);
00479 return ret;
00480 }
00481
00482 static inline int drv_ampdu_action(struct ieee80211_local *local,
00483 struct ieee80211_sub_if_data *sdata,
00484 enum ieee80211_ampdu_mlme_action action,
00485 struct ieee80211_sta *sta, u16 tid,
00486 u16 *ssn, u8 buf_size)
00487 {
00488 int ret = -EOPNOTSUPP;
00489
00490 might_sleep();
00491
00492 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
00493
00494 if (local->ops->ampdu_action)
00495 ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action,
00496 sta, tid, ssn, buf_size);
00497
00498 trace_drv_return_int(local, ret);
00499
00500 return ret;
00501 }
00502
00503 static inline int drv_get_survey(struct ieee80211_local *local, int idx,
00504 struct survey_info *survey)
00505 {
00506 int ret = -EOPNOTSUPP;
00507
00508 trace_drv_get_survey(local, idx, survey);
00509
00510 if (local->ops->get_survey)
00511 ret = local->ops->get_survey(&local->hw, idx, survey);
00512
00513 trace_drv_return_int(local, ret);
00514
00515 return ret;
00516 }
00517
00518 static inline void drv_rfkill_poll(struct ieee80211_local *local)
00519 {
00520 might_sleep();
00521
00522 if (local->ops->rfkill_poll)
00523 local->ops->rfkill_poll(&local->hw);
00524 }
00525
00526 static inline void drv_flush(struct ieee80211_local *local, bool drop)
00527 {
00528 might_sleep();
00529
00530 trace_drv_flush(local, drop);
00531 if (local->ops->flush)
00532 local->ops->flush(&local->hw, drop);
00533 trace_drv_return_void(local);
00534 }
00535
00536 static inline void drv_channel_switch(struct ieee80211_local *local,
00537 struct ieee80211_channel_switch *ch_switch)
00538 {
00539 might_sleep();
00540
00541 trace_drv_channel_switch(local, ch_switch);
00542 local->ops->channel_switch(&local->hw, ch_switch);
00543 trace_drv_return_void(local);
00544 }
00545
00546
00547 static inline int drv_set_antenna(struct ieee80211_local *local,
00548 u32 tx_ant, u32 rx_ant)
00549 {
00550 int ret = -EOPNOTSUPP;
00551 might_sleep();
00552 if (local->ops->set_antenna)
00553 ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
00554 trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
00555 return ret;
00556 }
00557
00558 static inline int drv_get_antenna(struct ieee80211_local *local,
00559 u32 *tx_ant, u32 *rx_ant)
00560 {
00561 int ret = -EOPNOTSUPP;
00562 might_sleep();
00563 if (local->ops->get_antenna)
00564 ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
00565 trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
00566 return ret;
00567 }
00568
00569 static inline int drv_remain_on_channel(struct ieee80211_local *local,
00570 struct ieee80211_channel *chan,
00571 enum nl80211_channel_type chantype,
00572 unsigned int duration)
00573 {
00574 int ret;
00575
00576 might_sleep();
00577
00578 trace_drv_remain_on_channel(local, chan, chantype, duration);
00579 ret = local->ops->remain_on_channel(&local->hw, chan, chantype,
00580 duration);
00581 trace_drv_return_int(local, ret);
00582
00583 return ret;
00584 }
00585
00586 static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
00587 {
00588 int ret;
00589
00590 might_sleep();
00591
00592 trace_drv_cancel_remain_on_channel(local);
00593 ret = local->ops->cancel_remain_on_channel(&local->hw);
00594 trace_drv_return_int(local, ret);
00595
00596 return ret;
00597 }
00598
00599 static inline int drv_set_ringparam(struct ieee80211_local *local,
00600 u32 tx, u32 rx)
00601 {
00602 int ret = -ENOTSUPP;
00603
00604 might_sleep();
00605
00606 trace_drv_set_ringparam(local, tx, rx);
00607 if (local->ops->set_ringparam)
00608 ret = local->ops->set_ringparam(&local->hw, tx, rx);
00609 trace_drv_return_int(local, ret);
00610
00611 return ret;
00612 }
00613
00614 static inline void drv_get_ringparam(struct ieee80211_local *local,
00615 u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
00616 {
00617 might_sleep();
00618
00619 trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max);
00620 if (local->ops->get_ringparam)
00621 local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max);
00622 trace_drv_return_void(local);
00623 }
00624
00625 static inline bool drv_tx_frames_pending(struct ieee80211_local *local)
00626 {
00627 bool ret = false;
00628
00629 might_sleep();
00630
00631 trace_drv_tx_frames_pending(local);
00632 if (local->ops->tx_frames_pending)
00633 ret = local->ops->tx_frames_pending(&local->hw);
00634 trace_drv_return_bool(local, ret);
00635
00636 return ret;
00637 }
00638
00639 static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
00640 struct ieee80211_sub_if_data *sdata,
00641 const struct cfg80211_bitrate_mask *mask)
00642 {
00643 int ret = -EOPNOTSUPP;
00644
00645 might_sleep();
00646
00647 trace_drv_set_bitrate_mask(local, sdata, mask);
00648 if (local->ops->set_bitrate_mask)
00649 ret = local->ops->set_bitrate_mask(&local->hw,
00650 &sdata->vif, mask);
00651 trace_drv_return_int(local, ret);
00652
00653 return ret;
00654 }
00655
00656 static inline void drv_set_rekey_data(struct ieee80211_local *local,
00657 struct ieee80211_sub_if_data *sdata,
00658 struct cfg80211_gtk_rekey_data *data)
00659 {
00660 trace_drv_set_rekey_data(local, sdata, data);
00661 if (local->ops->set_rekey_data)
00662 local->ops->set_rekey_data(&local->hw, &sdata->vif, data);
00663 trace_drv_return_void(local);
00664 }
00665
00666 static inline void drv_rssi_callback(struct ieee80211_local *local,
00667 const enum ieee80211_rssi_event event)
00668 {
00669 trace_drv_rssi_callback(local, event);
00670 if (local->ops->rssi_callback)
00671 local->ops->rssi_callback(&local->hw, event);
00672 trace_drv_return_void(local);
00673 }
00674
00675 static inline void
00676 drv_release_buffered_frames(struct ieee80211_local *local,
00677 struct sta_info *sta, u16 tids, int num_frames,
00678 enum ieee80211_frame_release_type reason,
00679 bool more_data)
00680 {
00681 trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames,
00682 reason, more_data);
00683 if (local->ops->release_buffered_frames)
00684 local->ops->release_buffered_frames(&local->hw, &sta->sta, tids,
00685 num_frames, reason,
00686 more_data);
00687 trace_drv_return_void(local);
00688 }
00689
00690 static inline void
00691 drv_allow_buffered_frames(struct ieee80211_local *local,
00692 struct sta_info *sta, u16 tids, int num_frames,
00693 enum ieee80211_frame_release_type reason,
00694 bool more_data)
00695 {
00696 trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames,
00697 reason, more_data);
00698 if (local->ops->allow_buffered_frames)
00699 local->ops->allow_buffered_frames(&local->hw, &sta->sta,
00700 tids, num_frames, reason,
00701 more_data);
00702 trace_drv_return_void(local);
00703 }
00704 #endif