1*f59374ebSSara Sharon /* 2*f59374ebSSara Sharon * Portions of this file 3*f59374ebSSara Sharon * Copyright(c) 2016 Intel Deutschland GmbH 4*f59374ebSSara Sharon */ 5*f59374ebSSara Sharon 624487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS 724487981SJohannes Berg #define __MAC80211_DRIVER_OPS 824487981SJohannes Berg 924487981SJohannes Berg #include <net/mac80211.h> 1024487981SJohannes Berg #include "ieee80211_i.h" 11011ad0e9SJohannes Berg #include "trace.h" 1224487981SJohannes Berg 13f6837ba8SJohannes Berg static inline bool check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) 147b7eab6fSJohannes Berg { 15f6837ba8SJohannes Berg return !WARN(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), 16d17087e7SBen Greear "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", 17f142c6b9SJohannes Berg sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); 187b7eab6fSJohannes Berg } 197b7eab6fSJohannes Berg 20bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data * 21bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata) 22bc192f89SFelix Fietkau { 23bc192f89SFelix Fietkau if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 24bc192f89SFelix Fietkau sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 25bc192f89SFelix Fietkau u.ap); 26bc192f89SFelix Fietkau 27bc192f89SFelix Fietkau return sdata; 28bc192f89SFelix Fietkau } 29bc192f89SFelix Fietkau 3036323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local, 3136323f81SThomas Huehn struct ieee80211_tx_control *control, 3236323f81SThomas Huehn struct sk_buff *skb) 3324487981SJohannes Berg { 3436323f81SThomas Huehn local->ops->tx(&local->hw, control, skb); 3524487981SJohannes Berg } 3624487981SJohannes Berg 37*f59374ebSSara Sharon static inline void drv_sync_rx_queues(struct ieee80211_local *local, 38*f59374ebSSara Sharon struct sta_info *sta) 39*f59374ebSSara Sharon { 40*f59374ebSSara Sharon if (local->ops->sync_rx_queues) { 41*f59374ebSSara Sharon trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta); 42*f59374ebSSara Sharon local->ops->sync_rx_queues(&local->hw); 43*f59374ebSSara Sharon trace_drv_return_void(local); 44*f59374ebSSara Sharon } 45*f59374ebSSara Sharon } 46*f59374ebSSara Sharon 47e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 48e352114fSBen Greear u32 sset, u8 *data) 49e352114fSBen Greear { 50e352114fSBen Greear struct ieee80211_local *local = sdata->local; 51e352114fSBen Greear if (local->ops->get_et_strings) { 52e352114fSBen Greear trace_drv_get_et_strings(local, sset); 53e352114fSBen Greear local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data); 54e352114fSBen Greear trace_drv_return_void(local); 55e352114fSBen Greear } 56e352114fSBen Greear } 57e352114fSBen Greear 58e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, 59e352114fSBen Greear struct ethtool_stats *stats, 60e352114fSBen Greear u64 *data) 61e352114fSBen Greear { 62e352114fSBen Greear struct ieee80211_local *local = sdata->local; 63e352114fSBen Greear if (local->ops->get_et_stats) { 64e352114fSBen Greear trace_drv_get_et_stats(local); 65e352114fSBen Greear local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); 66e352114fSBen Greear trace_drv_return_void(local); 67e352114fSBen Greear } 68e352114fSBen Greear } 69e352114fSBen Greear 70e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata, 71e352114fSBen Greear int sset) 72e352114fSBen Greear { 73e352114fSBen Greear struct ieee80211_local *local = sdata->local; 74e352114fSBen Greear int rv = 0; 75e352114fSBen Greear if (local->ops->get_et_sset_count) { 76e352114fSBen Greear trace_drv_get_et_sset_count(local, sset); 77e352114fSBen Greear rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif, 78e352114fSBen Greear sset); 79e352114fSBen Greear trace_drv_return_int(local, rv); 80e352114fSBen Greear } 81e352114fSBen Greear return rv; 82e352114fSBen Greear } 83e352114fSBen Greear 84968a76ceSEliad Peller int drv_start(struct ieee80211_local *local); 85968a76ceSEliad Peller void drv_stop(struct ieee80211_local *local); 8624487981SJohannes Berg 87eecc4800SJohannes Berg #ifdef CONFIG_PM 88eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local, 89eecc4800SJohannes Berg struct cfg80211_wowlan *wowlan) 90eecc4800SJohannes Berg { 91eecc4800SJohannes Berg int ret; 92eecc4800SJohannes Berg 93eecc4800SJohannes Berg might_sleep(); 94eecc4800SJohannes Berg 95eecc4800SJohannes Berg trace_drv_suspend(local); 96eecc4800SJohannes Berg ret = local->ops->suspend(&local->hw, wowlan); 97eecc4800SJohannes Berg trace_drv_return_int(local, ret); 98eecc4800SJohannes Berg return ret; 99eecc4800SJohannes Berg } 100eecc4800SJohannes Berg 101eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local) 102eecc4800SJohannes Berg { 103eecc4800SJohannes Berg int ret; 104eecc4800SJohannes Berg 105eecc4800SJohannes Berg might_sleep(); 106eecc4800SJohannes Berg 107eecc4800SJohannes Berg trace_drv_resume(local); 108eecc4800SJohannes Berg ret = local->ops->resume(&local->hw); 109eecc4800SJohannes Berg trace_drv_return_int(local, ret); 110eecc4800SJohannes Berg return ret; 111eecc4800SJohannes Berg } 1126d52563fSJohannes Berg 1136d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local, 1146d52563fSJohannes Berg bool enabled) 1156d52563fSJohannes Berg { 1166d52563fSJohannes Berg might_sleep(); 1176d52563fSJohannes Berg 1186d52563fSJohannes Berg if (!local->ops->set_wakeup) 1196d52563fSJohannes Berg return; 1206d52563fSJohannes Berg 1216d52563fSJohannes Berg trace_drv_set_wakeup(local, enabled); 1226d52563fSJohannes Berg local->ops->set_wakeup(&local->hw, enabled); 1236d52563fSJohannes Berg trace_drv_return_void(local); 1246d52563fSJohannes Berg } 125eecc4800SJohannes Berg #endif 126eecc4800SJohannes Berg 1279aae296aSDenys Vlasenko int drv_add_interface(struct ieee80211_local *local, 1289aae296aSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 129e1781ed3SKalle Valo 1309aae296aSDenys Vlasenko int drv_change_interface(struct ieee80211_local *local, 13134d4bc4dSJohannes Berg struct ieee80211_sub_if_data *sdata, 1329aae296aSDenys Vlasenko enum nl80211_iftype type, bool p2p); 13334d4bc4dSJohannes Berg 1349aae296aSDenys Vlasenko void drv_remove_interface(struct ieee80211_local *local, 1359aae296aSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 13624487981SJohannes Berg 13724487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed) 13824487981SJohannes Berg { 139e1781ed3SKalle Valo int ret; 140e1781ed3SKalle Valo 141e1781ed3SKalle Valo might_sleep(); 142e1781ed3SKalle Valo 1434efc76bdSJohannes Berg trace_drv_config(local, changed); 144e1781ed3SKalle Valo ret = local->ops->config(&local->hw, changed); 1454efc76bdSJohannes Berg trace_drv_return_int(local, ret); 1460a2b8bb2SJohannes Berg return ret; 14724487981SJohannes Berg } 14824487981SJohannes Berg 14924487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local, 15012375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 15124487981SJohannes Berg struct ieee80211_bss_conf *info, 15224487981SJohannes Berg u32 changed) 15324487981SJohannes Berg { 154e1781ed3SKalle Valo might_sleep(); 155e1781ed3SKalle Valo 1565bbe754dSJohannes Berg if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON | 157b8dc1a35SJohannes Berg BSS_CHANGED_BEACON_ENABLED) && 158b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_AP && 159b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_ADHOC && 160239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 161239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_OCB)) 1625bbe754dSJohannes Berg return; 1635bbe754dSJohannes Berg 1645bbe754dSJohannes Berg if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 1655bbe754dSJohannes Berg sdata->vif.type == NL80211_IFTYPE_MONITOR)) 1665bbe754dSJohannes Berg return; 167b8dc1a35SJohannes Berg 168f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 169f6837ba8SJohannes Berg return; 1707b7eab6fSJohannes Berg 1714efc76bdSJohannes Berg trace_drv_bss_info_changed(local, sdata, info, changed); 17224487981SJohannes Berg if (local->ops->bss_info_changed) 17312375ef9SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 1744efc76bdSJohannes Berg trace_drv_return_void(local); 17524487981SJohannes Berg } 17624487981SJohannes Berg 1773ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 17822bedad3SJiri Pirko struct netdev_hw_addr_list *mc_list) 17924487981SJohannes Berg { 1803ac64beeSJohannes Berg u64 ret = 0; 1813ac64beeSJohannes Berg 1824efc76bdSJohannes Berg trace_drv_prepare_multicast(local, mc_list->count); 1834efc76bdSJohannes Berg 1843ac64beeSJohannes Berg if (local->ops->prepare_multicast) 18522bedad3SJiri Pirko ret = local->ops->prepare_multicast(&local->hw, mc_list); 1863ac64beeSJohannes Berg 1874efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 1883ac64beeSJohannes Berg 1893ac64beeSJohannes Berg return ret; 1903ac64beeSJohannes Berg } 1913ac64beeSJohannes Berg 1923ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local, 1933ac64beeSJohannes Berg unsigned int changed_flags, 1943ac64beeSJohannes Berg unsigned int *total_flags, 1953ac64beeSJohannes Berg u64 multicast) 1963ac64beeSJohannes Berg { 1973ac64beeSJohannes Berg might_sleep(); 1983ac64beeSJohannes Berg 1990a2b8bb2SJohannes Berg trace_drv_configure_filter(local, changed_flags, total_flags, 2003ac64beeSJohannes Berg multicast); 2014efc76bdSJohannes Berg local->ops->configure_filter(&local->hw, changed_flags, total_flags, 2024efc76bdSJohannes Berg multicast); 2034efc76bdSJohannes Berg trace_drv_return_void(local); 20424487981SJohannes Berg } 20524487981SJohannes Berg 2061b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local, 2071b09b556SAndrei Otcheretianski struct ieee80211_sub_if_data *sdata, 2081b09b556SAndrei Otcheretianski unsigned int filter_flags, 2091b09b556SAndrei Otcheretianski unsigned int changed_flags) 2101b09b556SAndrei Otcheretianski { 2111b09b556SAndrei Otcheretianski might_sleep(); 2121b09b556SAndrei Otcheretianski 2131b09b556SAndrei Otcheretianski trace_drv_config_iface_filter(local, sdata, filter_flags, 2141b09b556SAndrei Otcheretianski changed_flags); 2151b09b556SAndrei Otcheretianski if (local->ops->config_iface_filter) 2161b09b556SAndrei Otcheretianski local->ops->config_iface_filter(&local->hw, &sdata->vif, 2171b09b556SAndrei Otcheretianski filter_flags, 2181b09b556SAndrei Otcheretianski changed_flags); 2191b09b556SAndrei Otcheretianski trace_drv_return_void(local); 2201b09b556SAndrei Otcheretianski } 2211b09b556SAndrei Otcheretianski 22224487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local, 22324487981SJohannes Berg struct ieee80211_sta *sta, bool set) 22424487981SJohannes Berg { 2250a2b8bb2SJohannes Berg int ret = 0; 2264efc76bdSJohannes Berg trace_drv_set_tim(local, sta, set); 22724487981SJohannes Berg if (local->ops->set_tim) 2280a2b8bb2SJohannes Berg ret = local->ops->set_tim(&local->hw, sta, set); 2294efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2300a2b8bb2SJohannes Berg return ret; 23124487981SJohannes Berg } 23224487981SJohannes Berg 23324487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local, 23412375ef9SJohannes Berg enum set_key_cmd cmd, 23512375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 23624487981SJohannes Berg struct ieee80211_sta *sta, 23724487981SJohannes Berg struct ieee80211_key_conf *key) 23824487981SJohannes Berg { 239e1781ed3SKalle Valo int ret; 240e1781ed3SKalle Valo 241e1781ed3SKalle Valo might_sleep(); 242e1781ed3SKalle Valo 243077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 244f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 245f6837ba8SJohannes Berg return -EIO; 2467b7eab6fSJohannes Berg 2474efc76bdSJohannes Berg trace_drv_set_key(local, cmd, sdata, sta, key); 248e1781ed3SKalle Valo ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 2494efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2500a2b8bb2SJohannes Berg return ret; 25124487981SJohannes Berg } 25224487981SJohannes Berg 25324487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local, 254b3fbdcf4SJohannes Berg struct ieee80211_sub_if_data *sdata, 25524487981SJohannes Berg struct ieee80211_key_conf *conf, 256b3fbdcf4SJohannes Berg struct sta_info *sta, u32 iv32, 25724487981SJohannes Berg u16 *phase1key) 25824487981SJohannes Berg { 259b3fbdcf4SJohannes Berg struct ieee80211_sta *ista = NULL; 260b3fbdcf4SJohannes Berg 261b3fbdcf4SJohannes Berg if (sta) 262b3fbdcf4SJohannes Berg ista = &sta->sta; 263b3fbdcf4SJohannes Berg 264077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 265f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 266f6837ba8SJohannes Berg return; 2677b7eab6fSJohannes Berg 2684efc76bdSJohannes Berg trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 26924487981SJohannes Berg if (local->ops->update_tkip_key) 270b3fbdcf4SJohannes Berg local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 271b3fbdcf4SJohannes Berg ista, iv32, phase1key); 2724efc76bdSJohannes Berg trace_drv_return_void(local); 27324487981SJohannes Berg } 27424487981SJohannes Berg 27524487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local, 276a060bbfeSJohannes Berg struct ieee80211_sub_if_data *sdata, 277c56ef672SDavid Spinadel struct ieee80211_scan_request *req) 27824487981SJohannes Berg { 279e1781ed3SKalle Valo int ret; 280e1781ed3SKalle Valo 281e1781ed3SKalle Valo might_sleep(); 282e1781ed3SKalle Valo 283f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 284f6837ba8SJohannes Berg return -EIO; 2857b7eab6fSJohannes Berg 28679f460caSLuciano Coelho trace_drv_hw_scan(local, sdata); 287a060bbfeSJohannes Berg ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 2884efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2890a2b8bb2SJohannes Berg return ret; 29024487981SJohannes Berg } 29124487981SJohannes Berg 292b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 293b856439bSEliad Peller struct ieee80211_sub_if_data *sdata) 294b856439bSEliad Peller { 295b856439bSEliad Peller might_sleep(); 296b856439bSEliad Peller 297f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 298f6837ba8SJohannes Berg return; 2997b7eab6fSJohannes Berg 300b856439bSEliad Peller trace_drv_cancel_hw_scan(local, sdata); 301b856439bSEliad Peller local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 302b856439bSEliad Peller trace_drv_return_void(local); 303b856439bSEliad Peller } 304b856439bSEliad Peller 30579f460caSLuciano Coelho static inline int 30679f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local, 30779f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata, 30879f460caSLuciano Coelho struct cfg80211_sched_scan_request *req, 309633e2713SDavid Spinadel struct ieee80211_scan_ies *ies) 31079f460caSLuciano Coelho { 31179f460caSLuciano Coelho int ret; 31279f460caSLuciano Coelho 31379f460caSLuciano Coelho might_sleep(); 31479f460caSLuciano Coelho 315f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 316f6837ba8SJohannes Berg return -EIO; 3177b7eab6fSJohannes Berg 31879f460caSLuciano Coelho trace_drv_sched_scan_start(local, sdata); 31979f460caSLuciano Coelho ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 32079f460caSLuciano Coelho req, ies); 32179f460caSLuciano Coelho trace_drv_return_int(local, ret); 32279f460caSLuciano Coelho return ret; 32379f460caSLuciano Coelho } 32479f460caSLuciano Coelho 32537e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local, 32679f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata) 32779f460caSLuciano Coelho { 32837e3308cSJohannes Berg int ret; 32937e3308cSJohannes Berg 33079f460caSLuciano Coelho might_sleep(); 33179f460caSLuciano Coelho 332f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 333f6837ba8SJohannes Berg return -EIO; 3347b7eab6fSJohannes Berg 33579f460caSLuciano Coelho trace_drv_sched_scan_stop(local, sdata); 33637e3308cSJohannes Berg ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); 33737e3308cSJohannes Berg trace_drv_return_int(local, ret); 33837e3308cSJohannes Berg 33937e3308cSJohannes Berg return ret; 34079f460caSLuciano Coelho } 34179f460caSLuciano Coelho 342a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local, 343a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata, 344a344d677SJohannes Berg const u8 *mac_addr) 34524487981SJohannes Berg { 346e1781ed3SKalle Valo might_sleep(); 347e1781ed3SKalle Valo 348a344d677SJohannes Berg trace_drv_sw_scan_start(local, sdata, mac_addr); 34924487981SJohannes Berg if (local->ops->sw_scan_start) 350a344d677SJohannes Berg local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); 3514efc76bdSJohannes Berg trace_drv_return_void(local); 35224487981SJohannes Berg } 35324487981SJohannes Berg 354a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local, 355a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata) 35624487981SJohannes Berg { 357e1781ed3SKalle Valo might_sleep(); 358e1781ed3SKalle Valo 359a344d677SJohannes Berg trace_drv_sw_scan_complete(local, sdata); 36024487981SJohannes Berg if (local->ops->sw_scan_complete) 361a344d677SJohannes Berg local->ops->sw_scan_complete(&local->hw, &sdata->vif); 3624efc76bdSJohannes Berg trace_drv_return_void(local); 36324487981SJohannes Berg } 36424487981SJohannes Berg 36524487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local, 36624487981SJohannes Berg struct ieee80211_low_level_stats *stats) 36724487981SJohannes Berg { 3680a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 3690a2b8bb2SJohannes Berg 370e1781ed3SKalle Valo might_sleep(); 371e1781ed3SKalle Valo 3720a2b8bb2SJohannes Berg if (local->ops->get_stats) 3730a2b8bb2SJohannes Berg ret = local->ops->get_stats(&local->hw, stats); 3740a2b8bb2SJohannes Berg trace_drv_get_stats(local, stats, ret); 3750a2b8bb2SJohannes Berg 3760a2b8bb2SJohannes Berg return ret; 37724487981SJohannes Berg } 37824487981SJohannes Berg 3799352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local, 3809352c19fSJohannes Berg struct ieee80211_key *key, 3819352c19fSJohannes Berg struct ieee80211_key_seq *seq) 38224487981SJohannes Berg { 3839352c19fSJohannes Berg if (local->ops->get_key_seq) 3849352c19fSJohannes Berg local->ops->get_key_seq(&local->hw, &key->conf, seq); 3859352c19fSJohannes Berg trace_drv_get_key_seq(local, &key->conf); 38624487981SJohannes Berg } 38724487981SJohannes Berg 388f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local, 389f23a4780SArik Nemtsov u32 value) 390f23a4780SArik Nemtsov { 391f23a4780SArik Nemtsov int ret = 0; 392f23a4780SArik Nemtsov 393f23a4780SArik Nemtsov might_sleep(); 394f23a4780SArik Nemtsov 395f23a4780SArik Nemtsov trace_drv_set_frag_threshold(local, value); 396f23a4780SArik Nemtsov if (local->ops->set_frag_threshold) 397f23a4780SArik Nemtsov ret = local->ops->set_frag_threshold(&local->hw, value); 398f23a4780SArik Nemtsov trace_drv_return_int(local, ret); 399f23a4780SArik Nemtsov return ret; 400f23a4780SArik Nemtsov } 401f23a4780SArik Nemtsov 40224487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local, 40324487981SJohannes Berg u32 value) 40424487981SJohannes Berg { 4050a2b8bb2SJohannes Berg int ret = 0; 406e1781ed3SKalle Valo 407e1781ed3SKalle Valo might_sleep(); 408e1781ed3SKalle Valo 4094efc76bdSJohannes Berg trace_drv_set_rts_threshold(local, value); 41024487981SJohannes Berg if (local->ops->set_rts_threshold) 4110a2b8bb2SJohannes Berg ret = local->ops->set_rts_threshold(&local->hw, value); 4124efc76bdSJohannes Berg trace_drv_return_int(local, ret); 4130a2b8bb2SJohannes Berg return ret; 41424487981SJohannes Berg } 41524487981SJohannes Berg 416310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local, 417a4bcaf55SLorenzo Bianconi s16 value) 418310bc676SLukáš Turek { 419310bc676SLukáš Turek int ret = 0; 420310bc676SLukáš Turek might_sleep(); 421310bc676SLukáš Turek 4224efc76bdSJohannes Berg trace_drv_set_coverage_class(local, value); 423310bc676SLukáš Turek if (local->ops->set_coverage_class) 424310bc676SLukáš Turek local->ops->set_coverage_class(&local->hw, value); 425310bc676SLukáš Turek else 426310bc676SLukáš Turek ret = -EOPNOTSUPP; 427310bc676SLukáš Turek 4284efc76bdSJohannes Berg trace_drv_return_int(local, ret); 429310bc676SLukáš Turek return ret; 430310bc676SLukáš Turek } 431310bc676SLukáš Turek 43224487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local, 43312375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 43424487981SJohannes Berg enum sta_notify_cmd cmd, 43524487981SJohannes Berg struct ieee80211_sta *sta) 43624487981SJohannes Berg { 437bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 438f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 439f6837ba8SJohannes Berg return; 4407b7eab6fSJohannes Berg 4414efc76bdSJohannes Berg trace_drv_sta_notify(local, sdata, cmd, sta); 44224487981SJohannes Berg if (local->ops->sta_notify) 44312375ef9SJohannes Berg local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 4444efc76bdSJohannes Berg trace_drv_return_void(local); 44524487981SJohannes Berg } 44624487981SJohannes Berg 44734e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local, 44834e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 44934e89507SJohannes Berg struct ieee80211_sta *sta) 45034e89507SJohannes Berg { 45134e89507SJohannes Berg int ret = 0; 45234e89507SJohannes Berg 45334e89507SJohannes Berg might_sleep(); 45434e89507SJohannes Berg 455bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 456f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 457f6837ba8SJohannes Berg return -EIO; 4587b7eab6fSJohannes Berg 4594efc76bdSJohannes Berg trace_drv_sta_add(local, sdata, sta); 46034e89507SJohannes Berg if (local->ops->sta_add) 46134e89507SJohannes Berg ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 46234e89507SJohannes Berg 4634efc76bdSJohannes Berg trace_drv_return_int(local, ret); 46434e89507SJohannes Berg 46534e89507SJohannes Berg return ret; 46634e89507SJohannes Berg } 46734e89507SJohannes Berg 46834e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local, 46934e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 47034e89507SJohannes Berg struct ieee80211_sta *sta) 47134e89507SJohannes Berg { 47234e89507SJohannes Berg might_sleep(); 47334e89507SJohannes Berg 474bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 475f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 476f6837ba8SJohannes Berg return; 4777b7eab6fSJohannes Berg 4784efc76bdSJohannes Berg trace_drv_sta_remove(local, sdata, sta); 47934e89507SJohannes Berg if (local->ops->sta_remove) 48034e89507SJohannes Berg local->ops->sta_remove(&local->hw, &sdata->vif, sta); 48134e89507SJohannes Berg 4824efc76bdSJohannes Berg trace_drv_return_void(local); 48334e89507SJohannes Berg } 48434e89507SJohannes Berg 48577d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS 48677d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 48777d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 48877d2ece6SSujith Manoharan struct ieee80211_sta *sta, 48977d2ece6SSujith Manoharan struct dentry *dir) 49077d2ece6SSujith Manoharan { 49177d2ece6SSujith Manoharan might_sleep(); 49277d2ece6SSujith Manoharan 49377d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 494f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 495f6837ba8SJohannes Berg return; 49677d2ece6SSujith Manoharan 49777d2ece6SSujith Manoharan if (local->ops->sta_add_debugfs) 49877d2ece6SSujith Manoharan local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 49977d2ece6SSujith Manoharan sta, dir); 50077d2ece6SSujith Manoharan } 50177d2ece6SSujith Manoharan 50277d2ece6SSujith Manoharan static inline void drv_sta_remove_debugfs(struct ieee80211_local *local, 50377d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 50477d2ece6SSujith Manoharan struct ieee80211_sta *sta, 50577d2ece6SSujith Manoharan struct dentry *dir) 50677d2ece6SSujith Manoharan { 50777d2ece6SSujith Manoharan might_sleep(); 50877d2ece6SSujith Manoharan 50977d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 51077d2ece6SSujith Manoharan check_sdata_in_driver(sdata); 51177d2ece6SSujith Manoharan 51277d2ece6SSujith Manoharan if (local->ops->sta_remove_debugfs) 51377d2ece6SSujith Manoharan local->ops->sta_remove_debugfs(&local->hw, &sdata->vif, 51477d2ece6SSujith Manoharan sta, dir); 51577d2ece6SSujith Manoharan } 51677d2ece6SSujith Manoharan #endif 51777d2ece6SSujith Manoharan 5186a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, 5196a9d1b91SJohannes Berg struct ieee80211_sub_if_data *sdata, 5206a9d1b91SJohannes Berg struct sta_info *sta) 5216a9d1b91SJohannes Berg { 5226a9d1b91SJohannes Berg might_sleep(); 5236a9d1b91SJohannes Berg 5246a9d1b91SJohannes Berg sdata = get_bss_sdata(sdata); 525f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 526f6837ba8SJohannes Berg return; 5276a9d1b91SJohannes Berg 5286a9d1b91SJohannes Berg trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); 5296a9d1b91SJohannes Berg if (local->ops->sta_pre_rcu_remove) 5306a9d1b91SJohannes Berg local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif, 5316a9d1b91SJohannes Berg &sta->sta); 5326a9d1b91SJohannes Berg trace_drv_return_void(local); 5336a9d1b91SJohannes Berg } 5346a9d1b91SJohannes Berg 535727da60bSDenys Vlasenko __must_check 536f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local, 537f09603a2SJohannes Berg struct ieee80211_sub_if_data *sdata, 538f09603a2SJohannes Berg struct sta_info *sta, 539f09603a2SJohannes Berg enum ieee80211_sta_state old_state, 540727da60bSDenys Vlasenko enum ieee80211_sta_state new_state); 541f09603a2SJohannes Berg 5424fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local, 5438f727ef3SJohannes Berg struct ieee80211_sub_if_data *sdata, 5444fbd572cSDenys Vlasenko struct ieee80211_sta *sta, u32 changed); 5458f727ef3SJohannes Berg 546f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, 547f815e2b3SJohannes Berg struct ieee80211_sub_if_data *sdata, 548f815e2b3SJohannes Berg struct ieee80211_sta *sta) 549f815e2b3SJohannes Berg { 550f815e2b3SJohannes Berg sdata = get_bss_sdata(sdata); 551f815e2b3SJohannes Berg if (!check_sdata_in_driver(sdata)) 552f815e2b3SJohannes Berg return; 553f815e2b3SJohannes Berg 554f815e2b3SJohannes Berg trace_drv_sta_rate_tbl_update(local, sdata, sta); 555f815e2b3SJohannes Berg if (local->ops->sta_rate_tbl_update) 556f815e2b3SJohannes Berg local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta); 557f815e2b3SJohannes Berg 558f815e2b3SJohannes Berg trace_drv_return_void(local); 559f815e2b3SJohannes Berg } 560f815e2b3SJohannes Berg 5612b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local, 5622b9a7e1bSJohannes Berg struct ieee80211_sub_if_data *sdata, 5632b9a7e1bSJohannes Berg struct ieee80211_sta *sta, 5642b9a7e1bSJohannes Berg struct station_info *sinfo) 5652b9a7e1bSJohannes Berg { 5662b9a7e1bSJohannes Berg sdata = get_bss_sdata(sdata); 5672b9a7e1bSJohannes Berg if (!check_sdata_in_driver(sdata)) 5682b9a7e1bSJohannes Berg return; 5692b9a7e1bSJohannes Berg 5702b9a7e1bSJohannes Berg trace_drv_sta_statistics(local, sdata, sta); 5712b9a7e1bSJohannes Berg if (local->ops->sta_statistics) 5722b9a7e1bSJohannes Berg local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); 5732b9a7e1bSJohannes Berg trace_drv_return_void(local); 5742b9a7e1bSJohannes Berg } 5752b9a7e1bSJohannes Berg 576b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local, 577a3304b0aSJohannes Berg struct ieee80211_sub_if_data *sdata, u16 ac, 578b23dcd4aSDenys Vlasenko const struct ieee80211_tx_queue_params *params); 57924487981SJohannes Berg 580416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local, 581416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 582416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local, 58337a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata, 584416eb9fcSDenys Vlasenko u64 tsf); 585416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local, 586416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 58724487981SJohannes Berg 58824487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local) 58924487981SJohannes Berg { 59002582e9bSMasanari Iida int ret = 0; /* default unsupported op for less congestion */ 591e1781ed3SKalle Valo 592e1781ed3SKalle Valo might_sleep(); 593e1781ed3SKalle Valo 5944efc76bdSJohannes Berg trace_drv_tx_last_beacon(local); 59524487981SJohannes Berg if (local->ops->tx_last_beacon) 5960a2b8bb2SJohannes Berg ret = local->ops->tx_last_beacon(&local->hw); 5974efc76bdSJohannes Berg trace_drv_return_int(local, ret); 5980a2b8bb2SJohannes Berg return ret; 59924487981SJohannes Berg } 60024487981SJohannes Berg 6016db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local, 60212375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 60350ea05efSSara Sharon struct ieee80211_ampdu_params *params); 6041f87f7d3SJohannes Berg 6051289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx, 6061289723eSHolger Schurig struct survey_info *survey) 6071289723eSHolger Schurig { 6081289723eSHolger Schurig int ret = -EOPNOTSUPP; 609c466d4efSJohn W. Linville 610c466d4efSJohn W. Linville trace_drv_get_survey(local, idx, survey); 611c466d4efSJohn W. Linville 61235dd0509SHolger Schurig if (local->ops->get_survey) 6131289723eSHolger Schurig ret = local->ops->get_survey(&local->hw, idx, survey); 614c466d4efSJohn W. Linville 615c466d4efSJohn W. Linville trace_drv_return_int(local, ret); 616c466d4efSJohn W. Linville 6171289723eSHolger Schurig return ret; 6181289723eSHolger Schurig } 6191f87f7d3SJohannes Berg 6201f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local) 6211f87f7d3SJohannes Berg { 622e1781ed3SKalle Valo might_sleep(); 623e1781ed3SKalle Valo 6241f87f7d3SJohannes Berg if (local->ops->rfkill_poll) 6251f87f7d3SJohannes Berg local->ops->rfkill_poll(&local->hw); 6261f87f7d3SJohannes Berg } 627a80f7c0bSJohannes Berg 62839ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, 62977be2c54SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 63039ecc01dSJohannes Berg u32 queues, bool drop) 631a80f7c0bSJohannes Berg { 63277be2c54SEmmanuel Grumbach struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL; 63377be2c54SEmmanuel Grumbach 634e1781ed3SKalle Valo might_sleep(); 635e1781ed3SKalle Valo 636f6837ba8SJohannes Berg if (sdata && !check_sdata_in_driver(sdata)) 637f6837ba8SJohannes Berg return; 63877be2c54SEmmanuel Grumbach 63939ecc01dSJohannes Berg trace_drv_flush(local, queues, drop); 640a80f7c0bSJohannes Berg if (local->ops->flush) 64177be2c54SEmmanuel Grumbach local->ops->flush(&local->hw, vif, queues, drop); 6424efc76bdSJohannes Berg trace_drv_return_void(local); 643a80f7c0bSJohannes Berg } 6445ce6e438SJohannes Berg 6455ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local, 6460f791eb4SLuciano Coelho struct ieee80211_sub_if_data *sdata, 6475ce6e438SJohannes Berg struct ieee80211_channel_switch *ch_switch) 6485ce6e438SJohannes Berg { 6495ce6e438SJohannes Berg might_sleep(); 6505ce6e438SJohannes Berg 6510f791eb4SLuciano Coelho trace_drv_channel_switch(local, sdata, ch_switch); 6520f791eb4SLuciano Coelho local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); 6534efc76bdSJohannes Berg trace_drv_return_void(local); 6545ce6e438SJohannes Berg } 6555ce6e438SJohannes Berg 65615d96753SBruno Randolf 65715d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local, 65815d96753SBruno Randolf u32 tx_ant, u32 rx_ant) 65915d96753SBruno Randolf { 66015d96753SBruno Randolf int ret = -EOPNOTSUPP; 66115d96753SBruno Randolf might_sleep(); 66215d96753SBruno Randolf if (local->ops->set_antenna) 66315d96753SBruno Randolf ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 66415d96753SBruno Randolf trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 66515d96753SBruno Randolf return ret; 66615d96753SBruno Randolf } 66715d96753SBruno Randolf 66815d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local, 66915d96753SBruno Randolf u32 *tx_ant, u32 *rx_ant) 67015d96753SBruno Randolf { 67115d96753SBruno Randolf int ret = -EOPNOTSUPP; 67215d96753SBruno Randolf might_sleep(); 67315d96753SBruno Randolf if (local->ops->get_antenna) 67415d96753SBruno Randolf ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 67515d96753SBruno Randolf trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 67615d96753SBruno Randolf return ret; 67715d96753SBruno Randolf } 67815d96753SBruno Randolf 67921f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local, 68049884568SEliad Peller struct ieee80211_sub_if_data *sdata, 68121f83589SJohannes Berg struct ieee80211_channel *chan, 682d339d5caSIlan Peer unsigned int duration, 683d339d5caSIlan Peer enum ieee80211_roc_type type) 68421f83589SJohannes Berg { 68521f83589SJohannes Berg int ret; 68621f83589SJohannes Berg 68721f83589SJohannes Berg might_sleep(); 68821f83589SJohannes Berg 689d339d5caSIlan Peer trace_drv_remain_on_channel(local, sdata, chan, duration, type); 69049884568SEliad Peller ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 691d339d5caSIlan Peer chan, duration, type); 69221f83589SJohannes Berg trace_drv_return_int(local, ret); 69321f83589SJohannes Berg 69421f83589SJohannes Berg return ret; 69521f83589SJohannes Berg } 69621f83589SJohannes Berg 69721f83589SJohannes Berg static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local) 69821f83589SJohannes Berg { 69921f83589SJohannes Berg int ret; 70021f83589SJohannes Berg 70121f83589SJohannes Berg might_sleep(); 70221f83589SJohannes Berg 70321f83589SJohannes Berg trace_drv_cancel_remain_on_channel(local); 70421f83589SJohannes Berg ret = local->ops->cancel_remain_on_channel(&local->hw); 70521f83589SJohannes Berg trace_drv_return_int(local, ret); 70621f83589SJohannes Berg 70721f83589SJohannes Berg return ret; 70821f83589SJohannes Berg } 70921f83589SJohannes Berg 71038c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local, 71138c09159SJohn W. Linville u32 tx, u32 rx) 71238c09159SJohn W. Linville { 71338c09159SJohn W. Linville int ret = -ENOTSUPP; 71438c09159SJohn W. Linville 71538c09159SJohn W. Linville might_sleep(); 71638c09159SJohn W. Linville 71738c09159SJohn W. Linville trace_drv_set_ringparam(local, tx, rx); 71838c09159SJohn W. Linville if (local->ops->set_ringparam) 71938c09159SJohn W. Linville ret = local->ops->set_ringparam(&local->hw, tx, rx); 72038c09159SJohn W. Linville trace_drv_return_int(local, ret); 72138c09159SJohn W. Linville 72238c09159SJohn W. Linville return ret; 72338c09159SJohn W. Linville } 72438c09159SJohn W. Linville 72538c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local, 72638c09159SJohn W. Linville u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 72738c09159SJohn W. Linville { 72838c09159SJohn W. Linville might_sleep(); 72938c09159SJohn W. Linville 73038c09159SJohn W. Linville trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 73138c09159SJohn W. Linville if (local->ops->get_ringparam) 73238c09159SJohn W. Linville local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 73338c09159SJohn W. Linville trace_drv_return_void(local); 73438c09159SJohn W. Linville } 73538c09159SJohn W. Linville 736e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 737e8306f98SVivek Natarajan { 738e8306f98SVivek Natarajan bool ret = false; 739e8306f98SVivek Natarajan 740e8306f98SVivek Natarajan might_sleep(); 741e8306f98SVivek Natarajan 742e8306f98SVivek Natarajan trace_drv_tx_frames_pending(local); 743e8306f98SVivek Natarajan if (local->ops->tx_frames_pending) 744e8306f98SVivek Natarajan ret = local->ops->tx_frames_pending(&local->hw); 745e8306f98SVivek Natarajan trace_drv_return_bool(local, ret); 746e8306f98SVivek Natarajan 747e8306f98SVivek Natarajan return ret; 748e8306f98SVivek Natarajan } 749bdbfd6b5SSujith Manoharan 750bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 751bdbfd6b5SSujith Manoharan struct ieee80211_sub_if_data *sdata, 752bdbfd6b5SSujith Manoharan const struct cfg80211_bitrate_mask *mask) 753bdbfd6b5SSujith Manoharan { 754bdbfd6b5SSujith Manoharan int ret = -EOPNOTSUPP; 755bdbfd6b5SSujith Manoharan 756bdbfd6b5SSujith Manoharan might_sleep(); 757bdbfd6b5SSujith Manoharan 758f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 759f6837ba8SJohannes Berg return -EIO; 7607b7eab6fSJohannes Berg 761bdbfd6b5SSujith Manoharan trace_drv_set_bitrate_mask(local, sdata, mask); 762bdbfd6b5SSujith Manoharan if (local->ops->set_bitrate_mask) 763bdbfd6b5SSujith Manoharan ret = local->ops->set_bitrate_mask(&local->hw, 764bdbfd6b5SSujith Manoharan &sdata->vif, mask); 765bdbfd6b5SSujith Manoharan trace_drv_return_int(local, ret); 766bdbfd6b5SSujith Manoharan 767bdbfd6b5SSujith Manoharan return ret; 768bdbfd6b5SSujith Manoharan } 769bdbfd6b5SSujith Manoharan 770c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local, 771c68f4b89SJohannes Berg struct ieee80211_sub_if_data *sdata, 772c68f4b89SJohannes Berg struct cfg80211_gtk_rekey_data *data) 773c68f4b89SJohannes Berg { 774f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 775f6837ba8SJohannes Berg return; 7767b7eab6fSJohannes Berg 777c68f4b89SJohannes Berg trace_drv_set_rekey_data(local, sdata, data); 778c68f4b89SJohannes Berg if (local->ops->set_rekey_data) 779c68f4b89SJohannes Berg local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 780c68f4b89SJohannes Berg trace_drv_return_void(local); 781c68f4b89SJohannes Berg } 782c68f4b89SJohannes Berg 783a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local, 784887da917SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 785a8182929SEmmanuel Grumbach const struct ieee80211_event *event) 786615f7b9bSMeenakshi Venkataraman { 787a8182929SEmmanuel Grumbach trace_drv_event_callback(local, sdata, event); 788a8182929SEmmanuel Grumbach if (local->ops->event_callback) 789a8182929SEmmanuel Grumbach local->ops->event_callback(&local->hw, &sdata->vif, event); 790615f7b9bSMeenakshi Venkataraman trace_drv_return_void(local); 791615f7b9bSMeenakshi Venkataraman } 7924049e09aSJohannes Berg 7934049e09aSJohannes Berg static inline void 7944049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local, 7954049e09aSJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 7964049e09aSJohannes Berg enum ieee80211_frame_release_type reason, 7974049e09aSJohannes Berg bool more_data) 7984049e09aSJohannes Berg { 7994049e09aSJohannes Berg trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 8004049e09aSJohannes Berg reason, more_data); 8014049e09aSJohannes Berg if (local->ops->release_buffered_frames) 8024049e09aSJohannes Berg local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 8034049e09aSJohannes Berg num_frames, reason, 8044049e09aSJohannes Berg more_data); 8054049e09aSJohannes Berg trace_drv_return_void(local); 8064049e09aSJohannes Berg } 80740b96408SJohannes Berg 80840b96408SJohannes Berg static inline void 80940b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local, 81040b96408SJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 81140b96408SJohannes Berg enum ieee80211_frame_release_type reason, 81240b96408SJohannes Berg bool more_data) 81340b96408SJohannes Berg { 81440b96408SJohannes Berg trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 81540b96408SJohannes Berg reason, more_data); 81640b96408SJohannes Berg if (local->ops->allow_buffered_frames) 81740b96408SJohannes Berg local->ops->allow_buffered_frames(&local->hw, &sta->sta, 81840b96408SJohannes Berg tids, num_frames, reason, 81940b96408SJohannes Berg more_data); 82040b96408SJohannes Berg trace_drv_return_void(local); 82140b96408SJohannes Berg } 82266572cfcSVictor Goldenshtein 823a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 824a1845fc7SJohannes Berg struct ieee80211_sub_if_data *sdata) 825a1845fc7SJohannes Berg { 826a1845fc7SJohannes Berg might_sleep(); 827a1845fc7SJohannes Berg 828f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 829f6837ba8SJohannes Berg return; 830a1845fc7SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 831a1845fc7SJohannes Berg 832a1845fc7SJohannes Berg trace_drv_mgd_prepare_tx(local, sdata); 833a1845fc7SJohannes Berg if (local->ops->mgd_prepare_tx) 834a1845fc7SJohannes Berg local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); 835a1845fc7SJohannes Berg trace_drv_return_void(local); 836a1845fc7SJohannes Berg } 837c3645eacSMichal Kazior 838ee10f2c7SArik Nemtsov static inline void 839ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local, 840ee10f2c7SArik Nemtsov struct ieee80211_sub_if_data *sdata) 841ee10f2c7SArik Nemtsov { 842ee10f2c7SArik Nemtsov might_sleep(); 843ee10f2c7SArik Nemtsov 844ee10f2c7SArik Nemtsov if (!check_sdata_in_driver(sdata)) 845ee10f2c7SArik Nemtsov return; 846ee10f2c7SArik Nemtsov WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 847ee10f2c7SArik Nemtsov 848ee10f2c7SArik Nemtsov trace_drv_mgd_protect_tdls_discover(local, sdata); 849ee10f2c7SArik Nemtsov if (local->ops->mgd_protect_tdls_discover) 850ee10f2c7SArik Nemtsov local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); 851ee10f2c7SArik Nemtsov trace_drv_return_void(local); 852ee10f2c7SArik Nemtsov } 853ee10f2c7SArik Nemtsov 854c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local, 855c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 856c3645eacSMichal Kazior { 857c3645eacSMichal Kazior int ret = -EOPNOTSUPP; 858c3645eacSMichal Kazior 859dcae9e02SChaitanya T K might_sleep(); 860dcae9e02SChaitanya T K 861c3645eacSMichal Kazior trace_drv_add_chanctx(local, ctx); 862c3645eacSMichal Kazior if (local->ops->add_chanctx) 863c3645eacSMichal Kazior ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 864c3645eacSMichal Kazior trace_drv_return_int(local, ret); 8658a61af65SJohannes Berg if (!ret) 8668a61af65SJohannes Berg ctx->driver_present = true; 867c3645eacSMichal Kazior 868c3645eacSMichal Kazior return ret; 869c3645eacSMichal Kazior } 870c3645eacSMichal Kazior 871c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local, 872c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 873c3645eacSMichal Kazior { 874dcae9e02SChaitanya T K might_sleep(); 875dcae9e02SChaitanya T K 876f6837ba8SJohannes Berg if (WARN_ON(!ctx->driver_present)) 877f6837ba8SJohannes Berg return; 878f6837ba8SJohannes Berg 879c3645eacSMichal Kazior trace_drv_remove_chanctx(local, ctx); 880c3645eacSMichal Kazior if (local->ops->remove_chanctx) 881c3645eacSMichal Kazior local->ops->remove_chanctx(&local->hw, &ctx->conf); 882c3645eacSMichal Kazior trace_drv_return_void(local); 8838a61af65SJohannes Berg ctx->driver_present = false; 884c3645eacSMichal Kazior } 885c3645eacSMichal Kazior 886c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local, 887c3645eacSMichal Kazior struct ieee80211_chanctx *ctx, 888c3645eacSMichal Kazior u32 changed) 889c3645eacSMichal Kazior { 890dcae9e02SChaitanya T K might_sleep(); 891dcae9e02SChaitanya T K 892c3645eacSMichal Kazior trace_drv_change_chanctx(local, ctx, changed); 8938a61af65SJohannes Berg if (local->ops->change_chanctx) { 8948a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 895c3645eacSMichal Kazior local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 8968a61af65SJohannes Berg } 897c3645eacSMichal Kazior trace_drv_return_void(local); 898c3645eacSMichal Kazior } 899c3645eacSMichal Kazior 900c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, 901c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 902c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 903c3645eacSMichal Kazior { 904c3645eacSMichal Kazior int ret = 0; 905c3645eacSMichal Kazior 906f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 907f6837ba8SJohannes Berg return -EIO; 908c3645eacSMichal Kazior 909c3645eacSMichal Kazior trace_drv_assign_vif_chanctx(local, sdata, ctx); 9108a61af65SJohannes Berg if (local->ops->assign_vif_chanctx) { 9118a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 912c3645eacSMichal Kazior ret = local->ops->assign_vif_chanctx(&local->hw, 913c3645eacSMichal Kazior &sdata->vif, 914c3645eacSMichal Kazior &ctx->conf); 9158a61af65SJohannes Berg } 916c3645eacSMichal Kazior trace_drv_return_int(local, ret); 917c3645eacSMichal Kazior 918c3645eacSMichal Kazior return ret; 919c3645eacSMichal Kazior } 920c3645eacSMichal Kazior 921c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, 922c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 923c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 924c3645eacSMichal Kazior { 925dcae9e02SChaitanya T K might_sleep(); 926dcae9e02SChaitanya T K 927f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 928f6837ba8SJohannes Berg return; 929c3645eacSMichal Kazior 930c3645eacSMichal Kazior trace_drv_unassign_vif_chanctx(local, sdata, ctx); 9318a61af65SJohannes Berg if (local->ops->unassign_vif_chanctx) { 9328a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 933c3645eacSMichal Kazior local->ops->unassign_vif_chanctx(&local->hw, 934c3645eacSMichal Kazior &sdata->vif, 935c3645eacSMichal Kazior &ctx->conf); 9368a61af65SJohannes Berg } 937c3645eacSMichal Kazior trace_drv_return_void(local); 938c3645eacSMichal Kazior } 939c3645eacSMichal Kazior 94042677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local, 9411a5f0c13SLuciano Coelho struct ieee80211_vif_chanctx_switch *vifs, 94242677ed3SDenys Vlasenko int n_vifs, enum ieee80211_chanctx_switch_mode mode); 9431a5f0c13SLuciano Coelho 9441041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local, 9451041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9461041638fSJohannes Berg { 9471041638fSJohannes Berg int ret = 0; 9481041638fSJohannes Berg 949dcae9e02SChaitanya T K might_sleep(); 950dcae9e02SChaitanya T K 951f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 952f6837ba8SJohannes Berg return -EIO; 9531041638fSJohannes Berg 9541041638fSJohannes Berg trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); 9551041638fSJohannes Berg if (local->ops->start_ap) 9561041638fSJohannes Berg ret = local->ops->start_ap(&local->hw, &sdata->vif); 9571041638fSJohannes Berg trace_drv_return_int(local, ret); 9581041638fSJohannes Berg return ret; 9591041638fSJohannes Berg } 9601041638fSJohannes Berg 9611041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local, 9621041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9631041638fSJohannes Berg { 964f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 965f6837ba8SJohannes Berg return; 9661041638fSJohannes Berg 9671041638fSJohannes Berg trace_drv_stop_ap(local, sdata); 9681041638fSJohannes Berg if (local->ops->stop_ap) 9691041638fSJohannes Berg local->ops->stop_ap(&local->hw, &sdata->vif); 9701041638fSJohannes Berg trace_drv_return_void(local); 9711041638fSJohannes Berg } 9721041638fSJohannes Berg 973cf2c92d8SEliad Peller static inline void 974cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local, 975cf2c92d8SEliad Peller enum ieee80211_reconfig_type reconfig_type) 9769214ad7fSJohannes Berg { 9779214ad7fSJohannes Berg might_sleep(); 9789214ad7fSJohannes Berg 979cf2c92d8SEliad Peller trace_drv_reconfig_complete(local, reconfig_type); 980cf2c92d8SEliad Peller if (local->ops->reconfig_complete) 981cf2c92d8SEliad Peller local->ops->reconfig_complete(&local->hw, reconfig_type); 9829214ad7fSJohannes Berg trace_drv_return_void(local); 9839214ad7fSJohannes Berg } 9849214ad7fSJohannes Berg 985de5fad81SYoni Divinsky static inline void 986de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local, 987de5fad81SYoni Divinsky struct ieee80211_sub_if_data *sdata, 988de5fad81SYoni Divinsky int key_idx) 989de5fad81SYoni Divinsky { 990f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 991f6837ba8SJohannes Berg return; 992de5fad81SYoni Divinsky 993de5fad81SYoni Divinsky WARN_ON_ONCE(key_idx < -1 || key_idx > 3); 994de5fad81SYoni Divinsky 995de5fad81SYoni Divinsky trace_drv_set_default_unicast_key(local, sdata, key_idx); 996de5fad81SYoni Divinsky if (local->ops->set_default_unicast_key) 997de5fad81SYoni Divinsky local->ops->set_default_unicast_key(&local->hw, &sdata->vif, 998de5fad81SYoni Divinsky key_idx); 999de5fad81SYoni Divinsky trace_drv_return_void(local); 1000de5fad81SYoni Divinsky } 1001de5fad81SYoni Divinsky 1002a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6) 1003a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local, 1004a65240c1SJohannes Berg struct ieee80211_sub_if_data *sdata, 1005a65240c1SJohannes Berg struct inet6_dev *idev) 1006a65240c1SJohannes Berg { 1007a65240c1SJohannes Berg trace_drv_ipv6_addr_change(local, sdata); 1008a65240c1SJohannes Berg if (local->ops->ipv6_addr_change) 1009a65240c1SJohannes Berg local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev); 1010a65240c1SJohannes Berg trace_drv_return_void(local); 1011a65240c1SJohannes Berg } 1012a65240c1SJohannes Berg #endif 1013a65240c1SJohannes Berg 101473da7d5bSSimon Wunderlich static inline void 101573da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, 101673da7d5bSSimon Wunderlich struct cfg80211_chan_def *chandef) 101773da7d5bSSimon Wunderlich { 101873da7d5bSSimon Wunderlich struct ieee80211_local *local = sdata->local; 101973da7d5bSSimon Wunderlich 102073da7d5bSSimon Wunderlich if (local->ops->channel_switch_beacon) { 102173da7d5bSSimon Wunderlich trace_drv_channel_switch_beacon(local, sdata, chandef); 102273da7d5bSSimon Wunderlich local->ops->channel_switch_beacon(&local->hw, &sdata->vif, 102373da7d5bSSimon Wunderlich chandef); 102473da7d5bSSimon Wunderlich } 102573da7d5bSSimon Wunderlich } 102673da7d5bSSimon Wunderlich 10276d027bccSLuciano Coelho static inline int 10286d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, 10296d027bccSLuciano Coelho struct ieee80211_channel_switch *ch_switch) 10306d027bccSLuciano Coelho { 10316d027bccSLuciano Coelho struct ieee80211_local *local = sdata->local; 10326d027bccSLuciano Coelho int ret = 0; 10336d027bccSLuciano Coelho 10346d027bccSLuciano Coelho if (!check_sdata_in_driver(sdata)) 10356d027bccSLuciano Coelho return -EIO; 10366d027bccSLuciano Coelho 10376d027bccSLuciano Coelho trace_drv_pre_channel_switch(local, sdata, ch_switch); 10386d027bccSLuciano Coelho if (local->ops->pre_channel_switch) 10396d027bccSLuciano Coelho ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, 10406d027bccSLuciano Coelho ch_switch); 10416d027bccSLuciano Coelho trace_drv_return_int(local, ret); 10426d027bccSLuciano Coelho return ret; 10436d027bccSLuciano Coelho } 10446d027bccSLuciano Coelho 1045f1d65583SLuciano Coelho static inline int 1046f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) 1047f1d65583SLuciano Coelho { 1048f1d65583SLuciano Coelho struct ieee80211_local *local = sdata->local; 1049f1d65583SLuciano Coelho int ret = 0; 1050f1d65583SLuciano Coelho 1051f1d65583SLuciano Coelho if (!check_sdata_in_driver(sdata)) 1052f1d65583SLuciano Coelho return -EIO; 1053f1d65583SLuciano Coelho 1054f1d65583SLuciano Coelho trace_drv_post_channel_switch(local, sdata); 1055f1d65583SLuciano Coelho if (local->ops->post_channel_switch) 1056f1d65583SLuciano Coelho ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); 1057f1d65583SLuciano Coelho trace_drv_return_int(local, ret); 1058f1d65583SLuciano Coelho return ret; 1059f1d65583SLuciano Coelho } 1060f1d65583SLuciano Coelho 106155fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local, 106255fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 106355fff501SJohannes Berg { 106455fff501SJohannes Berg int ret = 0; 106555fff501SJohannes Berg 106655fff501SJohannes Berg might_sleep(); 1067f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1068f6837ba8SJohannes Berg return -EIO; 106955fff501SJohannes Berg 107055fff501SJohannes Berg trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); 107155fff501SJohannes Berg if (local->ops->join_ibss) 107255fff501SJohannes Berg ret = local->ops->join_ibss(&local->hw, &sdata->vif); 107355fff501SJohannes Berg trace_drv_return_int(local, ret); 107455fff501SJohannes Berg return ret; 107555fff501SJohannes Berg } 107655fff501SJohannes Berg 107755fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local, 107855fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 107955fff501SJohannes Berg { 108055fff501SJohannes Berg might_sleep(); 1081f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1082f6837ba8SJohannes Berg return; 108355fff501SJohannes Berg 108455fff501SJohannes Berg trace_drv_leave_ibss(local, sdata); 108555fff501SJohannes Berg if (local->ops->leave_ibss) 108655fff501SJohannes Berg local->ops->leave_ibss(&local->hw, &sdata->vif); 108755fff501SJohannes Berg trace_drv_return_void(local); 108855fff501SJohannes Berg } 108955fff501SJohannes Berg 1090cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, 1091cca674d4SAntonio Quartulli struct ieee80211_sta *sta) 1092cca674d4SAntonio Quartulli { 1093cca674d4SAntonio Quartulli u32 ret = 0; 1094cca674d4SAntonio Quartulli 1095cca674d4SAntonio Quartulli trace_drv_get_expected_throughput(sta); 1096cca674d4SAntonio Quartulli if (local->ops->get_expected_throughput) 1097cca674d4SAntonio Quartulli ret = local->ops->get_expected_throughput(sta); 1098cca674d4SAntonio Quartulli trace_drv_return_u32(local, ret); 1099cca674d4SAntonio Quartulli 1100cca674d4SAntonio Quartulli return ret; 1101cca674d4SAntonio Quartulli } 1102cca674d4SAntonio Quartulli 11035b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local, 11045b3dc42bSFelix Fietkau struct ieee80211_sub_if_data *sdata, int *dbm) 11055b3dc42bSFelix Fietkau { 11065b3dc42bSFelix Fietkau int ret; 11075b3dc42bSFelix Fietkau 11085b3dc42bSFelix Fietkau if (!local->ops->get_txpower) 11095b3dc42bSFelix Fietkau return -EOPNOTSUPP; 11105b3dc42bSFelix Fietkau 11115b3dc42bSFelix Fietkau ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); 11125b3dc42bSFelix Fietkau trace_drv_get_txpower(local, sdata, *dbm, ret); 11135b3dc42bSFelix Fietkau 11145b3dc42bSFelix Fietkau return ret; 11155b3dc42bSFelix Fietkau } 11165b3dc42bSFelix Fietkau 1117a7a6bdd0SArik Nemtsov static inline int 1118a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local, 1119a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1120a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta, u8 oper_class, 1121a7a6bdd0SArik Nemtsov struct cfg80211_chan_def *chandef, 1122a7a6bdd0SArik Nemtsov struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) 1123a7a6bdd0SArik Nemtsov { 1124a7a6bdd0SArik Nemtsov int ret; 1125a7a6bdd0SArik Nemtsov 1126a7a6bdd0SArik Nemtsov might_sleep(); 1127a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1128a7a6bdd0SArik Nemtsov return -EIO; 1129a7a6bdd0SArik Nemtsov 1130a7a6bdd0SArik Nemtsov if (!local->ops->tdls_channel_switch) 1131a7a6bdd0SArik Nemtsov return -EOPNOTSUPP; 1132a7a6bdd0SArik Nemtsov 1133a7a6bdd0SArik Nemtsov trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef); 1134a7a6bdd0SArik Nemtsov ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta, 1135a7a6bdd0SArik Nemtsov oper_class, chandef, tmpl_skb, 1136a7a6bdd0SArik Nemtsov ch_sw_tm_ie); 1137a7a6bdd0SArik Nemtsov trace_drv_return_int(local, ret); 1138a7a6bdd0SArik Nemtsov return ret; 1139a7a6bdd0SArik Nemtsov } 1140a7a6bdd0SArik Nemtsov 1141a7a6bdd0SArik Nemtsov static inline void 1142a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local, 1143a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1144a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta) 1145a7a6bdd0SArik Nemtsov { 1146a7a6bdd0SArik Nemtsov might_sleep(); 1147a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1148a7a6bdd0SArik Nemtsov return; 1149a7a6bdd0SArik Nemtsov 1150a7a6bdd0SArik Nemtsov if (!local->ops->tdls_cancel_channel_switch) 1151a7a6bdd0SArik Nemtsov return; 1152a7a6bdd0SArik Nemtsov 1153a7a6bdd0SArik Nemtsov trace_drv_tdls_cancel_channel_switch(local, sdata, sta); 1154a7a6bdd0SArik Nemtsov local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta); 1155a7a6bdd0SArik Nemtsov trace_drv_return_void(local); 1156a7a6bdd0SArik Nemtsov } 1157a7a6bdd0SArik Nemtsov 11588a4d32f3SArik Nemtsov static inline void 11598a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local, 11608a4d32f3SArik Nemtsov struct ieee80211_sub_if_data *sdata, 11618a4d32f3SArik Nemtsov struct ieee80211_tdls_ch_sw_params *params) 11628a4d32f3SArik Nemtsov { 11638a4d32f3SArik Nemtsov trace_drv_tdls_recv_channel_switch(local, sdata, params); 11648a4d32f3SArik Nemtsov if (local->ops->tdls_recv_channel_switch) 11658a4d32f3SArik Nemtsov local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif, 11668a4d32f3SArik Nemtsov params); 11678a4d32f3SArik Nemtsov trace_drv_return_void(local); 11688a4d32f3SArik Nemtsov } 11698a4d32f3SArik Nemtsov 1170ba8c3d6fSFelix Fietkau static inline void drv_wake_tx_queue(struct ieee80211_local *local, 1171ba8c3d6fSFelix Fietkau struct txq_info *txq) 1172ba8c3d6fSFelix Fietkau { 1173ba8c3d6fSFelix Fietkau struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); 1174ba8c3d6fSFelix Fietkau 1175ba8c3d6fSFelix Fietkau if (!check_sdata_in_driver(sdata)) 1176ba8c3d6fSFelix Fietkau return; 1177ba8c3d6fSFelix Fietkau 1178ba8c3d6fSFelix Fietkau trace_drv_wake_tx_queue(local, sdata, txq); 1179ba8c3d6fSFelix Fietkau local->ops->wake_tx_queue(&local->hw, &txq->txq); 1180ba8c3d6fSFelix Fietkau } 1181ba8c3d6fSFelix Fietkau 118224487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */ 1183