1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 2f59374ebSSara Sharon /* 3f59374ebSSara Sharon * Portions of this file 4f59374ebSSara Sharon * Copyright(c) 2016 Intel Deutschland GmbH 515fae341SJohannes Berg * Copyright (C) 2018 - 2019, 2021 Intel Corporation 6f59374ebSSara Sharon */ 7f59374ebSSara Sharon 824487981SJohannes Berg #ifndef __MAC80211_DRIVER_OPS 924487981SJohannes Berg #define __MAC80211_DRIVER_OPS 1024487981SJohannes Berg 1124487981SJohannes Berg #include <net/mac80211.h> 1224487981SJohannes Berg #include "ieee80211_i.h" 13011ad0e9SJohannes Berg #include "trace.h" 1424487981SJohannes Berg 15c8ad0106SJohannes Berg #define check_sdata_in_driver(sdata) ({ \ 16c8ad0106SJohannes Berg !WARN_ONCE(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER), \ 17c8ad0106SJohannes Berg "%s: Failed check-sdata-in-driver check, flags: 0x%x\n", \ 18c8ad0106SJohannes Berg sdata->dev ? sdata->dev->name : sdata->name, sdata->flags); \ 19c8ad0106SJohannes Berg }) 207b7eab6fSJohannes Berg 21bc192f89SFelix Fietkau static inline struct ieee80211_sub_if_data * 22bc192f89SFelix Fietkau get_bss_sdata(struct ieee80211_sub_if_data *sdata) 23bc192f89SFelix Fietkau { 24bc192f89SFelix Fietkau if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 25bc192f89SFelix Fietkau sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 26bc192f89SFelix Fietkau u.ap); 27bc192f89SFelix Fietkau 28bc192f89SFelix Fietkau return sdata; 29bc192f89SFelix Fietkau } 30bc192f89SFelix Fietkau 3136323f81SThomas Huehn static inline void drv_tx(struct ieee80211_local *local, 3236323f81SThomas Huehn struct ieee80211_tx_control *control, 3336323f81SThomas Huehn struct sk_buff *skb) 3424487981SJohannes Berg { 3536323f81SThomas Huehn local->ops->tx(&local->hw, control, skb); 3624487981SJohannes Berg } 3724487981SJohannes Berg 38f59374ebSSara Sharon static inline void drv_sync_rx_queues(struct ieee80211_local *local, 39f59374ebSSara Sharon struct sta_info *sta) 40f59374ebSSara Sharon { 41f59374ebSSara Sharon if (local->ops->sync_rx_queues) { 42f59374ebSSara Sharon trace_drv_sync_rx_queues(local, sta->sdata, &sta->sta); 43f59374ebSSara Sharon local->ops->sync_rx_queues(&local->hw); 44f59374ebSSara Sharon trace_drv_return_void(local); 45f59374ebSSara Sharon } 46f59374ebSSara Sharon } 47f59374ebSSara Sharon 48e352114fSBen Greear static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, 49e352114fSBen Greear u32 sset, u8 *data) 50e352114fSBen Greear { 51e352114fSBen Greear struct ieee80211_local *local = sdata->local; 52e352114fSBen Greear if (local->ops->get_et_strings) { 53e352114fSBen Greear trace_drv_get_et_strings(local, sset); 54e352114fSBen Greear local->ops->get_et_strings(&local->hw, &sdata->vif, sset, data); 55e352114fSBen Greear trace_drv_return_void(local); 56e352114fSBen Greear } 57e352114fSBen Greear } 58e352114fSBen Greear 59e352114fSBen Greear static inline void drv_get_et_stats(struct ieee80211_sub_if_data *sdata, 60e352114fSBen Greear struct ethtool_stats *stats, 61e352114fSBen Greear u64 *data) 62e352114fSBen Greear { 63e352114fSBen Greear struct ieee80211_local *local = sdata->local; 64e352114fSBen Greear if (local->ops->get_et_stats) { 65e352114fSBen Greear trace_drv_get_et_stats(local); 66e352114fSBen Greear local->ops->get_et_stats(&local->hw, &sdata->vif, stats, data); 67e352114fSBen Greear trace_drv_return_void(local); 68e352114fSBen Greear } 69e352114fSBen Greear } 70e352114fSBen Greear 71e352114fSBen Greear static inline int drv_get_et_sset_count(struct ieee80211_sub_if_data *sdata, 72e352114fSBen Greear int sset) 73e352114fSBen Greear { 74e352114fSBen Greear struct ieee80211_local *local = sdata->local; 75e352114fSBen Greear int rv = 0; 76e352114fSBen Greear if (local->ops->get_et_sset_count) { 77e352114fSBen Greear trace_drv_get_et_sset_count(local, sset); 78e352114fSBen Greear rv = local->ops->get_et_sset_count(&local->hw, &sdata->vif, 79e352114fSBen Greear sset); 80e352114fSBen Greear trace_drv_return_int(local, rv); 81e352114fSBen Greear } 82e352114fSBen Greear return rv; 83e352114fSBen Greear } 84e352114fSBen Greear 85968a76ceSEliad Peller int drv_start(struct ieee80211_local *local); 86968a76ceSEliad Peller void drv_stop(struct ieee80211_local *local); 8724487981SJohannes Berg 88eecc4800SJohannes Berg #ifdef CONFIG_PM 89eecc4800SJohannes Berg static inline int drv_suspend(struct ieee80211_local *local, 90eecc4800SJohannes Berg struct cfg80211_wowlan *wowlan) 91eecc4800SJohannes Berg { 92eecc4800SJohannes Berg int ret; 93eecc4800SJohannes Berg 94eecc4800SJohannes Berg might_sleep(); 95eecc4800SJohannes Berg 96eecc4800SJohannes Berg trace_drv_suspend(local); 97eecc4800SJohannes Berg ret = local->ops->suspend(&local->hw, wowlan); 98eecc4800SJohannes Berg trace_drv_return_int(local, ret); 99eecc4800SJohannes Berg return ret; 100eecc4800SJohannes Berg } 101eecc4800SJohannes Berg 102eecc4800SJohannes Berg static inline int drv_resume(struct ieee80211_local *local) 103eecc4800SJohannes Berg { 104eecc4800SJohannes Berg int ret; 105eecc4800SJohannes Berg 106eecc4800SJohannes Berg might_sleep(); 107eecc4800SJohannes Berg 108eecc4800SJohannes Berg trace_drv_resume(local); 109eecc4800SJohannes Berg ret = local->ops->resume(&local->hw); 110eecc4800SJohannes Berg trace_drv_return_int(local, ret); 111eecc4800SJohannes Berg return ret; 112eecc4800SJohannes Berg } 1136d52563fSJohannes Berg 1146d52563fSJohannes Berg static inline void drv_set_wakeup(struct ieee80211_local *local, 1156d52563fSJohannes Berg bool enabled) 1166d52563fSJohannes Berg { 1176d52563fSJohannes Berg might_sleep(); 1186d52563fSJohannes Berg 1196d52563fSJohannes Berg if (!local->ops->set_wakeup) 1206d52563fSJohannes Berg return; 1216d52563fSJohannes Berg 1226d52563fSJohannes Berg trace_drv_set_wakeup(local, enabled); 1236d52563fSJohannes Berg local->ops->set_wakeup(&local->hw, enabled); 1246d52563fSJohannes Berg trace_drv_return_void(local); 1256d52563fSJohannes Berg } 126eecc4800SJohannes Berg #endif 127eecc4800SJohannes Berg 1289aae296aSDenys Vlasenko int drv_add_interface(struct ieee80211_local *local, 1299aae296aSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 130e1781ed3SKalle Valo 1319aae296aSDenys Vlasenko int drv_change_interface(struct ieee80211_local *local, 13234d4bc4dSJohannes Berg struct ieee80211_sub_if_data *sdata, 1339aae296aSDenys Vlasenko enum nl80211_iftype type, bool p2p); 13434d4bc4dSJohannes Berg 1359aae296aSDenys Vlasenko void drv_remove_interface(struct ieee80211_local *local, 1369aae296aSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 13724487981SJohannes Berg 13824487981SJohannes Berg static inline int drv_config(struct ieee80211_local *local, u32 changed) 13924487981SJohannes Berg { 140e1781ed3SKalle Valo int ret; 141e1781ed3SKalle Valo 142e1781ed3SKalle Valo might_sleep(); 143e1781ed3SKalle Valo 1444efc76bdSJohannes Berg trace_drv_config(local, changed); 145e1781ed3SKalle Valo ret = local->ops->config(&local->hw, changed); 1464efc76bdSJohannes Berg trace_drv_return_int(local, ret); 1470a2b8bb2SJohannes Berg return ret; 14824487981SJohannes Berg } 14924487981SJohannes Berg 15024487981SJohannes Berg static inline void drv_bss_info_changed(struct ieee80211_local *local, 15112375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 15224487981SJohannes Berg struct ieee80211_bss_conf *info, 15324487981SJohannes Berg u32 changed) 15424487981SJohannes Berg { 155e1781ed3SKalle Valo might_sleep(); 156e1781ed3SKalle Valo 1575bbe754dSJohannes Berg if (WARN_ON_ONCE(changed & (BSS_CHANGED_BEACON | 158b8dc1a35SJohannes Berg BSS_CHANGED_BEACON_ENABLED) && 159b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_AP && 160b8dc1a35SJohannes Berg sdata->vif.type != NL80211_IFTYPE_ADHOC && 161239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_MESH_POINT && 162239281f8SRostislav Lisovy sdata->vif.type != NL80211_IFTYPE_OCB)) 1635bbe754dSJohannes Berg return; 1645bbe754dSJohannes Berg 1655bbe754dSJohannes Berg if (WARN_ON_ONCE(sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE || 166708d50edSAyala Beker sdata->vif.type == NL80211_IFTYPE_NAN || 16742bd20d9SAviya Erenfeld (sdata->vif.type == NL80211_IFTYPE_MONITOR && 1683a3713ecSPeter Große !sdata->vif.mu_mimo_owner && 1693a3713ecSPeter Große !(changed & BSS_CHANGED_TXPOWER)))) 1705bbe754dSJohannes Berg return; 171b8dc1a35SJohannes Berg 172f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 173f6837ba8SJohannes Berg return; 1747b7eab6fSJohannes Berg 1754efc76bdSJohannes Berg trace_drv_bss_info_changed(local, sdata, info, changed); 17624487981SJohannes Berg if (local->ops->bss_info_changed) 17712375ef9SJohannes Berg local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 1784efc76bdSJohannes Berg trace_drv_return_void(local); 17924487981SJohannes Berg } 18024487981SJohannes Berg 1813ac64beeSJohannes Berg static inline u64 drv_prepare_multicast(struct ieee80211_local *local, 18222bedad3SJiri Pirko struct netdev_hw_addr_list *mc_list) 18324487981SJohannes Berg { 1843ac64beeSJohannes Berg u64 ret = 0; 1853ac64beeSJohannes Berg 1864efc76bdSJohannes Berg trace_drv_prepare_multicast(local, mc_list->count); 1874efc76bdSJohannes Berg 1883ac64beeSJohannes Berg if (local->ops->prepare_multicast) 18922bedad3SJiri Pirko ret = local->ops->prepare_multicast(&local->hw, mc_list); 1903ac64beeSJohannes Berg 1914efc76bdSJohannes Berg trace_drv_return_u64(local, ret); 1923ac64beeSJohannes Berg 1933ac64beeSJohannes Berg return ret; 1943ac64beeSJohannes Berg } 1953ac64beeSJohannes Berg 1963ac64beeSJohannes Berg static inline void drv_configure_filter(struct ieee80211_local *local, 1973ac64beeSJohannes Berg unsigned int changed_flags, 1983ac64beeSJohannes Berg unsigned int *total_flags, 1993ac64beeSJohannes Berg u64 multicast) 2003ac64beeSJohannes Berg { 2013ac64beeSJohannes Berg might_sleep(); 2023ac64beeSJohannes Berg 2030a2b8bb2SJohannes Berg trace_drv_configure_filter(local, changed_flags, total_flags, 2043ac64beeSJohannes Berg multicast); 2054efc76bdSJohannes Berg local->ops->configure_filter(&local->hw, changed_flags, total_flags, 2064efc76bdSJohannes Berg multicast); 2074efc76bdSJohannes Berg trace_drv_return_void(local); 20824487981SJohannes Berg } 20924487981SJohannes Berg 2101b09b556SAndrei Otcheretianski static inline void drv_config_iface_filter(struct ieee80211_local *local, 2111b09b556SAndrei Otcheretianski struct ieee80211_sub_if_data *sdata, 2121b09b556SAndrei Otcheretianski unsigned int filter_flags, 2131b09b556SAndrei Otcheretianski unsigned int changed_flags) 2141b09b556SAndrei Otcheretianski { 2151b09b556SAndrei Otcheretianski might_sleep(); 2161b09b556SAndrei Otcheretianski 2171b09b556SAndrei Otcheretianski trace_drv_config_iface_filter(local, sdata, filter_flags, 2181b09b556SAndrei Otcheretianski changed_flags); 2191b09b556SAndrei Otcheretianski if (local->ops->config_iface_filter) 2201b09b556SAndrei Otcheretianski local->ops->config_iface_filter(&local->hw, &sdata->vif, 2211b09b556SAndrei Otcheretianski filter_flags, 2221b09b556SAndrei Otcheretianski changed_flags); 2231b09b556SAndrei Otcheretianski trace_drv_return_void(local); 2241b09b556SAndrei Otcheretianski } 2251b09b556SAndrei Otcheretianski 22624487981SJohannes Berg static inline int drv_set_tim(struct ieee80211_local *local, 22724487981SJohannes Berg struct ieee80211_sta *sta, bool set) 22824487981SJohannes Berg { 2290a2b8bb2SJohannes Berg int ret = 0; 2304efc76bdSJohannes Berg trace_drv_set_tim(local, sta, set); 23124487981SJohannes Berg if (local->ops->set_tim) 2320a2b8bb2SJohannes Berg ret = local->ops->set_tim(&local->hw, sta, set); 2334efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2340a2b8bb2SJohannes Berg return ret; 23524487981SJohannes Berg } 23624487981SJohannes Berg 23724487981SJohannes Berg static inline int drv_set_key(struct ieee80211_local *local, 23812375ef9SJohannes Berg enum set_key_cmd cmd, 23912375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 24024487981SJohannes Berg struct ieee80211_sta *sta, 24124487981SJohannes Berg struct ieee80211_key_conf *key) 24224487981SJohannes Berg { 243e1781ed3SKalle Valo int ret; 244e1781ed3SKalle Valo 245e1781ed3SKalle Valo might_sleep(); 246e1781ed3SKalle Valo 247077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 248f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 249f6837ba8SJohannes Berg return -EIO; 2507b7eab6fSJohannes Berg 2514efc76bdSJohannes Berg trace_drv_set_key(local, cmd, sdata, sta, key); 252e1781ed3SKalle Valo ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 2534efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2540a2b8bb2SJohannes Berg return ret; 25524487981SJohannes Berg } 25624487981SJohannes Berg 25724487981SJohannes Berg static inline void drv_update_tkip_key(struct ieee80211_local *local, 258b3fbdcf4SJohannes Berg struct ieee80211_sub_if_data *sdata, 25924487981SJohannes Berg struct ieee80211_key_conf *conf, 260b3fbdcf4SJohannes Berg struct sta_info *sta, u32 iv32, 26124487981SJohannes Berg u16 *phase1key) 26224487981SJohannes Berg { 263b3fbdcf4SJohannes Berg struct ieee80211_sta *ista = NULL; 264b3fbdcf4SJohannes Berg 265b3fbdcf4SJohannes Berg if (sta) 266b3fbdcf4SJohannes Berg ista = &sta->sta; 267b3fbdcf4SJohannes Berg 268077f4939SJohannes Berg sdata = get_bss_sdata(sdata); 269f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 270f6837ba8SJohannes Berg return; 2717b7eab6fSJohannes Berg 2724efc76bdSJohannes Berg trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 27324487981SJohannes Berg if (local->ops->update_tkip_key) 274b3fbdcf4SJohannes Berg local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 275b3fbdcf4SJohannes Berg ista, iv32, phase1key); 2764efc76bdSJohannes Berg trace_drv_return_void(local); 27724487981SJohannes Berg } 27824487981SJohannes Berg 27924487981SJohannes Berg static inline int drv_hw_scan(struct ieee80211_local *local, 280a060bbfeSJohannes Berg struct ieee80211_sub_if_data *sdata, 281c56ef672SDavid Spinadel struct ieee80211_scan_request *req) 28224487981SJohannes Berg { 283e1781ed3SKalle Valo int ret; 284e1781ed3SKalle Valo 285e1781ed3SKalle Valo might_sleep(); 286e1781ed3SKalle Valo 287f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 288f6837ba8SJohannes Berg return -EIO; 2897b7eab6fSJohannes Berg 29079f460caSLuciano Coelho trace_drv_hw_scan(local, sdata); 291a060bbfeSJohannes Berg ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 2924efc76bdSJohannes Berg trace_drv_return_int(local, ret); 2930a2b8bb2SJohannes Berg return ret; 29424487981SJohannes Berg } 29524487981SJohannes Berg 296b856439bSEliad Peller static inline void drv_cancel_hw_scan(struct ieee80211_local *local, 297b856439bSEliad Peller struct ieee80211_sub_if_data *sdata) 298b856439bSEliad Peller { 299b856439bSEliad Peller might_sleep(); 300b856439bSEliad Peller 301f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 302f6837ba8SJohannes Berg return; 3037b7eab6fSJohannes Berg 304b856439bSEliad Peller trace_drv_cancel_hw_scan(local, sdata); 305b856439bSEliad Peller local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 306b856439bSEliad Peller trace_drv_return_void(local); 307b856439bSEliad Peller } 308b856439bSEliad Peller 30979f460caSLuciano Coelho static inline int 31079f460caSLuciano Coelho drv_sched_scan_start(struct ieee80211_local *local, 31179f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata, 31279f460caSLuciano Coelho struct cfg80211_sched_scan_request *req, 313633e2713SDavid Spinadel struct ieee80211_scan_ies *ies) 31479f460caSLuciano Coelho { 31579f460caSLuciano Coelho int ret; 31679f460caSLuciano Coelho 31779f460caSLuciano Coelho might_sleep(); 31879f460caSLuciano Coelho 319f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 320f6837ba8SJohannes Berg return -EIO; 3217b7eab6fSJohannes Berg 32279f460caSLuciano Coelho trace_drv_sched_scan_start(local, sdata); 32379f460caSLuciano Coelho ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 32479f460caSLuciano Coelho req, ies); 32579f460caSLuciano Coelho trace_drv_return_int(local, ret); 32679f460caSLuciano Coelho return ret; 32779f460caSLuciano Coelho } 32879f460caSLuciano Coelho 32937e3308cSJohannes Berg static inline int drv_sched_scan_stop(struct ieee80211_local *local, 33079f460caSLuciano Coelho struct ieee80211_sub_if_data *sdata) 33179f460caSLuciano Coelho { 33237e3308cSJohannes Berg int ret; 33337e3308cSJohannes Berg 33479f460caSLuciano Coelho might_sleep(); 33579f460caSLuciano Coelho 336f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 337f6837ba8SJohannes Berg return -EIO; 3387b7eab6fSJohannes Berg 33979f460caSLuciano Coelho trace_drv_sched_scan_stop(local, sdata); 34037e3308cSJohannes Berg ret = local->ops->sched_scan_stop(&local->hw, &sdata->vif); 34137e3308cSJohannes Berg trace_drv_return_int(local, ret); 34237e3308cSJohannes Berg 34337e3308cSJohannes Berg return ret; 34479f460caSLuciano Coelho } 34579f460caSLuciano Coelho 346a344d677SJohannes Berg static inline void drv_sw_scan_start(struct ieee80211_local *local, 347a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata, 348a344d677SJohannes Berg const u8 *mac_addr) 34924487981SJohannes Berg { 350e1781ed3SKalle Valo might_sleep(); 351e1781ed3SKalle Valo 352a344d677SJohannes Berg trace_drv_sw_scan_start(local, sdata, mac_addr); 35324487981SJohannes Berg if (local->ops->sw_scan_start) 354a344d677SJohannes Berg local->ops->sw_scan_start(&local->hw, &sdata->vif, mac_addr); 3554efc76bdSJohannes Berg trace_drv_return_void(local); 35624487981SJohannes Berg } 35724487981SJohannes Berg 358a344d677SJohannes Berg static inline void drv_sw_scan_complete(struct ieee80211_local *local, 359a344d677SJohannes Berg struct ieee80211_sub_if_data *sdata) 36024487981SJohannes Berg { 361e1781ed3SKalle Valo might_sleep(); 362e1781ed3SKalle Valo 363a344d677SJohannes Berg trace_drv_sw_scan_complete(local, sdata); 36424487981SJohannes Berg if (local->ops->sw_scan_complete) 365a344d677SJohannes Berg local->ops->sw_scan_complete(&local->hw, &sdata->vif); 3664efc76bdSJohannes Berg trace_drv_return_void(local); 36724487981SJohannes Berg } 36824487981SJohannes Berg 36924487981SJohannes Berg static inline int drv_get_stats(struct ieee80211_local *local, 37024487981SJohannes Berg struct ieee80211_low_level_stats *stats) 37124487981SJohannes Berg { 3720a2b8bb2SJohannes Berg int ret = -EOPNOTSUPP; 3730a2b8bb2SJohannes Berg 374e1781ed3SKalle Valo might_sleep(); 375e1781ed3SKalle Valo 3760a2b8bb2SJohannes Berg if (local->ops->get_stats) 3770a2b8bb2SJohannes Berg ret = local->ops->get_stats(&local->hw, stats); 3780a2b8bb2SJohannes Berg trace_drv_get_stats(local, stats, ret); 3790a2b8bb2SJohannes Berg 3800a2b8bb2SJohannes Berg return ret; 38124487981SJohannes Berg } 38224487981SJohannes Berg 3839352c19fSJohannes Berg static inline void drv_get_key_seq(struct ieee80211_local *local, 3849352c19fSJohannes Berg struct ieee80211_key *key, 3859352c19fSJohannes Berg struct ieee80211_key_seq *seq) 38624487981SJohannes Berg { 3879352c19fSJohannes Berg if (local->ops->get_key_seq) 3889352c19fSJohannes Berg local->ops->get_key_seq(&local->hw, &key->conf, seq); 3899352c19fSJohannes Berg trace_drv_get_key_seq(local, &key->conf); 39024487981SJohannes Berg } 39124487981SJohannes Berg 392f23a4780SArik Nemtsov static inline int drv_set_frag_threshold(struct ieee80211_local *local, 393f23a4780SArik Nemtsov u32 value) 394f23a4780SArik Nemtsov { 395f23a4780SArik Nemtsov int ret = 0; 396f23a4780SArik Nemtsov 397f23a4780SArik Nemtsov might_sleep(); 398f23a4780SArik Nemtsov 399f23a4780SArik Nemtsov trace_drv_set_frag_threshold(local, value); 400f23a4780SArik Nemtsov if (local->ops->set_frag_threshold) 401f23a4780SArik Nemtsov ret = local->ops->set_frag_threshold(&local->hw, value); 402f23a4780SArik Nemtsov trace_drv_return_int(local, ret); 403f23a4780SArik Nemtsov return ret; 404f23a4780SArik Nemtsov } 405f23a4780SArik Nemtsov 40624487981SJohannes Berg static inline int drv_set_rts_threshold(struct ieee80211_local *local, 40724487981SJohannes Berg u32 value) 40824487981SJohannes Berg { 4090a2b8bb2SJohannes Berg int ret = 0; 410e1781ed3SKalle Valo 411e1781ed3SKalle Valo might_sleep(); 412e1781ed3SKalle Valo 4134efc76bdSJohannes Berg trace_drv_set_rts_threshold(local, value); 41424487981SJohannes Berg if (local->ops->set_rts_threshold) 4150a2b8bb2SJohannes Berg ret = local->ops->set_rts_threshold(&local->hw, value); 4164efc76bdSJohannes Berg trace_drv_return_int(local, ret); 4170a2b8bb2SJohannes Berg return ret; 41824487981SJohannes Berg } 41924487981SJohannes Berg 420310bc676SLukáš Turek static inline int drv_set_coverage_class(struct ieee80211_local *local, 421a4bcaf55SLorenzo Bianconi s16 value) 422310bc676SLukáš Turek { 423310bc676SLukáš Turek int ret = 0; 424310bc676SLukáš Turek might_sleep(); 425310bc676SLukáš Turek 4264efc76bdSJohannes Berg trace_drv_set_coverage_class(local, value); 427310bc676SLukáš Turek if (local->ops->set_coverage_class) 428310bc676SLukáš Turek local->ops->set_coverage_class(&local->hw, value); 429310bc676SLukáš Turek else 430310bc676SLukáš Turek ret = -EOPNOTSUPP; 431310bc676SLukáš Turek 4324efc76bdSJohannes Berg trace_drv_return_int(local, ret); 433310bc676SLukáš Turek return ret; 434310bc676SLukáš Turek } 435310bc676SLukáš Turek 43624487981SJohannes Berg static inline void drv_sta_notify(struct ieee80211_local *local, 43712375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 43824487981SJohannes Berg enum sta_notify_cmd cmd, 43924487981SJohannes Berg struct ieee80211_sta *sta) 44024487981SJohannes Berg { 441bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 442f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 443f6837ba8SJohannes Berg return; 4447b7eab6fSJohannes Berg 4454efc76bdSJohannes Berg trace_drv_sta_notify(local, sdata, cmd, sta); 44624487981SJohannes Berg if (local->ops->sta_notify) 44712375ef9SJohannes Berg local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 4484efc76bdSJohannes Berg trace_drv_return_void(local); 44924487981SJohannes Berg } 45024487981SJohannes Berg 45134e89507SJohannes Berg static inline int drv_sta_add(struct ieee80211_local *local, 45234e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 45334e89507SJohannes Berg struct ieee80211_sta *sta) 45434e89507SJohannes Berg { 45534e89507SJohannes Berg int ret = 0; 45634e89507SJohannes Berg 45734e89507SJohannes Berg might_sleep(); 45834e89507SJohannes Berg 459bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 460f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 461f6837ba8SJohannes Berg return -EIO; 4627b7eab6fSJohannes Berg 4634efc76bdSJohannes Berg trace_drv_sta_add(local, sdata, sta); 46434e89507SJohannes Berg if (local->ops->sta_add) 46534e89507SJohannes Berg ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 46634e89507SJohannes Berg 4674efc76bdSJohannes Berg trace_drv_return_int(local, ret); 46834e89507SJohannes Berg 46934e89507SJohannes Berg return ret; 47034e89507SJohannes Berg } 47134e89507SJohannes Berg 47234e89507SJohannes Berg static inline void drv_sta_remove(struct ieee80211_local *local, 47334e89507SJohannes Berg struct ieee80211_sub_if_data *sdata, 47434e89507SJohannes Berg struct ieee80211_sta *sta) 47534e89507SJohannes Berg { 47634e89507SJohannes Berg might_sleep(); 47734e89507SJohannes Berg 478bc192f89SFelix Fietkau sdata = get_bss_sdata(sdata); 479f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 480f6837ba8SJohannes Berg return; 4817b7eab6fSJohannes Berg 4824efc76bdSJohannes Berg trace_drv_sta_remove(local, sdata, sta); 48334e89507SJohannes Berg if (local->ops->sta_remove) 48434e89507SJohannes Berg local->ops->sta_remove(&local->hw, &sdata->vif, sta); 48534e89507SJohannes Berg 4864efc76bdSJohannes Berg trace_drv_return_void(local); 48734e89507SJohannes Berg } 48834e89507SJohannes Berg 48977d2ece6SSujith Manoharan #ifdef CONFIG_MAC80211_DEBUGFS 49077d2ece6SSujith Manoharan static inline void drv_sta_add_debugfs(struct ieee80211_local *local, 49177d2ece6SSujith Manoharan struct ieee80211_sub_if_data *sdata, 49277d2ece6SSujith Manoharan struct ieee80211_sta *sta, 49377d2ece6SSujith Manoharan struct dentry *dir) 49477d2ece6SSujith Manoharan { 49577d2ece6SSujith Manoharan might_sleep(); 49677d2ece6SSujith Manoharan 49777d2ece6SSujith Manoharan sdata = get_bss_sdata(sdata); 498f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 499f6837ba8SJohannes Berg return; 50077d2ece6SSujith Manoharan 50177d2ece6SSujith Manoharan if (local->ops->sta_add_debugfs) 50277d2ece6SSujith Manoharan local->ops->sta_add_debugfs(&local->hw, &sdata->vif, 50377d2ece6SSujith Manoharan sta, dir); 50477d2ece6SSujith Manoharan } 50577d2ece6SSujith Manoharan #endif 50677d2ece6SSujith Manoharan 5076a9d1b91SJohannes Berg static inline void drv_sta_pre_rcu_remove(struct ieee80211_local *local, 5086a9d1b91SJohannes Berg struct ieee80211_sub_if_data *sdata, 5096a9d1b91SJohannes Berg struct sta_info *sta) 5106a9d1b91SJohannes Berg { 5116a9d1b91SJohannes Berg might_sleep(); 5126a9d1b91SJohannes Berg 5136a9d1b91SJohannes Berg sdata = get_bss_sdata(sdata); 514f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 515f6837ba8SJohannes Berg return; 5166a9d1b91SJohannes Berg 5176a9d1b91SJohannes Berg trace_drv_sta_pre_rcu_remove(local, sdata, &sta->sta); 5186a9d1b91SJohannes Berg if (local->ops->sta_pre_rcu_remove) 5196a9d1b91SJohannes Berg local->ops->sta_pre_rcu_remove(&local->hw, &sdata->vif, 5206a9d1b91SJohannes Berg &sta->sta); 5216a9d1b91SJohannes Berg trace_drv_return_void(local); 5226a9d1b91SJohannes Berg } 5236a9d1b91SJohannes Berg 524727da60bSDenys Vlasenko __must_check 525f09603a2SJohannes Berg int drv_sta_state(struct ieee80211_local *local, 526f09603a2SJohannes Berg struct ieee80211_sub_if_data *sdata, 527f09603a2SJohannes Berg struct sta_info *sta, 528f09603a2SJohannes Berg enum ieee80211_sta_state old_state, 529727da60bSDenys Vlasenko enum ieee80211_sta_state new_state); 530f09603a2SJohannes Berg 531ba905bf4SAshok Raj Nagarajan __must_check 532ba905bf4SAshok Raj Nagarajan int drv_sta_set_txpwr(struct ieee80211_local *local, 533ba905bf4SAshok Raj Nagarajan struct ieee80211_sub_if_data *sdata, 534ba905bf4SAshok Raj Nagarajan struct sta_info *sta); 535ba905bf4SAshok Raj Nagarajan 5364fbd572cSDenys Vlasenko void drv_sta_rc_update(struct ieee80211_local *local, 5378f727ef3SJohannes Berg struct ieee80211_sub_if_data *sdata, 5384fbd572cSDenys Vlasenko struct ieee80211_sta *sta, u32 changed); 5398f727ef3SJohannes Berg 540f815e2b3SJohannes Berg static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local, 541f815e2b3SJohannes Berg struct ieee80211_sub_if_data *sdata, 542f815e2b3SJohannes Berg struct ieee80211_sta *sta) 543f815e2b3SJohannes Berg { 544f815e2b3SJohannes Berg sdata = get_bss_sdata(sdata); 545f815e2b3SJohannes Berg if (!check_sdata_in_driver(sdata)) 546f815e2b3SJohannes Berg return; 547f815e2b3SJohannes Berg 548f815e2b3SJohannes Berg trace_drv_sta_rate_tbl_update(local, sdata, sta); 549f815e2b3SJohannes Berg if (local->ops->sta_rate_tbl_update) 550f815e2b3SJohannes Berg local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta); 551f815e2b3SJohannes Berg 552f815e2b3SJohannes Berg trace_drv_return_void(local); 553f815e2b3SJohannes Berg } 554f815e2b3SJohannes Berg 5552b9a7e1bSJohannes Berg static inline void drv_sta_statistics(struct ieee80211_local *local, 5562b9a7e1bSJohannes Berg struct ieee80211_sub_if_data *sdata, 5572b9a7e1bSJohannes Berg struct ieee80211_sta *sta, 5582b9a7e1bSJohannes Berg struct station_info *sinfo) 5592b9a7e1bSJohannes Berg { 5602b9a7e1bSJohannes Berg sdata = get_bss_sdata(sdata); 5612b9a7e1bSJohannes Berg if (!check_sdata_in_driver(sdata)) 5622b9a7e1bSJohannes Berg return; 5632b9a7e1bSJohannes Berg 5642b9a7e1bSJohannes Berg trace_drv_sta_statistics(local, sdata, sta); 5652b9a7e1bSJohannes Berg if (local->ops->sta_statistics) 5662b9a7e1bSJohannes Berg local->ops->sta_statistics(&local->hw, &sdata->vif, sta, sinfo); 5672b9a7e1bSJohannes Berg trace_drv_return_void(local); 5682b9a7e1bSJohannes Berg } 5692b9a7e1bSJohannes Berg 570b23dcd4aSDenys Vlasenko int drv_conf_tx(struct ieee80211_local *local, 571a3304b0aSJohannes Berg struct ieee80211_sub_if_data *sdata, u16 ac, 572b23dcd4aSDenys Vlasenko const struct ieee80211_tx_queue_params *params); 57324487981SJohannes Berg 574416eb9fcSDenys Vlasenko u64 drv_get_tsf(struct ieee80211_local *local, 575416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 576416eb9fcSDenys Vlasenko void drv_set_tsf(struct ieee80211_local *local, 57737a41b4aSEliad Peller struct ieee80211_sub_if_data *sdata, 578416eb9fcSDenys Vlasenko u64 tsf); 579354d381bSPedersen, Thomas void drv_offset_tsf(struct ieee80211_local *local, 580354d381bSPedersen, Thomas struct ieee80211_sub_if_data *sdata, 581354d381bSPedersen, Thomas s64 offset); 582416eb9fcSDenys Vlasenko void drv_reset_tsf(struct ieee80211_local *local, 583416eb9fcSDenys Vlasenko struct ieee80211_sub_if_data *sdata); 58424487981SJohannes Berg 58524487981SJohannes Berg static inline int drv_tx_last_beacon(struct ieee80211_local *local) 58624487981SJohannes Berg { 58702582e9bSMasanari Iida int ret = 0; /* default unsupported op for less congestion */ 588e1781ed3SKalle Valo 589e1781ed3SKalle Valo might_sleep(); 590e1781ed3SKalle Valo 5914efc76bdSJohannes Berg trace_drv_tx_last_beacon(local); 59224487981SJohannes Berg if (local->ops->tx_last_beacon) 5930a2b8bb2SJohannes Berg ret = local->ops->tx_last_beacon(&local->hw); 5944efc76bdSJohannes Berg trace_drv_return_int(local, ret); 5950a2b8bb2SJohannes Berg return ret; 59624487981SJohannes Berg } 59724487981SJohannes Berg 5986db96838SDenys Vlasenko int drv_ampdu_action(struct ieee80211_local *local, 59912375ef9SJohannes Berg struct ieee80211_sub_if_data *sdata, 60050ea05efSSara Sharon struct ieee80211_ampdu_params *params); 6011f87f7d3SJohannes Berg 6021289723eSHolger Schurig static inline int drv_get_survey(struct ieee80211_local *local, int idx, 6031289723eSHolger Schurig struct survey_info *survey) 6041289723eSHolger Schurig { 6051289723eSHolger Schurig int ret = -EOPNOTSUPP; 606c466d4efSJohn W. Linville 607c466d4efSJohn W. Linville trace_drv_get_survey(local, idx, survey); 608c466d4efSJohn W. Linville 60935dd0509SHolger Schurig if (local->ops->get_survey) 6101289723eSHolger Schurig ret = local->ops->get_survey(&local->hw, idx, survey); 611c466d4efSJohn W. Linville 612c466d4efSJohn W. Linville trace_drv_return_int(local, ret); 613c466d4efSJohn W. Linville 6141289723eSHolger Schurig return ret; 6151289723eSHolger Schurig } 6161f87f7d3SJohannes Berg 6171f87f7d3SJohannes Berg static inline void drv_rfkill_poll(struct ieee80211_local *local) 6181f87f7d3SJohannes Berg { 619e1781ed3SKalle Valo might_sleep(); 620e1781ed3SKalle Valo 6211f87f7d3SJohannes Berg if (local->ops->rfkill_poll) 6221f87f7d3SJohannes Berg local->ops->rfkill_poll(&local->hw); 6231f87f7d3SJohannes Berg } 624a80f7c0bSJohannes Berg 62539ecc01dSJohannes Berg static inline void drv_flush(struct ieee80211_local *local, 62677be2c54SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 62739ecc01dSJohannes Berg u32 queues, bool drop) 628a80f7c0bSJohannes Berg { 62977be2c54SEmmanuel Grumbach struct ieee80211_vif *vif = sdata ? &sdata->vif : NULL; 63077be2c54SEmmanuel Grumbach 631e1781ed3SKalle Valo might_sleep(); 632e1781ed3SKalle Valo 633f6837ba8SJohannes Berg if (sdata && !check_sdata_in_driver(sdata)) 634f6837ba8SJohannes Berg return; 63577be2c54SEmmanuel Grumbach 63639ecc01dSJohannes Berg trace_drv_flush(local, queues, drop); 637a80f7c0bSJohannes Berg if (local->ops->flush) 63877be2c54SEmmanuel Grumbach local->ops->flush(&local->hw, vif, queues, drop); 6394efc76bdSJohannes Berg trace_drv_return_void(local); 640a80f7c0bSJohannes Berg } 6415ce6e438SJohannes Berg 6425ce6e438SJohannes Berg static inline void drv_channel_switch(struct ieee80211_local *local, 6430f791eb4SLuciano Coelho struct ieee80211_sub_if_data *sdata, 6445ce6e438SJohannes Berg struct ieee80211_channel_switch *ch_switch) 6455ce6e438SJohannes Berg { 6465ce6e438SJohannes Berg might_sleep(); 6475ce6e438SJohannes Berg 6480f791eb4SLuciano Coelho trace_drv_channel_switch(local, sdata, ch_switch); 6490f791eb4SLuciano Coelho local->ops->channel_switch(&local->hw, &sdata->vif, ch_switch); 6504efc76bdSJohannes Berg trace_drv_return_void(local); 6515ce6e438SJohannes Berg } 6525ce6e438SJohannes Berg 65315d96753SBruno Randolf 65415d96753SBruno Randolf static inline int drv_set_antenna(struct ieee80211_local *local, 65515d96753SBruno Randolf u32 tx_ant, u32 rx_ant) 65615d96753SBruno Randolf { 65715d96753SBruno Randolf int ret = -EOPNOTSUPP; 65815d96753SBruno Randolf might_sleep(); 65915d96753SBruno Randolf if (local->ops->set_antenna) 66015d96753SBruno Randolf ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant); 66115d96753SBruno Randolf trace_drv_set_antenna(local, tx_ant, rx_ant, ret); 66215d96753SBruno Randolf return ret; 66315d96753SBruno Randolf } 66415d96753SBruno Randolf 66515d96753SBruno Randolf static inline int drv_get_antenna(struct ieee80211_local *local, 66615d96753SBruno Randolf u32 *tx_ant, u32 *rx_ant) 66715d96753SBruno Randolf { 66815d96753SBruno Randolf int ret = -EOPNOTSUPP; 66915d96753SBruno Randolf might_sleep(); 67015d96753SBruno Randolf if (local->ops->get_antenna) 67115d96753SBruno Randolf ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant); 67215d96753SBruno Randolf trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret); 67315d96753SBruno Randolf return ret; 67415d96753SBruno Randolf } 67515d96753SBruno Randolf 67621f83589SJohannes Berg static inline int drv_remain_on_channel(struct ieee80211_local *local, 67749884568SEliad Peller struct ieee80211_sub_if_data *sdata, 67821f83589SJohannes Berg struct ieee80211_channel *chan, 679d339d5caSIlan Peer unsigned int duration, 680d339d5caSIlan Peer enum ieee80211_roc_type type) 68121f83589SJohannes Berg { 68221f83589SJohannes Berg int ret; 68321f83589SJohannes Berg 68421f83589SJohannes Berg might_sleep(); 68521f83589SJohannes Berg 686d339d5caSIlan Peer trace_drv_remain_on_channel(local, sdata, chan, duration, type); 68749884568SEliad Peller ret = local->ops->remain_on_channel(&local->hw, &sdata->vif, 688d339d5caSIlan Peer chan, duration, type); 68921f83589SJohannes Berg trace_drv_return_int(local, ret); 69021f83589SJohannes Berg 69121f83589SJohannes Berg return ret; 69221f83589SJohannes Berg } 69321f83589SJohannes Berg 6945db4c4b9SEmmanuel Grumbach static inline int 6955db4c4b9SEmmanuel Grumbach drv_cancel_remain_on_channel(struct ieee80211_local *local, 6965db4c4b9SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata) 69721f83589SJohannes Berg { 69821f83589SJohannes Berg int ret; 69921f83589SJohannes Berg 70021f83589SJohannes Berg might_sleep(); 70121f83589SJohannes Berg 7025db4c4b9SEmmanuel Grumbach trace_drv_cancel_remain_on_channel(local, sdata); 7035db4c4b9SEmmanuel Grumbach ret = local->ops->cancel_remain_on_channel(&local->hw, &sdata->vif); 70421f83589SJohannes Berg trace_drv_return_int(local, ret); 70521f83589SJohannes Berg 70621f83589SJohannes Berg return ret; 70721f83589SJohannes Berg } 70821f83589SJohannes Berg 70938c09159SJohn W. Linville static inline int drv_set_ringparam(struct ieee80211_local *local, 71038c09159SJohn W. Linville u32 tx, u32 rx) 71138c09159SJohn W. Linville { 71238c09159SJohn W. Linville int ret = -ENOTSUPP; 71338c09159SJohn W. Linville 71438c09159SJohn W. Linville might_sleep(); 71538c09159SJohn W. Linville 71638c09159SJohn W. Linville trace_drv_set_ringparam(local, tx, rx); 71738c09159SJohn W. Linville if (local->ops->set_ringparam) 71838c09159SJohn W. Linville ret = local->ops->set_ringparam(&local->hw, tx, rx); 71938c09159SJohn W. Linville trace_drv_return_int(local, ret); 72038c09159SJohn W. Linville 72138c09159SJohn W. Linville return ret; 72238c09159SJohn W. Linville } 72338c09159SJohn W. Linville 72438c09159SJohn W. Linville static inline void drv_get_ringparam(struct ieee80211_local *local, 72538c09159SJohn W. Linville u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max) 72638c09159SJohn W. Linville { 72738c09159SJohn W. Linville might_sleep(); 72838c09159SJohn W. Linville 72938c09159SJohn W. Linville trace_drv_get_ringparam(local, tx, tx_max, rx, rx_max); 73038c09159SJohn W. Linville if (local->ops->get_ringparam) 73138c09159SJohn W. Linville local->ops->get_ringparam(&local->hw, tx, tx_max, rx, rx_max); 73238c09159SJohn W. Linville trace_drv_return_void(local); 73338c09159SJohn W. Linville } 73438c09159SJohn W. Linville 735e8306f98SVivek Natarajan static inline bool drv_tx_frames_pending(struct ieee80211_local *local) 736e8306f98SVivek Natarajan { 737e8306f98SVivek Natarajan bool ret = false; 738e8306f98SVivek Natarajan 739e8306f98SVivek Natarajan might_sleep(); 740e8306f98SVivek Natarajan 741e8306f98SVivek Natarajan trace_drv_tx_frames_pending(local); 742e8306f98SVivek Natarajan if (local->ops->tx_frames_pending) 743e8306f98SVivek Natarajan ret = local->ops->tx_frames_pending(&local->hw); 744e8306f98SVivek Natarajan trace_drv_return_bool(local, ret); 745e8306f98SVivek Natarajan 746e8306f98SVivek Natarajan return ret; 747e8306f98SVivek Natarajan } 748bdbfd6b5SSujith Manoharan 749bdbfd6b5SSujith Manoharan static inline int drv_set_bitrate_mask(struct ieee80211_local *local, 750bdbfd6b5SSujith Manoharan struct ieee80211_sub_if_data *sdata, 751bdbfd6b5SSujith Manoharan const struct cfg80211_bitrate_mask *mask) 752bdbfd6b5SSujith Manoharan { 753bdbfd6b5SSujith Manoharan int ret = -EOPNOTSUPP; 754bdbfd6b5SSujith Manoharan 755bdbfd6b5SSujith Manoharan might_sleep(); 756bdbfd6b5SSujith Manoharan 757f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 758f6837ba8SJohannes Berg return -EIO; 7597b7eab6fSJohannes Berg 760bdbfd6b5SSujith Manoharan trace_drv_set_bitrate_mask(local, sdata, mask); 761bdbfd6b5SSujith Manoharan if (local->ops->set_bitrate_mask) 762bdbfd6b5SSujith Manoharan ret = local->ops->set_bitrate_mask(&local->hw, 763bdbfd6b5SSujith Manoharan &sdata->vif, mask); 764bdbfd6b5SSujith Manoharan trace_drv_return_int(local, ret); 765bdbfd6b5SSujith Manoharan 766bdbfd6b5SSujith Manoharan return ret; 767bdbfd6b5SSujith Manoharan } 768bdbfd6b5SSujith Manoharan 769c68f4b89SJohannes Berg static inline void drv_set_rekey_data(struct ieee80211_local *local, 770c68f4b89SJohannes Berg struct ieee80211_sub_if_data *sdata, 771c68f4b89SJohannes Berg struct cfg80211_gtk_rekey_data *data) 772c68f4b89SJohannes Berg { 773f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 774f6837ba8SJohannes Berg return; 7757b7eab6fSJohannes Berg 776c68f4b89SJohannes Berg trace_drv_set_rekey_data(local, sdata, data); 777c68f4b89SJohannes Berg if (local->ops->set_rekey_data) 778c68f4b89SJohannes Berg local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 779c68f4b89SJohannes Berg trace_drv_return_void(local); 780c68f4b89SJohannes Berg } 781c68f4b89SJohannes Berg 782a8182929SEmmanuel Grumbach static inline void drv_event_callback(struct ieee80211_local *local, 783887da917SEmmanuel Grumbach struct ieee80211_sub_if_data *sdata, 784a8182929SEmmanuel Grumbach const struct ieee80211_event *event) 785615f7b9bSMeenakshi Venkataraman { 786a8182929SEmmanuel Grumbach trace_drv_event_callback(local, sdata, event); 787a8182929SEmmanuel Grumbach if (local->ops->event_callback) 788a8182929SEmmanuel Grumbach local->ops->event_callback(&local->hw, &sdata->vif, event); 789615f7b9bSMeenakshi Venkataraman trace_drv_return_void(local); 790615f7b9bSMeenakshi Venkataraman } 7914049e09aSJohannes Berg 7924049e09aSJohannes Berg static inline void 7934049e09aSJohannes Berg drv_release_buffered_frames(struct ieee80211_local *local, 7944049e09aSJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 7954049e09aSJohannes Berg enum ieee80211_frame_release_type reason, 7964049e09aSJohannes Berg bool more_data) 7974049e09aSJohannes Berg { 7984049e09aSJohannes Berg trace_drv_release_buffered_frames(local, &sta->sta, tids, num_frames, 7994049e09aSJohannes Berg reason, more_data); 8004049e09aSJohannes Berg if (local->ops->release_buffered_frames) 8014049e09aSJohannes Berg local->ops->release_buffered_frames(&local->hw, &sta->sta, tids, 8024049e09aSJohannes Berg num_frames, reason, 8034049e09aSJohannes Berg more_data); 8044049e09aSJohannes Berg trace_drv_return_void(local); 8054049e09aSJohannes Berg } 80640b96408SJohannes Berg 80740b96408SJohannes Berg static inline void 80840b96408SJohannes Berg drv_allow_buffered_frames(struct ieee80211_local *local, 80940b96408SJohannes Berg struct sta_info *sta, u16 tids, int num_frames, 81040b96408SJohannes Berg enum ieee80211_frame_release_type reason, 81140b96408SJohannes Berg bool more_data) 81240b96408SJohannes Berg { 81340b96408SJohannes Berg trace_drv_allow_buffered_frames(local, &sta->sta, tids, num_frames, 81440b96408SJohannes Berg reason, more_data); 81540b96408SJohannes Berg if (local->ops->allow_buffered_frames) 81640b96408SJohannes Berg local->ops->allow_buffered_frames(&local->hw, &sta->sta, 81740b96408SJohannes Berg tids, num_frames, reason, 81840b96408SJohannes Berg more_data); 81940b96408SJohannes Berg trace_drv_return_void(local); 82040b96408SJohannes Berg } 82166572cfcSVictor Goldenshtein 822a1845fc7SJohannes Berg static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, 823d4e36e55SIlan Peer struct ieee80211_sub_if_data *sdata, 82415fae341SJohannes Berg struct ieee80211_prep_tx_info *info) 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 83215fae341SJohannes Berg trace_drv_mgd_prepare_tx(local, sdata, info->duration, 83315fae341SJohannes Berg info->subtype, info->success); 834a1845fc7SJohannes Berg if (local->ops->mgd_prepare_tx) 83515fae341SJohannes Berg local->ops->mgd_prepare_tx(&local->hw, &sdata->vif, info); 83615fae341SJohannes Berg trace_drv_return_void(local); 83715fae341SJohannes Berg } 83815fae341SJohannes Berg 83915fae341SJohannes Berg static inline void drv_mgd_complete_tx(struct ieee80211_local *local, 84015fae341SJohannes Berg struct ieee80211_sub_if_data *sdata, 84115fae341SJohannes Berg struct ieee80211_prep_tx_info *info) 84215fae341SJohannes Berg { 84315fae341SJohannes Berg might_sleep(); 84415fae341SJohannes Berg 84515fae341SJohannes Berg if (!check_sdata_in_driver(sdata)) 84615fae341SJohannes Berg return; 84715fae341SJohannes Berg WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 84815fae341SJohannes Berg 84915fae341SJohannes Berg trace_drv_mgd_complete_tx(local, sdata, info->duration, 85015fae341SJohannes Berg info->subtype, info->success); 85115fae341SJohannes Berg if (local->ops->mgd_complete_tx) 85215fae341SJohannes Berg local->ops->mgd_complete_tx(&local->hw, &sdata->vif, info); 853a1845fc7SJohannes Berg trace_drv_return_void(local); 854a1845fc7SJohannes Berg } 855c3645eacSMichal Kazior 856ee10f2c7SArik Nemtsov static inline void 857ee10f2c7SArik Nemtsov drv_mgd_protect_tdls_discover(struct ieee80211_local *local, 858ee10f2c7SArik Nemtsov struct ieee80211_sub_if_data *sdata) 859ee10f2c7SArik Nemtsov { 860ee10f2c7SArik Nemtsov might_sleep(); 861ee10f2c7SArik Nemtsov 862ee10f2c7SArik Nemtsov if (!check_sdata_in_driver(sdata)) 863ee10f2c7SArik Nemtsov return; 864ee10f2c7SArik Nemtsov WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); 865ee10f2c7SArik Nemtsov 866ee10f2c7SArik Nemtsov trace_drv_mgd_protect_tdls_discover(local, sdata); 867ee10f2c7SArik Nemtsov if (local->ops->mgd_protect_tdls_discover) 868ee10f2c7SArik Nemtsov local->ops->mgd_protect_tdls_discover(&local->hw, &sdata->vif); 869ee10f2c7SArik Nemtsov trace_drv_return_void(local); 870ee10f2c7SArik Nemtsov } 871ee10f2c7SArik Nemtsov 872c3645eacSMichal Kazior static inline int drv_add_chanctx(struct ieee80211_local *local, 873c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 874c3645eacSMichal Kazior { 875c3645eacSMichal Kazior int ret = -EOPNOTSUPP; 876c3645eacSMichal Kazior 877dcae9e02SChaitanya T K might_sleep(); 878dcae9e02SChaitanya T K 879c3645eacSMichal Kazior trace_drv_add_chanctx(local, ctx); 880c3645eacSMichal Kazior if (local->ops->add_chanctx) 881c3645eacSMichal Kazior ret = local->ops->add_chanctx(&local->hw, &ctx->conf); 882c3645eacSMichal Kazior trace_drv_return_int(local, ret); 8838a61af65SJohannes Berg if (!ret) 8848a61af65SJohannes Berg ctx->driver_present = true; 885c3645eacSMichal Kazior 886c3645eacSMichal Kazior return ret; 887c3645eacSMichal Kazior } 888c3645eacSMichal Kazior 889c3645eacSMichal Kazior static inline void drv_remove_chanctx(struct ieee80211_local *local, 890c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 891c3645eacSMichal Kazior { 892dcae9e02SChaitanya T K might_sleep(); 893dcae9e02SChaitanya T K 894f6837ba8SJohannes Berg if (WARN_ON(!ctx->driver_present)) 895f6837ba8SJohannes Berg return; 896f6837ba8SJohannes Berg 897c3645eacSMichal Kazior trace_drv_remove_chanctx(local, ctx); 898c3645eacSMichal Kazior if (local->ops->remove_chanctx) 899c3645eacSMichal Kazior local->ops->remove_chanctx(&local->hw, &ctx->conf); 900c3645eacSMichal Kazior trace_drv_return_void(local); 9018a61af65SJohannes Berg ctx->driver_present = false; 902c3645eacSMichal Kazior } 903c3645eacSMichal Kazior 904c3645eacSMichal Kazior static inline void drv_change_chanctx(struct ieee80211_local *local, 905c3645eacSMichal Kazior struct ieee80211_chanctx *ctx, 906c3645eacSMichal Kazior u32 changed) 907c3645eacSMichal Kazior { 908dcae9e02SChaitanya T K might_sleep(); 909dcae9e02SChaitanya T K 910c3645eacSMichal Kazior trace_drv_change_chanctx(local, ctx, changed); 9118a61af65SJohannes Berg if (local->ops->change_chanctx) { 9128a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 913c3645eacSMichal Kazior local->ops->change_chanctx(&local->hw, &ctx->conf, changed); 9148a61af65SJohannes Berg } 915c3645eacSMichal Kazior trace_drv_return_void(local); 916c3645eacSMichal Kazior } 917c3645eacSMichal Kazior 918c3645eacSMichal Kazior static inline int drv_assign_vif_chanctx(struct ieee80211_local *local, 919c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 920c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 921c3645eacSMichal Kazior { 922c3645eacSMichal Kazior int ret = 0; 923c3645eacSMichal Kazior 924f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 925f6837ba8SJohannes Berg return -EIO; 926c3645eacSMichal Kazior 927c3645eacSMichal Kazior trace_drv_assign_vif_chanctx(local, sdata, ctx); 9288a61af65SJohannes Berg if (local->ops->assign_vif_chanctx) { 9298a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 930c3645eacSMichal Kazior ret = local->ops->assign_vif_chanctx(&local->hw, 931c3645eacSMichal Kazior &sdata->vif, 932c3645eacSMichal Kazior &ctx->conf); 9338a61af65SJohannes Berg } 934c3645eacSMichal Kazior trace_drv_return_int(local, ret); 935c3645eacSMichal Kazior 936c3645eacSMichal Kazior return ret; 937c3645eacSMichal Kazior } 938c3645eacSMichal Kazior 939c3645eacSMichal Kazior static inline void drv_unassign_vif_chanctx(struct ieee80211_local *local, 940c3645eacSMichal Kazior struct ieee80211_sub_if_data *sdata, 941c3645eacSMichal Kazior struct ieee80211_chanctx *ctx) 942c3645eacSMichal Kazior { 943dcae9e02SChaitanya T K might_sleep(); 944dcae9e02SChaitanya T K 945f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 946f6837ba8SJohannes Berg return; 947c3645eacSMichal Kazior 948c3645eacSMichal Kazior trace_drv_unassign_vif_chanctx(local, sdata, ctx); 9498a61af65SJohannes Berg if (local->ops->unassign_vif_chanctx) { 9508a61af65SJohannes Berg WARN_ON_ONCE(!ctx->driver_present); 951c3645eacSMichal Kazior local->ops->unassign_vif_chanctx(&local->hw, 952c3645eacSMichal Kazior &sdata->vif, 953c3645eacSMichal Kazior &ctx->conf); 9548a61af65SJohannes Berg } 955c3645eacSMichal Kazior trace_drv_return_void(local); 956c3645eacSMichal Kazior } 957c3645eacSMichal Kazior 95842677ed3SDenys Vlasenko int drv_switch_vif_chanctx(struct ieee80211_local *local, 9591a5f0c13SLuciano Coelho struct ieee80211_vif_chanctx_switch *vifs, 96042677ed3SDenys Vlasenko int n_vifs, enum ieee80211_chanctx_switch_mode mode); 9611a5f0c13SLuciano Coelho 9621041638fSJohannes Berg static inline int drv_start_ap(struct ieee80211_local *local, 9631041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9641041638fSJohannes Berg { 9651041638fSJohannes Berg int ret = 0; 9661041638fSJohannes Berg 967dcae9e02SChaitanya T K might_sleep(); 968dcae9e02SChaitanya T K 969f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 970f6837ba8SJohannes Berg return -EIO; 9711041638fSJohannes Berg 9721041638fSJohannes Berg trace_drv_start_ap(local, sdata, &sdata->vif.bss_conf); 9731041638fSJohannes Berg if (local->ops->start_ap) 9741041638fSJohannes Berg ret = local->ops->start_ap(&local->hw, &sdata->vif); 9751041638fSJohannes Berg trace_drv_return_int(local, ret); 9761041638fSJohannes Berg return ret; 9771041638fSJohannes Berg } 9781041638fSJohannes Berg 9791041638fSJohannes Berg static inline void drv_stop_ap(struct ieee80211_local *local, 9801041638fSJohannes Berg struct ieee80211_sub_if_data *sdata) 9811041638fSJohannes Berg { 982f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 983f6837ba8SJohannes Berg return; 9841041638fSJohannes Berg 9851041638fSJohannes Berg trace_drv_stop_ap(local, sdata); 9861041638fSJohannes Berg if (local->ops->stop_ap) 9871041638fSJohannes Berg local->ops->stop_ap(&local->hw, &sdata->vif); 9881041638fSJohannes Berg trace_drv_return_void(local); 9891041638fSJohannes Berg } 9901041638fSJohannes Berg 991cf2c92d8SEliad Peller static inline void 992cf2c92d8SEliad Peller drv_reconfig_complete(struct ieee80211_local *local, 993cf2c92d8SEliad Peller enum ieee80211_reconfig_type reconfig_type) 9949214ad7fSJohannes Berg { 9959214ad7fSJohannes Berg might_sleep(); 9969214ad7fSJohannes Berg 997cf2c92d8SEliad Peller trace_drv_reconfig_complete(local, reconfig_type); 998cf2c92d8SEliad Peller if (local->ops->reconfig_complete) 999cf2c92d8SEliad Peller local->ops->reconfig_complete(&local->hw, reconfig_type); 10009214ad7fSJohannes Berg trace_drv_return_void(local); 10019214ad7fSJohannes Berg } 10029214ad7fSJohannes Berg 1003de5fad81SYoni Divinsky static inline void 1004de5fad81SYoni Divinsky drv_set_default_unicast_key(struct ieee80211_local *local, 1005de5fad81SYoni Divinsky struct ieee80211_sub_if_data *sdata, 1006de5fad81SYoni Divinsky int key_idx) 1007de5fad81SYoni Divinsky { 1008f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1009f6837ba8SJohannes Berg return; 1010de5fad81SYoni Divinsky 1011de5fad81SYoni Divinsky WARN_ON_ONCE(key_idx < -1 || key_idx > 3); 1012de5fad81SYoni Divinsky 1013de5fad81SYoni Divinsky trace_drv_set_default_unicast_key(local, sdata, key_idx); 1014de5fad81SYoni Divinsky if (local->ops->set_default_unicast_key) 1015de5fad81SYoni Divinsky local->ops->set_default_unicast_key(&local->hw, &sdata->vif, 1016de5fad81SYoni Divinsky key_idx); 1017de5fad81SYoni Divinsky trace_drv_return_void(local); 1018de5fad81SYoni Divinsky } 1019de5fad81SYoni Divinsky 1020a65240c1SJohannes Berg #if IS_ENABLED(CONFIG_IPV6) 1021a65240c1SJohannes Berg static inline void drv_ipv6_addr_change(struct ieee80211_local *local, 1022a65240c1SJohannes Berg struct ieee80211_sub_if_data *sdata, 1023a65240c1SJohannes Berg struct inet6_dev *idev) 1024a65240c1SJohannes Berg { 1025a65240c1SJohannes Berg trace_drv_ipv6_addr_change(local, sdata); 1026a65240c1SJohannes Berg if (local->ops->ipv6_addr_change) 1027a65240c1SJohannes Berg local->ops->ipv6_addr_change(&local->hw, &sdata->vif, idev); 1028a65240c1SJohannes Berg trace_drv_return_void(local); 1029a65240c1SJohannes Berg } 1030a65240c1SJohannes Berg #endif 1031a65240c1SJohannes Berg 103273da7d5bSSimon Wunderlich static inline void 103373da7d5bSSimon Wunderlich drv_channel_switch_beacon(struct ieee80211_sub_if_data *sdata, 103473da7d5bSSimon Wunderlich struct cfg80211_chan_def *chandef) 103573da7d5bSSimon Wunderlich { 103673da7d5bSSimon Wunderlich struct ieee80211_local *local = sdata->local; 103773da7d5bSSimon Wunderlich 103873da7d5bSSimon Wunderlich if (local->ops->channel_switch_beacon) { 103973da7d5bSSimon Wunderlich trace_drv_channel_switch_beacon(local, sdata, chandef); 104073da7d5bSSimon Wunderlich local->ops->channel_switch_beacon(&local->hw, &sdata->vif, 104173da7d5bSSimon Wunderlich chandef); 104273da7d5bSSimon Wunderlich } 104373da7d5bSSimon Wunderlich } 104473da7d5bSSimon Wunderlich 10456d027bccSLuciano Coelho static inline int 10466d027bccSLuciano Coelho drv_pre_channel_switch(struct ieee80211_sub_if_data *sdata, 10476d027bccSLuciano Coelho struct ieee80211_channel_switch *ch_switch) 10486d027bccSLuciano Coelho { 10496d027bccSLuciano Coelho struct ieee80211_local *local = sdata->local; 10506d027bccSLuciano Coelho int ret = 0; 10516d027bccSLuciano Coelho 10526d027bccSLuciano Coelho if (!check_sdata_in_driver(sdata)) 10536d027bccSLuciano Coelho return -EIO; 10546d027bccSLuciano Coelho 10556d027bccSLuciano Coelho trace_drv_pre_channel_switch(local, sdata, ch_switch); 10566d027bccSLuciano Coelho if (local->ops->pre_channel_switch) 10576d027bccSLuciano Coelho ret = local->ops->pre_channel_switch(&local->hw, &sdata->vif, 10586d027bccSLuciano Coelho ch_switch); 10596d027bccSLuciano Coelho trace_drv_return_int(local, ret); 10606d027bccSLuciano Coelho return ret; 10616d027bccSLuciano Coelho } 10626d027bccSLuciano Coelho 1063f1d65583SLuciano Coelho static inline int 1064f1d65583SLuciano Coelho drv_post_channel_switch(struct ieee80211_sub_if_data *sdata) 1065f1d65583SLuciano Coelho { 1066f1d65583SLuciano Coelho struct ieee80211_local *local = sdata->local; 1067f1d65583SLuciano Coelho int ret = 0; 1068f1d65583SLuciano Coelho 1069f1d65583SLuciano Coelho if (!check_sdata_in_driver(sdata)) 1070f1d65583SLuciano Coelho return -EIO; 1071f1d65583SLuciano Coelho 1072f1d65583SLuciano Coelho trace_drv_post_channel_switch(local, sdata); 1073f1d65583SLuciano Coelho if (local->ops->post_channel_switch) 1074f1d65583SLuciano Coelho ret = local->ops->post_channel_switch(&local->hw, &sdata->vif); 1075f1d65583SLuciano Coelho trace_drv_return_int(local, ret); 1076f1d65583SLuciano Coelho return ret; 1077f1d65583SLuciano Coelho } 1078f1d65583SLuciano Coelho 1079b9cc81d8SSara Sharon static inline void 1080b9cc81d8SSara Sharon drv_abort_channel_switch(struct ieee80211_sub_if_data *sdata) 1081b9cc81d8SSara Sharon { 1082b9cc81d8SSara Sharon struct ieee80211_local *local = sdata->local; 1083b9cc81d8SSara Sharon 1084b9cc81d8SSara Sharon if (!check_sdata_in_driver(sdata)) 1085b9cc81d8SSara Sharon return; 1086b9cc81d8SSara Sharon 1087b9cc81d8SSara Sharon trace_drv_abort_channel_switch(local, sdata); 1088b9cc81d8SSara Sharon 1089b9cc81d8SSara Sharon if (local->ops->abort_channel_switch) 1090b9cc81d8SSara Sharon local->ops->abort_channel_switch(&local->hw, &sdata->vif); 1091b9cc81d8SSara Sharon } 1092b9cc81d8SSara Sharon 1093fafd2bceSSara Sharon static inline void 1094fafd2bceSSara Sharon drv_channel_switch_rx_beacon(struct ieee80211_sub_if_data *sdata, 1095fafd2bceSSara Sharon struct ieee80211_channel_switch *ch_switch) 1096fafd2bceSSara Sharon { 1097fafd2bceSSara Sharon struct ieee80211_local *local = sdata->local; 1098fafd2bceSSara Sharon 1099fafd2bceSSara Sharon if (!check_sdata_in_driver(sdata)) 1100fafd2bceSSara Sharon return; 1101fafd2bceSSara Sharon 1102fafd2bceSSara Sharon trace_drv_channel_switch_rx_beacon(local, sdata, ch_switch); 1103fafd2bceSSara Sharon if (local->ops->channel_switch_rx_beacon) 1104fafd2bceSSara Sharon local->ops->channel_switch_rx_beacon(&local->hw, &sdata->vif, 1105fafd2bceSSara Sharon ch_switch); 1106fafd2bceSSara Sharon } 1107fafd2bceSSara Sharon 110855fff501SJohannes Berg static inline int drv_join_ibss(struct ieee80211_local *local, 110955fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 111055fff501SJohannes Berg { 111155fff501SJohannes Berg int ret = 0; 111255fff501SJohannes Berg 111355fff501SJohannes Berg might_sleep(); 1114f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1115f6837ba8SJohannes Berg return -EIO; 111655fff501SJohannes Berg 111755fff501SJohannes Berg trace_drv_join_ibss(local, sdata, &sdata->vif.bss_conf); 111855fff501SJohannes Berg if (local->ops->join_ibss) 111955fff501SJohannes Berg ret = local->ops->join_ibss(&local->hw, &sdata->vif); 112055fff501SJohannes Berg trace_drv_return_int(local, ret); 112155fff501SJohannes Berg return ret; 112255fff501SJohannes Berg } 112355fff501SJohannes Berg 112455fff501SJohannes Berg static inline void drv_leave_ibss(struct ieee80211_local *local, 112555fff501SJohannes Berg struct ieee80211_sub_if_data *sdata) 112655fff501SJohannes Berg { 112755fff501SJohannes Berg might_sleep(); 1128f6837ba8SJohannes Berg if (!check_sdata_in_driver(sdata)) 1129f6837ba8SJohannes Berg return; 113055fff501SJohannes Berg 113155fff501SJohannes Berg trace_drv_leave_ibss(local, sdata); 113255fff501SJohannes Berg if (local->ops->leave_ibss) 113355fff501SJohannes Berg local->ops->leave_ibss(&local->hw, &sdata->vif); 113455fff501SJohannes Berg trace_drv_return_void(local); 113555fff501SJohannes Berg } 113655fff501SJohannes Berg 1137cca674d4SAntonio Quartulli static inline u32 drv_get_expected_throughput(struct ieee80211_local *local, 11384fdbc67aSMaxim Altshul struct sta_info *sta) 1139cca674d4SAntonio Quartulli { 1140cca674d4SAntonio Quartulli u32 ret = 0; 1141cca674d4SAntonio Quartulli 11424fdbc67aSMaxim Altshul trace_drv_get_expected_throughput(&sta->sta); 11434fdbc67aSMaxim Altshul if (local->ops->get_expected_throughput && sta->uploaded) 11444fdbc67aSMaxim Altshul ret = local->ops->get_expected_throughput(&local->hw, &sta->sta); 1145cca674d4SAntonio Quartulli trace_drv_return_u32(local, ret); 1146cca674d4SAntonio Quartulli 1147cca674d4SAntonio Quartulli return ret; 1148cca674d4SAntonio Quartulli } 1149cca674d4SAntonio Quartulli 11505b3dc42bSFelix Fietkau static inline int drv_get_txpower(struct ieee80211_local *local, 11515b3dc42bSFelix Fietkau struct ieee80211_sub_if_data *sdata, int *dbm) 11525b3dc42bSFelix Fietkau { 11535b3dc42bSFelix Fietkau int ret; 11545b3dc42bSFelix Fietkau 11555b3dc42bSFelix Fietkau if (!local->ops->get_txpower) 11565b3dc42bSFelix Fietkau return -EOPNOTSUPP; 11575b3dc42bSFelix Fietkau 11585b3dc42bSFelix Fietkau ret = local->ops->get_txpower(&local->hw, &sdata->vif, dbm); 11595b3dc42bSFelix Fietkau trace_drv_get_txpower(local, sdata, *dbm, ret); 11605b3dc42bSFelix Fietkau 11615b3dc42bSFelix Fietkau return ret; 11625b3dc42bSFelix Fietkau } 11635b3dc42bSFelix Fietkau 1164a7a6bdd0SArik Nemtsov static inline int 1165a7a6bdd0SArik Nemtsov drv_tdls_channel_switch(struct ieee80211_local *local, 1166a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1167a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta, u8 oper_class, 1168a7a6bdd0SArik Nemtsov struct cfg80211_chan_def *chandef, 1169a7a6bdd0SArik Nemtsov struct sk_buff *tmpl_skb, u32 ch_sw_tm_ie) 1170a7a6bdd0SArik Nemtsov { 1171a7a6bdd0SArik Nemtsov int ret; 1172a7a6bdd0SArik Nemtsov 1173a7a6bdd0SArik Nemtsov might_sleep(); 1174a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1175a7a6bdd0SArik Nemtsov return -EIO; 1176a7a6bdd0SArik Nemtsov 1177a7a6bdd0SArik Nemtsov if (!local->ops->tdls_channel_switch) 1178a7a6bdd0SArik Nemtsov return -EOPNOTSUPP; 1179a7a6bdd0SArik Nemtsov 1180a7a6bdd0SArik Nemtsov trace_drv_tdls_channel_switch(local, sdata, sta, oper_class, chandef); 1181a7a6bdd0SArik Nemtsov ret = local->ops->tdls_channel_switch(&local->hw, &sdata->vif, sta, 1182a7a6bdd0SArik Nemtsov oper_class, chandef, tmpl_skb, 1183a7a6bdd0SArik Nemtsov ch_sw_tm_ie); 1184a7a6bdd0SArik Nemtsov trace_drv_return_int(local, ret); 1185a7a6bdd0SArik Nemtsov return ret; 1186a7a6bdd0SArik Nemtsov } 1187a7a6bdd0SArik Nemtsov 1188a7a6bdd0SArik Nemtsov static inline void 1189a7a6bdd0SArik Nemtsov drv_tdls_cancel_channel_switch(struct ieee80211_local *local, 1190a7a6bdd0SArik Nemtsov struct ieee80211_sub_if_data *sdata, 1191a7a6bdd0SArik Nemtsov struct ieee80211_sta *sta) 1192a7a6bdd0SArik Nemtsov { 1193a7a6bdd0SArik Nemtsov might_sleep(); 1194a7a6bdd0SArik Nemtsov if (!check_sdata_in_driver(sdata)) 1195a7a6bdd0SArik Nemtsov return; 1196a7a6bdd0SArik Nemtsov 1197a7a6bdd0SArik Nemtsov if (!local->ops->tdls_cancel_channel_switch) 1198a7a6bdd0SArik Nemtsov return; 1199a7a6bdd0SArik Nemtsov 1200a7a6bdd0SArik Nemtsov trace_drv_tdls_cancel_channel_switch(local, sdata, sta); 1201a7a6bdd0SArik Nemtsov local->ops->tdls_cancel_channel_switch(&local->hw, &sdata->vif, sta); 1202a7a6bdd0SArik Nemtsov trace_drv_return_void(local); 1203a7a6bdd0SArik Nemtsov } 1204a7a6bdd0SArik Nemtsov 12058a4d32f3SArik Nemtsov static inline void 12068a4d32f3SArik Nemtsov drv_tdls_recv_channel_switch(struct ieee80211_local *local, 12078a4d32f3SArik Nemtsov struct ieee80211_sub_if_data *sdata, 12088a4d32f3SArik Nemtsov struct ieee80211_tdls_ch_sw_params *params) 12098a4d32f3SArik Nemtsov { 12108a4d32f3SArik Nemtsov trace_drv_tdls_recv_channel_switch(local, sdata, params); 12118a4d32f3SArik Nemtsov if (local->ops->tdls_recv_channel_switch) 12128a4d32f3SArik Nemtsov local->ops->tdls_recv_channel_switch(&local->hw, &sdata->vif, 12138a4d32f3SArik Nemtsov params); 12148a4d32f3SArik Nemtsov trace_drv_return_void(local); 12158a4d32f3SArik Nemtsov } 12168a4d32f3SArik Nemtsov 1217e7881bd5SJohannes Berg static inline void drv_wake_tx_queue(struct ieee80211_local *local, 1218e7881bd5SJohannes Berg struct txq_info *txq) 1219ba8c3d6fSFelix Fietkau { 1220e7881bd5SJohannes Berg struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); 1221e7881bd5SJohannes Berg 12224856bfd2SFelix Fietkau if (local->in_reconfig) 12234856bfd2SFelix Fietkau return; 12244856bfd2SFelix Fietkau 1225e7881bd5SJohannes Berg if (!check_sdata_in_driver(sdata)) 1226e7881bd5SJohannes Berg return; 1227e7881bd5SJohannes Berg 1228e7881bd5SJohannes Berg trace_drv_wake_tx_queue(local, sdata, txq); 1229e7881bd5SJohannes Berg local->ops->wake_tx_queue(&local->hw, &txq->txq); 1230ba8c3d6fSFelix Fietkau } 1231ba8c3d6fSFelix Fietkau 123218667600SToke Høiland-Jørgensen static inline void schedule_and_wake_txq(struct ieee80211_local *local, 123318667600SToke Høiland-Jørgensen struct txq_info *txqi) 123418667600SToke Høiland-Jørgensen { 1235390298e8SToke Høiland-Jørgensen ieee80211_schedule_txq(&local->hw, &txqi->txq); 123618667600SToke Høiland-Jørgensen drv_wake_tx_queue(local, txqi); 123718667600SToke Høiland-Jørgensen } 123818667600SToke Høiland-Jørgensen 12399739fe29SSara Sharon static inline int drv_can_aggregate_in_amsdu(struct ieee80211_local *local, 12409739fe29SSara Sharon struct sk_buff *head, 12419739fe29SSara Sharon struct sk_buff *skb) 12429739fe29SSara Sharon { 12439739fe29SSara Sharon if (!local->ops->can_aggregate_in_amsdu) 12449739fe29SSara Sharon return true; 12459739fe29SSara Sharon 12469739fe29SSara Sharon return local->ops->can_aggregate_in_amsdu(&local->hw, head, skb); 12479739fe29SSara Sharon } 12489739fe29SSara Sharon 1249bc847970SPradeep Kumar Chitrapu static inline int 1250bc847970SPradeep Kumar Chitrapu drv_get_ftm_responder_stats(struct ieee80211_local *local, 1251bc847970SPradeep Kumar Chitrapu struct ieee80211_sub_if_data *sdata, 1252bc847970SPradeep Kumar Chitrapu struct cfg80211_ftm_responder_stats *ftm_stats) 1253bc847970SPradeep Kumar Chitrapu { 1254bc847970SPradeep Kumar Chitrapu u32 ret = -EOPNOTSUPP; 1255bc847970SPradeep Kumar Chitrapu 1256bc847970SPradeep Kumar Chitrapu if (local->ops->get_ftm_responder_stats) 1257bc847970SPradeep Kumar Chitrapu ret = local->ops->get_ftm_responder_stats(&local->hw, 1258bc847970SPradeep Kumar Chitrapu &sdata->vif, 1259bc847970SPradeep Kumar Chitrapu ftm_stats); 1260bc847970SPradeep Kumar Chitrapu trace_drv_get_ftm_responder_stats(local, sdata, ftm_stats); 1261bc847970SPradeep Kumar Chitrapu 1262bc847970SPradeep Kumar Chitrapu return ret; 1263bc847970SPradeep Kumar Chitrapu } 1264bc847970SPradeep Kumar Chitrapu 1265cee7013bSJohannes Berg static inline int drv_start_pmsr(struct ieee80211_local *local, 1266cee7013bSJohannes Berg struct ieee80211_sub_if_data *sdata, 1267cee7013bSJohannes Berg struct cfg80211_pmsr_request *request) 1268cee7013bSJohannes Berg { 1269cee7013bSJohannes Berg int ret = -EOPNOTSUPP; 1270cee7013bSJohannes Berg 1271cee7013bSJohannes Berg might_sleep(); 1272cee7013bSJohannes Berg if (!check_sdata_in_driver(sdata)) 1273cee7013bSJohannes Berg return -EIO; 1274cee7013bSJohannes Berg 1275cee7013bSJohannes Berg trace_drv_start_pmsr(local, sdata); 1276cee7013bSJohannes Berg 1277cee7013bSJohannes Berg if (local->ops->start_pmsr) 1278cee7013bSJohannes Berg ret = local->ops->start_pmsr(&local->hw, &sdata->vif, request); 1279cee7013bSJohannes Berg trace_drv_return_int(local, ret); 1280cee7013bSJohannes Berg 1281cee7013bSJohannes Berg return ret; 1282cee7013bSJohannes Berg } 1283cee7013bSJohannes Berg 1284cee7013bSJohannes Berg static inline void drv_abort_pmsr(struct ieee80211_local *local, 1285cee7013bSJohannes Berg struct ieee80211_sub_if_data *sdata, 1286cee7013bSJohannes Berg struct cfg80211_pmsr_request *request) 1287cee7013bSJohannes Berg { 1288cee7013bSJohannes Berg trace_drv_abort_pmsr(local, sdata); 1289cee7013bSJohannes Berg 1290cee7013bSJohannes Berg might_sleep(); 1291cee7013bSJohannes Berg if (!check_sdata_in_driver(sdata)) 1292cee7013bSJohannes Berg return; 1293cee7013bSJohannes Berg 1294cee7013bSJohannes Berg if (local->ops->abort_pmsr) 1295cee7013bSJohannes Berg local->ops->abort_pmsr(&local->hw, &sdata->vif, request); 1296cee7013bSJohannes Berg trace_drv_return_void(local); 1297cee7013bSJohannes Berg } 1298cee7013bSJohannes Berg 1299708d50edSAyala Beker static inline int drv_start_nan(struct ieee80211_local *local, 1300708d50edSAyala Beker struct ieee80211_sub_if_data *sdata, 1301708d50edSAyala Beker struct cfg80211_nan_conf *conf) 1302708d50edSAyala Beker { 1303708d50edSAyala Beker int ret; 1304708d50edSAyala Beker 1305708d50edSAyala Beker might_sleep(); 1306708d50edSAyala Beker check_sdata_in_driver(sdata); 1307708d50edSAyala Beker 1308708d50edSAyala Beker trace_drv_start_nan(local, sdata, conf); 1309708d50edSAyala Beker ret = local->ops->start_nan(&local->hw, &sdata->vif, conf); 1310708d50edSAyala Beker trace_drv_return_int(local, ret); 1311708d50edSAyala Beker return ret; 1312708d50edSAyala Beker } 1313708d50edSAyala Beker 1314708d50edSAyala Beker static inline void drv_stop_nan(struct ieee80211_local *local, 1315708d50edSAyala Beker struct ieee80211_sub_if_data *sdata) 1316708d50edSAyala Beker { 1317708d50edSAyala Beker might_sleep(); 1318708d50edSAyala Beker check_sdata_in_driver(sdata); 1319708d50edSAyala Beker 1320708d50edSAyala Beker trace_drv_stop_nan(local, sdata); 1321708d50edSAyala Beker local->ops->stop_nan(&local->hw, &sdata->vif); 1322708d50edSAyala Beker trace_drv_return_void(local); 1323708d50edSAyala Beker } 1324708d50edSAyala Beker 13255953ff6dSAyala Beker static inline int drv_nan_change_conf(struct ieee80211_local *local, 13265953ff6dSAyala Beker struct ieee80211_sub_if_data *sdata, 13275953ff6dSAyala Beker struct cfg80211_nan_conf *conf, 13285953ff6dSAyala Beker u32 changes) 13295953ff6dSAyala Beker { 13305953ff6dSAyala Beker int ret; 13315953ff6dSAyala Beker 13325953ff6dSAyala Beker might_sleep(); 13335953ff6dSAyala Beker check_sdata_in_driver(sdata); 13345953ff6dSAyala Beker 13355953ff6dSAyala Beker if (!local->ops->nan_change_conf) 13365953ff6dSAyala Beker return -EOPNOTSUPP; 13375953ff6dSAyala Beker 13385953ff6dSAyala Beker trace_drv_nan_change_conf(local, sdata, conf, changes); 13395953ff6dSAyala Beker ret = local->ops->nan_change_conf(&local->hw, &sdata->vif, conf, 13405953ff6dSAyala Beker changes); 13415953ff6dSAyala Beker trace_drv_return_int(local, ret); 13425953ff6dSAyala Beker 13435953ff6dSAyala Beker return ret; 13445953ff6dSAyala Beker } 13455953ff6dSAyala Beker 1346167e33f4SAyala Beker static inline int drv_add_nan_func(struct ieee80211_local *local, 1347167e33f4SAyala Beker struct ieee80211_sub_if_data *sdata, 1348167e33f4SAyala Beker const struct cfg80211_nan_func *nan_func) 1349167e33f4SAyala Beker { 1350167e33f4SAyala Beker int ret; 1351167e33f4SAyala Beker 1352167e33f4SAyala Beker might_sleep(); 1353167e33f4SAyala Beker check_sdata_in_driver(sdata); 1354167e33f4SAyala Beker 1355167e33f4SAyala Beker if (!local->ops->add_nan_func) 1356167e33f4SAyala Beker return -EOPNOTSUPP; 1357167e33f4SAyala Beker 1358167e33f4SAyala Beker trace_drv_add_nan_func(local, sdata, nan_func); 1359167e33f4SAyala Beker ret = local->ops->add_nan_func(&local->hw, &sdata->vif, nan_func); 1360167e33f4SAyala Beker trace_drv_return_int(local, ret); 1361167e33f4SAyala Beker 1362167e33f4SAyala Beker return ret; 1363167e33f4SAyala Beker } 1364167e33f4SAyala Beker 1365167e33f4SAyala Beker static inline void drv_del_nan_func(struct ieee80211_local *local, 1366167e33f4SAyala Beker struct ieee80211_sub_if_data *sdata, 1367167e33f4SAyala Beker u8 instance_id) 1368167e33f4SAyala Beker { 1369167e33f4SAyala Beker might_sleep(); 1370167e33f4SAyala Beker check_sdata_in_driver(sdata); 1371167e33f4SAyala Beker 1372167e33f4SAyala Beker trace_drv_del_nan_func(local, sdata, instance_id); 1373167e33f4SAyala Beker if (local->ops->del_nan_func) 1374167e33f4SAyala Beker local->ops->del_nan_func(&local->hw, &sdata->vif, instance_id); 1375167e33f4SAyala Beker trace_drv_return_void(local); 1376167e33f4SAyala Beker } 1377167e33f4SAyala Beker 1378370f51d5STamizh chelvam static inline int drv_set_tid_config(struct ieee80211_local *local, 1379370f51d5STamizh chelvam struct ieee80211_sub_if_data *sdata, 1380370f51d5STamizh chelvam struct ieee80211_sta *sta, 1381370f51d5STamizh chelvam struct cfg80211_tid_config *tid_conf) 1382370f51d5STamizh chelvam { 1383370f51d5STamizh chelvam int ret; 1384370f51d5STamizh chelvam 1385370f51d5STamizh chelvam might_sleep(); 1386370f51d5STamizh chelvam ret = local->ops->set_tid_config(&local->hw, &sdata->vif, sta, 1387370f51d5STamizh chelvam tid_conf); 1388370f51d5STamizh chelvam trace_drv_return_int(local, ret); 1389370f51d5STamizh chelvam 1390370f51d5STamizh chelvam return ret; 1391370f51d5STamizh chelvam } 1392370f51d5STamizh chelvam 1393370f51d5STamizh chelvam static inline int drv_reset_tid_config(struct ieee80211_local *local, 1394370f51d5STamizh chelvam struct ieee80211_sub_if_data *sdata, 139560c2ef0eSSergey Matyukevich struct ieee80211_sta *sta, u8 tids) 1396370f51d5STamizh chelvam { 1397370f51d5STamizh chelvam int ret; 1398370f51d5STamizh chelvam 1399370f51d5STamizh chelvam might_sleep(); 140060c2ef0eSSergey Matyukevich ret = local->ops->reset_tid_config(&local->hw, &sdata->vif, sta, tids); 1401370f51d5STamizh chelvam trace_drv_return_int(local, ret); 1402370f51d5STamizh chelvam 1403370f51d5STamizh chelvam return ret; 1404370f51d5STamizh chelvam } 14056aea26ceSFelix Fietkau 14066aea26ceSFelix Fietkau static inline void drv_update_vif_offload(struct ieee80211_local *local, 14076aea26ceSFelix Fietkau struct ieee80211_sub_if_data *sdata) 14086aea26ceSFelix Fietkau { 14096aea26ceSFelix Fietkau might_sleep(); 14106aea26ceSFelix Fietkau check_sdata_in_driver(sdata); 14116aea26ceSFelix Fietkau 14126aea26ceSFelix Fietkau if (!local->ops->update_vif_offload) 14136aea26ceSFelix Fietkau return; 14146aea26ceSFelix Fietkau 14156aea26ceSFelix Fietkau trace_drv_update_vif_offload(local, sdata); 14166aea26ceSFelix Fietkau local->ops->update_vif_offload(&local->hw, &sdata->vif); 14176aea26ceSFelix Fietkau trace_drv_return_void(local); 14186aea26ceSFelix Fietkau } 14196aea26ceSFelix Fietkau 14201ff4e8f2SFelix Fietkau static inline void drv_sta_set_4addr(struct ieee80211_local *local, 14211ff4e8f2SFelix Fietkau struct ieee80211_sub_if_data *sdata, 14221ff4e8f2SFelix Fietkau struct ieee80211_sta *sta, bool enabled) 14231ff4e8f2SFelix Fietkau { 14241ff4e8f2SFelix Fietkau sdata = get_bss_sdata(sdata); 14251ff4e8f2SFelix Fietkau if (!check_sdata_in_driver(sdata)) 14261ff4e8f2SFelix Fietkau return; 14271ff4e8f2SFelix Fietkau 14281ff4e8f2SFelix Fietkau trace_drv_sta_set_4addr(local, sdata, sta, enabled); 14291ff4e8f2SFelix Fietkau if (local->ops->sta_set_4addr) 14301ff4e8f2SFelix Fietkau local->ops->sta_set_4addr(&local->hw, &sdata->vif, sta, enabled); 14311ff4e8f2SFelix Fietkau trace_drv_return_void(local); 14321ff4e8f2SFelix Fietkau } 14331ff4e8f2SFelix Fietkau 143480a915ecSFelix Fietkau static inline void drv_sta_set_decap_offload(struct ieee80211_local *local, 143580a915ecSFelix Fietkau struct ieee80211_sub_if_data *sdata, 143680a915ecSFelix Fietkau struct ieee80211_sta *sta, 143780a915ecSFelix Fietkau bool enabled) 143880a915ecSFelix Fietkau { 143980a915ecSFelix Fietkau sdata = get_bss_sdata(sdata); 144080a915ecSFelix Fietkau if (!check_sdata_in_driver(sdata)) 144180a915ecSFelix Fietkau return; 144280a915ecSFelix Fietkau 144380a915ecSFelix Fietkau trace_drv_sta_set_decap_offload(local, sdata, sta, enabled); 144480a915ecSFelix Fietkau if (local->ops->sta_set_decap_offload) 144580a915ecSFelix Fietkau local->ops->sta_set_decap_offload(&local->hw, &sdata->vif, sta, 144680a915ecSFelix Fietkau enabled); 144780a915ecSFelix Fietkau trace_drv_return_void(local); 144880a915ecSFelix Fietkau } 144980a915ecSFelix Fietkau 1450f5a4c24eSLorenzo Bianconi static inline void drv_add_twt_setup(struct ieee80211_local *local, 1451f5a4c24eSLorenzo Bianconi struct ieee80211_sub_if_data *sdata, 1452f5a4c24eSLorenzo Bianconi struct ieee80211_sta *sta, 1453f5a4c24eSLorenzo Bianconi struct ieee80211_twt_setup *twt) 1454f5a4c24eSLorenzo Bianconi { 1455f5a4c24eSLorenzo Bianconi struct ieee80211_twt_params *twt_agrt; 1456f5a4c24eSLorenzo Bianconi 1457f5a4c24eSLorenzo Bianconi might_sleep(); 1458f5a4c24eSLorenzo Bianconi 1459f5a4c24eSLorenzo Bianconi if (!check_sdata_in_driver(sdata)) 1460f5a4c24eSLorenzo Bianconi return; 1461f5a4c24eSLorenzo Bianconi 1462f5a4c24eSLorenzo Bianconi twt_agrt = (void *)twt->params; 1463f5a4c24eSLorenzo Bianconi 1464f5a4c24eSLorenzo Bianconi trace_drv_add_twt_setup(local, sta, twt, twt_agrt); 1465f5a4c24eSLorenzo Bianconi local->ops->add_twt_setup(&local->hw, sta, twt); 1466f5a4c24eSLorenzo Bianconi trace_drv_return_void(local); 1467f5a4c24eSLorenzo Bianconi } 1468f5a4c24eSLorenzo Bianconi 1469f5a4c24eSLorenzo Bianconi static inline void drv_twt_teardown_request(struct ieee80211_local *local, 1470f5a4c24eSLorenzo Bianconi struct ieee80211_sub_if_data *sdata, 1471f5a4c24eSLorenzo Bianconi struct ieee80211_sta *sta, 1472f5a4c24eSLorenzo Bianconi u8 flowid) 1473f5a4c24eSLorenzo Bianconi { 1474f5a4c24eSLorenzo Bianconi might_sleep(); 1475f5a4c24eSLorenzo Bianconi if (!check_sdata_in_driver(sdata)) 1476f5a4c24eSLorenzo Bianconi return; 1477f5a4c24eSLorenzo Bianconi 1478f5a4c24eSLorenzo Bianconi if (!local->ops->twt_teardown_request) 1479f5a4c24eSLorenzo Bianconi return; 1480f5a4c24eSLorenzo Bianconi 1481f5a4c24eSLorenzo Bianconi trace_drv_twt_teardown_request(local, sta, flowid); 1482f5a4c24eSLorenzo Bianconi local->ops->twt_teardown_request(&local->hw, sta, flowid); 1483f5a4c24eSLorenzo Bianconi trace_drv_return_void(local); 1484f5a4c24eSLorenzo Bianconi } 1485f5a4c24eSLorenzo Bianconi 1486*d787a3e3SFelix Fietkau static inline int drv_net_fill_forward_path(struct ieee80211_local *local, 1487*d787a3e3SFelix Fietkau struct ieee80211_sub_if_data *sdata, 1488*d787a3e3SFelix Fietkau struct ieee80211_sta *sta, 1489*d787a3e3SFelix Fietkau struct net_device_path_ctx *ctx, 1490*d787a3e3SFelix Fietkau struct net_device_path *path) 1491*d787a3e3SFelix Fietkau { 1492*d787a3e3SFelix Fietkau int ret = -EOPNOTSUPP; 1493*d787a3e3SFelix Fietkau 1494*d787a3e3SFelix Fietkau sdata = get_bss_sdata(sdata); 1495*d787a3e3SFelix Fietkau if (!check_sdata_in_driver(sdata)) 1496*d787a3e3SFelix Fietkau return -EIO; 1497*d787a3e3SFelix Fietkau 1498*d787a3e3SFelix Fietkau trace_drv_net_fill_forward_path(local, sdata, sta); 1499*d787a3e3SFelix Fietkau if (local->ops->net_fill_forward_path) 1500*d787a3e3SFelix Fietkau ret = local->ops->net_fill_forward_path(&local->hw, 1501*d787a3e3SFelix Fietkau &sdata->vif, sta, 1502*d787a3e3SFelix Fietkau ctx, path); 1503*d787a3e3SFelix Fietkau trace_drv_return_int(local, ret); 1504*d787a3e3SFelix Fietkau 1505*d787a3e3SFelix Fietkau return ret; 1506*d787a3e3SFelix Fietkau } 1507*d787a3e3SFelix Fietkau 150824487981SJohannes Berg #endif /* __MAC80211_DRIVER_OPS */ 1509