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" 6011ad0e9SJohannes 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", 12f142c6b9SJohannes Berg sdata->dev ? sdata->dev->name : sdata->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 2536323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local, 2636323f81SThomas Huehn struct ieee80211_tx_control *control, 2736323f81SThomas Huehn struct sk_buff *skb) 2824487981SJohannes Berg { 2936323f81SThomas Huehn local->ops->tx(&local->hw, control, skb); 3024487981SJohannes Berg } 3124487981SJohannes Berg 32e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 33e352114fSBen Greear u32 sset, u8 *data) 34e352114fSBen Greear { 35e352114fSBen Greear struct ieee80211_local *local = sdata->local; 36e352114fSBen Greear if (local->ops->get_et_strings) { 37e352114fSBen Greear trace_drv_get_et_strings(local, sset); 38e352114fSBen Greear local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data); 39e352114fSBen Greear trace_drv_return_void(local); 40e352114fSBen Greear } 41e352114fSBen Greear } 42e352114fSBen Greear 43e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, 44e352114fSBen Greear struct ethtool_stats *stats, 45e352114fSBen Greear u64 *data) 46e352114fSBen Greear { 47e352114fSBen Greear struct ieee80211_local *local = sdata->local; 48e352114fSBen Greear if (local->ops->get_et_stats) { 49e352114fSBen Greear trace_drv_get_et_stats(local); 50e352114fSBen Greear local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); 51e352114fSBen Greear trace_drv_return_void(local); 52e352114fSBen Greear } 53e352114fSBen Greear } 54e352114fSBen Greear 55e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata, 56e352114fSBen Greear int sset) 57e352114fSBen Greear { 58e352114fSBen Greear struct ieee80211_local *local = sdata->local; 59e352114fSBen Greear int rv = 0; 60e352114fSBen Greear if (local->ops->get_et_sset_count) { 61e352114fSBen Greear trace_drv_get_et_sset_count(local, sset); 62e352114fSBen Greear rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif, 63e352114fSBen Greear sset); 64e352114fSBen Greear trace_drv_return_int(local, rv); 65e352114fSBen Greear } 66e352114fSBen Greear return rv; 67e352114fSBen Greear } 68e352114fSBen Greear 6924487981SJohannes Berg static inline int drv_start(struct ieee80211_local *local) 7024487981SJohannes Berg { 71ea77f12fSJohannes Berg int ret; 72ea77f12fSJohannes Berg 73e1781ed3SKalle Valo might_sleep(); 74e1781ed3SKalle Valo 754efc76bdSJohannes Berg trace_drv_start(local); 76ea77f12fSJohannes Berg local->started = true; 77ea77f12fSJohannes Berg smp_mb(); 78ea77f12fSJohannes Berg ret = local->ops->start(&local->hw); 794efc76bdSJohannes Berg trace_drv_return_int(local, ret); 800a2b8bb2SJohannes Berg return ret; 8124487981SJohannes Berg } 8224487981SJohannes Berg 8324487981SJohannes Berg static inline void drv_stop(struct ieee80211_local *local) 8424487981SJohannes Berg { 85e1781ed3SKalle Valo might_sleep(); 86e1781ed3SKalle Valo 870a2b8bb2SJohannes Berg trace_drv_stop(local); 884efc76bdSJohannes Berg local->ops->stop(&local->hw); 894efc76bdSJohannes Berg trace_drv_return_void(local); 90ea77f12fSJohannes Berg 91ea77f12fSJohannes Berg /* sync away all work on the tasklet before clearing started */ 92ea77f12fSJohannes Berg tasklet_disable(&local->tasklet); 93ea77f12fSJohannes Berg tasklet_enable(&local->tasklet); 94ea77f12fSJohannes Berg 95ea77f12fSJohannes Berg barrier(); 96ea77f12fSJohannes Berg 97ea77f12fSJohannes Berg local->started = false; 9824487981SJohannes Berg } 9924487981SJohannes Berg 100eecc4800SJohannes Berg #ifdef CONFIG_PM 101eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local, 102eecc4800SJohannes Berg struct cfg80211_wowlan *wowlan) 103eecc4800SJohannes Berg { 104eecc4800SJohannes Berg int ret; 105eecc4800SJohannes Berg 106eecc4800SJohannes Berg might_sleep(); 107eecc4800SJohannes Berg 108eecc4800SJohannes Berg trace_drv_suspend(local); 109eecc4800SJohannes Berg ret = local->ops->suspend(&local->hw, wowlan); 110eecc4800SJohannes Berg trace_drv_return_int(local, ret); 111eecc4800SJohannes Berg return ret; 112eecc4800SJohannes Berg } 113eecc4800SJohannes Berg 114eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local) 115eecc4800SJohannes Berg { 116eecc4800SJohannes Berg int ret; 117eecc4800SJohannes Berg 118eecc4800SJohannes Berg might_sleep(); 119eecc4800SJohannes Berg 120eecc4800SJohannes Berg trace_drv_resume(local); 121eecc4800SJohannes Berg ret = local->ops->resume(&local->hw); 122eecc4800SJohannes Berg trace_drv_return_int(local, ret); 123eecc4800SJohannes Berg return ret; 124eecc4800SJohannes Berg } 1256d52563fSJohannes Berg 1266d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local, 1276d52563fSJohannes Berg bool enabled) 1286d52563fSJohannes Berg { 1296d52563fSJohannes Berg might_sleep(); 1306d52563fSJohannes Berg 1316d52563fSJohannes Berg if (!local->ops->set_wakeup) 1326d52563fSJohannes Berg return; 1336d52563fSJohannes Berg 1346d52563fSJohannes Berg trace_drv_set_wakeup(local, enabled); 1356d52563fSJohannes Berg local->ops->set_wakeup(&local->hw, enabled); 1366d52563fSJohannes Berg trace_drv_return_void(local); 1376d52563fSJohannes Berg } 138eecc4800SJohannes Berg #endif 139eecc4800SJohannes Berg 14024487981SJohannes Berg static inline int drv_add_interface(struct ieee80211_local *local, 1417b7eab6fSJohannes Berg struct ieee80211_sub_if_data *sdata) 14224487981SJohannes Berg { 143e1781ed3SKalle Valo int ret; 144e1781ed3SKalle Valo 145e1781ed3SKalle Valo might_sleep(); 146e1781ed3SKalle Valo 1477b7eab6fSJohannes Berg if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || 1484b6f1dd6SJohannes Berg (sdata->vif.type == NL80211_IFTYPE_MONITOR && 1494b6f1dd6SJohannes Berg !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)))) 1507b7eab6fSJohannes Berg return -EINVAL; 1517b7eab6fSJohannes Berg 1527b7eab6fSJohannes Berg trace_drv_add_interface(local, sdata); 1537b7eab6fSJohannes Berg ret = local->ops->add_interface(&local->hw, &sdata->vif); 1544efc76bdSJohannes Berg trace_drv_return_int(local, ret); 1557b7eab6fSJohannes Berg 1567b7eab6fSJohannes Berg if (ret == 0) 1577b7eab6fSJohannes Berg sdata->flags |= IEEE80211_SDATA_IN_DRIVER; 1587b7eab6fSJohannes Berg 1590a2b8bb2SJohannes Berg return ret; 16024487981SJohannes Berg } 16124487981SJohannes Berg 16234d4bc4dSJohannes Berg static inline int drv_change_interface(struct ieee80211_local *local, 16334d4bc4dSJohannes Berg struct ieee80211_sub_if_data *sdata, 1642ca27bcfSJohannes Berg enum nl80211_iftype type, bool p2p) 16534d4bc4dSJohannes Berg { 16634d4bc4dSJohannes Berg int ret; 16734d4bc4dSJohannes Berg 16834d4bc4dSJohannes Berg might_sleep(); 16934d4bc4dSJohannes Berg 1707b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 1717b7eab6fSJohannes Berg 1722ca27bcfSJohannes Berg trace_drv_change_interface(local, sdata, type, p2p); 1732ca27bcfSJohannes Berg ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); 17434d4bc4dSJohannes Berg trace_drv_return_int(local, ret); 17534d4bc4dSJohannes Berg return ret; 17634d4bc4dSJohannes Berg } 17734d4bc4dSJohannes Berg 17824487981SJohannes Berg static inline void drv_remove_interface(struct ieee80211_local *local, 1797b7eab6fSJohannes Berg struct ieee80211_sub_if_data *sdata) 18024487981SJohannes Berg { 181e1781ed3SKalle Valo might_sleep(); 182e1781ed3SKalle Valo 1837b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 1847b7eab6fSJohannes Berg 1857b7eab6fSJohannes Berg trace_drv_remove_interface(local, sdata); 1867b7eab6fSJohannes Berg local->ops->remove_interface(&local->hw, &sdata->vif); 1877b7eab6fSJohannes Berg sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER; 1884efc76bdSJohannes Berg trace_drv_return_void(local); 18924487981SJohannes Berg } 19024487981SJohannes Berg 19124487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed) 19224487981SJohannes Berg { 193e1781ed3SKalle Valo int ret; 194e1781ed3SKalle Valo 195e1781ed3SKalle Valo might_sleep(); 196e1781ed3SKalle Valo 1974efc76bdSJohannes Berg trace_drv_config(local, changed); 198e1781ed3SKalle Valo ret = local->ops->config(&local->hw, changed); 1994efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2000a2b8bb2SJohannes Berg return ret; 20124487981SJohannes Berg } 20224487981SJohannes Berg 20324487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local, 20412375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 20524487981SJohannes Berg struct ieee80211_bss_conf *info, 20624487981SJohannes Berg u32 changed) 20724487981SJohannes Berg { 208e1781ed3SKalle Valo might_sleep(); 209e1781ed3SKalle Valo 2107b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2117b7eab6fSJohannes Berg 2124efc76bdSJohannes Berg trace_drv_bss_info_changed(local, sdata, info, changed); 21324487981SJohannes Berg if (local->ops->bss_info_changed) 21412375ef9SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 2154efc76bdSJohannes Berg trace_drv_return_void(local); 21624487981SJohannes Berg } 21724487981SJohannes Berg 2183ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 21922bedad3SJiri Pirko struct netdev_hw_addr_list *mc_list) 22024487981SJohannes Berg { 2213ac64beeSJohannes Berg u64 ret = 0; 2223ac64beeSJohannes Berg 2234efc76bdSJohannes Berg trace_drv_prepare_multicast(local, mc_list->count); 2244efc76bdSJohannes Berg 2253ac64beeSJohannes Berg if (local->ops->prepare_multicast) 22622bedad3SJiri Pirko ret = local->ops->prepare_multicast(&local->hw, mc_list); 2273ac64beeSJohannes Berg 2284efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 2293ac64beeSJohannes Berg 2303ac64beeSJohannes Berg return ret; 2313ac64beeSJohannes Berg } 2323ac64beeSJohannes Berg 2333ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local, 2343ac64beeSJohannes Berg unsigned int changed_flags, 2353ac64beeSJohannes Berg unsigned int *total_flags, 2363ac64beeSJohannes Berg u64 multicast) 2373ac64beeSJohannes Berg { 2383ac64beeSJohannes Berg might_sleep(); 2393ac64beeSJohannes Berg 2400a2b8bb2SJohannes Berg trace_drv_configure_filter(local, changed_flags, total_flags, 2413ac64beeSJohannes Berg multicast); 2424efc76bdSJohannes Berg local->ops->configure_filter(&local->hw, changed_flags, total_flags, 2434efc76bdSJohannes Berg multicast); 2444efc76bdSJohannes Berg trace_drv_return_void(local); 24524487981SJohannes Berg } 24624487981SJohannes Berg 24724487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local, 24824487981SJohannes Berg struct ieee80211_sta *sta, bool set) 24924487981SJohannes Berg { 2500a2b8bb2SJohannes Berg int ret = 0; 2514efc76bdSJohannes Berg trace_drv_set_tim(local, sta, set); 25224487981SJohannes Berg if (local->ops->set_tim) 2530a2b8bb2SJohannes Berg ret = local->ops->set_tim(&local->hw, sta, set); 2544efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2550a2b8bb2SJohannes Berg return ret; 25624487981SJohannes Berg } 25724487981SJohannes Berg 25824487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local, 25912375ef9SJohannes Berg enum set_key_cmd cmd, 26012375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 26124487981SJohannes Berg struct ieee80211_sta *sta, 26224487981SJohannes Berg struct ieee80211_key_conf *key) 26324487981SJohannes Berg { 264e1781ed3SKalle Valo int ret; 265e1781ed3SKalle Valo 266e1781ed3SKalle Valo might_sleep(); 267e1781ed3SKalle Valo 268077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 2697b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2707b7eab6fSJohannes Berg 2714efc76bdSJohannes Berg trace_drv_set_key(local, cmd, sdata, sta, key); 272e1781ed3SKalle Valo ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 2734efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2740a2b8bb2SJohannes Berg return ret; 27524487981SJohannes Berg } 27624487981SJohannes Berg 27724487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local, 278b3fbdcf4SJohannes Berg struct ieee80211_sub_if_data *sdata, 27924487981SJohannes Berg struct ieee80211_key_conf *conf, 280b3fbdcf4SJohannes Berg struct sta_info *sta, u32 iv32, 28124487981SJohannes Berg u16 *phase1key) 28224487981SJohannes Berg { 283b3fbdcf4SJohannes Berg struct ieee80211_sta *ista = NULL; 284b3fbdcf4SJohannes Berg 285b3fbdcf4SJohannes Berg if (sta) 286b3fbdcf4SJohannes Berg ista = &sta->sta; 287b3fbdcf4SJohannes Berg 288077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 2897b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 2907b7eab6fSJohannes Berg 2914efc76bdSJohannes Berg trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 29224487981SJohannes Berg if (local->ops->update_tkip_key) 293b3fbdcf4SJohannes Berg local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 294b3fbdcf4SJohannes Berg ista, iv32, phase1key); 2954efc76bdSJohannes Berg trace_drv_return_void(local); 29624487981SJohannes Berg } 29724487981SJohannes Berg 29824487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local, 299a060bbfeSJohannes Berg struct ieee80211_sub_if_data *sdata, 30024487981SJohannes Berg struct cfg80211_scan_request *req) 30124487981SJohannes Berg { 302e1781ed3SKalle Valo int ret; 303e1781ed3SKalle Valo 304e1781ed3SKalle Valo might_sleep(); 305e1781ed3SKalle Valo 3067b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3077b7eab6fSJohannes Berg 30879f460caSLuciano Coelho trace_drv_hw_scan(local, sdata); 309a060bbfeSJohannes Berg ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 3104efc76bdSJohannes Berg trace_drv_return_int(local, ret); 3110a2b8bb2SJohannes Berg return ret; 31224487981SJohannes Berg } 31324487981SJohannes Berg 314b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 315b856439bSEliad Peller struct ieee80211_sub_if_data *sdata) 316b856439bSEliad Peller { 317b856439bSEliad Peller might_sleep(); 318b856439bSEliad Peller 3197b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3207b7eab6fSJohannes Berg 321b856439bSEliad Peller trace_drv_cancel_hw_scan(local, sdata); 322b856439bSEliad Peller local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 323b856439bSEliad Peller trace_drv_return_void(local); 324b856439bSEliad Peller } 325b856439bSEliad Peller 32679f460caSLuciano Coelho static inline int 32779f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local, 32879f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata, 32979f460caSLuciano Coelho struct cfg80211_sched_scan_request *req, 33079f460caSLuciano Coelho struct ieee80211_sched_scan_ies *ies) 33179f460caSLuciano Coelho { 33279f460caSLuciano Coelho int ret; 33379f460caSLuciano Coelho 33479f460caSLuciano Coelho might_sleep(); 33579f460caSLuciano Coelho 3367b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3377b7eab6fSJohannes Berg 33879f460caSLuciano Coelho trace_drv_sched_scan_start(local, sdata); 33979f460caSLuciano Coelho ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 34079f460caSLuciano Coelho req, ies); 34179f460caSLuciano Coelho trace_drv_return_int(local, ret); 34279f460caSLuciano Coelho return ret; 34379f460caSLuciano Coelho } 34479f460caSLuciano Coelho 34579f460caSLuciano Coelho static inline void drv_sched_scan_stop(struct ieee80211_local *local, 34679f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata) 34779f460caSLuciano Coelho { 34879f460caSLuciano Coelho might_sleep(); 34979f460caSLuciano Coelho 3507b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 3517b7eab6fSJohannes Berg 35279f460caSLuciano Coelho trace_drv_sched_scan_stop(local, sdata); 35379f460caSLuciano Coelho local->ops->sched_scan_stop(&local->hw, &sdata->vif); 35479f460caSLuciano Coelho trace_drv_return_void(local); 35579f460caSLuciano Coelho } 35679f460caSLuciano Coelho 35724487981SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local) 35824487981SJohannes Berg { 359e1781ed3SKalle Valo might_sleep(); 360e1781ed3SKalle Valo 3614efc76bdSJohannes Berg trace_drv_sw_scan_start(local); 36224487981SJohannes Berg if (local->ops->sw_scan_start) 36324487981SJohannes Berg local->ops->sw_scan_start(&local->hw); 3644efc76bdSJohannes Berg trace_drv_return_void(local); 36524487981SJohannes Berg } 36624487981SJohannes Berg 36724487981SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local) 36824487981SJohannes Berg { 369e1781ed3SKalle Valo might_sleep(); 370e1781ed3SKalle Valo 3714efc76bdSJohannes Berg trace_drv_sw_scan_complete(local); 37224487981SJohannes Berg if (local->ops->sw_scan_complete) 37324487981SJohannes Berg local->ops->sw_scan_complete(&local->hw); 3744efc76bdSJohannes Berg trace_drv_return_void(local); 37524487981SJohannes Berg } 37624487981SJohannes Berg 37724487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local, 37824487981SJohannes Berg struct ieee80211_low_level_stats *stats) 37924487981SJohannes Berg { 3800a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 3810a2b8bb2SJohannes Berg 382e1781ed3SKalle Valo might_sleep(); 383e1781ed3SKalle Valo 3840a2b8bb2SJohannes Berg if (local->ops->get_stats) 3850a2b8bb2SJohannes Berg ret = local->ops->get_stats(&local->hw, stats); 3860a2b8bb2SJohannes Berg trace_drv_get_stats(local, stats, ret); 3870a2b8bb2SJohannes Berg 3880a2b8bb2SJohannes Berg return ret; 38924487981SJohannes Berg } 39024487981SJohannes Berg 39124487981SJohannes Berg static inline void drv_get_tkip_seq(struct ieee80211_local *local, 39224487981SJohannes Berg u8 hw_key_idx, u32 *iv32, u16 *iv16) 39324487981SJohannes Berg { 39424487981SJohannes Berg if (local->ops->get_tkip_seq) 39524487981SJohannes Berg local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16); 3960a2b8bb2SJohannes Berg trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16); 39724487981SJohannes Berg } 39824487981SJohannes Berg 399f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local, 400f23a4780SArik Nemtsov u32 value) 401f23a4780SArik Nemtsov { 402f23a4780SArik Nemtsov int ret = 0; 403f23a4780SArik Nemtsov 404f23a4780SArik Nemtsov might_sleep(); 405f23a4780SArik Nemtsov 406f23a4780SArik Nemtsov trace_drv_set_frag_threshold(local, value); 407f23a4780SArik Nemtsov if (local->ops->set_frag_threshold) 408f23a4780SArik Nemtsov ret = local->ops->set_frag_threshold(&local->hw, value); 409f23a4780SArik Nemtsov trace_drv_return_int(local, ret); 410f23a4780SArik Nemtsov return ret; 411f23a4780SArik Nemtsov } 412f23a4780SArik Nemtsov 41324487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local, 41424487981SJohannes Berg u32 value) 41524487981SJohannes Berg { 4160a2b8bb2SJohannes Berg int ret = 0; 417e1781ed3SKalle Valo 418e1781ed3SKalle Valo might_sleep(); 419e1781ed3SKalle Valo 4204efc76bdSJohannes Berg trace_drv_set_rts_threshold(local, value); 42124487981SJohannes Berg if (local->ops->set_rts_threshold) 4220a2b8bb2SJohannes Berg ret = local->ops->set_rts_threshold(&local->hw, value); 4234efc76bdSJohannes Berg trace_drv_return_int(local, ret); 4240a2b8bb2SJohannes Berg return ret; 42524487981SJohannes Berg } 42624487981SJohannes Berg 427310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local, 428310bc676SLukáš Turek u8 value) 429310bc676SLukáš Turek { 430310bc676SLukáš Turek int ret = 0; 431310bc676SLukáš Turek might_sleep(); 432310bc676SLukáš Turek 4334efc76bdSJohannes Berg trace_drv_set_coverage_class(local, value); 434310bc676SLukáš Turek if (local->ops->set_coverage_class) 435310bc676SLukáš Turek local->ops->set_coverage_class(&local->hw, value); 436310bc676SLukáš Turek else 437310bc676SLukáš Turek ret = -EOPNOTSUPP; 438310bc676SLukáš Turek 4394efc76bdSJohannes Berg trace_drv_return_int(local, ret); 440310bc676SLukáš Turek return ret; 441310bc676SLukáš Turek } 442310bc676SLukáš Turek 44324487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local, 44412375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 44524487981SJohannes Berg enum sta_notify_cmd cmd, 44624487981SJohannes Berg struct ieee80211_sta *sta) 44724487981SJohannes Berg { 448bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4497b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4507b7eab6fSJohannes Berg 4514efc76bdSJohannes Berg trace_drv_sta_notify(local, sdata, cmd, sta); 45224487981SJohannes Berg if (local->ops->sta_notify) 45312375ef9SJohannes Berg local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 4544efc76bdSJohannes Berg trace_drv_return_void(local); 45524487981SJohannes Berg } 45624487981SJohannes Berg 45734e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local, 45834e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 45934e89507SJohannes Berg struct ieee80211_sta *sta) 46034e89507SJohannes Berg { 46134e89507SJohannes Berg int ret = 0; 46234e89507SJohannes Berg 46334e89507SJohannes Berg might_sleep(); 46434e89507SJohannes Berg 465bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4667b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4677b7eab6fSJohannes Berg 4684efc76bdSJohannes Berg trace_drv_sta_add(local, sdata, sta); 46934e89507SJohannes Berg if (local->ops->sta_add) 47034e89507SJohannes Berg ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 47134e89507SJohannes Berg 4724efc76bdSJohannes Berg trace_drv_return_int(local, ret); 47334e89507SJohannes Berg 47434e89507SJohannes Berg return ret; 47534e89507SJohannes Berg } 47634e89507SJohannes Berg 47734e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local, 47834e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 47934e89507SJohannes Berg struct ieee80211_sta *sta) 48034e89507SJohannes Berg { 48134e89507SJohannes Berg might_sleep(); 48234e89507SJohannes Berg 483bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 4847b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 4857b7eab6fSJohannes Berg 4864efc76bdSJohannes Berg trace_drv_sta_remove(local, sdata, sta); 48734e89507SJohannes Berg if (local->ops->sta_remove) 48834e89507SJohannes Berg local->ops->sta_remove(&local->hw, &sdata->vif, sta); 48934e89507SJohannes Berg 4904efc76bdSJohannes Berg trace_drv_return_void(local); 49134e89507SJohannes Berg } 49234e89507SJohannes Berg 49377d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS 49477d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 49577d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 49677d2ece6SSujith Manoharan struct ieee80211_sta *sta, 49777d2ece6SSujith Manoharan struct dentry *dir) 49877d2ece6SSujith Manoharan { 49977d2ece6SSujith Manoharan might_sleep(); 50077d2ece6SSujith Manoharan 50177d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 50277d2ece6SSujith Manoharan check_sdata_in_driver(sdata); 50377d2ece6SSujith Manoharan 50477d2ece6SSujith Manoharan if (local->ops->sta_add_debugfs) 50577d2ece6SSujith Manoharan local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 50677d2ece6SSujith Manoharan sta, dir); 50777d2ece6SSujith Manoharan } 50877d2ece6SSujith Manoharan 50977d2ece6SSujith Manoharan static inline void drv_sta_remove_debugfs(struct ieee80211_local *local, 51077d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 51177d2ece6SSujith Manoharan struct ieee80211_sta *sta, 51277d2ece6SSujith Manoharan struct dentry *dir) 51377d2ece6SSujith Manoharan { 51477d2ece6SSujith Manoharan might_sleep(); 51577d2ece6SSujith Manoharan 51677d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 51777d2ece6SSujith Manoharan check_sdata_in_driver(sdata); 51877d2ece6SSujith Manoharan 51977d2ece6SSujith Manoharan if (local->ops->sta_remove_debugfs) 52077d2ece6SSujith Manoharan local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, 52177d2ece6SSujith Manoharan sta, dir); 52277d2ece6SSujith Manoharan } 52377d2ece6SSujith Manoharan #endif 52477d2ece6SSujith Manoharan 525f09603a2SJohannes Berg static inline __must_check 526f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local, 527f09603a2SJohannes Berg struct ieee80211_sub_if_data *sdata, 528f09603a2SJohannes Berg struct sta_info *sta, 529f09603a2SJohannes Berg enum ieee80211_sta_state old_state, 530f09603a2SJohannes Berg enum ieee80211_sta_state new_state) 531f09603a2SJohannes Berg { 532f09603a2SJohannes Berg int ret = 0; 533f09603a2SJohannes Berg 534f09603a2SJohannes Berg might_sleep(); 535f09603a2SJohannes Berg 536f09603a2SJohannes Berg sdata = get_bss_sdata(sdata); 537f09603a2SJohannes Berg check_sdata_in_driver(sdata); 538f09603a2SJohannes Berg 539f09603a2SJohannes Berg trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state); 540a4ec45a4SJohannes Berg if (local->ops->sta_state) { 541f09603a2SJohannes Berg ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta, 542f09603a2SJohannes Berg old_state, new_state); 543a4ec45a4SJohannes Berg } else if (old_state == IEEE80211_STA_AUTH && 544a4ec45a4SJohannes Berg new_state == IEEE80211_STA_ASSOC) { 545a4ec45a4SJohannes Berg ret = drv_sta_add(local, sdata, &sta->sta); 546a4ec45a4SJohannes Berg if (ret == 0) 547a4ec45a4SJohannes Berg sta->uploaded = true; 548a4ec45a4SJohannes Berg } else if (old_state == IEEE80211_STA_ASSOC && 549a4ec45a4SJohannes Berg new_state == IEEE80211_STA_AUTH) { 550a4ec45a4SJohannes Berg drv_sta_remove(local, sdata, &sta->sta); 551a4ec45a4SJohannes Berg } 552f09603a2SJohannes Berg trace_drv_return_int(local, ret); 553f09603a2SJohannes Berg return ret; 554f09603a2SJohannes Berg } 555f09603a2SJohannes Berg 5568f727ef3SJohannes Berg static inline void drv_sta_rc_update(struct ieee80211_local *local, 5578f727ef3SJohannes Berg struct ieee80211_sub_if_data *sdata, 5588f727ef3SJohannes Berg struct ieee80211_sta *sta, u32 changed) 5598f727ef3SJohannes Berg { 5608f727ef3SJohannes Berg sdata = get_bss_sdata(sdata); 5618f727ef3SJohannes Berg check_sdata_in_driver(sdata); 5628f727ef3SJohannes Berg 563e687f61eSAntonio Quartulli WARN_ON(changed & IEEE80211_RC_SUPP_RATES_CHANGED && 564e687f61eSAntonio Quartulli sdata->vif.type != NL80211_IFTYPE_ADHOC); 565e687f61eSAntonio Quartulli 5668f727ef3SJohannes Berg trace_drv_sta_rc_update(local, sdata, sta, changed); 5678f727ef3SJohannes Berg if (local->ops->sta_rc_update) 5688f727ef3SJohannes Berg local->ops->sta_rc_update(&local->hw, &sdata->vif, 5698f727ef3SJohannes Berg sta, changed); 5708f727ef3SJohannes Berg 5718f727ef3SJohannes Berg trace_drv_return_void(local); 5728f727ef3SJohannes Berg } 5738f727ef3SJohannes Berg 574f6f3def3SEliad Peller static inline int drv_conf_tx(struct ieee80211_local *local, 575a3304b0aSJohannes Berg struct ieee80211_sub_if_data *sdata, u16 ac, 57624487981SJohannes Berg const struct ieee80211_tx_queue_params *params) 57724487981SJohannes Berg { 5780a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 579e1781ed3SKalle Valo 580e1781ed3SKalle Valo might_sleep(); 581e1781ed3SKalle Valo 5827b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 5837b7eab6fSJohannes Berg 584a3304b0aSJohannes Berg trace_drv_conf_tx(local, sdata, ac, params); 58524487981SJohannes Berg if (local->ops->conf_tx) 5868a3a3c85SEliad Peller ret = local->ops->conf_tx(&local->hw, &sdata->vif, 587a3304b0aSJohannes Berg ac, params); 5884efc76bdSJohannes Berg trace_drv_return_int(local, ret); 5890a2b8bb2SJohannes Berg return ret; 59024487981SJohannes Berg } 59124487981SJohannes Berg 59237a41b4aSEliad Peller static inline u64 drv_get_tsf(struct ieee80211_local *local, 59337a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata) 59424487981SJohannes Berg { 5950a2b8bb2SJohannes Berg u64 ret = -1ULL; 596e1781ed3SKalle Valo 597e1781ed3SKalle Valo might_sleep(); 598e1781ed3SKalle Valo 5997b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 6007b7eab6fSJohannes Berg 60137a41b4aSEliad Peller trace_drv_get_tsf(local, sdata); 60224487981SJohannes Berg if (local->ops->get_tsf) 60337a41b4aSEliad Peller ret = local->ops->get_tsf(&local->hw, &sdata->vif); 6044efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 6050a2b8bb2SJohannes Berg return ret; 60624487981SJohannes Berg } 60724487981SJohannes Berg 60837a41b4aSEliad Peller static inline void drv_set_tsf(struct ieee80211_local *local, 60937a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata, 61037a41b4aSEliad Peller u64 tsf) 61124487981SJohannes Berg { 612e1781ed3SKalle Valo might_sleep(); 613e1781ed3SKalle Valo 6147b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 6157b7eab6fSJohannes Berg 61637a41b4aSEliad Peller trace_drv_set_tsf(local, sdata, tsf); 61724487981SJohannes Berg if (local->ops->set_tsf) 61837a41b4aSEliad Peller local->ops->set_tsf(&local->hw, &sdata->vif, tsf); 6194efc76bdSJohannes Berg trace_drv_return_void(local); 62024487981SJohannes Berg } 62124487981SJohannes Berg 62237a41b4aSEliad Peller static inline void drv_reset_tsf(struct ieee80211_local *local, 62337a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata) 62424487981SJohannes Berg { 625e1781ed3SKalle Valo might_sleep(); 626e1781ed3SKalle Valo 6277b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 6287b7eab6fSJohannes Berg 62937a41b4aSEliad Peller trace_drv_reset_tsf(local, sdata); 63024487981SJohannes Berg if (local->ops->reset_tsf) 63137a41b4aSEliad Peller local->ops->reset_tsf(&local->hw, &sdata->vif); 6324efc76bdSJohannes Berg trace_drv_return_void(local); 63324487981SJohannes Berg } 63424487981SJohannes Berg 63524487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local) 63624487981SJohannes Berg { 63702582e9bSMasanari Iida int ret = 0; /* default unsupported op for less congestion */ 638e1781ed3SKalle Valo 639e1781ed3SKalle Valo might_sleep(); 640e1781ed3SKalle Valo 6414efc76bdSJohannes Berg trace_drv_tx_last_beacon(local); 64224487981SJohannes Berg if (local->ops->tx_last_beacon) 6430a2b8bb2SJohannes Berg ret = local->ops->tx_last_beacon(&local->hw); 6444efc76bdSJohannes Berg trace_drv_return_int(local, ret); 6450a2b8bb2SJohannes Berg return ret; 64624487981SJohannes Berg } 64724487981SJohannes Berg 64824487981SJohannes Berg static inline int drv_ampdu_action(struct ieee80211_local *local, 64912375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 65024487981SJohannes Berg enum ieee80211_ampdu_mlme_action action, 65124487981SJohannes Berg struct ieee80211_sta *sta, u16 tid, 6520b01f030SJohannes Berg u16 *ssn, u8 buf_size) 65324487981SJohannes Berg { 6540a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 655cfcdbde3SJohannes Berg 656cfcdbde3SJohannes Berg might_sleep(); 657cfcdbde3SJohannes Berg 658bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 6597b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 6607b7eab6fSJohannes Berg 6610b01f030SJohannes Berg trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); 6624efc76bdSJohannes Berg 66324487981SJohannes Berg if (local->ops->ampdu_action) 66412375ef9SJohannes Berg ret = local->ops->ampdu_action(&local->hw, &sdata->vif, action, 6650b01f030SJohannes Berg sta, tid, ssn, buf_size); 66685ad181eSJohannes Berg 6674efc76bdSJohannes Berg trace_drv_return_int(local, ret); 6684efc76bdSJohannes Berg 6690a2b8bb2SJohannes Berg return ret; 67024487981SJohannes Berg } 6711f87f7d3SJohannes Berg 6721289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx, 6731289723eSHolger Schurig struct survey_info *survey) 6741289723eSHolger Schurig { 6751289723eSHolger Schurig int ret = -EOPNOTSUPP; 676c466d4efSJohn W. Linville 677c466d4efSJohn W. Linville trace_drv_get_survey(local, idx, survey); 678c466d4efSJohn W. Linville 67935dd0509SHolger Schurig if (local->ops->get_survey) 6801289723eSHolger Schurig ret = local->ops->get_survey(&local->hw, idx, survey); 681c466d4efSJohn W. Linville 682c466d4efSJohn W. Linville trace_drv_return_int(local, ret); 683c466d4efSJohn W. Linville 6841289723eSHolger Schurig return ret; 6851289723eSHolger Schurig } 6861f87f7d3SJohannes Berg 6871f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local) 6881f87f7d3SJohannes Berg { 689e1781ed3SKalle Valo might_sleep(); 690e1781ed3SKalle Valo 6911f87f7d3SJohannes Berg if (local->ops->rfkill_poll) 6921f87f7d3SJohannes Berg local->ops->rfkill_poll(&local->hw); 6931f87f7d3SJohannes Berg } 694a80f7c0bSJohannes Berg 695a80f7c0bSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, bool drop) 696a80f7c0bSJohannes Berg { 697e1781ed3SKalle Valo might_sleep(); 698e1781ed3SKalle Valo 699a80f7c0bSJohannes Berg trace_drv_flush(local, drop); 700a80f7c0bSJohannes Berg if (local->ops->flush) 701a80f7c0bSJohannes Berg local->ops->flush(&local->hw, drop); 7024efc76bdSJohannes Berg trace_drv_return_void(local); 703a80f7c0bSJohannes Berg } 7045ce6e438SJohannes Berg 7055ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local, 7065ce6e438SJohannes Berg struct ieee80211_channel_switch *ch_switch) 7075ce6e438SJohannes Berg { 7085ce6e438SJohannes Berg might_sleep(); 7095ce6e438SJohannes Berg 7105ce6e438SJohannes Berg trace_drv_channel_switch(local, ch_switch); 7114efc76bdSJohannes Berg local->ops->channel_switch(&local->hw, ch_switch); 7124efc76bdSJohannes Berg trace_drv_return_void(local); 7135ce6e438SJohannes Berg } 7145ce6e438SJohannes Berg 71515d96753SBruno Randolf 71615d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local, 71715d96753SBruno Randolf u32 tx_ant, u32 rx_ant) 71815d96753SBruno Randolf { 71915d96753SBruno Randolf int ret = -EOPNOTSUPP; 72015d96753SBruno Randolf might_sleep(); 72115d96753SBruno Randolf if (local->ops->set_antenna) 72215d96753SBruno Randolf ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 72315d96753SBruno Randolf trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 72415d96753SBruno Randolf return ret; 72515d96753SBruno Randolf } 72615d96753SBruno Randolf 72715d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local, 72815d96753SBruno Randolf u32 *tx_ant, u32 *rx_ant) 72915d96753SBruno Randolf { 73015d96753SBruno Randolf int ret = -EOPNOTSUPP; 73115d96753SBruno Randolf might_sleep(); 73215d96753SBruno Randolf if (local->ops->get_antenna) 73315d96753SBruno Randolf ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 73415d96753SBruno Randolf trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 73515d96753SBruno Randolf return ret; 73615d96753SBruno Randolf } 73715d96753SBruno Randolf 73821f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local, 73949884568SEliad Peller struct ieee80211_sub_if_data *sdata, 74021f83589SJohannes Berg struct ieee80211_channel *chan, 74121f83589SJohannes Berg unsigned int duration) 74221f83589SJohannes Berg { 74321f83589SJohannes Berg int ret; 74421f83589SJohannes Berg 74521f83589SJohannes Berg might_sleep(); 74621f83589SJohannes Berg 74742d97a59SJohannes Berg trace_drv_remain_on_channel(local, sdata, chan, duration); 74849884568SEliad Peller ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 74942d97a59SJohannes Berg chan, duration); 75021f83589SJohannes Berg trace_drv_return_int(local, ret); 75121f83589SJohannes Berg 75221f83589SJohannes Berg return ret; 75321f83589SJohannes Berg } 75421f83589SJohannes Berg 75521f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local) 75621f83589SJohannes Berg { 75721f83589SJohannes Berg int ret; 75821f83589SJohannes Berg 75921f83589SJohannes Berg might_sleep(); 76021f83589SJohannes Berg 76121f83589SJohannes Berg trace_drv_cancel_remain_on_channel(local); 76221f83589SJohannes Berg ret = local->ops->cancel_remain_on_channel(&local->hw); 76321f83589SJohannes Berg trace_drv_return_int(local, ret); 76421f83589SJohannes Berg 76521f83589SJohannes Berg return ret; 76621f83589SJohannes Berg } 76721f83589SJohannes Berg 76838c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local, 76938c09159SJohn W. Linville u32 tx, u32 rx) 77038c09159SJohn W. Linville { 77138c09159SJohn W. Linville int ret = -ENOTSUPP; 77238c09159SJohn W. Linville 77338c09159SJohn W. Linville might_sleep(); 77438c09159SJohn W. Linville 77538c09159SJohn W. Linville trace_drv_set_ringparam(local, tx, rx); 77638c09159SJohn W. Linville if (local->ops->set_ringparam) 77738c09159SJohn W. Linville ret = local->ops->set_ringparam(&local->hw, tx, rx); 77838c09159SJohn W. Linville trace_drv_return_int(local, ret); 77938c09159SJohn W. Linville 78038c09159SJohn W. Linville return ret; 78138c09159SJohn W. Linville } 78238c09159SJohn W. Linville 78338c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local, 78438c09159SJohn W. Linville u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 78538c09159SJohn W. Linville { 78638c09159SJohn W. Linville might_sleep(); 78738c09159SJohn W. Linville 78838c09159SJohn W. Linville trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 78938c09159SJohn W. Linville if (local->ops->get_ringparam) 79038c09159SJohn W. Linville local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 79138c09159SJohn W. Linville trace_drv_return_void(local); 79238c09159SJohn W. Linville } 79338c09159SJohn W. Linville 794e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 795e8306f98SVivek Natarajan { 796e8306f98SVivek Natarajan bool ret = false; 797e8306f98SVivek Natarajan 798e8306f98SVivek Natarajan might_sleep(); 799e8306f98SVivek Natarajan 800e8306f98SVivek Natarajan trace_drv_tx_frames_pending(local); 801e8306f98SVivek Natarajan if (local->ops->tx_frames_pending) 802e8306f98SVivek Natarajan ret = local->ops->tx_frames_pending(&local->hw); 803e8306f98SVivek Natarajan trace_drv_return_bool(local, ret); 804e8306f98SVivek Natarajan 805e8306f98SVivek Natarajan return ret; 806e8306f98SVivek Natarajan } 807bdbfd6b5SSujith Manoharan 808bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 809bdbfd6b5SSujith Manoharan struct ieee80211_sub_if_data *sdata, 810bdbfd6b5SSujith Manoharan const struct cfg80211_bitrate_mask *mask) 811bdbfd6b5SSujith Manoharan { 812bdbfd6b5SSujith Manoharan int ret = -EOPNOTSUPP; 813bdbfd6b5SSujith Manoharan 814bdbfd6b5SSujith Manoharan might_sleep(); 815bdbfd6b5SSujith Manoharan 8167b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 8177b7eab6fSJohannes Berg 818bdbfd6b5SSujith Manoharan trace_drv_set_bitrate_mask(local, sdata, mask); 819bdbfd6b5SSujith Manoharan if (local->ops->set_bitrate_mask) 820bdbfd6b5SSujith Manoharan ret = local->ops->set_bitrate_mask(&local->hw, 821bdbfd6b5SSujith Manoharan &sdata->vif, mask); 822bdbfd6b5SSujith Manoharan trace_drv_return_int(local, ret); 823bdbfd6b5SSujith Manoharan 824bdbfd6b5SSujith Manoharan return ret; 825bdbfd6b5SSujith Manoharan } 826bdbfd6b5SSujith Manoharan 827c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local, 828c68f4b89SJohannes Berg struct ieee80211_sub_if_data *sdata, 829c68f4b89SJohannes Berg struct cfg80211_gtk_rekey_data *data) 830c68f4b89SJohannes Berg { 8317b7eab6fSJohannes Berg check_sdata_in_driver(sdata); 8327b7eab6fSJohannes Berg 833c68f4b89SJohannes Berg trace_drv_set_rekey_data(local, sdata, data); 834c68f4b89SJohannes Berg if (local->ops->set_rekey_data) 835c68f4b89SJohannes Berg local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 836c68f4b89SJohannes Berg trace_drv_return_void(local); 837c68f4b89SJohannes Berg } 838c68f4b89SJohannes Berg 839615f7b9bSMeenakshi Venkataraman static inline void drv_rssi_callback(struct ieee80211_local *local, 840615f7b9bSMeenakshi Venkataraman const enum ieee80211_rssi_event event) 841615f7b9bSMeenakshi Venkataraman { 842615f7b9bSMeenakshi Venkataraman trace_drv_rssi_callback(local, event); 843615f7b9bSMeenakshi Venkataraman if (local->ops->rssi_callback) 844615f7b9bSMeenakshi Venkataraman local->ops->rssi_callback(&local->hw, event); 845615f7b9bSMeenakshi Venkataraman trace_drv_return_void(local); 846615f7b9bSMeenakshi Venkataraman } 8474049e09aSJohannes Berg 8484049e09aSJohannes Berg static inline void 8494049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local, 8504049e09aSJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 8514049e09aSJohannes Berg enum ieee80211_frame_release_type reason, 8524049e09aSJohannes Berg bool more_data) 8534049e09aSJohannes Berg { 8544049e09aSJohannes Berg trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 8554049e09aSJohannes Berg reason, more_data); 8564049e09aSJohannes Berg if (local->ops->release_buffered_frames) 8574049e09aSJohannes Berg local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 8584049e09aSJohannes Berg num_frames, reason, 8594049e09aSJohannes Berg more_data); 8604049e09aSJohannes Berg trace_drv_return_void(local); 8614049e09aSJohannes Berg } 86240b96408SJohannes Berg 86340b96408SJohannes Berg static inline void 86440b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local, 86540b96408SJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 86640b96408SJohannes Berg enum ieee80211_frame_release_type reason, 86740b96408SJohannes Berg bool more_data) 86840b96408SJohannes Berg { 86940b96408SJohannes Berg trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 87040b96408SJohannes Berg reason, more_data); 87140b96408SJohannes Berg if (local->ops->allow_buffered_frames) 87240b96408SJohannes Berg local->ops->allow_buffered_frames(&local->hw, &sta->sta, 87340b96408SJohannes Berg tids, num_frames, reason, 87440b96408SJohannes Berg more_data); 87540b96408SJohannes Berg trace_drv_return_void(local); 87640b96408SJohannes Berg } 87766572cfcSVictor Goldenshtein 87866572cfcSVictor Goldenshtein static inline int drv_get_rssi(struct ieee80211_local *local, 87966572cfcSVictor Goldenshtein struct ieee80211_sub_if_data *sdata, 88066572cfcSVictor Goldenshtein struct ieee80211_sta *sta, 88166572cfcSVictor Goldenshtein s8 *rssi_dbm) 88266572cfcSVictor Goldenshtein { 88366572cfcSVictor Goldenshtein int ret; 88466572cfcSVictor Goldenshtein 88566572cfcSVictor Goldenshtein might_sleep(); 88666572cfcSVictor Goldenshtein 88766572cfcSVictor Goldenshtein ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); 88866572cfcSVictor Goldenshtein trace_drv_get_rssi(local, sta, *rssi_dbm, ret); 88966572cfcSVictor Goldenshtein 89066572cfcSVictor Goldenshtein return ret; 89166572cfcSVictor Goldenshtein } 892a1845fc7SJohannes Berg 893a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 894a1845fc7SJohannes Berg struct ieee80211_sub_if_data *sdata) 895a1845fc7SJohannes Berg { 896a1845fc7SJohannes Berg might_sleep(); 897a1845fc7SJohannes Berg 898a1845fc7SJohannes Berg check_sdata_in_driver(sdata); 899a1845fc7SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 900a1845fc7SJohannes Berg 901a1845fc7SJohannes Berg trace_drv_mgd_prepare_tx(local, sdata); 902a1845fc7SJohannes Berg if (local->ops->mgd_prepare_tx) 903a1845fc7SJohannes Berg local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); 904a1845fc7SJohannes Berg trace_drv_return_void(local); 905a1845fc7SJohannes Berg } 906c3645eacSMichal Kazior 907c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local, 908c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 909c3645eacSMichal Kazior { 910c3645eacSMichal Kazior int ret = -EOPNOTSUPP; 911c3645eacSMichal Kazior 912c3645eacSMichal Kazior trace_drv_add_chanctx(local, ctx); 913c3645eacSMichal Kazior if (local->ops->add_chanctx) 914c3645eacSMichal Kazior ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 915c3645eacSMichal Kazior trace_drv_return_int(local, ret); 9168a61af65SJohannes Berg if (!ret) 9178a61af65SJohannes Berg ctx->driver_present = true; 918c3645eacSMichal Kazior 919c3645eacSMichal Kazior return ret; 920c3645eacSMichal Kazior } 921c3645eacSMichal Kazior 922c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local, 923c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 924c3645eacSMichal Kazior { 925c3645eacSMichal Kazior trace_drv_remove_chanctx(local, ctx); 926c3645eacSMichal Kazior if (local->ops->remove_chanctx) 927c3645eacSMichal Kazior local->ops->remove_chanctx(&local->hw, &ctx->conf); 928c3645eacSMichal Kazior trace_drv_return_void(local); 9298a61af65SJohannes Berg ctx->driver_present = false; 930c3645eacSMichal Kazior } 931c3645eacSMichal Kazior 932c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local, 933c3645eacSMichal Kazior struct ieee80211_chanctx *ctx, 934c3645eacSMichal Kazior u32 changed) 935c3645eacSMichal Kazior { 936c3645eacSMichal Kazior trace_drv_change_chanctx(local, ctx, changed); 9378a61af65SJohannes Berg if (local->ops->change_chanctx) { 9388a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 939c3645eacSMichal Kazior local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 9408a61af65SJohannes Berg } 941c3645eacSMichal Kazior trace_drv_return_void(local); 942c3645eacSMichal Kazior } 943c3645eacSMichal Kazior 944c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, 945c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 946c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 947c3645eacSMichal Kazior { 948c3645eacSMichal Kazior int ret = 0; 949c3645eacSMichal Kazior 950c3645eacSMichal Kazior check_sdata_in_driver(sdata); 951c3645eacSMichal Kazior 952c3645eacSMichal Kazior trace_drv_assign_vif_chanctx(local, sdata, ctx); 9538a61af65SJohannes Berg if (local->ops->assign_vif_chanctx) { 9548a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 955c3645eacSMichal Kazior ret = local->ops->assign_vif_chanctx(&local->hw, 956c3645eacSMichal Kazior &sdata->vif, 957c3645eacSMichal Kazior &ctx->conf); 9588a61af65SJohannes Berg } 959c3645eacSMichal Kazior trace_drv_return_int(local, ret); 960c3645eacSMichal Kazior 961c3645eacSMichal Kazior return ret; 962c3645eacSMichal Kazior } 963c3645eacSMichal Kazior 964c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, 965c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 966c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 967c3645eacSMichal Kazior { 968c3645eacSMichal Kazior check_sdata_in_driver(sdata); 969c3645eacSMichal Kazior 970c3645eacSMichal Kazior trace_drv_unassign_vif_chanctx(local, sdata, ctx); 9718a61af65SJohannes Berg if (local->ops->unassign_vif_chanctx) { 9728a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 973c3645eacSMichal Kazior local->ops->unassign_vif_chanctx(&local->hw, 974c3645eacSMichal Kazior &sdata->vif, 975c3645eacSMichal Kazior &ctx->conf); 9768a61af65SJohannes Berg } 977c3645eacSMichal Kazior trace_drv_return_void(local); 978c3645eacSMichal Kazior } 979c3645eacSMichal Kazior 9801041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local, 9811041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9821041638fSJohannes Berg { 9831041638fSJohannes Berg int ret = 0; 9841041638fSJohannes Berg 9851041638fSJohannes Berg check_sdata_in_driver(sdata); 9861041638fSJohannes Berg 9871041638fSJohannes Berg trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); 9881041638fSJohannes Berg if (local->ops->start_ap) 9891041638fSJohannes Berg ret = local->ops->start_ap(&local->hw, &sdata->vif); 9901041638fSJohannes Berg trace_drv_return_int(local, ret); 9911041638fSJohannes Berg return ret; 9921041638fSJohannes Berg } 9931041638fSJohannes Berg 9941041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local, 9951041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9961041638fSJohannes Berg { 9971041638fSJohannes Berg check_sdata_in_driver(sdata); 9981041638fSJohannes Berg 9991041638fSJohannes Berg trace_drv_stop_ap(local, sdata); 10001041638fSJohannes Berg if (local->ops->stop_ap) 10011041638fSJohannes Berg local->ops->stop_ap(&local->hw, &sdata->vif); 10021041638fSJohannes Berg trace_drv_return_void(local); 10031041638fSJohannes Berg } 10041041638fSJohannes Berg 10059214ad7fSJohannes Berg static inline void drv_restart_complete(struct ieee80211_local *local) 10069214ad7fSJohannes Berg { 10079214ad7fSJohannes Berg might_sleep(); 10089214ad7fSJohannes Berg 10099214ad7fSJohannes Berg trace_drv_restart_complete(local); 10109214ad7fSJohannes Berg if (local->ops->restart_complete) 10119214ad7fSJohannes Berg local->ops->restart_complete(&local->hw); 10129214ad7fSJohannes Berg trace_drv_return_void(local); 10139214ad7fSJohannes Berg } 10149214ad7fSJohannes Berg 101524487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */ 1016