124487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS 224487981SJohannes Berg #define __MAC80211_DRIVER_OPS 324487981SJohannes Berg 424487981SJohannes Berg #include <net/mac80211.h> 524487981SJohannes Berg #include "ieee80211_i.h" 6*011ad0e9SJohannes Berg #include "trace.h" 724487981SJohannes Berg 87b7eab6fSJohannes Berg static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) 97b7eab6fSJohannes Berg { 10d17087e7SBen Greear WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), 11d17087e7SBen Greear "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", 12d17087e7SBen Greear sdata->dev->name, sdata->flags); 137b7eab6fSJohannes Berg } 147b7eab6fSJohannes Berg 15bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data * 16bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata) 17bc192f89SFelix Fietkau { 18bc192f89SFelix Fietkau if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 19bc192f89SFelix Fietkau sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 20bc192f89SFelix Fietkau u.ap); 21bc192f89SFelix Fietkau 22bc192f89SFelix Fietkau return sdata; 23bc192f89SFelix Fietkau } 24bc192f89SFelix Fietkau 257bb45683SJohannes Berg static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) 2624487981SJohannes Berg { 277bb45683SJohannes Berg local->ops->tx(&local->hw, skb); 2824487981SJohannes Berg } 2924487981SJohannes Berg 3011127e91SJohannes Berg static inline void drv_tx_frags(struct ieee80211_local *local, 3111127e91SJohannes Berg struct ieee80211_vif *vif, 3211127e91SJohannes Berg struct ieee80211_sta *sta, 3311127e91SJohannes Berg struct sk_buff_head *skbs) 3411127e91SJohannes Berg { 3511127e91SJohannes Berg local->ops->tx_frags(&local->hw, vif, sta, skbs); 3611127e91SJohannes Berg } 3711127e91SJohannes Berg 38e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 39e352114fSBen Greear u32 sset, u8 *data) 40e352114fSBen Greear { 41e352114fSBen Greear struct ieee80211_local *local = sdata->local; 42e352114fSBen Greear if (local->ops->get_et_strings) { 43e352114fSBen Greear trace_drv_get_et_strings(local, sset); 44e352114fSBen Greear local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data); 45e352114fSBen Greear trace_drv_return_void(local); 46e352114fSBen Greear } 47e352114fSBen Greear } 48e352114fSBen Greear 49e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, 50e352114fSBen Greear struct ethtool_stats *stats, 51e352114fSBen Greear u64 *data) 52e352114fSBen Greear { 53e352114fSBen Greear struct ieee80211_local *local = sdata->local; 54e352114fSBen Greear if (local->ops->get_et_stats) { 55e352114fSBen Greear trace_drv_get_et_stats(local); 56e352114fSBen Greear local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); 57e352114fSBen Greear trace_drv_return_void(local); 58e352114fSBen Greear } 59e352114fSBen Greear } 60e352114fSBen Greear 61e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata, 62e352114fSBen Greear int sset) 63e352114fSBen Greear { 64e352114fSBen Greear struct ieee80211_local *local = sdata->local; 65e352114fSBen Greear int rv = 0; 66e352114fSBen Greear if (local->ops->get_et_sset_count) { 67e352114fSBen Greear trace_drv_get_et_sset_count(local, sset); 68e352114fSBen Greear rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif, 69e352114fSBen Greear sset); 70e352114fSBen Greear trace_drv_return_int(local, rv); 71e352114fSBen Greear } 72e352114fSBen Greear return rv; 73e352114fSBen Greear } 74e352114fSBen Greear 7524487981SJohannes Berg static inline int drv_start(struct ieee80211_local *local) 7624487981SJohannes Berg { 77ea77f12fSJohannes Berg int ret; 78ea77f12fSJohannes Berg 79e1781ed3SKalle Valo might_sleep(); 80e1781ed3SKalle Valo 814efc76bdSJohannes Berg trace_drv_start(local); 82ea77f12fSJohannes Berg local->started = true; 83ea77f12fSJohannes Berg smp_mb(); 84ea77f12fSJohannes Berg ret = local->ops->start(&local->hw); 854efc76bdSJohannes Berg trace_drv_return_int(local, ret); 860a2b8bb2SJohannes Berg return ret; 8724487981SJohannes Berg } 8824487981SJohannes Berg 8924487981SJohannes Berg static inline void drv_stop(struct ieee80211_local *local) 9024487981SJohannes Berg { 91e1781ed3SKalle Valo might_sleep(); 92e1781ed3SKalle Valo 930a2b8bb2SJohannes Berg trace_drv_stop(local); 944efc76bdSJohannes Berg local->ops->stop(&local->hw); 954efc76bdSJohannes Berg trace_drv_return_void(local); 96ea77f12fSJohannes Berg 97ea77f12fSJohannes Berg /* sync away all work on the tasklet before clearing started */ 98ea77f12fSJohannes Berg tasklet_disable(&local->tasklet); 99ea77f12fSJohannes Berg tasklet_enable(&local->tasklet); 100ea77f12fSJohannes Berg 101ea77f12fSJohannes Berg barrier(); 102ea77f12fSJohannes Berg 103ea77f12fSJohannes Berg local->started = false; 10424487981SJohannes Berg } 10524487981SJohannes Berg 106eecc4800SJohannes Berg #ifdef CONFIG_PM 107eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local, 108eecc4800SJohannes Berg struct cfg80211_wowlan *wowlan) 109eecc4800SJohannes Berg { 110eecc4800SJohannes Berg int ret; 111eecc4800SJohannes Berg 112eecc4800SJohannes Berg might_sleep(); 113eecc4800SJohannes Berg 114eecc4800SJohannes Berg trace_drv_suspend(local); 115eecc4800SJohannes Berg ret = local->ops->suspend(&local->hw, wowlan); 116eecc4800SJohannes Berg trace_drv_return_int(local, ret); 117eecc4800SJohannes Berg return ret; 118eecc4800SJohannes Berg } 119eecc4800SJohannes Berg 120eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local) 121eecc4800SJohannes Berg { 122eecc4800SJohannes Berg int ret; 123eecc4800SJohannes Berg 124eecc4800SJohannes Berg might_sleep(); 125eecc4800SJohannes Berg 126eecc4800SJohannes Berg trace_drv_resume(local); 127eecc4800SJohannes Berg ret = local->ops->resume(&local->hw); 128eecc4800SJohannes Berg trace_drv_return_int(local, ret); 129eecc4800SJohannes Berg return ret; 130eecc4800SJohannes Berg } 1316d52563fSJohannes Berg 1326d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local, 1336d52563fSJohannes Berg bool enabled) 1346d52563fSJohannes Berg { 1356d52563fSJohannes Berg might_sleep(); 1366d52563fSJohannes Berg 1376d52563fSJohannes Berg if (!local->ops->set_wakeup) 1386d52563fSJohannes Berg return; 1396d52563fSJohannes Berg 1406d52563fSJohannes Berg trace_drv_set_wakeup(local, enabled); 1416d52563fSJohannes Berg local->ops->set_wakeup(&local->hw, enabled); 1426d52563fSJohannes Berg trace_drv_return_void(local); 1436d52563fSJohannes Berg } 144eecc4800SJohannes Berg #endif 145eecc4800SJohannes Berg 14624487981SJohannes Berg static inline int drv_add_interface(struct ieee80211_local *local, 1477b7eab6fSJohannes Berg struct ieee80211_sub_if_data *sdata) 14824487981SJohannes Berg { 149e1781ed3SKalle Valo int ret; 150e1781ed3SKalle Valo 151e1781ed3SKalle Valo might_sleep(); 152e1781ed3SKalle Valo 1537b7eab6fSJohannes Berg if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 1544b6f1dd6SJohannes Berg (sdata->vif.type == NL80211_IFTYPE_MONITOR && 1554b6f1dd6SJohannes Berg !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)))) 1567b7eab6fSJohannes Berg return -EINVAL; 1577b7eab6fSJohannes Berg 1587b7eab6fSJohannes Berg trace_drv_add_interface(local, sdata); 1597b7eab6fSJohannes Berg ret = local->ops->add_interface(&local->hw, &sdata->vif); 1604efc76bdSJohannes Berg trace_drv_return_int(local, ret); 1617b7eab6fSJohannes Berg 1627b7eab6fSJohannes Berg if (ret == 0) 1637b7eab6fSJohannes Berg sdata->flags |= IEEE80211_SDATA_IN_DRIVER; 1647b7eab6fSJohannes Berg 1650a2b8bb2SJohannes Berg return ret; 16624487981SJohannes Berg } 16724487981SJohannes Berg 16834d4bc4dSJohannes Berg static inline int drv_change_interface(struct ieee80211_local *local, 16934d4bc4dSJohannes Berg struct ieee80211_sub_if_data *sdata, 1702ca27bcfSJohannes Berg enum nl80211_iftype type, bool p2p) 17134d4bc4dSJohannes Berg { 17234d4bc4dSJohannes Berg int ret; 17334d4bc4dSJohannes Berg 17434d4bc4dSJohannes Berg might_sleep(); 17534d4bc4dSJohannes Berg 1767b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 1777b7eab6fSJohannes Berg 1782ca27bcfSJohannes Berg trace_drv_change_interface(local, sdata, type, p2p); 1792ca27bcfSJohannes Berg ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); 18034d4bc4dSJohannes Berg trace_drv_return_int(local, ret); 18134d4bc4dSJohannes Berg return ret; 18234d4bc4dSJohannes Berg } 18334d4bc4dSJohannes Berg 18424487981SJohannes Berg static inline void drv_remove_interface(struct ieee80211_local *local, 1857b7eab6fSJohannes Berg struct ieee80211_sub_if_data *sdata) 18624487981SJohannes Berg { 187e1781ed3SKalle Valo might_sleep(); 188e1781ed3SKalle Valo 1897b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 1907b7eab6fSJohannes Berg 1917b7eab6fSJohannes Berg trace_drv_remove_interface(local, sdata); 1927b7eab6fSJohannes Berg local->ops->remove_interface(&local->hw, &sdata->vif); 1937b7eab6fSJohannes Berg sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; 1944efc76bdSJohannes Berg trace_drv_return_void(local); 19524487981SJohannes Berg } 19624487981SJohannes Berg 19724487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed) 19824487981SJohannes Berg { 199e1781ed3SKalle Valo int ret; 200e1781ed3SKalle Valo 201e1781ed3SKalle Valo might_sleep(); 202e1781ed3SKalle Valo 2034efc76bdSJohannes Berg trace_drv_config(local, changed); 204e1781ed3SKalle Valo ret = local->ops->config(&local->hw, changed); 2054efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2060a2b8bb2SJohannes Berg return ret; 20724487981SJohannes Berg } 20824487981SJohannes Berg 20924487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local, 21012375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 21124487981SJohannes Berg struct ieee80211_bss_conf *info, 21224487981SJohannes Berg u32 changed) 21324487981SJohannes Berg { 214e1781ed3SKalle Valo might_sleep(); 215e1781ed3SKalle Valo 2167b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2177b7eab6fSJohannes Berg 2184efc76bdSJohannes Berg trace_drv_bss_info_changed(local, sdata, info, changed); 21924487981SJohannes Berg if (local->ops->bss_info_changed) 22012375ef9SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 2214efc76bdSJohannes Berg trace_drv_return_void(local); 22224487981SJohannes Berg } 22324487981SJohannes Berg 2243ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 22522bedad3SJiri Pirko struct netdev_hw_addr_list *mc_list) 22624487981SJohannes Berg { 2273ac64beeSJohannes Berg u64 ret = 0; 2283ac64beeSJohannes Berg 2294efc76bdSJohannes Berg trace_drv_prepare_multicast(local, mc_list->count); 2304efc76bdSJohannes Berg 2313ac64beeSJohannes Berg if (local->ops->prepare_multicast) 23222bedad3SJiri Pirko ret = local->ops->prepare_multicast(&local->hw, mc_list); 2333ac64beeSJohannes Berg 2344efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 2353ac64beeSJohannes Berg 2363ac64beeSJohannes Berg return ret; 2373ac64beeSJohannes Berg } 2383ac64beeSJohannes Berg 2393ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local, 2403ac64beeSJohannes Berg unsigned int changed_flags, 2413ac64beeSJohannes Berg unsigned int *total_flags, 2423ac64beeSJohannes Berg u64 multicast) 2433ac64beeSJohannes Berg { 2443ac64beeSJohannes Berg might_sleep(); 2453ac64beeSJohannes Berg 2460a2b8bb2SJohannes Berg trace_drv_configure_filter(local, changed_flags, total_flags, 2473ac64beeSJohannes Berg multicast); 2484efc76bdSJohannes Berg local->ops->configure_filter(&local->hw, changed_flags, total_flags, 2494efc76bdSJohannes Berg multicast); 2504efc76bdSJohannes Berg trace_drv_return_void(local); 25124487981SJohannes Berg } 25224487981SJohannes Berg 25324487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local, 25424487981SJohannes Berg struct ieee80211_sta *sta, bool set) 25524487981SJohannes Berg { 2560a2b8bb2SJohannes Berg int ret = 0; 2574efc76bdSJohannes Berg trace_drv_set_tim(local, sta, set); 25824487981SJohannes Berg if (local->ops->set_tim) 2590a2b8bb2SJohannes Berg ret = local->ops->set_tim(&local->hw, sta, set); 2604efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2610a2b8bb2SJohannes Berg return ret; 26224487981SJohannes Berg } 26324487981SJohannes Berg 26424487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local, 26512375ef9SJohannes Berg enum set_key_cmd cmd, 26612375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 26724487981SJohannes Berg struct ieee80211_sta *sta, 26824487981SJohannes Berg struct ieee80211_key_conf *key) 26924487981SJohannes Berg { 270e1781ed3SKalle Valo int ret; 271e1781ed3SKalle Valo 272e1781ed3SKalle Valo might_sleep(); 273e1781ed3SKalle Valo 274077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 2757b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2767b7eab6fSJohannes Berg 2774efc76bdSJohannes Berg trace_drv_set_key(local, cmd, sdata, sta, key); 278e1781ed3SKalle Valo ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 2794efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2800a2b8bb2SJohannes Berg return ret; 28124487981SJohannes Berg } 28224487981SJohannes Berg 28324487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local, 284b3fbdcf4SJohannes Berg struct ieee80211_sub_if_data *sdata, 28524487981SJohannes Berg struct ieee80211_key_conf *conf, 286b3fbdcf4SJohannes Berg struct sta_info *sta, u32 iv32, 28724487981SJohannes Berg u16 *phase1key) 28824487981SJohannes Berg { 289b3fbdcf4SJohannes Berg struct ieee80211_sta *ista = NULL; 290b3fbdcf4SJohannes Berg 291b3fbdcf4SJohannes Berg if (sta) 292b3fbdcf4SJohannes Berg ista = &sta->sta; 293b3fbdcf4SJohannes Berg 294077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 2957b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2967b7eab6fSJohannes Berg 2974efc76bdSJohannes Berg trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 29824487981SJohannes Berg if (local->ops->update_tkip_key) 299b3fbdcf4SJohannes Berg local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 300b3fbdcf4SJohannes Berg ista, iv32, phase1key); 3014efc76bdSJohannes Berg trace_drv_return_void(local); 30224487981SJohannes Berg } 30324487981SJohannes Berg 30424487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local, 305a060bbfeSJohannes Berg struct ieee80211_sub_if_data *sdata, 30624487981SJohannes Berg struct cfg80211_scan_request *req) 30724487981SJohannes Berg { 308e1781ed3SKalle Valo int ret; 309e1781ed3SKalle Valo 310e1781ed3SKalle Valo might_sleep(); 311e1781ed3SKalle Valo 3127b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3137b7eab6fSJohannes Berg 31479f460caSLuciano Coelho trace_drv_hw_scan(local, sdata); 315a060bbfeSJohannes Berg ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 3164efc76bdSJohannes Berg trace_drv_return_int(local, ret); 3170a2b8bb2SJohannes Berg return ret; 31824487981SJohannes Berg } 31924487981SJohannes Berg 320b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 321b856439bSEliad Peller struct ieee80211_sub_if_data *sdata) 322b856439bSEliad Peller { 323b856439bSEliad Peller might_sleep(); 324b856439bSEliad Peller 3257b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3267b7eab6fSJohannes Berg 327b856439bSEliad Peller trace_drv_cancel_hw_scan(local, sdata); 328b856439bSEliad Peller local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 329b856439bSEliad Peller trace_drv_return_void(local); 330b856439bSEliad Peller } 331b856439bSEliad Peller 33279f460caSLuciano Coelho static inline int 33379f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local, 33479f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata, 33579f460caSLuciano Coelho struct cfg80211_sched_scan_request *req, 33679f460caSLuciano Coelho struct ieee80211_sched_scan_ies *ies) 33779f460caSLuciano Coelho { 33879f460caSLuciano Coelho int ret; 33979f460caSLuciano Coelho 34079f460caSLuciano Coelho might_sleep(); 34179f460caSLuciano Coelho 3427b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3437b7eab6fSJohannes Berg 34479f460caSLuciano Coelho trace_drv_sched_scan_start(local, sdata); 34579f460caSLuciano Coelho ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 34679f460caSLuciano Coelho req, ies); 34779f460caSLuciano Coelho trace_drv_return_int(local, ret); 34879f460caSLuciano Coelho return ret; 34979f460caSLuciano Coelho } 35079f460caSLuciano Coelho 35179f460caSLuciano Coelho static inline void drv_sched_scan_stop(struct ieee80211_local *local, 35279f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata) 35379f460caSLuciano Coelho { 35479f460caSLuciano Coelho might_sleep(); 35579f460caSLuciano Coelho 3567b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3577b7eab6fSJohannes Berg 35879f460caSLuciano Coelho trace_drv_sched_scan_stop(local, sdata); 35979f460caSLuciano Coelho local->ops->sched_scan_stop(&local->hw, &sdata->vif); 36079f460caSLuciano Coelho trace_drv_return_void(local); 36179f460caSLuciano Coelho } 36279f460caSLuciano Coelho 36324487981SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local) 36424487981SJohannes Berg { 365e1781ed3SKalle Valo might_sleep(); 366e1781ed3SKalle Valo 3674efc76bdSJohannes Berg trace_drv_sw_scan_start(local); 36824487981SJohannes Berg if (local->ops->sw_scan_start) 36924487981SJohannes Berg local->ops->sw_scan_start(&local->hw); 3704efc76bdSJohannes Berg trace_drv_return_void(local); 37124487981SJohannes Berg } 37224487981SJohannes Berg 37324487981SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local) 37424487981SJohannes Berg { 375e1781ed3SKalle Valo might_sleep(); 376e1781ed3SKalle Valo 3774efc76bdSJohannes Berg trace_drv_sw_scan_complete(local); 37824487981SJohannes Berg if (local->ops->sw_scan_complete) 37924487981SJohannes Berg local->ops->sw_scan_complete(&local->hw); 3804efc76bdSJohannes Berg trace_drv_return_void(local); 38124487981SJohannes Berg } 38224487981SJohannes Berg 38324487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local, 38424487981SJohannes Berg struct ieee80211_low_level_stats *stats) 38524487981SJohannes Berg { 3860a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 3870a2b8bb2SJohannes Berg 388e1781ed3SKalle Valo might_sleep(); 389e1781ed3SKalle Valo 3900a2b8bb2SJohannes Berg if (local->ops->get_stats) 3910a2b8bb2SJohannes Berg ret = local->ops->get_stats(&local->hw, stats); 3920a2b8bb2SJohannes Berg trace_drv_get_stats(local, stats, ret); 3930a2b8bb2SJohannes Berg 3940a2b8bb2SJohannes Berg return ret; 39524487981SJohannes Berg } 39624487981SJohannes Berg 39724487981SJohannes Berg static inline void drv_get_tkip_seq(struct ieee80211_local *local, 39824487981SJohannes Berg u8 hw_key_idx, u32 *iv32, u16 *iv16) 39924487981SJohannes Berg { 40024487981SJohannes Berg if (local->ops->get_tkip_seq) 40124487981SJohannes Berg local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16); 4020a2b8bb2SJohannes Berg trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); 40324487981SJohannes Berg } 40424487981SJohannes Berg 405f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local, 406f23a4780SArik Nemtsov u32 value) 407f23a4780SArik Nemtsov { 408f23a4780SArik Nemtsov int ret = 0; 409f23a4780SArik Nemtsov 410f23a4780SArik Nemtsov might_sleep(); 411f23a4780SArik Nemtsov 412f23a4780SArik Nemtsov trace_drv_set_frag_threshold(local, value); 413f23a4780SArik Nemtsov if (local->ops->set_frag_threshold) 414f23a4780SArik Nemtsov ret = local->ops->set_frag_threshold(&local->hw, value); 415f23a4780SArik Nemtsov trace_drv_return_int(local, ret); 416f23a4780SArik Nemtsov return ret; 417f23a4780SArik Nemtsov } 418f23a4780SArik Nemtsov 41924487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local, 42024487981SJohannes Berg u32 value) 42124487981SJohannes Berg { 4220a2b8bb2SJohannes Berg int ret = 0; 423e1781ed3SKalle Valo 424e1781ed3SKalle Valo might_sleep(); 425e1781ed3SKalle Valo 4264efc76bdSJohannes Berg trace_drv_set_rts_threshold(local, value); 42724487981SJohannes Berg if (local->ops->set_rts_threshold) 4280a2b8bb2SJohannes Berg ret = local->ops->set_rts_threshold(&local->hw, value); 4294efc76bdSJohannes Berg trace_drv_return_int(local, ret); 4300a2b8bb2SJohannes Berg return ret; 43124487981SJohannes Berg } 43224487981SJohannes Berg 433310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local, 434310bc676SLukáš Turek u8 value) 435310bc676SLukáš Turek { 436310bc676SLukáš Turek int ret = 0; 437310bc676SLukáš Turek might_sleep(); 438310bc676SLukáš Turek 4394efc76bdSJohannes Berg trace_drv_set_coverage_class(local, value); 440310bc676SLukáš Turek if (local->ops->set_coverage_class) 441310bc676SLukáš Turek local->ops->set_coverage_class(&local->hw, value); 442310bc676SLukáš Turek else 443310bc676SLukáš Turek ret = -EOPNOTSUPP; 444310bc676SLukáš Turek 4454efc76bdSJohannes Berg trace_drv_return_int(local, ret); 446310bc676SLukáš Turek return ret; 447310bc676SLukáš Turek } 448310bc676SLukáš Turek 44924487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local, 45012375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 45124487981SJohannes Berg enum sta_notify_cmd cmd, 45224487981SJohannes Berg struct ieee80211_sta *sta) 45324487981SJohannes Berg { 454bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4557b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4567b7eab6fSJohannes Berg 4574efc76bdSJohannes Berg trace_drv_sta_notify(local, sdata, cmd, sta); 45824487981SJohannes Berg if (local->ops->sta_notify) 45912375ef9SJohannes Berg local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 4604efc76bdSJohannes Berg trace_drv_return_void(local); 46124487981SJohannes Berg } 46224487981SJohannes Berg 46334e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local, 46434e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 46534e89507SJohannes Berg struct ieee80211_sta *sta) 46634e89507SJohannes Berg { 46734e89507SJohannes Berg int ret = 0; 46834e89507SJohannes Berg 46934e89507SJohannes Berg might_sleep(); 47034e89507SJohannes Berg 471bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4727b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4737b7eab6fSJohannes Berg 4744efc76bdSJohannes Berg trace_drv_sta_add(local, sdata, sta); 47534e89507SJohannes Berg if (local->ops->sta_add) 47634e89507SJohannes Berg ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 47734e89507SJohannes Berg 4784efc76bdSJohannes Berg trace_drv_return_int(local, ret); 47934e89507SJohannes Berg 48034e89507SJohannes Berg return ret; 48134e89507SJohannes Berg } 48234e89507SJohannes Berg 48334e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local, 48434e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 48534e89507SJohannes Berg struct ieee80211_sta *sta) 48634e89507SJohannes Berg { 48734e89507SJohannes Berg might_sleep(); 48834e89507SJohannes Berg 489bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4907b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4917b7eab6fSJohannes Berg 4924efc76bdSJohannes Berg trace_drv_sta_remove(local, sdata, sta); 49334e89507SJohannes Berg if (local->ops->sta_remove) 49434e89507SJohannes Berg local->ops->sta_remove(&local->hw, &sdata->vif, sta); 49534e89507SJohannes Berg 4964efc76bdSJohannes Berg trace_drv_return_void(local); 49734e89507SJohannes Berg } 49834e89507SJohannes Berg 499f09603a2SJohannes Berg static inline __must_check 500f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local, 501f09603a2SJohannes Berg struct ieee80211_sub_if_data *sdata, 502f09603a2SJohannes Berg struct sta_info *sta, 503f09603a2SJohannes Berg enum ieee80211_sta_state old_state, 504f09603a2SJohannes Berg enum ieee80211_sta_state new_state) 505f09603a2SJohannes Berg { 506f09603a2SJohannes Berg int ret = 0; 507f09603a2SJohannes Berg 508f09603a2SJohannes Berg might_sleep(); 509f09603a2SJohannes Berg 510f09603a2SJohannes Berg sdata = get_bss_sdata(sdata); 511f09603a2SJohannes Berg check_sdata_in_driver(sdata); 512f09603a2SJohannes Berg 513f09603a2SJohannes Berg trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); 514a4ec45a4SJohannes Berg if (local->ops->sta_state) { 515f09603a2SJohannes Berg ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta, 516f09603a2SJohannes Berg old_state, new_state); 517a4ec45a4SJohannes Berg } else if (old_state == IEEE80211_STA_AUTH && 518a4ec45a4SJohannes Berg new_state == IEEE80211_STA_ASSOC) { 519a4ec45a4SJohannes Berg ret = drv_sta_add(local, sdata, &sta->sta); 520a4ec45a4SJohannes Berg if (ret == 0) 521a4ec45a4SJohannes Berg sta->uploaded = true; 522a4ec45a4SJohannes Berg } else if (old_state == IEEE80211_STA_ASSOC && 523a4ec45a4SJohannes Berg new_state == IEEE80211_STA_AUTH) { 524a4ec45a4SJohannes Berg drv_sta_remove(local, sdata, &sta->sta); 525a4ec45a4SJohannes Berg } 526f09603a2SJohannes Berg trace_drv_return_int(local, ret); 527f09603a2SJohannes Berg return ret; 528f09603a2SJohannes Berg } 529f09603a2SJohannes Berg 5308f727ef3SJohannes Berg static inline void drv_sta_rc_update(struct ieee80211_local *local, 5318f727ef3SJohannes Berg struct ieee80211_sub_if_data *sdata, 5328f727ef3SJohannes Berg struct ieee80211_sta *sta, u32 changed) 5338f727ef3SJohannes Berg { 5348f727ef3SJohannes Berg sdata = get_bss_sdata(sdata); 5358f727ef3SJohannes Berg check_sdata_in_driver(sdata); 5368f727ef3SJohannes Berg 5378f727ef3SJohannes Berg trace_drv_sta_rc_update(local, sdata, sta, changed); 5388f727ef3SJohannes Berg if (local->ops->sta_rc_update) 5398f727ef3SJohannes Berg local->ops->sta_rc_update(&local->hw, &sdata->vif, 5408f727ef3SJohannes Berg sta, changed); 5418f727ef3SJohannes Berg 5428f727ef3SJohannes Berg trace_drv_return_void(local); 5438f727ef3SJohannes Berg } 5448f727ef3SJohannes Berg 545f6f3def3SEliad Peller static inline int drv_conf_tx(struct ieee80211_local *local, 546a3304b0aSJohannes Berg struct ieee80211_sub_if_data *sdata, u16 ac, 54724487981SJohannes Berg const struct ieee80211_tx_queue_params *params) 54824487981SJohannes Berg { 5490a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 550e1781ed3SKalle Valo 551e1781ed3SKalle Valo might_sleep(); 552e1781ed3SKalle Valo 5537b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 5547b7eab6fSJohannes Berg 555a3304b0aSJohannes Berg trace_drv_conf_tx(local, sdata, ac, params); 55624487981SJohannes Berg if (local->ops->conf_tx) 5578a3a3c85SEliad Peller ret = local->ops->conf_tx(&local->hw, &sdata->vif, 558a3304b0aSJohannes Berg ac, params); 5594efc76bdSJohannes Berg trace_drv_return_int(local, ret); 5600a2b8bb2SJohannes Berg return ret; 56124487981SJohannes Berg } 56224487981SJohannes Berg 56337a41b4aSEliad Peller static inline u64 drv_get_tsf(struct ieee80211_local *local, 56437a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata) 56524487981SJohannes Berg { 5660a2b8bb2SJohannes Berg u64 ret = -1ULL; 567e1781ed3SKalle Valo 568e1781ed3SKalle Valo might_sleep(); 569e1781ed3SKalle Valo 5707b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 5717b7eab6fSJohannes Berg 57237a41b4aSEliad Peller trace_drv_get_tsf(local, sdata); 57324487981SJohannes Berg if (local->ops->get_tsf) 57437a41b4aSEliad Peller ret = local->ops->get_tsf(&local->hw, &sdata->vif); 5754efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 5760a2b8bb2SJohannes Berg return ret; 57724487981SJohannes Berg } 57824487981SJohannes Berg 57937a41b4aSEliad Peller static inline void drv_set_tsf(struct ieee80211_local *local, 58037a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata, 58137a41b4aSEliad Peller u64 tsf) 58224487981SJohannes Berg { 583e1781ed3SKalle Valo might_sleep(); 584e1781ed3SKalle Valo 5857b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 5867b7eab6fSJohannes Berg 58737a41b4aSEliad Peller trace_drv_set_tsf(local, sdata, tsf); 58824487981SJohannes Berg if (local->ops->set_tsf) 58937a41b4aSEliad Peller local->ops->set_tsf(&local->hw, &sdata->vif, tsf); 5904efc76bdSJohannes Berg trace_drv_return_void(local); 59124487981SJohannes Berg } 59224487981SJohannes Berg 59337a41b4aSEliad Peller static inline void drv_reset_tsf(struct ieee80211_local *local, 59437a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata) 59524487981SJohannes Berg { 596e1781ed3SKalle Valo might_sleep(); 597e1781ed3SKalle Valo 5987b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 5997b7eab6fSJohannes Berg 60037a41b4aSEliad Peller trace_drv_reset_tsf(local, sdata); 60124487981SJohannes Berg if (local->ops->reset_tsf) 60237a41b4aSEliad Peller local->ops->reset_tsf(&local->hw, &sdata->vif); 6034efc76bdSJohannes Berg trace_drv_return_void(local); 60424487981SJohannes Berg } 60524487981SJohannes Berg 60624487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local) 60724487981SJohannes Berg { 60891f44b02STim Harvey int ret = 0; /* default unsuported op for less congestion */ 609e1781ed3SKalle Valo 610e1781ed3SKalle Valo might_sleep(); 611e1781ed3SKalle Valo 6124efc76bdSJohannes Berg trace_drv_tx_last_beacon(local); 61324487981SJohannes Berg if (local->ops->tx_last_beacon) 6140a2b8bb2SJohannes Berg ret = local->ops->tx_last_beacon(&local->hw); 6154efc76bdSJohannes Berg trace_drv_return_int(local, ret); 6160a2b8bb2SJohannes Berg return ret; 61724487981SJohannes Berg } 61824487981SJohannes Berg 61924487981SJohannes Berg static inline int drv_ampdu_action(struct ieee80211_local *local, 62012375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 62124487981SJohannes Berg enum ieee80211_ampdu_mlme_action action, 62224487981SJohannes Berg struct ieee80211_sta *sta, u16 tid, 6230b01f030SJohannes Berg u16 *ssn, u8 buf_size) 62424487981SJohannes Berg { 6250a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 626cfcdbde3SJohannes Berg 627cfcdbde3SJohannes Berg might_sleep(); 628cfcdbde3SJohannes Berg 629bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 6307b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 6317b7eab6fSJohannes Berg 6320b01f030SJohannes Berg trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); 6334efc76bdSJohannes Berg 63424487981SJohannes Berg if (local->ops->ampdu_action) 63512375ef9SJohannes Berg ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action, 6360b01f030SJohannes Berg sta, tid, ssn, buf_size); 63785ad181eSJohannes Berg 6384efc76bdSJohannes Berg trace_drv_return_int(local, ret); 6394efc76bdSJohannes Berg 6400a2b8bb2SJohannes Berg return ret; 64124487981SJohannes Berg } 6421f87f7d3SJohannes Berg 6431289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx, 6441289723eSHolger Schurig struct survey_info *survey) 6451289723eSHolger Schurig { 6461289723eSHolger Schurig int ret = -EOPNOTSUPP; 647c466d4efSJohn W. Linville 648c466d4efSJohn W. Linville trace_drv_get_survey(local, idx, survey); 649c466d4efSJohn W. Linville 65035dd0509SHolger Schurig if (local->ops->get_survey) 6511289723eSHolger Schurig ret = local->ops->get_survey(&local->hw, idx, survey); 652c466d4efSJohn W. Linville 653c466d4efSJohn W. Linville trace_drv_return_int(local, ret); 654c466d4efSJohn W. Linville 6551289723eSHolger Schurig return ret; 6561289723eSHolger Schurig } 6571f87f7d3SJohannes Berg 6581f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local) 6591f87f7d3SJohannes Berg { 660e1781ed3SKalle Valo might_sleep(); 661e1781ed3SKalle Valo 6621f87f7d3SJohannes Berg if (local->ops->rfkill_poll) 6631f87f7d3SJohannes Berg local->ops->rfkill_poll(&local->hw); 6641f87f7d3SJohannes Berg } 665a80f7c0bSJohannes Berg 666a80f7c0bSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, bool drop) 667a80f7c0bSJohannes Berg { 668e1781ed3SKalle Valo might_sleep(); 669e1781ed3SKalle Valo 670a80f7c0bSJohannes Berg trace_drv_flush(local, drop); 671a80f7c0bSJohannes Berg if (local->ops->flush) 672a80f7c0bSJohannes Berg local->ops->flush(&local->hw, drop); 6734efc76bdSJohannes Berg trace_drv_return_void(local); 674a80f7c0bSJohannes Berg } 6755ce6e438SJohannes Berg 6765ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local, 6775ce6e438SJohannes Berg struct ieee80211_channel_switch *ch_switch) 6785ce6e438SJohannes Berg { 6795ce6e438SJohannes Berg might_sleep(); 6805ce6e438SJohannes Berg 6815ce6e438SJohannes Berg trace_drv_channel_switch(local, ch_switch); 6824efc76bdSJohannes Berg local->ops->channel_switch(&local->hw, ch_switch); 6834efc76bdSJohannes Berg trace_drv_return_void(local); 6845ce6e438SJohannes Berg } 6855ce6e438SJohannes Berg 68615d96753SBruno Randolf 68715d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local, 68815d96753SBruno Randolf u32 tx_ant, u32 rx_ant) 68915d96753SBruno Randolf { 69015d96753SBruno Randolf int ret = -EOPNOTSUPP; 69115d96753SBruno Randolf might_sleep(); 69215d96753SBruno Randolf if (local->ops->set_antenna) 69315d96753SBruno Randolf ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 69415d96753SBruno Randolf trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 69515d96753SBruno Randolf return ret; 69615d96753SBruno Randolf } 69715d96753SBruno Randolf 69815d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local, 69915d96753SBruno Randolf u32 *tx_ant, u32 *rx_ant) 70015d96753SBruno Randolf { 70115d96753SBruno Randolf int ret = -EOPNOTSUPP; 70215d96753SBruno Randolf might_sleep(); 70315d96753SBruno Randolf if (local->ops->get_antenna) 70415d96753SBruno Randolf ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 70515d96753SBruno Randolf trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 70615d96753SBruno Randolf return ret; 70715d96753SBruno Randolf } 70815d96753SBruno Randolf 70921f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local, 71021f83589SJohannes Berg struct ieee80211_channel *chan, 71121f83589SJohannes Berg enum nl80211_channel_type chantype, 71221f83589SJohannes Berg unsigned int duration) 71321f83589SJohannes Berg { 71421f83589SJohannes Berg int ret; 71521f83589SJohannes Berg 71621f83589SJohannes Berg might_sleep(); 71721f83589SJohannes Berg 71821f83589SJohannes Berg trace_drv_remain_on_channel(local, chan, chantype, duration); 71921f83589SJohannes Berg ret = local->ops->remain_on_channel(&local->hw, chan, chantype, 72021f83589SJohannes Berg duration); 72121f83589SJohannes Berg trace_drv_return_int(local, ret); 72221f83589SJohannes Berg 72321f83589SJohannes Berg return ret; 72421f83589SJohannes Berg } 72521f83589SJohannes Berg 72621f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local) 72721f83589SJohannes Berg { 72821f83589SJohannes Berg int ret; 72921f83589SJohannes Berg 73021f83589SJohannes Berg might_sleep(); 73121f83589SJohannes Berg 73221f83589SJohannes Berg trace_drv_cancel_remain_on_channel(local); 73321f83589SJohannes Berg ret = local->ops->cancel_remain_on_channel(&local->hw); 73421f83589SJohannes Berg trace_drv_return_int(local, ret); 73521f83589SJohannes Berg 73621f83589SJohannes Berg return ret; 73721f83589SJohannes Berg } 73821f83589SJohannes Berg 73938c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local, 74038c09159SJohn W. Linville u32 tx, u32 rx) 74138c09159SJohn W. Linville { 74238c09159SJohn W. Linville int ret = -ENOTSUPP; 74338c09159SJohn W. Linville 74438c09159SJohn W. Linville might_sleep(); 74538c09159SJohn W. Linville 74638c09159SJohn W. Linville trace_drv_set_ringparam(local, tx, rx); 74738c09159SJohn W. Linville if (local->ops->set_ringparam) 74838c09159SJohn W. Linville ret = local->ops->set_ringparam(&local->hw, tx, rx); 74938c09159SJohn W. Linville trace_drv_return_int(local, ret); 75038c09159SJohn W. Linville 75138c09159SJohn W. Linville return ret; 75238c09159SJohn W. Linville } 75338c09159SJohn W. Linville 75438c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local, 75538c09159SJohn W. Linville u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 75638c09159SJohn W. Linville { 75738c09159SJohn W. Linville might_sleep(); 75838c09159SJohn W. Linville 75938c09159SJohn W. Linville trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 76038c09159SJohn W. Linville if (local->ops->get_ringparam) 76138c09159SJohn W. Linville local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 76238c09159SJohn W. Linville trace_drv_return_void(local); 76338c09159SJohn W. Linville } 76438c09159SJohn W. Linville 765e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 766e8306f98SVivek Natarajan { 767e8306f98SVivek Natarajan bool ret = false; 768e8306f98SVivek Natarajan 769e8306f98SVivek Natarajan might_sleep(); 770e8306f98SVivek Natarajan 771e8306f98SVivek Natarajan trace_drv_tx_frames_pending(local); 772e8306f98SVivek Natarajan if (local->ops->tx_frames_pending) 773e8306f98SVivek Natarajan ret = local->ops->tx_frames_pending(&local->hw); 774e8306f98SVivek Natarajan trace_drv_return_bool(local, ret); 775e8306f98SVivek Natarajan 776e8306f98SVivek Natarajan return ret; 777e8306f98SVivek Natarajan } 778bdbfd6b5SSujith Manoharan 779bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 780bdbfd6b5SSujith Manoharan struct ieee80211_sub_if_data *sdata, 781bdbfd6b5SSujith Manoharan const struct cfg80211_bitrate_mask *mask) 782bdbfd6b5SSujith Manoharan { 783bdbfd6b5SSujith Manoharan int ret = -EOPNOTSUPP; 784bdbfd6b5SSujith Manoharan 785bdbfd6b5SSujith Manoharan might_sleep(); 786bdbfd6b5SSujith Manoharan 7877b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 7887b7eab6fSJohannes Berg 789bdbfd6b5SSujith Manoharan trace_drv_set_bitrate_mask(local, sdata, mask); 790bdbfd6b5SSujith Manoharan if (local->ops->set_bitrate_mask) 791bdbfd6b5SSujith Manoharan ret = local->ops->set_bitrate_mask(&local->hw, 792bdbfd6b5SSujith Manoharan &sdata->vif, mask); 793bdbfd6b5SSujith Manoharan trace_drv_return_int(local, ret); 794bdbfd6b5SSujith Manoharan 795bdbfd6b5SSujith Manoharan return ret; 796bdbfd6b5SSujith Manoharan } 797bdbfd6b5SSujith Manoharan 798c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local, 799c68f4b89SJohannes Berg struct ieee80211_sub_if_data *sdata, 800c68f4b89SJohannes Berg struct cfg80211_gtk_rekey_data *data) 801c68f4b89SJohannes Berg { 8027b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 8037b7eab6fSJohannes Berg 804c68f4b89SJohannes Berg trace_drv_set_rekey_data(local, sdata, data); 805c68f4b89SJohannes Berg if (local->ops->set_rekey_data) 806c68f4b89SJohannes Berg local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 807c68f4b89SJohannes Berg trace_drv_return_void(local); 808c68f4b89SJohannes Berg } 809c68f4b89SJohannes Berg 810615f7b9bSMeenakshi Venkataraman static inline void drv_rssi_callback(struct ieee80211_local *local, 811615f7b9bSMeenakshi Venkataraman const enum ieee80211_rssi_event event) 812615f7b9bSMeenakshi Venkataraman { 813615f7b9bSMeenakshi Venkataraman trace_drv_rssi_callback(local, event); 814615f7b9bSMeenakshi Venkataraman if (local->ops->rssi_callback) 815615f7b9bSMeenakshi Venkataraman local->ops->rssi_callback(&local->hw, event); 816615f7b9bSMeenakshi Venkataraman trace_drv_return_void(local); 817615f7b9bSMeenakshi Venkataraman } 8184049e09aSJohannes Berg 8194049e09aSJohannes Berg static inline void 8204049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local, 8214049e09aSJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 8224049e09aSJohannes Berg enum ieee80211_frame_release_type reason, 8234049e09aSJohannes Berg bool more_data) 8244049e09aSJohannes Berg { 8254049e09aSJohannes Berg trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 8264049e09aSJohannes Berg reason, more_data); 8274049e09aSJohannes Berg if (local->ops->release_buffered_frames) 8284049e09aSJohannes Berg local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 8294049e09aSJohannes Berg num_frames, reason, 8304049e09aSJohannes Berg more_data); 8314049e09aSJohannes Berg trace_drv_return_void(local); 8324049e09aSJohannes Berg } 83340b96408SJohannes Berg 83440b96408SJohannes Berg static inline void 83540b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local, 83640b96408SJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 83740b96408SJohannes Berg enum ieee80211_frame_release_type reason, 83840b96408SJohannes Berg bool more_data) 83940b96408SJohannes Berg { 84040b96408SJohannes Berg trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 84140b96408SJohannes Berg reason, more_data); 84240b96408SJohannes Berg if (local->ops->allow_buffered_frames) 84340b96408SJohannes Berg local->ops->allow_buffered_frames(&local->hw, &sta->sta, 84440b96408SJohannes Berg tids, num_frames, reason, 84540b96408SJohannes Berg more_data); 84640b96408SJohannes Berg trace_drv_return_void(local); 84740b96408SJohannes Berg } 84866572cfcSVictor Goldenshtein 84966572cfcSVictor Goldenshtein static inline int drv_get_rssi(struct ieee80211_local *local, 85066572cfcSVictor Goldenshtein struct ieee80211_sub_if_data *sdata, 85166572cfcSVictor Goldenshtein struct ieee80211_sta *sta, 85266572cfcSVictor Goldenshtein s8 *rssi_dbm) 85366572cfcSVictor Goldenshtein { 85466572cfcSVictor Goldenshtein int ret; 85566572cfcSVictor Goldenshtein 85666572cfcSVictor Goldenshtein might_sleep(); 85766572cfcSVictor Goldenshtein 85866572cfcSVictor Goldenshtein ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); 85966572cfcSVictor Goldenshtein trace_drv_get_rssi(local, sta, *rssi_dbm, ret); 86066572cfcSVictor Goldenshtein 86166572cfcSVictor Goldenshtein return ret; 86266572cfcSVictor Goldenshtein } 86324487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */ 864